Computer Science 15-112, Spring 2012
Class Notes: Exceptions
#1) Simplest form def isFactor(factor, n): return (n % factor == 0) try: if isFactor(0, 2): print "0 is a factor of 2" if isFactor(2, 0): print "2 is a factor of 0" except: print "We just caught an error" #2) With Exception information try: if isFactor(0, 2): print "0 is a factor of 2" if isFactor(2, 0): print "2 is a factor of 0" except Exception as error: print "We just caught this error:", error #3) Catching specific exception types try: prompt = "Enter a number to invert: " n = float(raw_input(prompt)) # non-float ==> ValueError inverse = 1/n # n==0 ==> ZeroDivisionError if (n == 42): ruhRoh() # no such function! print "The inverse of", n, "is", inverse except ZeroDivisionError: print "Cannot divide by 0." except ValueError: print "You did not enter a number!" except Exception as error: print "Unknown error:", error print " Error type:", type(error)
#1) Buggy code that crashes (look at stack trace for clues)
# intentionally buggy code here!
def isFactor(factor, n):
return (n % factor == 0)
def digitFactors(n):
#returns the number of digits of n that are factors of n
count = 0
while (n > 0):
digit = n % 10
n /= 10
if isFactor(n, digit):
#found another digit that divides n
count += 1
return count
#8 is a factor of 80, but 0 is not, so digitFactors(80) should return 1
print digitFactors(80) #crashes
#2) Once again, but catching the exception to print out more information
# (but we lost the stack trace!)
def isFactor(factor, n):
return (n % factor == 0)
def digitFactors(n):
#returns the number of digits of n that are factors of n
count = 0
while (n > 0):
digit = n % 10
n /= 10
try:
if isFactor(n, digit):
#found another digit that divides n
count += 1
except:
print "crashed on this input:", n, digit
return count
print digitFactors(80) #does not crash (exception quietly caught)
#3) Yet again, this time explicitly printing the stack trace, and not crashing!
import traceback, sys
def isFactor(factor, n):
return (n % factor == 0)
def digitFactors(n):
#returns the number of digits of n that are factors of n
count = 0
while (n > 0):
digit = n % 10
n /= 10
try:
if isFactor(n, digit):
#found another digit that divides n
count += 1
except Exception as error:
print "crashed on this input:", n, digit
print "Error:", error
traceback.print_exc(file=sys.stdout)
return count
print digitFactors(80) #does not crash, but prints stack trace!
#4) Once more, this time re-raising the exception, so yet again crashing
def isFactor(factor, n):
return (n % factor == 0)
def digitFactors(n):
#returns the number of digits of n that are factors of n
count = 0
while (n > 0):
digit = n % 10
n /= 10
try:
if isFactor(n, digit):
#found another digit that divides n
count += 1
except:
print "crashed on this input:", n, digit
raise
return count
print digitFactors(80) #crashes!
def f(n): if (n == 42): raise Exception("I take exception to 42.") return n+1 try: print f(5) print f(42) print f(50) except Exception as error: print "Caught exception:", error
#1) Unnecessary raise def isFactor(factor, n): if (factor == 0): raise Exception("Cannot divide by 0") #wrong! return (n % factor == 0) print isFactor(0, 8) #2) Here's why... def isFactor(factor, n): return (n % factor == 0) print isFactor(0, 8) #3) But you may use assert here, if this violates a pre-condition # (which it presumably does) def isFactor(factor, n): assert(factor != 0) return (n % factor == 0) print isFactor(0, 8)
#1) Wrong way
filename = "non-existent-file.txt"
try:
file = open(filename, "r")
print filename, "has", len(file.readlines()), "lines"
except IOError:
print "Cannot open file", filename
finally:
file.close() #error: file not defined here!
#2) Right way
filename = "non-existent-file.txt"
file = None
try:
file = open(filename, "r")
print filename, "has", len(file.readlines()), "lines"
except IOError:
print "Cannot open file", filename
finally:
if (file != None): file.close() #ahh, that's better
filename = "non-existent-file.txt" try: # using "with", no need for file.close() in finally clause with open(filename, "r") as file: print filename, "has", len(file.readlines()), "lines" except IOError: print "Cannot open file", filename
carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem