Python Arena
Step 2 of 5

Catching errors with try and except

An error that happens while a program runs is called an exception. Python raises the exception, and unless something handles it, the program stops and prints a traceback. A program can prepare for an exception with try and except:

try:
    tickets = int(input("How many tickets? "))
    print(f"Total: {tickets * 15} euros")
except ValueError:
    print("That's not a whole number.")
print("Thank you!")
Input
two
Output
How many tickets? two
That's not a whole number.
Thank you!

Python runs the try block. If a line in it raises a ValueError, the rest of the try block is skipped and the except ValueError block runs instead. After that the program carries on below the whole structure, as if nothing had happened. When no exception happens, the except block is skipped.

The except line names the kind of exception it handles. Any other kind still stops the program, which is good: an error you didn't expect should show up, not be hidden.

A fallback value

Sometimes the best reaction to bad input is a sensible default:

text = input("Font size: ")
try:
    size = int(text)
except ValueError:
    size = 12
print("Using font size", size)
Input
big
Output
Font size: big
Using font size 12

Keep the try block small, with only the lines that can fail in the way you expect. Then it's clear what the except is for.

Asking until the input is good

Together with a loop, try and except can keep asking until the user types a number. In a function, return ends the loop as soon as the conversion succeeds:

def read_int(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("Please type a whole number.")


year = read_int("Year: ")
print("In ten years it will be", year + 10)
Input
twenty
20.5
2030
Output
Year: twenty
Please type a whole number.
Year: 20.5
Please type a whole number.
Year: 2030
In ten years it will be 2040

Doing nothing with pass

Sometimes there's nothing to do about an exception except skip the bad value. An except block can't be empty, so it gets pass, the statement that does nothing:

total = 0
for text in ["5", "abc", "12", "", "3"]:
    try:
        total += int(text)
    except ValueError:
        pass
print(total)
Output
20

Your task

Challenge 1 of 3

Fill in the blanks so the program prints the price with 24 % tax added, or Not a price when the input isn't a number. A run looks like this:

Price: 10
With tax: 12.40

Challenge 2

In many countries a decimal number is written with a comma, like 72,5, but float only accepts a point. Write a function read_decimal(prompt) that asks for a number with the given prompt until the user types one, and returns it as a float. It accepts both 72.5 and 72,5. After anything that isn't a number, it prints Not a number, try again and asks again.

With this main program

weight = read_decimal("Weight in kg: ")
print(weight)

a run looks like this:

Weight in kg: heavy
Not a number, try again
Weight in kg: 72,5
72.5

Challenge 3

Write a program that adds up whole numbers the user types, until the user types done. Anything that isn't a whole number is skipped with the message Skipped: and the text. At the end the program prints the sum.

A run looks like this:

Number: 4
Number: four
Skipped: four
Number: 10
Number: done
Sum: 14