What is debugging? It’s simply the process of isolating a problem in a program. In someways, it’s more challenging than just programming because it requires a different way of thinking. When you are debugging you are a detective.
“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” –Brian Kernighan
What not to do: randomly looking at code and making a guess. It’s much easier to work on a problem once you have narrowed down some options.
The best programmers (and detectives) are systematic about collecting information and acting on it.
Debugging is not just finding out why your code is not working. It’s not just diving into the code and staring at it intently for a few minutes and suddenly arriving at the solution.
The goal is not just to make the program work. The goal is to learn how to make the program work
The question to ask when you are debugging is not “Why isn’t it working?!”. This isn’t a helpful question or mindset. A better question would be:
How could it have produced this output?
This question sets you on the right path. Remember everything that happens on a computer - happens for a reason.
The answer to the “Why” question is simply - because the code told it to do that. The answer to the “How” question is much more useful.
Experienced programmers do this almost naturally just because of the frequency with which they run into bugs - so while they run into just as many (if not more) problems than beginnners - they always know what to do next. With practice - you can too!
I found an error. It crashed and/or produced an output that I didn’t expect. Now what?
Ask “How could it have produced that output?” (and not why doesn’t it work)
Approach the code with skepticism &the understanding that it’s wrong (because the interpreter says so)
Test the hypothesis.
Check if the error appears anywhere else.
You are a detective and anything could be to blame (Except for Python)! It’s common for beginner programmers to blame Python, but that should be your last resort. Remember that Python has been used to solve CS61A level problems millions of times by millions of other programmers. So, Python is probably not the problem.
The code is wrong. If it wasn’t - you wouldn’t be getting unexpected input. Approach the code with skepticism.
Find clues. This is the biggest job of the detective and right now there are two important kinds of clues for you to understand.
- Error Messages. Read them!
- Print Statements
Read the error messages.
Always read the error messages.
Always read the error messages. In their entirety.
Python is trying to be helpful with the error messages. Sometimes python will even make a best guess about where exactly the error was triggered.
How can we read a traceback?
Traceback (most recent call last): File "readingErrors.py", line 11, in <module> print(hey_there()) File "readingErrors.py", line 8, in hey_there return why_hello() File "readingErrors.py", line 7, in why_hello return even_more() File "readingErrors.py", line 6, in even_more return higher_order() File "readingErrors.py", line 5, in higher_order return 1/0 ZeroDivisionError: division by zero
Sometimes, Python will tell you exactly where there was a problem with the ^ character.
File "readingErrors.py", line 14 def why_hello() ^ SyntaxError: invalid syntax
If you get stuck during the debugging process - it’s often helpful to just walk through your entire process out loud to another person. This often times solves the error - often without the other person helping.
If you don’t want to get someone else - you can talk to a rubber duck. The rubber duck rather obviously will not solve the problem for you - but it help you walkthrough it.
Don’t fix the bug until you answer the questions first!:
def modSeven(x): return x % "7" modSeven(21)
Traceback (most recent call last): File "mod7.py", line 4, in <module> modSeven(21) File "mod7.py", line 2, in modSeven return x % "7" TypeError: unsupported operand type(s) for %: 'int' and 'str'
Read the entire error.
Where did it happen.
How did it happen?
>>> hi() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in hi File "<stdin>", line 5, in bye File "<stdin>", line 4, in k ZeroDivisionError: division by zero
Autograder: “It’s not working!”
Programmer: “No worries. Our debugging skills will help!”
Hint: Could a print statement be helpful? If so where? print(“p ”,p, “c”,c)
Hint 2: The function computes the Nth Fibonacci number, for n >= 2.
Debugging can be largely avoidable – if you work carefully & follow these steps.
Get something working and keep it working.
This is a hard notion to internalize - to many it may seem like this mantra is telling them to be satisifed with incomplete code.
It’s not- it’s an antidote to the inner perfectionist so we can adopt the mindset of Get something working and keep it working.
This is a mantra that you can repeat throughout your career as a programmer. It’s a great way to avoid the frustrations mentioned above.
Think of it this way. Every time you have a little success, your brain releases a tiny bit of a chemical that makes you happy. So, you can keep yourself happy and make programming more enjoyable by creating lots of small victories for yourself.
This is a huge guide to help you build your debugging skills. It’s pretty big (~8000 words) is a collection of debugging resources from ‘How To Think Like A Computer Scientist’
Be sure to read the Quick Guide to Getting Unstuck!