← Deeper Python in the console

When things go wrong

Catch an error with try and except, so a typing mistake gets a helpful reply and the program asks again.

Apps you trust never crash when you mistype: they catch the mistake, say what they wanted, and ask again.

In the console bridge you checked typed numbers with isdigit() before using them. Another way is to just try, and say what to do if it goes wrong. try runs some lines; if one of them causes a ValueError, Python jumps to except ValueError: instead of stopping the program.

PredictRead the code and say what it will do before you run anything. A wrong guess is fine: it shows you what to look for.

Predict

errors.py
text = "twelve"
try:
    age = int(text)
    print("Next year: " + str(age + 1))
except ValueError:
    print("That is not a number.")
print("Done")

int("twelve") cannot work. Inside try, what happens to the next line, and does the program stop?

What does it print?

RunRun it and compare the result with your prediction.

Run

Try three, then 3.5, then 4. The loop asks again after each mistake; break leaves it once int() works.

errors.py
while True:
    text = input("How many tickets? ")
    try:
        tickets = int(text)
        break
    except ValueError:
        print("Please type a whole number, such as 3.")
print("That will be $" + str(tickets * 12) + ".")
Try it yourselfYour edits are saved in this browser.

InvestigateTrace how each line of code connects to what you see.

Investigate

errors.py
while True:
    text = input("How many tickets? ")
    try:
        tickets = int(text)
        break
    except ValueError:
        print("Please type a whole number, such as 3.")
print("That will be $" + str(tickets * 12) + ".")

What int() accepts.

Two ways to deal with bad input.

An error that was not caught.

Which answer does int() accept, so the loop stops?

Compared with isdigit() in the console bridge, what does try let you do?

This should say There is no such room, but it stops with KeyError: attic. Click the line that is wrong.

ModifyChange the code on purpose and check the result.

Modify

A canteen with two kinds of mistake: an item that is not on the menu (KeyError) and a number that is not a number (ValueError). Try both.

Only accept 1 to 10 of an item.

Need a hint?

After count = int(text), only break if the count is between 1 and 10.

Another hint

if count >= 1 and count <= 10: then break; otherwise print Choose 1 to 10.

Let the customer type quit instead of an item.

Need a hint?

Before the try in the first loop, add: if item == "quit": break, and say goodbye instead of asking how many.

Try it yourselfYour edits are saved in this browser.

Only accept 1 to 10 of an item.

    Run your program. This ticks when your code does all of the above.

    Let the customer type quit instead of an item.

      Run your program. This ticks when your code does all of the above.

      MakeBuild something new using what you have learned. Expect a few tries; that is normal.

      Make a safe calculator

      Ask for two whole numbers and print the first divided by the second. Catch two kinds of mistake, each with its own except and its own message: a typing mistake (ValueError) and dividing by zero (ZeroDivisionError). After either, ask again.

      Try it yourselfYour edits are saved in this browser.

      Divide two numbers, catching ValueError and ZeroDivisionError, and ask again after either.

        Run your program. This ticks when your code does all of the above.

        Info

        Where this leads

        Next: the text adventure, built from the parser, the bag, the map and safe input.

        A game loads a saved file that has been deleted. What should a well-made program do?

        For teachers

        Students catch errors with try and except so typed mistakes get a reply instead of a crash, compare it with checking first (isdigit), and catch two kinds of error in one program. About 45 minutes.

        Open the teacher guide: answers, solutions, slides and a worksheet.

        Students will be able to

        Before class

        Read the unit primer first. try: runs its lines; if one causes the named error, Python jumps to except ThatError: and then carries on after it. Only the named error is caught: the bug task catches ValueError when the error is a KeyError, so the program still stops. int() accepts " 4 " and "-2" but not "3.5" or "three", so a caught error does not check whether a number is sensible (the first Investigate question). Avoid a bare except: that catches everything: it hides real mistakes.

        Running the lesson

        1. Predict: trace it on the board. The line after int() never runs.
        2. Run: ask students to find every kind of answer that gets through (including -2).
        3. Investigate: compare with isdigit() from the console bridge. Both are fine; try is the usual Python way.
        4. Bug task: read the error's name in the message, then the except line.
        5. Make: two excepts after one try. Ask which one runs for 10 / 0 and for ten.

        The hard part (on purpose)

        Catching the error that actually happens. Ask them to read the error's name in the message and match it to the except, rather than catching everything.

        When students get stuck

        Stretch and support

        Stretch: Make a function ask_number(question) that keeps asking until it gets a whole number, and use it twice.

        Support: Give students the try and the first except of the calculator, and ask them to add the second except.

        Where it leads

        Next lesson is the text adventure. Later, saving and loading a game uses the same idea for a missing file (FileNotFoundError).

        What each step is for

        Now you can
        Next lesson5. A text adventurePut the parser, the bag and the map together into a text adventure, in three milestones, then make it your own.