Exceptions and Tracebacks ------------------------- * so far we've ignored situations where errors occurred, but real software needs to handle errors or unexpected conditions all the time .. doctest:: >>> value = ' Aquamarine Falcon ' >>> float( value ) Traceback (most recent call last): File "", line 1, in ValueError: could not convert string to float: Aquamarine Falcon * when functions call other functions, the system creates a "stack" of "frames" * A stack is like a list where you can only add to the end or remove from the end * A frame is the namespace where a function is run (including which line of the function is running) * An uncaught error in Python will, by default, print out a "traceback" of these frames to let you see what was happening when your error occurred. * When something goes wrong, you use the traceback to help you find out where and what the problem was * in *python* the traceback is ordered from "top" to "bottom", that is, the "frame" printed first in the traceback ("" in the example below) is the "top level" caller * in *python*, the last line of the traceback is a string representation of the ``Exception`` which was raised, which generally attempts to be a useful description of what went wrong .. doctest:: >>> def will_fail(): ... 1/0 ... >>> def will_call(): ... will_fail() ... >>> will_call() Traceback (most recent call last): File "", line 1, in File "", line 2, in will_call File "", line 2, in will_fail ZeroDivisionError: division by zero * it is possible to catch these ``Exceptions`` in Python by using a special type of block around the code in which the exception may occur .. doctest:: >>> value = ' Aquamarine Falcon ' >>> try: ... value = float( value ) ... except ValueError as err: ... value = value.strip() ... >>> value 'Aquamarine Falcon' .. note:: We can catch multiple Exception types using ``except (ValueError,TypeError) as err`` instead.