← Python lessons

Debugging

Debugging means finding why a program behaves differently from its intended behaviour, fixing the cause, and checking the fix.

Use a repeatable process

  1. State the expected behaviour for a small example.
  2. Run that example and record what actually happens.
  3. Read any error message, including its type, line number and traceback.
  4. Trace the relevant code or print intermediate values to locate the first incorrect step.
  5. Change one cause at a time.
  6. Run the original example again, then check nearby and boundary inputs.

An error can be reported where a bad value is used, even if the value became wrong earlier. Work backwards through the relevant calls and assignments.

Recognise the kind of problem

  • Syntax error: Python cannot parse the code, such as a missing colon.
  • Runtime error: code starts but fails on a particular operation, such as accessing a missing list index.
  • Logic error: code runs but produces the wrong answer.

Do not catch every exception just to hide it. Handling an expected bad input is Data Validation; unexpected faults still need investigation.

Find a logic error

This function is intended to total all the values in a list:

def total_scores(scores):
    total = 0
    for score in scores:
        total = total + score
        return total

print(total_scores([3, 5, 2]))

Expected: 10. Actual: 3. A trace shows that return runs during the first iteration, ending the whole call.

Move return outside the loop:

def total_scores(scores):
    total = 0
    for score in scores:
        total = total + score
    return total

print(total_scores([3, 5, 2]))
print(total_scores([]))
print(total_scores([7]))

The results are 10, 0 and 7. Rechecking the original failing example and these boundaries gives evidence that the fix works.

Inspect a value without changing the calculation

Temporarily put print("score:", score, "total:", total) inside the loop after the addition. This reveals what each iteration did. Remove temporary prints before submitting work with an exact output requirement.

Your turn: fix the boundary

sum_up_to(limit) should return the sum of the integers from 1 through limit, including the limit. Assume limit is a positive integer. Fix the code, then check limits of 3 and 1.

def sum_up_to(limit):
    total = 0
    for number in range(1, limit):
        total = total + number
    return total

print(sum_up_to(3))
print(sum_up_to(1))

Expected output

6
1

Explain why changing the stop to limit + 1 fixes the cause. Do not replace the calculation with the two expected answers.

See also: Tracing Code, The range() Function, Parameters & Return.


Practise this in the free Python course, where every exercise checks your code instantly.