[英]Python – Breaking out of a deeply nested loop with `while`, `try`, `if`, and `except` statements
Here is my code that solves a quadratic equation given user inputs a, b, c
. 这是我的代码,它在给定用户输入a, b, c
求解二次方程。 However, I want to check for incorrect user inputs. 但是,我想检查用户输入是否错误。 If a user inputs anything but a float, the user is confronted with print "Not a valid input. Try again.\\n"
followed by a loop of the function quadratic2()
. 如果用户输入的内容不是浮点数,则用户将面临print "Not a valid input. Try again.\\n"
然后是函数quadratic2()
的循环。 However, this program is part of a larger program, so I want the user to have the option of typing in "next"
to terminate this function and move on. 但是,该程序是较大程序的一部分,因此我希望用户可以选择键入"next"
以终止此功能并继续。 My issue is that I am calling for 3 user inputs, but I want the "next"
input to be the first input, a
. 我的问题是我需要3个用户输入,但是我希望"next"
输入是第一个输入a
。 This works perfectly well until the user types in a random string, causing a ValueError
. 在用户键入随机字符串导致ValueError
之前,此方法非常有效。 Once this happens, my code does not want to loop back to check for if the input is next
. 一旦发生这种情况,我的代码就不想循环返回以检查输入是否为next
。 Please help me! 请帮我! I think something about the way this code is nested is messing me up. 我认为有关此代码嵌套方式的一些事情使我感到困惑。
def retest3():
print "Type in another a, b, and c. Or type \"Next\" to move on."
def quadratic1():
print ("This program calculates the zeroes of a quadratic equation."
"\nPlease enter a, b, and c, hitting \"Enter\" after each one: ")
def quadratic2():
while 1 == 1:
a = (raw_input())
if "next" == a.lower():
ontonextthing()
return 1 == 0
else:
try:
a = float(a)
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
c = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
if b**2-4*a*c>0:
root1=(-b+math.sqrt(b**2-4*a*c))/(2*a)
root2=(-b-math.sqrt(b**2-4*a*c))/(2*a)
print ("First Root: {0}\nSecond Root: {1}".format(root1,root2))
else:
print ("The discriminant is negative, so your"
" roots will contain \"i\".")
disc1=(b**2-4*a*c)
disc2=-disc1
sqrtdisc2=(math.sqrt(disc2))/(2*a)
b2=(-b)/(2*a)
print ("{0} + {1}i".format(b2, sqrtdisc2))
print ("{0} - {1}i\n".format(b2, sqrtdisc2))
retest3()
quadratic1()
quadratic2()
This works perfectly well until the user types in a random string, causing a ValueError. 在用户键入随机字符串导致ValueError之前,此方法非常有效。 Once this happens, my code does not want to loop back to check for if the input is next. 一旦发生这种情况,我的代码就不想循环返回以检查输入是否为下一个。
Seems like you want the continue
statement : 好像您要continue
声明 :
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
continue
The continue
statement takes you back to the beginning of your while
loop (the next iteration). continue
语句将您带回到while
循环的开始(下一次迭代)。 Currently you are calling quadratic2()
which makes your function recursive, and not what you want. 当前,您正在调用quadratic2()
,它使您的函数递归,而不是您想要的。
Because it's recursive, when you receive your Exception it exits the current function, but because you were using recursion, you simply return back to the previous function you were in the middle of ( which is the same function ). 因为它是递归的,所以当您收到Exception时,它会退出当前函数,但是由于您使用的是递归,您只需返回到中间的前一个函数( 即同一函数 )。 Therefore the next input you type could be parsed by 因此,您输入的下一个输入可以由
b = float(raw_input())
instead of 代替
a = (raw_input())
The "real" solution for your problem is not to use deeply nested constructs in the first place. 解决您的问题的“真正”解决方案不是一开始就使用深度嵌套的构造 。 Deeply nested statements make your code hard to read, hard to test, hard to maintain and hard to reuse. 深度嵌套的语句使您的代码难以阅读,难以测试,难以维护和难以重用。 Also, you will tend to duplicate code, which is bad. 另外,您将倾向于重复代码,这是不好的。 Especially in Python, deep nesting will cause you to count spaces to get the indentation right, which is really a pain in the neck. 尤其是在Python中,深层嵌套会导致您计算空间以使缩进正确,这确实是一个麻烦。
Break your code into functions, and follow the "single responsibility principle" by letting one function do exactly one thing. 将您的代码分解为功能,并通过让一个功能完全完成一件事来遵循“单一责任原则”。 This has several advantages: 这有几个优点:
return
early in a function, so you can avoid nesting in many cases. 您始终可以在函数中尽早return
,因此在许多情况下都可以避免嵌套。 In your case, the quadratic2
function does a lot of things: 在您的情况下, quadratic2
函数可以完成很多事情:
Now I don't say that you need one function for every detail listed above, but it is rather obvious that this function does too much. 现在,我并不是说您需要为上面列出的每个详细信息使用一个函数,但是很明显,该函数执行了太多操作。
Examples on how you could break it up: 有关如何分解的示例:
float
from the user, and call this three times instead of repeating the try...except
code three times. 编写一个函数以读取用户的float
,然后调用三次,而不是重复三次try...except
代码。 This has the added benefit that you can enhance this function to run in a loop, so that the user is asked to repeat the input for one value, instead of having to start all over again as your current solution does. 这样做还有一个好处,就是您可以增强此功能以使其在循环中运行,以便要求用户重复输入一个值,而不必像当前解决方案那样从头开始。 Other tips: 其他提示:
else
after return
, raise
, break
, or continue
. return
, raise
, break
或continue
后不要使用else
。 It is not necessary, since the next statement will not be reached anyway, and you can save one nesting level. 这是没有必要的,因为无论如何不会到达下一个语句,您可以保存一个嵌套级别。 1==1
or 1==0
. 不要使用像1==1
或1==0
这样的令人困惑的表达式。 This is just a complicated way of writing True
and False
. 这只是编写True
和False
的复杂方法。 In your example, it should read while True
and return False
instead. 在您的示例中,它应读为while True
然后return False
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.