Comp 150 – Computer Programming 1

March 8, 2008

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 you’re 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.