Skip to content
Free public beta until December 4, 2026: every course is open, no card needed. After that, the first chapter of each course stays free and full access is a one-time $39 ($19 for up to 100 founding members chosen for helpful feedback). Your progress is kept. How the beta works

Recipe

Find a bug systematically

Use when: a program raises an exception you don't understand, or finishes with a wrong answer

Goal: the cause found and fixed, and a check in place so it can't return

Taught in Debugging

  1. 1

    Find the smallest input that shows the bug every time, and write down the expected and actual result.

    Example

    checkout(80, "TENOFF"): expected 72, got 79.92.

    Why: a bug you can trigger on demand can be tested; a bug that comes and goes can't.

  2. 2

    Read the traceback bottom-up, or study the wrong output for a pattern.

    Example

    79.92 is 80 minus 0.08: almost nothing was taken off.

    Why: the evidence often points straight at the first wrong value.

  3. 3

    State one specific hypothesis about where a value first goes wrong.

    Example

    "cut is too small inside discount."

    Why: a precise guess can be checked with one look.

  4. 4

    Print the value with f"{name=}", or pause with breakpoint() and p name.

    Example

    At the pause, p percent, cut shows (0.1, 0.08).

    Why: seeing the real values tests the guess without adding new changes to the code.

  5. 5

    If the guess was wrong, check a value halfway along, or halve the input, and repeat.

    Example

    Is price right on entry to discount? Yes, 80, so the problem is inside the call or in its arguments.

    Why: each halving rules out half of the remaining places the bug could be.

  6. 6

    Make the single change the evidence supports and run the reproduction again.

    Example

    discount(price, 10), and the result is 72.0.

    Why: one change at a time means you know which change fixed it.

  7. 7

    Add an assert or a test that would have caught this bug.

    Example

    assert checkout(80, "TENOFF") == 72.

    Why: a bug that was made once can be made again, and the check catches it the moment it returns.