python-3.x - 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 课程,或者阅读在线书籍。我担心你会产生一些我已经在你的代码中看到的非常严重的误解。
首先,我不知道该怎么说,这样你就会吸收它,计算机按顺序执行指令,一次一个。这是一个很难学习的课程,特别是如果您在已经玩过一些代码之后尝试学习它!
我知道,因为我记得小时候想要一些与 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
计算一些东西,然后返回局部变量。_answer
question
而已。然后就完成了。它从不做任何其他事情。
这意味着稍后在您的程序中,当您说:
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
answer
question
+= 1
point = point + 1
point
global point
CheckAnswer
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)
推荐阅读
- html - 在 Chrome 控制台中从 xpath 获取属性类型
- scala - 如何解决scala中的类型不匹配
- c# - C# - 使用 Excel 在工作表中查找所有匹配项
- reactjs - 如何在 React 中创建可重用的目录组件
- c# - 我可以阻止 StreamReader 读取子目录吗?
- javascript - 多个愿望清单小部件混合
- python - 为什么我的 MLP 神经网络的输出在 0 和 1 之间?
- javascript - 分块算法帮助 JS
- unity3d - Unity:UI.Button 从脚本添加 OnClick 事件失败
- jestjs - 在 beforeEach() 和 afterEach() 中获取 Jest 测试名称