- testing and debugging
- how to write tests to find bugs
- how to find sources of bugs to fix them
Burkay Genç, Ahmet Selman Bozkır, and Selma Dilek
03/05/2023
test = [1,7,4] test[4] -> IndexError
int(test) -> TypeError
a -> NameError
'a'/4 -> TypeError
SyntaxError
: Python can’t parse programNameError
: local or global name not foundAttributeError
: attribute reference failsTypeError
: operand does not have correct typeValueError
: operand type okay, but value is illegalIOError
: IO system reports malfunction (e.g. file not found)try: a = int("burkay") b = int(5) print(a/b) except: print("Bug in user input.")
## Bug in user input.
try: print(1) # (1) executes print("burkay") # (2) executes print(int("genc")) # (!) creates exception print(2) # (-) this is never executed print("genc") # (-) this is never executed except: print("Bug found!") # (3) executes print("Please fix bug!") # (4) executes
## 1 ## burkay ## Bug found! ## Please fix bug!
try: for i in range(-2, 3): print("For i=",i, " 1/i=", 1/i) except: print("Bug found!")
## For i= -2 1/i= -0.5 ## For i= -1 1/i= -1.0 ## Bug found!
for i in range(-2, 3): try: print("For i=",i, " 1/i=", 1/i) except: print("Bug found!")
## For i= -2 1/i= -0.5 ## For i= -1 1/i= -1.0 ## Bug found! ## For i= 1 1/i= 1.0 ## For i= 2 1/i= 0.5
try: for i in range(-5, 5): for j in range(-5, 5): k = 2 * i + j l = 10 / k except: print("Bug at i=", i, "and j=", j)
## Bug at i= -2 and j= 4
try: a = int(input("Tell me one number: ")) b = int(input("Tell me another number: ")) print("a/b = ", a/b) print("a+b = ", a+b) except ValueError: print("Could not convert to a number.") except ZeroDivisionError: print("Can't divide by zero") except: print("Something went very wrong.")
else
:
try
body completes with no exceptionsfinally
:
always executed
after try, else
and except
clauses, even if they raised another error or executed a break, continue
or return
try: # First try to run the regular code except: # If there is AN exception in try, then run this else: # If there is NO exception in try, then run this finally: # No matter what, at the end, run this
try: i = 3 print(i / x) # is x defined? except: print("There is an error in the code.") else: print("There is no error in the code.") finally: print("procedure ended.")
## There is an error in the code. ## procedure ended.
vs.
try: i, x = 3, 4 print(i / x) # x is defined except: print("There is an error in the code.") else: print("There is no error in the code.") finally: print("procedure ended.")
## 0.75 ## There is no error in the code. ## procedure ended.
raise Exception("descriptive string")
def listSum(li1, li2): li3 = [] for i in range(len(li1)): li3.append(li1[i] + li2[i]) return li3 print(listSum([1,2,3], [4,5,6]))
## [5, 7, 9]
def listSum(li1, li2): li3 = [] for i in range(len(li1)): li3.append(li1[i] + li2[i]) return li3 print(listSum([1,2,3,4,5], [1,2,3]))
IndexError: list index out of range
def listSum(li1, li2): li3 = [] for i in range(min(len(li1), len(li2))): li3.append(li1[i] + li2[i]) return li3 print(listSum([1,2,3,4,5], [1,2,3]))
## [2, 4, 6]
def listSum(li1, li2): li3 = [] for i in range(max(len(li1), len(li2))): try: li3.append(li1[i] + li2[i]) except: if i >= len(li1): li3.append(li2[i]) else: li3.append(li1[i]) return li3 print(listSum([1,2,3,4,5], [1,2,3]))
## [2, 4, 6, 4, 5]
def listSum(li1, li2): if (len(li1) != len(li2)): raise Exception("Length of list1 is different than length of list2") li3 = [] for i in range(len(li1)): li3.append(li1[i] + li2[i]) return li3 print(listSum([1,2,3,4,5], [1,2,3]))
test_grades = [[['peter', 'parker'], [80.0, 70.0, 85.0]], [['bruce', 'wayne'], [100.0, 80.0, 74.0]]]
[[['peter', 'parker'], [80.0, 70.0, 85.0], 78.33333], [['bruce', 'wayne'], [100.0, 80.0, 74.0], 84.666667]]]
class_list
object[[['peter', 'parker'], [80.0, 70.0, 85.0]], [['bruce', 'wayne'], [100.0, 80.0, 74.0]]]
def get_stats(class_list): new_stats = [] for elt in class_list: new_stats.append([elt[0], elt[1], avg(elt[1])]) return new_stats def avg(grades): return sum(grades)/len(grades)
test_grades = [[['peter', 'parker'], [10.0, 5.0, 85.0]], [['bruce', 'wayne'], [10.0, 8.0, 74.0]], [['captain', 'america'], [8.0,10.0,96.0]], [['deadpool'], []]]
ZeroDivisionError: float division by zero
return sum(grades)/len(grades)
def avg(grades): try: return sum(grades)/len(grades) except ZeroDivisionError: print('warning: no grades data')
get_stats(test_grades)
## warning: no grades data ## [[['peter', 'parker'], [10.0, 5.0, 85.0], 33.333333333333336], [['bruce', 'wayne'], [10.0, 8.0, 74.0], 30.666666666666668], [['captain', 'america'], [8.0, 10.0, 96.0], 38.0], [['deadpool'], [], None]]
None
, because avg()
didn’t return anything in except block.def avg(grades): try: return sum(grades)/len(grades) except ZeroDivisionError: print('warning: no grades data') return 0.0
get_stats(test_grades)
## warning: no grades data ## [[['peter', 'parker'], [10.0, 5.0, 85.0], 33.333333333333336], [['bruce', 'wayne'], [10.0, 8.0, 74.0], 30.666666666666668], [['captain', 'america'], [8.0, 10.0, 96.0], 38.0], [['deadpool'], [], 0.0]]
0.0
AssertionError
exception if assumptions not metdef avg(grades): assert len(grades) != 0, 'no grades data' return sum(grades)/len(grades)
## AssertionError: no grades data
These slides are a direct adaptation of the slides used for MIT 6.0001 course present (as of February 2020) on MIT OCW web site.
Original work by:
Ana Bell, Eric Grimson, and John Guttag. 6.0001 Introduction to Computer Science and Programming in Python. Fall 2016. Massachusetts Institute of Technology: MIT OpenCourseWare. License: Creative Commons BY-NC-SA.
Adapted by and for:
Asst. Prof. Dr. Burkay Genç. MUH101 Introduction to Programming, Spring 2020. Hacettepe University, Computer Engineering Department.