By Paradigm Study · Updated September 6, 2026

Python Debugging Practice: Learn Beyond the AI Fix

When AI supplies a fix you do not understand, reduce the problem to one failing example and explain the expected behavior first. Then use progressively more specific hints. This exercise covers a wrong total, a missing return value and an empty-input failure. Each one requires a different diagnosis even though an assistant could rewrite all three functions at once.

Failure one: the total keeps changing

def total(values):
    result = 0
    for value in values:
        result = value
    return result

For [4, 7, 2], the expected total is 13, but the function returns 2. Hint one: track result after each iteration. Hint two: is the previous result used in the assignment? Hint three: replace the assignment with result += value.

The corrected function accumulates instead of replacing. Check [4, 7, 2], [0], [-2, 5] and []; their expected totals are 13, 0, 3 and 0. A fix that only returns 13 passes the original example while failing the task. Explain why initialization at zero supports the empty list case.

Failure two: the result is None

def doubled(values):
    result = [value * 2 for value in values]

Calling doubled([2, 5]) gives None, even though the list comprehension creates [4, 10]. Hint one: distinguish creating a local variable from returning a value. Hint two: inspect the final line of the function. The correction is return result after the comprehension.

Adding print(result) would display the list but would not return it to a caller. Test this by assigning answer = doubled([2, 5]) and checking answer == [4, 10]. This distinction matters when an AI assistant proposes a demonstration that prints the right output while the actual function contract remains broken.

Failure three: an average of nothing

def average(values):
    return sum(values) / len(values)

The function raises ZeroDivisionError for []. Hint one: write the denominator. Hint two: decide what an empty average should mean before catching the error. For this exercise, the contract rejects empty input with ValueError("at least one value required"). Add an explicit check before the division.

Returning zero would imply a meaningful numerical average where none was provided. A different application might return None, but its callers would then need to handle that result. The design decision should be visible in the contract and tests.

Run and reconstruct

Download the standalone debugging exercises and checks. Run python3 python_debugging.py. The file contains the broken demonstrations, corrected functions and checks. Use the broken versions for tracing, then compare your correction only after writing it yourself.

Python's errors tutorial explains how exception messages and tracebacks help locate failures. In these examples, however, the first two bugs do not require a traceback at all: the program runs and produces the wrong behavior. Always compare output with the contract, including types and return values.

Ask for a useful hint

Try: “Here is the smallest failing input, expected result and actual result. Give me one observation to check, without rewriting the function.” After fixing it, close the assistant and rebuild the function in a fresh file. Change the test data so you cannot rely on remembering one answer.

If your explanation is only “this version works,” repeat the trace. The CSV cleaning exercise combines these habits with real file input, and the SQL window exercise extends them to row-level calculations.

Sources and further practice

Python tutorial: Errors and Exceptions supports the reference principle used here. The exercise, example data and review routine on this page are original Paradigm Study teaching examples.

For a broader workflow, see coding learners. Bring your attempt and the step that confused you into Paradigm Study for a lesson or focused practice. Start a learning notebook.