In this activity, you will start with a working script and then modify it to cause an exception. As usual, the script will halt when it reaches the statement that causes the exception. You will then add statements to “handle” the exception and prevent the program from halting. Finally, you will add statements that display more helpful messages.
# exceptions_division_calc from microbit import * sleep(1000) print("Division Calculation") n = 20 d = 5 q = n / d print("q = n / d") print(" = ", n, " / ", d) print(" = ", q) print("Try again!") print()
Now let's break the script!
Let's break it a different way!
Let's look at the exceptions_division_calc script's arithmetic statements:
n = 20 d = 5 q = n / d
When n and d are integers, the script performs this calculation: q = n / d
So, if n is 20 and d is 5, then q = 20 / 5, and the answer is 4, and the script that solves the problem will report the correct answer.
What happened when you changed d to 0? Then, q = 20 / 0. There is no answer because no number can be multiplied by 0 to result in 20. Since this is a Python script, setting d to 0 will cause a type of exception called a ZeroDivisionError.
Next, what happened when you modified the script to d = “Hello” ? The string "Hello" isn’t even a number! This causes a type of exception called a TypeError.
The micro:bit stops executing the script’s statements at the point where the exception occurs. So, when there is an exception in the program, the micro:bit never gets to the statement that prints the “Try again!” message. But, the ZeroDivisionError and TypeError messages are helpful for debugging code.
The exceptions that caused the micro:bit to stop mid-script can be "handled" with Python's try, except, else, and finally statements. Note that try and except go together, but else and finally are optional. Here is a template for handling code that could cause exceptions:
try:
# Statements here that might cause an exception.
except:
# If there was an exception, do something about it here.
else:
# If there was not an exception, do these statements
finally:
# Regardless of whether or not there was an exception,
# do these statements.
Here a variation of except with statements that display the exception description and type. The exception is stored in the variable e. Printing print("Exception = ", e) shows “error = “ followed by the exception text. et = type(e) stores the type of exception in a variable named et. Printing the et variable with print("Exception type = ", et) displays the exception type in the terminal. Recall that exception types include ZeroDivisionError and TypeError.
except Exception as e: print("Exception = ", e) et = type(e) print("Exception type = ", et)
If you know that certain types of exceptions will occur, you can even add else statements that handle each type of exception differently, like this:
except ZeroDivisionError: print("Can't divide by zero.") except TypeError: print("Expected a number.")
Here are some of the more common exception types/messages you might encounter:
TypeError | When the item is the wrong type |
ValueError | When the item is the wrong type, as in it needs to be compatible with math operators |
NameError | When the item has not been defined |
ZeroDivisionError | When division by zero is attempted |
IndexError | When attempting to access an invalid index |
KeyError | When a key is not found |
StopIteration | When the next function goes past its limit |
The division script we have been using includes statements that will fit into each part of a full exception-handling compound statement.
# exceptions_division_calc_try_this from microbit import * sleep(1000) print("Division Calculation") try: n = 20 d = 5 q = n / d except Exception as e: print("Exception = ", e) et = type(e) print("Exception type = ", et) else: print("q = n / d") print(" = ", n, " / ", d) print(" = ", q) finally: print("Try again!") print()
Do you remember how to break the script?
Note that the script did not halt at the exception. Instead, it displayed the exception, but continued to print "Try again!"
Now let's break it with text one more time.
Note again that the script did not halt at the statement that caused the exception. It made it all the way through printing "Try again!"
A try...except...else...finally statement can have more than one except. Also, each except can have one or more statements that address specific errors. For example, instead of displaying the exception information, you can display a message that explains how to solve the problem.
except Exception as e: print("Exception = ", e) et = type(e) print("Exception type = ", et)
...with this:
except ZeroDivisionError: print("Can't divide by zero.") except TypeError: print("Expected a number.")
Now let's repeatt the tests three times, changing the value of d each time:
Links
[1] https://python.microbit.org/v/2