【问题标题】:How can I limit the amount of digits in an input?如何限制输入中的位数?
【发布时间】:2015-04-15 16:50:54
【问题描述】:

我是一名正在学习计算机科学课程的学生,为了进行部分评估,我们必须编写一个程序,该程序将从用户那里获取 10 位数字,并使用它们计算第 11 个数字以生成 ISBN。用户输入的数字必须限制为一位,如果输入多于一位,则应显示错误消息。这是我正在使用的代码:

print('Please enter your 10 digit number')
a = int(input("FIRST NUMBER: "))
aa = (a*11)
if len(a) > 1:
    print ("Error. Only 1 digit allowed!")
b = int(input("SECOND NUMBER: "))
bb = (b*10)
if len(a) > 1:
    print ("Error. Only 1 digit allowed!")

等等。

我必须将输入保持为整数,以便程序其余部分中的一些计算工作,但是当我运行程序时,错误提示“'int' 类型的对象没有 len()”。我假设它指的是它是一个整数并且没有长度的事实。有什么方法可以将“a”保留为整数但将长度限制为 1 位?

(我也知道可能有更高效的程序编写方式,但我对python的了解相当有限)

【问题讨论】:

  • aa = (a*11)bb = (b*10) 完全是假的,它们强制用户输入一个数字,然后将该数字乘以 10 或 11;而不是在调用 input() 时迭代 10 或 11 次

标签: python input limit digit


【解决方案1】:

您必须将 int 转换为字符串,因为 int 没有长度属性。此外,您正在检查数字是否超过 1 两次,所以我将第二个数字检查切换为 b

print('Please enter your 10 digit number')
a = raw_input("FIRST NUMBER: ")
if len(a) > 1:
    print ("Error. Only 1 digit allowed!")
a = int(a)
aa = (a*10)

b = raw_input("SECOND NUMBER: ")
if len(b) > 1:
    print ("Error. Only 1 digit allowed!")
b = int(b)
bb = (b*10)

或更简单地说:

您可以询问数字并继续询问,直到长度为 10 并且输入为数字

num = raw_input('Please enter your 10 digit number:')
while len(num) != 10 or (not num.isdigit()):
    print 'Not a 10 digit number'
    num = raw_input('Please enter your 10 digit number:')
num = int(num)
print 'The final number is: ', num

【讨论】:

  • 在将输入转换为 int 之前最好检查一下 - 所有这些 str(int(str)) 的东西有点傻。
  • aa = (a*11)bb = (b*10) 是伪造的,它们强制用户输入一位数字,然后将其乘以 10 或 11;而不是在调用 input() 时迭代 10 或 11 次
  • @smci 我想知道他为什么把它放在那里。我也添加了一个更简单的解决方案
【解决方案2】:

我建议创建一个函数来处理提示,然后在您的代码中调用它。这是一个简化的例子:

def single_num(prompt):
    num = ""
    while True:
        num = raw_input(prompt)

        if len(num) == 1:
            try:
                return int(num)
            except ValueError:
                print "Error, you must enter a number"
        else:
            print "Try again, now with a single number"

这将需要一个提示,并一遍又一遍地询问它,直到它收到一个长度为 1 的字符串。为了使这更加用户友好,您可以使用 try...except 添加保护以用于非数字输入等

【讨论】:

    【解决方案3】:

    您从未说过您使用的是 Windows 还是 Linux,下面列出的代码适用于 Windows(因为我现在使用的是 Windows 机器,无法在 Linux 上测试等效代码)。

    # For windows
    import msvcrt
    print('Please enter your 10 digit number')
    print('First number: ')
    a = int(msvcrt.getch())
    print(a)
    

    .getch()msvcrt 的调用仅从终端输入中获取单个字符。您还应该将对 int() 的调用包装在 try/except 块中,以防止您的应用程序在获取非整数输入时崩溃。

    【讨论】:

    • 这假设用户不能犯错误,这是不好的做法
    • 因此注释将 int 调用包装在代码 sn-p 下方的 try/except 块中。
    • 如果非整数。如果用户输入错误的 int 怎么办?
    • 他们不应该一次输入 1 个字符,而是允许输入 ISBN 的 10 位数字,然后您才进行处理。如果您假设用户将一直输入不正确的值,那么您应该有一个多步骤过程要求他们输入字符,然后按 y/n 如果那确实是正确的。如果你这么说是因为我的 sn-p 只有 1 次调用 getch() 而不是 10 次,那是因为这是最好留给 OP 的练习。
    • 问题的标题是“如何限制输入中的位数?”由于 OP 只想一次读取 1 个字符,我看不到如何编写一个完整的应用程序。
    【解决方案4】:

    首先,我假设您使用的是 3.x。其次,如果您使用的是 2.x,则不能在数字上使用 len

    这是我的建议:

    print('Please enter your 10 digit number')
    
    number = ''
    
    for x in range(1,11):
        digit = input('Please enter digit ' + str(x) + ': ')
        while len(digit) != 1:
            # digit is either empty or not a single digit so keep asking
            digit = input('That was not 1 digit. Please enter digit ' + str(x) + ': ')        
        number += digit # digit is a single digit so add to number
    
    # do the rest
    

    将所有数字保留在str 中更有意义,因为您可以稍后根据需要将它们拆分出来,例如number[0] 将是第一位,number[1] 将是第二位。

    如果您可以调整您的程序,使其不必显式使用 a、b、c、d 等,而是使用切片,那么构建起来将非常简单。

    显然,如果您可以使用一个完整的 10 位数字,那么最好的方法是:

    number = input('Please enter your 10 digit number: ')
    
    while len(number) != 10:
        number = input('That was not a 10 digit number. Please enter your 10 digit number ')
    

    作为最后的手段,如果您绝对必须为每个数字设置单独的变量名,您可以使用execeval

    var_names = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] # add more as needed
    
    for var, num in var_names:
        exec(var + ' = input("Please enter digit " + str(num) + ": ")')
        while eval('len(' + var + ')') != 1:
            exec(var + ' = input("That was not a single digit. Please enter digit " + str(num) + ": ")')
    

    这将使您的变量 a、b、c 和 d 等于给定的数字。

    【讨论】:

    • 我看到你看了我的想法:p
    • @Heinst hah,有点是也不是。我本来打算写它,然后看到他想要单个数字并且不认为,然后认为我应该给出一个完整的答案(并意识到你也提到了它)。如果你愿意,我可以删除并给你信用吗?我只是喜欢把所有东西都放在一个地方。
    • 不,没关系,我只是在胡闹,我不在乎:p
    【解决方案5】:

    这可能是最干净与验证包装器有关的。

    def validator(testfunc):
        def wrap(func):
            def wrapped(*args, **kwargs):
                result = func(*args, **kwargs)
                pass, *failfunc = testfunc(result)
                it pass:
                    return result
                elif failfunc:
                    failfunc[0]()
            return wrapped
        return wrap
    
    def ten_digits(num):
        pass = False
        if len(num) != 10:
            msg = "{} is not of length 10".format(num)
        elif not num.isdigit():
            msg = "{} is not a number".format(num)
        else:
            pass = True
        def failfunc():
            raise ValueError(msg)
        response = (pass, None if pass else failfunc)
        return response
    
    valid_input = validator(ten_digits)(input) # or raw_input in Python2
    response = valid_input("Enter your 10 digit number: ")
    

    这可能有点过度设计,但它具有令人难以置信的可重用性(需要验证一组不同的测试?写一个新的ten_digits 类比!)并且非常可配置(想要你的失败函数有不同的行为?把它写在!)这意味着您可以执行以下操作:

    ISBN = validator(ten_digits)(input)("ISBN# = ")
    title = validator(max_50_chars)(input)("Title = ")
    author = validator(no_digits)(input)("Author = ")
    price = decimal.Decimal(validator(float_between_1_and_50)(input)(
            "Price = ")).quantize(decimal.Decimal('1.00'))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2019-06-06
      • 1970-01-01
      相关资源
      最近更新 更多