首页 > 解决方案 > While 循环仅循环 3 次

问题描述

我正在尝试创建一个随机生成问题的求和游戏。我正在使用随机模块生成数字,然后要求用户输入答案,然后尝试将用户输入与已经包含正确答案的变量进行比较。

在 5 个问题之后,我希望 while 循环中断并“结束游戏”,但它正在做一些奇怪的事情。它会循环 3 次,然后调用不正确的正确答案(请参阅函数 CheckAnswer()) 这就像我检查用户输入与正确答案的函数没有运行,但我找不到它失败的地方。

我对 Python 很陌生,这是我自己尝试的第一个项目。我不想让它变得简单。

我真的只是试着弄乱我的函数和代码,看看是否有任何改进,直到现在它对我有用。

point = 0
q_num = 0

def RandomNums():
    rNum1 = random.randrange(51)
    rNum2 = random.randrange(51)
    return rNum1
    return rNum2

def Add():
    rNum1 = RandomNums()
    rNum2 = RandomNums()
    question = input("What is {} + {}?: ".format(rNum1, rNum2))
    answer = rNum1 + rNum2
    return question
    print(answer)
    return answer

#Check actual answer against user input
def CheckAnswer():
    if question == answer:
        point += 1
        print("Correct! +1 Point!")
        print(point)
    else:
        print("Wrong. Next question.")
        time.sleep(1)

# Ask user to choose their operator
op = input("Which operator do you want to use (x, -, /, +)?: ").strip().lower()

if op == 'x':
    while q_num < 5:
        RandomNums()
        Multiply()
        question = Multiply()
        answer = Multiply()
        CheckAnswer()
        q_num += 1
        print(point)
elif op == '+':
    while q_num < 5:
        RandomNums()
        Add()
        question = Add()
        answer = Add()
        CheckAnswer()
        q_num += 1
        print(point)
else:
    print("What!? That's not a choice!")

我希望如果我得到正确的答案(在输入时),我将在我的 CheckAnswer() 函数中获得打印语句,并且 1 将被添加到我的“点”变量中。我还希望我的 'q_num' 变量无论如何都会增加 1,因为我希望 while 循环在 5 个问题处中断,从而结束游戏。

当我运行程序时,我得到的是我可以输入任何东西,它不会告诉我任何东西,无论它是否正确。while 循环将循环 3 次,并在第 4 次循环时说我的答案不正确。然后它似乎重置了循环和 q_num 计数。

标签: python-3.x

解决方案


这里有几个问题,首先我强烈建议参加 Python 课程,或者阅读在线书籍。我担心你会产生一些我已经在你的代码中看到的非常严重的误解。

首先,我不知道该怎么说,这样你就会吸收它,计算机按顺序执行指令,一次一个。这是一个很难学习的课程,特别是如果您在已经玩过一些代码之后尝试学习它!

我知道,因为我记得小时候想要一些与 BASICfor循环一起工作的东西,如果你正确地吸收了这一课,那是没有意义的,但这在当时对我来说非常有意义。

在您的代码中,没有正确吸收这一课的后果是return函数中的多个语句。一旦计算机点击一个 return 语句,它就会离开该函数。这意味着return遇到的第一个语句之后的事情不会发生

那么让我们来看看你的Add功能:

def Add():
    rNum1 = RandomNums()
    rNum2 = RandomNums()
    question = input("What is {} + {}?: ".format(rNum1, rNum2))
    answer = rNum1 + rNum2
    return question
    print(answer)
    return answer

它会得到两个随机数(我们暂时忽略这些问题RandomNums),然后它会问一个问题,把用户做了什么,把它放在局部变量中,为局部变量question计算一些东西,然后返回局部变量。_answerquestion

而已。然后就完成了。它从不做任何其他事情。

这意味着稍后在您的程序中,当您说:

        question = Add()
        answer = Add()

发生的情况是,您问用户两个问题,然后将全局变量设置question为用户第一次说的内容,并将全局变量设置answer为用户第二次说的内容。

所以你的循环真的是这样做的:

        RandomNums()  # Compute two random numbers, return one, throw result away
        Add()         # Make a question, ask the user, throw the result away
        question = Add()  # Make a question, ask the user, store what they said
        answer = Add()    # Make a question, ask the user, store what they said
        CheckAnswer()     # Check if what the user said both times is the same, print message
        q_num += 1        # increment loop number
        print(point)      # print point total

所以你的while循环没有运行三次——它运行了一次,在那个循环中你问用户一个问题三次。

所以你会认为你可以做的事情就是最后两次回答同样的事情,然后你至少会得到“正确答案”的信息。不幸的是,你没有这样做,因为另一个关于 Python 的问题有点棘手。会发生什么:

Which operator do you want to use (x, -, /, +)?: +
What is 40 + 31?: 3
What is 13 + 31?: 3
What is 2 + 9?: 3
Traceback (most recent call last):
  File "/tmp/quiz.py", line 49, in <module>
    CheckAnswer()
  File "/tmp/quiz.py", line 24, in CheckAnswer
    point += 1
UnboundLocalError: local variable 'point' referenced before assignment

这里发生的情况是,python 认为这point是函数本地CheckAnswer变量名,当您当然想要CheckAnswer修改名为. 通常,python 对变量应该是全局变量还是局部变量做正确的事情(毕竟,它正确推断出您想要处理全局和),但看起来您正在设置一个新值(它相当于),所以 python 认为你的意思是一个名为. 您可以通过在顶部添加一条语句来告诉它:point answerquestion+= 1point = point + 1pointglobal pointCheckAnswer

def CheckAnswer():
    global point
    if question == answer:
        point += 1
        print("Correct! +1 Point!")
        print(point)
    else:
        print("Wrong. Next question.")
        time.sleep(1)

现在,当我玩你的测验时,会发生这种情况:

$ python /tmp/tst.py
Which operator do you want to use (x, -, /, +)?: +
What is 19 + 18?: 3
What is 4 + 39?: 3
What is 15 + 27?: 3
Correct! +1 Point!
1
1
What is 19 + 31?: 3
What is 21 + 47?: 4
What is 23 + 39?: 3
Wrong. Next question.
1
What is 45 + 12?: 2
What is 8 + 32?: 3
What is 28 + 16?: 3
Correct! +1 Point!
2
2
What is 23 + 0?: 0
What is 20 + 28?: 1
What is 0 + 49?: 2
Wrong. Next question.
2
What is 42 + 4?: 0 
What is 27 + 18?: 1
What is 16 + 8?: 2
Wrong. Next question.
2

所以这是一个微小的改进,您可以看到循环按预期发生了五次。

好的,那么您之前遇到的问题是什么,您需要返回两个东西,但函数在第一个return语句处停止?

你可以做的是返回一些在 python 中称为tuple的东西,然后你可以在另一端解压它:

def RandomNums():
    rNum1 = random.randrange(51)
    rNum2 = random.randrange(51)
    return (rNum1, rNum2)           # return two things as a tuple

def Add():
    (rNum1, rNum2) = RandomNums()   # Unpack the tuple into two variables
    question = input("What is {} + {}?: ".format(rNum1, rNum2))
    answer = rNum1 + rNum2
    return (question, answer)       # return a tuple of question and answer

然后后来:

elif op == '+':
    while q_num < 5:
        (question, answer) = Add()
        CheckAnswer()
        q_num += 1
        print("Points are: {}".format(point))

所以这几乎可以工作。不幸的是,它每次都说我们的答案是错误的!

那是因为在 python 中,字符串和整数是不同的东西。您从 user( question) 获得的将是字符串 '40',而answer您计算的将是整数 40。因此,要正确比较它们,您需要answer转换为字符串或question转换为整数。

我在下面的代码中选择了将其answer转换为字符串,但是如果您可以在用户输入不是整数的内容时让程序崩溃,您可以选择其他选择。(我对用户的经验是,他们会开始在你的程序中输入脏话,这自然不会变成整数)。python 中将大多数东西转换为字符串的函数是str.

所以现在是整个程序:

# in your post, you forgot these import statements
import time
import random

# set up global variables
point = 0
q_num = 0

def RandomNums():
    rNum1 = random.randrange(51)
    rNum2 = random.randrange(51)
    return (rNum1, rNum2)          # return a tuple

def Add():
    (rNum1, rNum2) = RandomNums()  # unpack tuple into two variables
    question = input("What is {} + {}?: ".format(rNum1, rNum2))
    answer = str(rNum1 + rNum2)    # Note how answer is now a string
    return (question, answer)

#Check actual answer against user input
def CheckAnswer():
    global point             # need this since we assign to point in this function
    if question == answer:
        point += 1
        print("Correct! +1 Point!")
        print(point)
    else:
        print("Wrong. Next question.")
        time.sleep(1)

# Ask user to choose their operator
op = input("Which operator do you want to use (x, -, /, +)?: ").strip().lower()

if op == 'x':
    while q_num < 5:
        print("Not done yet, come back later")
        break  # Now the computer won't try anything below; break exits the while loop
        (question, answer) = Multiply()
        CheckAnswer()
        q_num += 1
        print("Points are: {}".format(point))
elif op == '+':
    while q_num < 5:
        (question, answer) = Add()
        CheckAnswer()
        q_num += 1
        print("Points are: {}".format(point))
else:
    print("What!? That's not a choice! (yet)")

现在去实施剩下的测验。


一个小建议:对于-特别是对于/,您可能希望选择两个随机数作为第二个操作数和答案,而不是两个操作数。例如:

def Divide():
    (answer, rNum2) = RandomNums()  # unpack tuple into two variables
    product = rNum2 * answer  # good thing answer isn't a string yet, or this wouldn't work
    question = input("What is {} / {}?: ".format(product, rNum2))
    answer = str(answer)      # change answer to a string, now that we're done doing math
    return (question, answer)

推荐阅读