Chapter 8: Debugging your code

Finding the bug

face Josiah Wang

If you receive some error messages regarding the bug, count yourself lucky. They are clues about where the bug is hiding (and even what the cause of the error is). Always remember that error messages are your friend!

Beware that sometimes the real cause of the bug is not exactly at where the error indicates, but is actually because of something your program did before that.

Here is an example (taken from Think Python):

1
2
3
4
5
6
import math
signal_power = 9
noise_power = 10
ratio = signal_power // noise_power
decibels = 10 * math.log10(ratio)
print(decibels)

Running the program, you might get an error message as follows:

Traceback (most recent call last):
  File "sny.py", line 5, in ?
    decibels = 10 * math.log10(ratio)
ValueError: math domain error

The program says that there is an error in line 5. The problem, you might infer, is with math.log10(ratio). Since the error says “ValueError”, you would think that it’s likely that the value of ratio might be invalid. Of course, there is nothing wrong with the code in Line 5 itself. It is likely some value of ratio that is wrong before.

To confirm this, you can use the crude (but effective) method of adding a print() statement before that line to print out the value of ratio.

1
2
3
4
5
6
7
import math
signal_power = 9
noise_power = 10
ratio = signal_power // noise_power
print(ratio)
decibels = 10 * math.log10(ratio)
print(decibels)

And you might find that 0 is printed out when you run it. And of course log10(0) is undefined, causing the error. Then you can fix the problem appropriately.

So figuring out where the program is not working is often one of the first key steps to debugging.