Exception
Handling: Trapping errors before they
do damage!
Question! What happens
if a Python input statement like number = input("Enter a number: ")gets the wrong input?
For example:
>>> number = input("Enter
a number: ")
Enter a number: abc
Traceback (most recent call
last):
File
"<pyshell#0>", line 1, in <module>
number = input("Enter a number: ")
File
"<string>", line 1, in <module>
NameError: name 'abc' is not defined
>>>
>>>
number = input("Enter a number: ")
Enter a number: "ABC"+2
Traceback (most recent call
last):
File
"<pyshell#7>", line 1, in <module>
number = input("Enter a number: ")
File
"<string>", line 1, in <module>
TypeError: cannot
concatenate 'str' and 'int'
objects
>>>
IDLE
1.2
>>>
number = input("Enter
a number: ")
Enter a number: $1.95
Traceback (most recent call
last):
File
"<pyshell#0>", line 1, in <module>
number = input("Enter a number: ")
File
"<string>", line 1
$1.95
^
SyntaxError: invalid syntax
>>>
The first is an example of a NameError as the name abc is not defined. The second is an example of a TypeError where youre
trying to illegally combine two different data types. The third is an example of
the catch all SyntaxError
where the structure of the response is wrong
Errors like these can be trapped and handled
using try:
except: blocks. If an error is
detected within a try: block an except: block that follows can handle the error.
1. isLeapYear(year) demonstrate exception handling using try: except:
#
# Name:
# File: LeapYear02.py
# Date: February 24, 2008
#
# Desc: Demonstrates a boolean values function
#
def
isLeapYear(year):
#
#
returns True if year is a leap year
#
return (year % 4 == 0) and (year % 100 !=
0 ) or (year % 400 == 0)
def
main():
# display title
print "\nLeap Year
Detector\n"
# ask-before-iterating loop
again = "y"
while (again == "y"):
try: # check for exceptions
year = input("Enter a
year: ")
if isLeapYear(year):
print "%d is a leap year" % year
else:
print "%d is not a leap year" % year
except TypeError:
print "\nType Error:
Entry should be a number\n"
except NameError:
print "\nName Error:
Identifier entered, need a number\n"
except Syntax Error:
print \nSyntax Error:
Illegal syntax used for input\n
except:
print "\nUnknown
error\n"
again = raw_input("\nAgain? (y/n): ")
main()
2. Lab08c1.py
Same as Lab08c.py expect a file while loop is introduced. This can be used to
handle more complicated input errors.
#
# File: Lab08c1.py
# Date: February
28, 2008
#
# Desc: Detects
illegal dates; incorporates a while filter loop
#
import
string
def
isLeapYear(year):
#
#
returns True if year is leap year
#
return (year % 4 == 0) and (year % 100 !=
0) or (year % 400 == 0)
def
main():
# display program title
print "\nProgram to
test for legal/illegal dates\n"
# ask-before-iterating loop
again = "y"
while (again == "y"):
# filter while loop
ok = False # initialize
ok to False to force while loop
while (not ok):
try: #
initialize exception handler
# get
date
print
date = raw_input("Enter
date in mm/dd/yyyy format: ")
print
# extract month, day and year as integer types
m, d, y = string.split(date, "/")
month = int(m)
day = int(d)
year = int(y)
ok = True # input in valid
format - set ok to exit loop
except:
print"Input Error -
try again"
ok = False # - set ok to loop again
# check for valid date
if (((month == 1) or (month == 3) or
(month == 5) or (month == 7) or
(month == 8) or (month == 10) or (month == 12)) and
((day >= 1) and (day <= 31))):
print date, "is legal"
elif (((month == 4) or
(month == 6) or (month == 9) or (month == 11)) and
((day >= 1) and (day <= 30))):
print date, "is legal"
elif ((month == 2) and isLeapYear(year) and (day >= 1) and (day
<= 29)):
print date, "is legal"
elif ((month == 2) and not isLeapYear(year) and (day >= 1) and (day
<= 28)):
print date, "is legal"
else:
print date, "is not legal"
# ask to go again?
print
again = raw_input("Again?
(y/n): ")
print
main()
3. Similar to Lab08b except it uses a filter while loop for range checking.
#
#
File: Lab08b.py
#
Date: February 28, 2008
#
# Desc: Computes day
number
#
def
isLeapYear(year):
#
# returns True if year is a leap year
#
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
def
main():
# display program title
print "\nDay
of Year Program\n"
# ask-before-iterating loop
again = "y"
while (again == "y"):
try: # start exception handler for bad input
# get date
ok
= False #
assume input is bad unless otherwise indicated
while (not ok): # range
checking filter loop
month, day, year = input("Enter month, day, year: ")
if (day < 1) or (day >
31):
ok = False
print "Illegal Day -
Re-enter date"
elif
(month < 1) or (month > 12):
ok = False
print "Illegal Month
- Re-enter date"
elif
(year < 1):
ok = False
print "Illegal Year -
Re-enter date"
else:
ok = True
# compute day of year
dayNum =
31 * (month - 1) + day
if (month > 2):
dayNum
= dayNum - (4 *month + 23)/10
if (isLeapYear(year) and month
>= 3):
dayNum
= dayNum + 1
# display results
print
print "%d/%d/%d is day %d of
the year" % (month, day, year, dayNum)
print
except:
print "\nInput
error ",
# ask to go again?
again = raw_input("Again? (y/n):
")
print
main()
N.B. It should be pointed out that the above range checking loop is incomplete. It ought to account for the different numbers of days in a month and for leap years.