Menu

Defensive Design

Validation loops

A validation loop checks input against a rule and asks again when the rule is broken. The asking happens inside a condition-controlled loop, so the same question repeats until an acceptable value is entered. A range check can be written this way: the loop condition tests whether the value is below the minimum or above the maximum.

seat_count = int(input("How many seats? "))
while seat_count < 1 or seat_count > 50:
    print("Enter a whole number from 1 to 50.")
    seat_count = int(input("How many seats? "))
print("Booking", seat_count, "seats.")

Output when the user types 0, 4:

How many seats? 0
Enter a whole number from 1 to 50.
How many seats? 4
Booking 4 seats.

The loop above keeps asking while the number of seats is outside 1 to 50. Enter 0 and the message appears before the question is asked again; the loop only ends when an allowed value is typed. This stops the program using a value that would give a wrong result.

The range check cannot run if the text cannot be converted, though. If you type many where a whole number is expected, int() cannot convert it, so Python raises a ValueError and the program stops with a run-time error before the comparison is made. The loop never gets the chance to ask again, so the program crashes instead of coping with the bad input.

Catching a conversion error

Python can also catch that error with try and except, although this is beyond what you need to write. The risky conversion goes in the try block; if it fails, control jumps to the except block and the remaining lines of the try block are skipped. Putting this inside a loop that repeats until an acceptable value has been stored means the question is asked again after an error.

seat_count = 0
while seat_count < 1 or seat_count > 50:
    try:
        seat_count = int(input("How many seats? "))
        if seat_count < 1 or seat_count > 50:
            print("Enter a whole number from 1 to 50.")
    except ValueError:
        print("Please type the seat count as digits.")
print("Booking", seat_count, "seats.")

Output when the user types many, 6:

How many seats? many
Please type the seat count as digits.
How many seats? 6
Booking 6 seats.

This catches text that is not a number, but it does not make a range check unnecessary: a whole number that is too small or too large is still the right data type, so it must be tested separately. Python says an error is raised; other languages say an exception is thrown. Invalid input is handled with validation: try and except does not replace it.

Practise this