Defensive Programming
Share this post
You’ve managed to identify several errors by testing, but it would be helpful if you could catch these errors (called exceptions) and handle them without halting your program. At the very least, you could display a more meaningful error message. This is known as defensive programming, and is a method of trapping exceptions and allowing your program to continue working without crashing. This step may be beyond the scope of Key Stage 3, but it is a useful technique to have available to stretch more able learners.
Analysing the errors
Start by seeing if you can reproduce some of the exceptions by entering invalid data into your program. Run this Trinket with the aim of deliberately causing these exceptions to occur.
When you receive an error message, it’s important to note the type of error, as you can make your program respond differently to each. For example, the following inputs produce two different errors: an “IndexError” and a “ValueError”.
Input data | Error |
---|---|
5 | IndexError: list index out of range |
abc | ValueError: invalid literal for int() with base 10 |
Exception handling
You can handle these exceptions by preceding some “risky” code with a try
statement:
try:
player = int(input("--> "))
except:
print("Oops, the computer didn’t like that input")
The code above will “try
” to run the line player = int(input("--> "))
. If any exception occurs, rather than throwing up a message and stopping the code from running, the code underneath the except
statement will run instead.
Using exception handling, you can be a bit more specific about your exceptions and give different messages to the user depending on what error has occurred, by including the error type after the word except
. It would be more useful to handle your two types of error separately, as the feedback you give to the user might be different in each case. For example, if they enter text, you can tell then to enter a number; if they enter a value that is a number but isn’t within the range, you can remind them what the range is.
Adding exception handling to your rock, paper, scissors game
You’re now going to create a new subroutine that will handle the user input separately to your round()
subroutine. Again, this will make our code easier to read and debug.
Start by creating a new subroutine above your round()
subroutine:
def player_input():
Your intention here is to catch the error and not allow the user to continue unless they put in valid input. You’ll add a while
loop into your new subroutine and start by placing the print
statements from your round()
subroutine into your player_input()
subroutine:
def player_input():
while True:
print("Type 0 for rock")
print("Type 1 for paper")
print("Type 2 for scissors")
The next step is to add your try
statement underneath these print
statements.
try:
player = int(input("--> "))
player_choice = rps_choices[player]
return player_choice
Notice that again you have taken two more lines of code from your round()
subroutine, but you have added a line that returns a value. This will therefore now try
to execute the three lines of code beneath it.
The first line of code in your round()
subroutine should now look as follows:
player_choice = player_input()
You might have noticed that we have two variables named player_choice
that exist in your round()
and player_input()
subroutines. As they exist in their own subroutines, they don’t affect each other. You may want to rename one of them to avoid confusion.
Except
Finally, you need to go back to your player_input()
subroutine and add your except
blocks. You have two possible exceptions to handle: a ValueError
and an IndexError
. You can handle these errors separately by writing two different except
statements, each time including the type of error after except
. As usual, indent your code to show it belongs to the except
statement above it.
Add two separate except
blocks under your try
statement and customise the error messages to explain how to avoid that type of error.
Your player_input()
subroutine should now look like this:
def player_input():
while True:
print("Type 0 for rock")
print("Type 1 for paper")
print("Type 2 for scissors")
try:
player = int(input("--> "))
player_choice = rps_choices[player]
return player_choice
except ValueError:
print("Oops, looks like you entered text instead of a number. Please enter a whole number between 0 and 2")
except IndexError:
print("Oops, looks like you entered an incorrect number that wasn't a whole number between 0 and 2")
As you saw earlier in this step, it is also possible to simply use the word except
and not be specific about the error, as follows. It can be good to use this to catch any errors that you haven’t thought of.
except:
print("An error occurred")
This doesn’t necessarily help the user understand what they did wrong, but it does stop your program from crashing if an unexpected error occurs.
You can read more about exceptions in the Python documentation.
Discuss
- From your experience, can you think of any situations other than user input where exception handling could be used?
At the end of this step your code could look similar to this Trinket.
Share this post
Programming Pedagogy in Secondary Schools: Inspiring Computing Teaching

Programming Pedagogy in Secondary Schools: Inspiring Computing Teaching

Reach your personal and professional goals
Unlock access to hundreds of expert online courses and degrees from top universities and educators to gain accredited qualifications and professional CV-building certificates.
Join over 18 million learners to launch, switch or build upon your career, all at your own pace, across a wide range of topic areas.
Register to receive updates
-
Create an account to receive our newsletter, course recommendations and promotions.
Register for free