Appendix B: Debugging¶
Exceptions occur when the interpreter can’t carry out a given instruction. The type of error (Exceptions are objects) communicates what is wrong.
We stress that most of programming is error driven. Don’t think of errors negatively rather they are problem solving opportunities.
Debugging is working out what went wrong and fixing it.
Learn to be guided by Errors, and use debugging tools to master programming.
Here we explore some common errors and then we introduce pdb the python debugger.
Errors¶
Errors always tell you what when wrong but not always why.
Read errors, first using intuition then by debugging and research.
Tip
You need to learn how to find information. Always read Errors and use your intuition, then Google. If that hsn’t helped only then ask an expert.
With time many errors map to solutions instantly.
AttributeError¶
An AttributeError means the interpreter can’t find the name you have asked for on the object.
>>> import turtle
>>> turtle.shp('waef')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'shp'
Here the programmer has misspelt shape.
SyntaxError¶
Learning a language involves making many syntax (grammatical) errors.
A function defined badly:
>>> def print_hi:
File "<stdin>", line 1
def print_hi
^
SyntaxError: invalid syntax
Parentheses () are required after the name and the ending colon :.
>>> def print_hi():
print('hi')
No error, print_hi is properly defined.
pdb¶
pdb is the python debugger. You can freeze execution at a particular point in time, step through it, examining objects as you go.
To execute code with pdb:
python3 -m pdb my.py
You can also pause the execution at any time by placing this line into your code:
import pdb; pdb.set_trace()
When you run your code normally (python my.py) the interpreter will break at the that line of code.
Type h to get a list of all the commands. The important ones for now are:
Move along the execution timeline:
- l print lines of code surrounding cursor
- n execute next line
- s step into a line. Typically used for entering functions.
- c continue till the end of the program (or next break point).
Inspect the current location:
- w print frames on the stack at current position
- u go up a frame in stack
- d go down a frame in the stack
To exit: * q exit the debugger. Will terminate program execution.
Tip
On any error or exeception enter a import pdb; pdb.set_trace() on the line preceeding your program terminating. Run the program, then inspect what went wrong.
example¶
We will use pythontutor hand in hand with pdb to exercise visualising program execution.
Put this code into a file named my.py:
x = 1
y = 2
success = 'works'
failure = 'broken'
def inc(p):
incremented = p + 1
return incremented
def print_result(result):
if result:
print(success)
else:
print(failure)
inc_x = inc(x)
print_result(inc_x == y)
Execute with:
python3 -m pdb my.py
pdb starts program and pauses at first line:
> /Users/greg/my.py(1)<module>()
-> x = 5
(Pdb)
Executing l results in:
(Pdb) l
1 -> x = 5
2 y = 6
3
4 def f():
5 z = 4
6 total = sum(x, y, z)
7 return total
8
9 print('hi')
10 print(f())
[EOF]
Step through each line of code keeping.
Ensure you explore the two frames when you enter the f functions’ frame.
Tip
We have used a python code visualiser in a similar way.
koans & pdb¶
pdb is a great tool to understand code. Here we will apply it to our koans.
Enter:
import pdb; pdb.set_trace()
In a koan method that caused you difficulty.
Step through the execution of the code. When you are done type c to continue normal execution.