Much of the material in this document is taken from Appendix F in the book *A Primer on Scientific Programming with Python*, 4th edition, by the same author, published by Springer, 2014.

A debugger is a program that can help you to find out what is going on in a computer program. You can stop the execution at any prescribed line number, print out variables, continue execution, stop again, execute statements one by one, and repeat such actions until you have tracked down abnormal behavior and found bugs.

Here we shall use the debugger to demonstrate the program flow
of the code `Simpson.py`
(which can integrate functions of
one variable with the famous Simpson's rule).
You are strongly encouraged to carry out the steps below on your computer
to get a glimpse of what a debugger can do.

Go to the folder
where the program `Simpson.py`

resides.

If you use the Spyder Integrated Development Environment, choose
*Debug* on the *Run* pull-down menu. If you run your programs in
a plain terminal window, start IPython:

```
Terminal> ipython
```

Run the program `Simpson.py`

with the
debugger on (`-d`

):

```
In [1]: run -d Simpson.py
```

We now enter the debugger and get a prompt

```
ipdb>
```

After this prompt we can issue various debugger commands. The most important ones will be described as we go along.

Type `continue`

or just `c`

to go to the first line
in the file. Now you can see a printout of where we are in the
program:

```
1---> 1 def Simpson(f, a, b, n=500):
2 """
3 Return the approximation of the integral of f
```

Each program line is numbered and the arrow points to the next line to
be executed. This is called the *current line*.

You can set a *break point* where you want the program to stop
so that you can examine variables and perhaps follow the execution
closely. We start by setting a break point in the `application`

function:

```
ipdb> break application
Breakpoint 2 at /home/.../src/funcif/Simpson.py:30
```

You can also say `break X`

, where `X`

is a line number in the
file.

Continue execution until the break point by writing `continue`

or
`c`

. Now the program stops at line 31 in the `application`

function:

```
ipdb> c
> /home/.../src/funcif/Simpson.py(31)application()
2 30 def application():
---> 31 from math import sin, pi
32 print 'Integral of 1.5*sin^3 from 0 to pi:'
```

Typing `step`

or just `s`

executes one statement at a time:

```
ipdb> s
> /home/.../src/funcif/Simpson.py(32)application()
31 from math import sin, pi
---> 32 print 'Integral of 1.5*sin^3 from 0 to pi:'
33 for n in 2, 6, 12, 100, 500:
ipdb> s
Integral of 1.5*sin^3 from 0 to pi:
> /home/.../src/funcif/Simpson.py(33)application()
32 print 'Integral of 1.5*sin^3 from 0 to pi:'
---> 33 for n in 2, 6, 12, 100, 500:
34 approx = Simpson(h, 0, pi, n)
```

Typing another `s`

reaches the call to `Simpson`

, and a new
`s`

steps *into* the function `Simpson`

:

```
ipdb> s
--Call--
> /home/.../src/funcif/Simpson.py(1)Simpson()
1---> 1 def Simpson(f, a, b, n=500):
2 """
3 Return the approximation of the integral of f
```

Type a few more `s`

to step ahead of the `if`

tests.

Examining the contents of variables is easy with the `print`

(or `p`

) command:

```
ipdb> print f, a, b, n
<function h at 0x898ef44> 0 3.14159265359 2
```

We can also check the type of the objects:

```
ipdb> whatis f
Function h
ipdb> whatis a
<type 'int'>
ipdb> whatis b
<type 'float'>
ipdb> whatis n
<type 'int'>
```

Set a new break point in the `application`

function so that we
can jump directly there without having to go manually through all the
statements in the `Simpson`

function. To see line numbers and
corresponding statements around some line with number `X`

, type
`list X`

. For example,

```
ipdb> list 32
27 def h(x):
28 return (3./2)*sin(x)**3
29
30 from math import sin, pi
31
2 32 def application():
33 print 'Integral of 1.5*sin^3 from 0 to pi:'
34 for n in 2, 6, 12, 100, 500:
35 approx = Simpson(h, 0, pi, n)
36 print 'n=%3d, approx=%18.15f, error=%9.2E' % \
37 (n, approx, 2-approx)
```

We set a line break at line 35:

```
ipdb> break 35
Breakpoint 3 at /home/.../src/funcif/Simpson.py:35
```

Typing `c`

continues execution up to the next break point, line 35.

The command `next`

or `n`

is like `step`

or `s`

in that the current line is executed, but the execution does not
step into functions, instead the function calls are just performed
and the program stops at the next line:

```
ipdb> n
> /home/.../src/funcif/Simpson.py(36)application()
3 35 approx = Simpson(h, 0, pi, n)
---> 36 print 'n=%3d, approx=%18.15f, error=%9.2E' % \
37 (n, approx, 2-approx)
ipdb> print approx, n
1.9891717005835792 6
```

The command `disable X Y Z`

disables break points with numbers
`X`

, `Y`

, and `Z`

, and so on.
To remove our three break points and continue
execution until the program naturally stops, we write

```
ipdb> disable 1 2 3
ipdb> c
n=100, approx= 1.999999902476350, error= 9.75E-08
n=500, approx= 1.999999999844138, error= 1.56E-10
In [2]:
```

At this point, I hope you realize that a debugger is a very handy tool for monitoring the program flow, checking variables, and thereby understanding why errors occur.