Non-Programmer's Tutorial for Python 2.6/Dealing with the imperfect
...or how to handle errors
So you now have the perfect program, it runs flawlessly, except for one detail, it will crash on invalid user input. Have no fear, for Python has a special control structure for you. It's called
try and it tries to do something. Here is an example of a program with a problem:
print "Type Control C or -1 to exit" number = 1 while number != -1: number = int(raw_input("Enter a number: ")) print "You entered:", number
Notice how when you enter
@#& it outputs something like:
Traceback (innermost last): File "try_less.py", line 4, in ? number = int(raw_input("Enter a number: "))</source> ValueError: invalid literal for int(): @#&
As you can see the
int() function is unhappy with the number
@#& (as well it should be). The last line shows what the problem is; Python found a
ValueError. How can our program deal with this? What we do is first: put the place where the errors occurs in a
try block, and second: tell Python how we want
ValueErrors handled. The following program does this:
print "Type Control C or -1 to exit" number = 1 while number != -1: try: number = int(raw_input("Enter a number: ")) print "You entered:", number except ValueError: print "That was not a number."
Now when we run the new program and give it
@#& it tells us "That was not a number." and continues with what it was doing before.
When your program keeps having some error that you know how to handle, put code in a
try block, and put the way to handle the error in the
Here is a more complex example of Error Handling.
# Program by Mitchell Aikens 2012 # No copyright. import math def main(): success = 0 while (success == 0): try: epact() success = 1 except ValueError: print "Error. Please enter an integer value." year = 0 except NameError: print "Error. Please enter an integer value." year = 0 except SyntaxError: print "Error. Please enter an integer value." year = 0 finally: print "Program Complete" def epact(): year = int(input("What year is it?\n")) C = year/100 epactval = (8 + (C/4) - C + ((8*C + 13)/25) + 11 * (year%19))%30 print "The Epact is: ",epactval main()
The program above uses concepts from previous lessons as well as the current lesson. Let's look at the above program in sections.
After we define the function called "main", we tell it that we want to "try" function named "epact". It does so "while" there is no "success". The interpreter then goes to the line
year = int(input("What year is it?\n")).
The interpreter takes the value entered by the user and stores it in the variable named "year".
If the value entered is not an integer or a floating point number (which would be converted to an integer by the interpreter), an exception would be raised, and execution of the
try block ends, just before
success is assigned the value 1.
Let's look at some possible exceptions. the program above does not have an
except clause for every possible exception, as there are numerous types or exceptions.
If the value entered for year is an alphabetical character, a
NameError exception is raised. In the program above, this is caught by the
except NameError: line, and the interpreter executes the print statement below the
except NameError:, then it sets the value of "year" to 0 as a precaution, clearing it of any non-numeric number. The interpreter then jumps back to the first line of the
while loop, and the process restarts.
The process above would be the same for the other exceptions we have. If an exception is raised, and there is an except clause for it in our program, the interpreter will jump to the statements under the appropriate except clause, and execute them.
finally statement, is sometimes used in exception handling as well.
Think of it as the trump card. Statements underneath the
finally clause will be executed regardless of if we raise and exception or not. The
finally statement will be executed after any
except clauses prior to it.
Below is a simpler example where we are not looped, and the
finally clause is executed regardless of exceptions.
#Program By Mitchell Aikens 2012 #Not copyright. def main(): try: number = int(input("Please enter a number.\n")) half = number/2 print "Half of the number you entered is ",half except NameError: print "Error." except ValueError: print "Error." except SyntaxError: print "Error." finally: print "I am executing the finally clause." main()
If we were to enter an alphabetic value for
number = int(input("Please enter a number.\n")), the output would be as follows:
Please enter a number. t Error. I am executing the finally clause.
Update at least the phone numbers program (in section File IO) so it doesn't crash if a user doesn't enter any data at the menu.