Print Debugging

Print debugging is exactly what it sounds like: adding print statements to your code to see what's happening inside. It's the oldest debugging technique, and despite fancier tools existing, it remains incredibly useful. Every programmer uses it.

Why Print Debugging Works

When code misbehaves, you need to see inside it. Print statements let you:

  • Check what values variables actually contain
  • Confirm which parts of code are executing
  • Track how values change over time
  • Find where things start going wrong

It's simple, requires no special tools, and works in any programming language.

Printing Variable Values

The most common use is checking what a variable contains at a specific point:

def calculate_average(numbers):
    print(f"DEBUG: numbers = {numbers}")  # What did we receive?
    total = sum(numbers)
    print(f"DEBUG: total = {total}")  # Is the sum correct?
    average = total / len(numbers)
    print(f"DEBUG: average = {average}")  # Final result
    return average

Using f-strings (formatted strings) makes this easy. The DEBUG: prefix helps you spot your debugging output among other program output.

Printing Checkpoints

Sometimes you need to know if code is even running:

def process_data(data):
    print("DEBUG: Starting process_data")
    
    if data is None:
        print("DEBUG: data is None, returning early")
        return []
    
    print("DEBUG: About to enter loop")
    for item in data:
        print(f"DEBUG: Processing item: {item}")
        # ... processing code
    
    print("DEBUG: Loop complete")
    return results

This reveals the execution path — which branches are taken, whether loops run, and where the code might be stopping unexpectedly.

Tracing Through a Loop

Loops are common sources of bugs. Print the loop variable and any accumulating values:

def find_bug(numbers):
    total = 0
    for i, n in enumerate(numbers):
        print(f"DEBUG: i={i}, n={n}, total before={total}")
        total += n
        print(f"DEBUG: total after={total}")
    return total / len(numbers)

This shows you exactly what happens on each iteration, making off-by-one errors and incorrect calculations visible.

Best Practices

Be specific: Print variable names with their values, not just values alone. print(f"x = {x}") is more useful than print(x).

Add context: Include which function or section the print is in if you have many.

Clean up after: Remove or comment out debug prints when you're done. Leaving them clutters output and can slow down your program.

# print(f"DEBUG: {x}")  # Commented out after debugging

Print debugging isn't sophisticated, but it's effective. When you're stuck, adding a few strategic prints often reveals the problem faster than staring at the code.

See More

You need to be signed in to leave a comment and join the discussion