【问题标题】:Python: Validating earlier in the codePython:在代码的前面进行验证
【发布时间】:2015-01-25 18:09:10
【问题描述】:

这是我的代码,是针对儿童的测验。我需要帮助的是,在代码向用户询问其类之后,它应该立即验证输入是否有效,而不是最终执行并显示消息 “抱歉,由于您输入的课程无效,我们无法保存您的数据。” 我尝试将整个 if、elif 和 else 语句移到后面:

users_class = int(input("Which class are you in? (1,2 or 3)"))

但这无济于事。任何帮助将不胜感激:)

import time
import random
import math
import operator as op

def test():
    num1 = random.randint(1, 10)
    num2 = random.randint(1, num1)

    ops = {
        '+': op.add,  
        '-': op.sub,
        '*': op.mul,
        }

    keys = list(ops.keys()) 
    rand_key = random.choice(keys)  
    operation = ops[rand_key]  

    correct_result = operation(num1, num2)

    print ("What is {} {} {}?".format(num1, rand_key, num2))
    user_answer= int(input("Your answer: "))

    if user_answer != correct_result:
        print ("Incorrect. The right answer is {}".format(correct_result))
        return False
    else:
        print("Correct!")
        return True

username=input("What is your name?")

print ("Hi {}! Wellcome to the Arithmetic quiz...".format(username))

users_class = int(input("Which class are you in? (1,2 or 3)"))

input("Press Enter to Start...")
start = time.time()

correct_answers = 0
num_questions = 10

for i in range(num_questions):
    if test():
        correct_answers +=1

print("{}: You got {}/{} {} correct.".format(username, correct_answers,  num_questions,
'question' if (correct_answers==1) else 'questions'))

end = time.time()
etime = end - start
timeTaken = round(etime)

print ("You completed the quiz in {} seconds.".format(timeTaken))

if users_class == 1:
    with open("class1.txt","a+") as f:
        f.write("   {}:Scored {} in {} seconds.".format(username,correct_answers,timeTaken))

elif users_class == 2:
    with open("class2.txt","a+") as f:
        f.write("   {}:Scored {} in {} seconds.".format(username,correct_answers,timeTaken))

elif users_class == 3:
    with open("class3.txt","a+") as f:
        f.write("   {}:Scored {} in {} seconds.".format(username,correct_answers,timeTaken))
else:
print("Sorry, we can not save your data as the class you entered is not valid.")

【问题讨论】:

  • 有效是指 1、2 还是 3 还是整数?另外,当您将 if 移到输入之后会发生什么(不)?
  • 它必须是 1,2 或 3。我收到此错误 - “NameError: name 'correct_answers' is not defined”
  • 然后将 correct_answers 和 timeTaken 也移到 if 之前。
  • 我试过了。但问题仍然被问到。如果此人输入无效值,我希望它结束​​
  • 但是Sorry, we can not save your data as the class you entered is not valid. 消息是否出现在问题之前?

标签: python validation


【解决方案1】:

您应该在input 之后立即检查输入是否有效,如下所示:

import sys

users_class = int(input("Which class are you in? (1,2 or 3)"))

if users_class not in {1,2,3}:
    print("Sorry, you must enter either a 1, 2, or 3!")
    sys.exit(1)

注意sys.exit(1) 调用将退出程序。

现在,这不是最可靠的做事方式。例如,如果用户输入的不是数字,int(...) 将引发异常,因为它不能将“dog”等转换为整数。此外,您可能更希望程序继续请求有效输入,而不是仅仅停止和退出。下面是一些可以做到这一点的代码:

while True:
    try:
        # try to convert the user's input to an integer
        users_class = int(input("Which class are you in? (1,2 or 3)"))
    except ValueError:
        # oh no!, the user didn't give us something that could be converted
        # to an int!
        print("Please enter a number!")
    else:
        # Ok, we have an integer... is it 1, 2, or 3?
        if users_class not in {1,2,3}:
            print("Please enter a number in {1,2,3}!")
        else:
            # the input was 1,2, or 3! break out of the infinite while...
            break

print(users_class)

【讨论】:

  • 谢谢!效果很好。但最后一个问题。如何只允许用户在测验期间输入整数?
  • @Hasiba 相同的想法,只是没有if users_class not in ... 部分。有关详细说明,请参阅this answer。由于您将在整个程序中多次执行此操作,因此将输入验证代码转换为函数可能是个好主意。该链接给出了一个这样的例子。
【解决方案2】:

您只需要在关于用户所在班级的问题之后添加一个额外的条件。通常我们会在此处设置一个循环,以便再次询问用户是否输入了无效响应。

print ("Hi {}! Welcome to the Arithmetic quiz...".format(username))
while True:
    users_class = int(input("Which class are you in? (1,2 or 3)"))
    if users_class in [1, 2, 3]:
        break
    print('Please make sure you enter a class from 1 to 3')

【讨论】:

  • 我收到一条错误消息 - NameError: name 'user_class' is not defined
  • 听起来你输入的是user_class而不是users_class
【解决方案3】:

您需要在询问后直接检查值是 1、2 还是 3,因此,您可以将 if 直接移到 users_class = int(input("Which class are you in? (1,2 or 3)")) 之后。

correct_answers=0 移到 if 的上方,并将 timeTaken 设置为之前的 0

这行得通:

import time
import random
import math
import operator as op
import sys

def test():
    num1 = random.randint(1, 10)
    num2 = random.randint(1, num1)

    ops = {
        '+': op.add,  
        '-': op.sub,
        '*': op.mul,
        }

    keys = list(ops.keys()) 
    rand_key = random.choice(keys)  
    operation = ops[rand_key]  

    correct_result = operation(num1, num2)

    print ("What is {} {} {}?".format(num1, rand_key, num2))
    user_answer= int(input("Your answer: "))

    if user_answer != correct_result:
        print ("Incorrect. The right answer is {}".format(correct_result))
        return False
    else:
        print("Correct!")
        return True

username=input("What is your name?")

print ("Hi {}! Wellcome to the Arithmetic quiz...".format(username))

users_class = int(input("Which class are you in? (1,2 or 3)"))

correct_answers = 0
timeTaken = 0

if users_class == 1:
    with open("class1.txt","a+") as f:
        f.write("   {}:Scored {} in {} seconds.".format(username,correct_answers,timeTaken))

elif users_class == 2:
    with open("class2.txt","a+") as f:
        f.write("   {}:Scored {} in {} seconds.".format(username,correct_answers,timeTaken))

elif users_class == 3:
    with open("class3.txt","a+") as f:
        f.write("   {}:Scored {} in {} seconds.".format(username,correct_answers,timeTaken))
else:
    print("Sorry, we can not save your data as the class you entered is not valid.")
    sys.exit(0);

input("Press Enter to Start...")
start = time.time()

num_questions = 10

for i in range(num_questions):
    if test():
        correct_answers +=1

print("{}: You got {}/{} {} correct.".format(username, correct_answers,  num_questions,
'question' if (correct_answers==1) else 'questions'))

end = time.time()
etime = end - start
timeTaken = round(etime)

print ("You completed the quiz in {} seconds.".format(timeTaken))

如果无效,则通过sys 退出,否则按照您当前的代码继续。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
相关资源
最近更新 更多