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?

Asked By: NukeSnicks

||

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")


Answered By: Ibrahim Berber

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:

  1. 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)
  2. Using return in a function (requires factoring the loop out of the function it is in)
  3. 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.

Answered By: ShadowRanger
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.