Debugging Jump to this section
Debugging is the process of finding and fixing problems (bugs) in your code. Every programmer debugs, and it is a vital skill to learn.
Many of the tools mentioned in this section are not available in the Python playground on this page. To use them, you can run your code in other editors.
Read the Error Message (Traceback) Jump to this section
When Python encounters an error it can't handle, it stops running and prints a traceback, or a message that shows what went wrong and where.
Read a traceback from the bottom up.
- The very last line tells you the type of error and a short description.
- The lines above it show the sequence of function calls that led to the error, with the most recent call at the bottom.
Common error types:
SyntaxError: code is not valid Python (often a typo or missing colon or parenthesis)IndentationError: wrong indentation (Python cares about spaces)NameError: a variable name is not definedTypeError: an operation on the wrong type (for example adding a string to a number)IndexError/KeyError: accessing a list index or dict key that does not existValueError: a function received a value of the right type but an inappropriate value
Always check the file and line number mentioned in the traceback; it tells you exactly where to look.
Simple Debugging Techniques Jump to this section
When you encounter a bug, start with these simple steps:
Reproduce the Error Make sure you can make the error happen again. If you can't reproduce it, it's harder to fix.
Read the Traceback Carefully
The error message often tells you exactly what's wrong. For example, NameError: name 'x' is not defined means you forgot to create the variable x.
Add print() Statements
This is the most common beginner debugging technique. Use print() to see what's happening inside your code.
Example: Let's say you're getting an IndexError in a loop.
numbers = [1, 2, 3]
for i in range(4): # This will go from 0 to 3
print(f"i = {i}, len(numbers) = {len(numbers)}") # Debug print
print(numbers[i]) # This will fail when i = 3
Running this shows:
i = 0, len(numbers) = 3
1
i = 1, len(numbers) = 3
2
i = 2, len(numbers) = 3
3
i = 3, len(numbers) = 3
IndexError: list index out of range
Now you can see the problem: when i = 3, you're trying to access numbers[3], but the list only has indices 0, 1, and 2.
If you're not sure which part of your code has the bug, you can temporarily comment out sections (using #) to narrow down where the problem is.
Catching Exceptions with try / except
Jump to this section
Sometimes you expect that an error might happen, and you want to handle it gracefully instead of crashing. You can use try and except.
Example: Asking the user for a number
try:
age = int(input("Please enter your age: "))
print(f"Next year you'll be {age + 1}")
except ValueError:
print("That's not a valid number! Please enter digits only.")
Here's what happens:
- The code inside try runs first.
- If a ValueError occurs (like if the user types "twenty" instead of "20"), Python jumps to the except block.
- The program doesn't crash; it just prints a message and continues.
- Important: Only catch errors you expect and know how to handle. Don't hide errors silently!
Using the Debugger (pdb)
Jump to this section
When print() statements aren't enough, you can use Python's built-in debugger. It lets you pause your program and look at what's happening step by step.
Quick use:
import pdb
pdb.set_trace()
# program will stop here; use commands like `n` (next), `c` (continue), `p var` (print variable)
The Python playground on this page does not have pdb functionality
Most code editors (like VS Code, PyCharm) have built-in debuggers that are easier to use—you can click to set breakpoints instead of adding pdb.set_trace() to your code.
Logging Instead of Printing Jump to this section
While print() is great for quick debugging, the logging module is more powerful for programs you plan to use regularly or share with others. One of the best features of logging is severity levels.
From least to most severe:
- DEBUG (detailed information, use when debugging)
- INFO (confirmation that things are working normally)
- WARNING (something unexpected happens but the program can continue)
- ERROR (a serious problem prevented something from working)
- CRITICAL (very serious error that may cause the program to stop working entirely)
When you set a logging level, you see that level and everything more severe. For example:
- If you set level to INFO, you'll see INFO, WARNING, ERROR, and CRITICAL messages.
- If you set level to ERROR, you'll only see ERROR and CRITICAL messages.
- If you set level to DEBUG, you'll see all messages.
import logging
# Set the level - try changing this to see different messages appear
logging.basicConfig(level=logging.INFO)
# Different types of log messages
logging.debug("This is a debug message - very detailed") # does not get shown because it is below 'INFO'
logging.info("Program started - normal operation")
logging.warning("Disk space is getting low - still working but be aware")
logging.error("Could not open config file - something failed")
logging.critical("Database connection lost - program may crash")
The Python playground does not have logging functionality
Assertions and Sanity Checks Jump to this section
Use assert to check assumptions while developing:
def divide(a, b):
assert b != 0, "b must not be zero"
return a / b
Assertions raise AssertionError when the condition is false. Remove or handle them in production as needed.
Making a Minimal Reproducible Example Jump to this section
- Reduce your code to the smallest version that still shows the bug.
- This helps you understand the cause and makes it easier to ask others for help.
Small Challenge Jump to this section
The code below produces an error. Fix it so it prints the average of the numbers.
numbers = [10, 20, 30]
total = 0
for n in numbers:
total += n
avg = total / len(numbers)
print("Average is " + avg)
Try to debug it yourself first.
Hint
Read the error message. What type of error mentions string concatenation? Consider converting types before printing.
Show example solution
numbers = [10, 20, 30]
total = 0
for n in numbers:
total += n
avg = total / len(numbers)
print("Average is", avg) # or: print("Average is " + str(avg))
Key Takeaways Jump to this section
- Read tracebacks from bottom (the error) to top (where it was called).
- Use
print()orloggingto inspect program state. Usepdbor another debugger for interactive inspection. - Validate inputs with
try/exceptorassertas appropriate. - Reduce code to a minimal example to isolate bugs.
- Keep calm. Debugging is a process. Follow the evidence the error messages give you.
