Computer Science 15-112, Summer 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