如何限制输入中的位数?

How can I limit the amount of digits in an input?

我是一名计算机科学课程的学生,为了进行部分评估,我们必须编写一个程序,从用户那里获取 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!")

等等

我必须将输入保持为整数,以便程序其余部分的某些计算能够正常工作,但是当我 运行 程序时,出现 "object of type 'int' has no len()" 错误。我假设它指的是它是一个整数并且没有长度。有什么方法可以将 'a' 保留为整数但将长度限制为 1 位数字?

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

您必须将 int 转换为字符串,因为 int 没有长度 属性。此外,您正在检查数字是否长于 1 两次,所以我将 SECOND NUMBER 检查切换为 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

首先,我假设您正在使用 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。

你从未说明你是在 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)

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

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

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 为非数字输入和诸如此类的东西添加保护

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

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'))