What commands are alternatives to "break"?
Question:
Our teacher wants us to make a program that asks if you are ready and if YES or NO are typed then it should move on to the next question. For some reason he doesn’t want us to use break
and I can’t find any command that really does anything similar to it other then continue, but continue only skips to the next line. Here is my code:
prompt = ""
while (prompt != "YES" or prompt != "NO"):
prompt = input ("Are you ready?(YES/NO): ")
if (prompt == "YES"):
print("Great!")
break
elif (prompt == "NO"):
print("How can I help?")
break
else:
print("Error, not a valid input")
while this would work in what I’m trying to achieve, I would get failed for having the break statement. Is there any alternative to this?
Answers:
You might want to have a variable to that will check the condition such as valid_answer
. Also, it is better practice to get rid of unnecessary parenthesis (if you expression is complex, they are fine, but in your case while
loop condition is much simpler without them).
valid_answer = False
while not valid_answer:
prompt = input("Are you ready?(YES/NO): ")
if prompt == "YES":
print("Great!")
valid_answer = True
elif prompt == "NO":
print("How can I help?")
valid_answer = True
else:
print("Error, not a valid input")
You could just delete break
from your code if you fixed your loop condition, changing:
while (prompt != "YES" or prompt != "NO"):
which is always true ("YES" is not equal to "NO", so the second test is true whenever the first one is false, so the loop condition is always true), with either:
while prompt != "YES" and prompt != "NO":
which is the minimal change to fix the logic (so it stops if it’s equal to either value, rather than only when it’s equal to both), or for a more English readability:
while prompt not in ("YES", "NO"):
which doesn’t have the tricks of how !=
and and
/or
interact in boolean logic to worry about. Either way, after fixing the test, the code will work as written without the need for break
at all.
To answer the broader question, the only alternatives to break
are:
- Careful use of tests to ensure the loop condition itself terminates when desired, and no code after the condition becomes true that should only execute when false is actually executed (this is what the minimal fix described above does)
- Using
return
in a function (requires factoring the loop out of the function it is in)
- Using an exception and
try
/except
to jump out of the loop.
Not coincidentally, these are also your options when you need to break
out of multiple levels of a nested loop (Python has no break
that can break an arbitrary number of loops). #1 is frequently unpythonic (especially if it relies on flag variables; in your case, it’s okay, just mildly redundant on the tests), as is #3, so if your code can’t use break
, and can’t be restructured to avoid the need for it, #2 is usually the best solution, especially in complex cases.
Personally, I usually wouldn’t put the handling of valid cases in the loop at all, leaving the loop to run and handle only invalid cases (which can occur 0-infinity times), with the valid cases handled after the loop is complete, exactly once.
A simple solution available on Python 3.8+ is to use the walrus operator (assignment expression for boring types) and just have the loop run until the result is valid, removing the handling for valid inputs from the loop entirely, putting them outside/after the loop entirely, so for your specific problem the end result would look like:
while (prompt := input("Are you ready?(YES/NO): ")) not in ("YES", "NO"):
print("Error, not a valid input")
if prompt == "YES":
print("Great!")
else: # No need for elif; only "YES" or "NO" would exit loop without throwing exception
print("How can I help?")
Pre-3.8, you could still do the same thing, the while
is just a little uglier (more repeated code):
prompt = input("Are you ready?(YES/NO): ")
while prompt not in ("YES", "NO"):
print("Error, not a valid input")
prompt = input("Are you ready?(YES/NO): ")
Bonus, with no particular increase in code complexity, you drop from 9-11 lines of code in your current design (9 without break
or explicit flag, 11 with) to 6-8 lines (6 with walrus, 8 without). With the walrus, it’s strictly better; no code is repeated, no tests are repeated multiple times per loop, the loop is kept very simple.
Our teacher wants us to make a program that asks if you are ready and if YES or NO are typed then it should move on to the next question. For some reason he doesn’t want us to use break
and I can’t find any command that really does anything similar to it other then continue, but continue only skips to the next line. Here is my code:
prompt = ""
while (prompt != "YES" or prompt != "NO"):
prompt = input ("Are you ready?(YES/NO): ")
if (prompt == "YES"):
print("Great!")
break
elif (prompt == "NO"):
print("How can I help?")
break
else:
print("Error, not a valid input")
while this would work in what I’m trying to achieve, I would get failed for having the break statement. Is there any alternative to this?
You might want to have a variable to that will check the condition such as valid_answer
. Also, it is better practice to get rid of unnecessary parenthesis (if you expression is complex, they are fine, but in your case while
loop condition is much simpler without them).
valid_answer = False
while not valid_answer:
prompt = input("Are you ready?(YES/NO): ")
if prompt == "YES":
print("Great!")
valid_answer = True
elif prompt == "NO":
print("How can I help?")
valid_answer = True
else:
print("Error, not a valid input")
You could just delete break
from your code if you fixed your loop condition, changing:
while (prompt != "YES" or prompt != "NO"):
which is always true ("YES" is not equal to "NO", so the second test is true whenever the first one is false, so the loop condition is always true), with either:
while prompt != "YES" and prompt != "NO":
which is the minimal change to fix the logic (so it stops if it’s equal to either value, rather than only when it’s equal to both), or for a more English readability:
while prompt not in ("YES", "NO"):
which doesn’t have the tricks of how !=
and and
/or
interact in boolean logic to worry about. Either way, after fixing the test, the code will work as written without the need for break
at all.
To answer the broader question, the only alternatives to break
are:
- Careful use of tests to ensure the loop condition itself terminates when desired, and no code after the condition becomes true that should only execute when false is actually executed (this is what the minimal fix described above does)
- Using
return
in a function (requires factoring the loop out of the function it is in) - Using an exception and
try
/except
to jump out of the loop.
Not coincidentally, these are also your options when you need to break
out of multiple levels of a nested loop (Python has no break
that can break an arbitrary number of loops). #1 is frequently unpythonic (especially if it relies on flag variables; in your case, it’s okay, just mildly redundant on the tests), as is #3, so if your code can’t use break
, and can’t be restructured to avoid the need for it, #2 is usually the best solution, especially in complex cases.
Personally, I usually wouldn’t put the handling of valid cases in the loop at all, leaving the loop to run and handle only invalid cases (which can occur 0-infinity times), with the valid cases handled after the loop is complete, exactly once.
A simple solution available on Python 3.8+ is to use the walrus operator (assignment expression for boring types) and just have the loop run until the result is valid, removing the handling for valid inputs from the loop entirely, putting them outside/after the loop entirely, so for your specific problem the end result would look like:
while (prompt := input("Are you ready?(YES/NO): ")) not in ("YES", "NO"):
print("Error, not a valid input")
if prompt == "YES":
print("Great!")
else: # No need for elif; only "YES" or "NO" would exit loop without throwing exception
print("How can I help?")
Pre-3.8, you could still do the same thing, the while
is just a little uglier (more repeated code):
prompt = input("Are you ready?(YES/NO): ")
while prompt not in ("YES", "NO"):
print("Error, not a valid input")
prompt = input("Are you ready?(YES/NO): ")
Bonus, with no particular increase in code complexity, you drop from 9-11 lines of code in your current design (9 without break
or explicit flag, 11 with) to 6-8 lines (6 with walrus, 8 without). With the walrus, it’s strictly better; no code is repeated, no tests are repeated multiple times per loop, the loop is kept very simple.