字符串出错

时间:2014-09-09 20:29:25

标签: python-3.x

我是一名新程序员,我决定尝试学习python 3.4.1。我决定尝试制作一个时间表测试程序。但是它在函数"问题"中有错误。输入字符串后输入正确的整数时会发生错误。它正确处理字符串,直到我输入正确的答案。之后python发出错误。我对此感到困惑,因为我不认为代码的这两部分应该相互影响。

有人可以向我解释一下我做错了什么,以及正确的做法是什么?请帮忙。

以下代码:

def main():
    global c
    c = 0
    ask_a()
    ask_b()
    print("Type Quit to stop the questions at any time")
    while c < 10:
        question()
    ans = input("Do you want to have another go?")
    if ans in("y","Y","yes","Yes"):
            main()
def question():
    global a
    global b
    global c
    print (str(a) + " x " + str(b+c) + " = ")
    answer = input()
    try:
        int(answer)
    except:
        if answer in ("q","Q","quit","Quit"):
            main()
        else:
            print("Try again!")
            question()
    if int(answer) == a*(b+c):
        print("Correct")
        c +=1
    else:
        print("Try again!")
        question()
def ask_a():
    global a
    a = input("What times tables would you like to do? \n")
    check_a()
def ask_b():
    global b
    b = input("What number would you like to start from? \n")
    check_b()
def check_a():
    global a
    try:
        a = int(a)
    except:
        print("You didn't enter a number...")
        ask_a()
def check_b():
    global b
    try:
        b = int(b)
    except:
        print("You didn't enter a number...")
        ask_b()
main()

2 个答案:

答案 0 :(得分:0)

您不应该使用question的强行号码。这是可能的,但问题的本质要求while循环。

请注意,在异常处理期间会调用递归question。很可能另一个异常发生得更深。与全局变量一起,它无法适应人类大脑来正确设计它。

但问题的根源可能是代码的以下部分:

try:
    int(answer)
except:
    ...

if int(answer) == ...:
    ...

int(answer)导致try/except构造中的异常时,在except分支中递归求解所有异常之后,它将导致相同的异常。

对于问题下面的第二条评论,我的+1到tobias_k。我只会更严格:作为初学者,永远不要使用global。您也不会将它用作高级程序员。它几乎总是糟糕设计的标志。

答案 1 :(得分:0)

这里有很多事情,但是近因导致失败涉及(如tobias_k所指出的)从异常处理程序中递归调用question()函数。

要查看正在进行的操作,您可以插入诊断print()函数来报告变量的对象ID&#39; answer&#39; (修改后的代码)并进行测试运行。在本次会议中,首先提供了错误的答案。然后在递归时,正确答案:

What times tables would you like to do? 
3
What number would you like to start from? 
4
Type Quit to stop the questions at any time
3 x 4 = 
wrong answer
trying answer: wrong answer id 53796784  in try block
Try again!
3 x 4 = 
12
trying answer: 12 id 53834112  in try block
trying answer: 12 id 53834112  in try block
Correct
trying answer: wrong answer id 53796784  in try block

... resulting in this traceback:

File "c:\xxxx\test.py", line 57, in <module>
  main()
File "c:\xxxx\test.py"", line 8, in main
  question()
File "c:\xxxx\test.py"", line 28, in question
  if int(answer) == a*(b+c):

builtins.ValueError: invalid literal for int() with base 10: 'wrong answer'

您会注意到在评估旧/错误答案(ID 53796784)时失败,而用户会认为它正在评估新的/正确答案(ID 53834112)。

这是您的代码,除了诊断打印声明外,原封不动:

 def main():
    global c
    c = 0
    ask_a()
    ask_b()
    print("Type Quit to stop the questions at any time")
    while c < 10:
        question()
    ans = input("Do you want to have another go?")
    if ans in("y","Y","yes","Yes"):
            main()
def question():
    global a
    global b
    global c
    print (str(a) + " x " + str(b+c) + " = ")
    answer = input()
    try:
        print('trying answer:', answer, 'id', id(answer), ' in try block')
        int(answer)
    except:
        if answer in ("q","Q","quit","Quit"):
            main()
        else:
            print("Try again!")
            question()
    print('trying answer:', answer, 'id', id(answer), ' in try block')        
    if int(answer) == a*(b+c):
        print("Correct")
        c +=1
    else:
        print("Try again!")
        print('question', id(question))
        question()
def ask_a():
    global a
    a = input("What times tables would you like to do? \n")
    check_a()
def ask_b():
    global b
    b = input("What number would you like to start from? \n")
    check_b()
def check_a():
    global a
    try:
        a = int(a)
    except:
        print("You didn't enter a number...")
        ask_a()
def check_b():
    global b
    try:
        b = int(b)
    except:
        print("You didn't enter a number...")
        ask_b()
main()

我同意tobias_k你应该尽可能避免使用全局。

通过将重要的信息作为参数传递,您可以实现大量的封装和清晰度。这是一个替代实现,可以保持大部分逻辑位完好无损,同时解决道路上的一些问题:

您可以使用内置字符串方法isdigit()完全避免使用try / except块。参看下面:

def check_int(q):
    "keep requesting input until an integer is provided"
    while True:
        test=input(q)
        if test.isdigit():   #quick and dirty integer test
            return int(test)
        else:
            print("You didn't enter a number...")

def check_ans(ans, a, b, c):
    "evaluate answer, return 0 if quit requested"
    if ans.isdigit():
        if int(ans) == a*(b+c):
            print("Correct")
            return 1
    elif ans.lower() not in ('q', 'quit'):
        print("Try again!")
        return 1
    else:
        return 0

a = check_int("What times tables would you like to do? \n")
b = check_int("What number would you like to start from? \n")
c = 0

print("Type Quit to stop the questions at any time")

while True:
    c+=1
    answer =input(str(a) + ' x ' + str(b+c) + ' = ')
    answer_eval = check_ans(answer, a , b, c)
    if c < 10 and answer_eval:
        ans = input("Do you want to have another go? ")
        if not ans.lower() in ('y', 'yes'):
            break
    else:
        break