Computer Science 15-110, Spring 2011
Class Notes: Debugging
Debugging
- Avoid bugs:
- top-down design
- one task per function
- test functions (also one per function)
- aggressively test as you go
- avoid copy-paste-edit code (bug propagation)
- use good style
- Find bugs:
- robust test cases
- test every logical path through the code
- test every edge case (maximum, minimum, negatives, 0, positives, first, last, None, ...)
- avoid duplicate/unnecessary test cases (extra work / false sense of security)
- read error message carefully!
- study reported line and previous lines
- study stack trace
- confirm bug is in code and not test case!
- construct minimal error-generating case
- predict (hand tracing) and confirm output
- print statements
print "x=",x - conditional print statements
if (i == 50):
print "x=",x - conditional with DEBUG local variable
DEBUG = True
...
if (DEBUG and (i == 50)):
print "x=",x - db function
def db(msg):
DEBUG = True
if (DEBUG):
print "DEBUG: " + msg
...
db("x=" + str(x))
if (i == 50): db("x=" + str(x))
- assertions (type-checking, preconditions, invariants, postconditions)
def sqrt(x):
assert(type(x) in [int, float]) # type-checking assertion
assert(x >= 0) # precondition assertion
return x**0.5 - random.seed(x)
- divide-and-conquer (binary-like search through thread of control)
- simulate block comments with """
- performance testing with large test cases
carpe
diem - carpe
diem - carpe
diem - carpe
diem - carpe
diem - carpe
diem - carpe
diem - carpe
diem - carpe diem