Skip to content

ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ

Debugging like a pro

4 min read

Every programmer writes bugs, beginners and professionals alike. What grows with practice is how fast you find them. Research finds that debugging is its own skill, and that learning a clear process makes people more confident and better at it. This lesson gives you that process. It all runs in the browser except the last section.

A process, not luck

A is a mistake that makes a program stop with an error or give a wrong result. is finding and fixing it. Changing lines at random is slow and adds bugs. Use six steps:

  1. Reproduce it

    Find an input that goes wrong every time.
  2. Read

    Read the error from the last line up (lesson 7.1), or say what you got and what you expected.
  3. Guess one cause

    Make a hypothesis (below), out loud.
  4. Check the guess

    Use the smallest check you can: one print, one smaller input.
  5. Fix one thing

    Change one thing and run again. If it didn't help, undo it.
  6. Remember it

    Note the bug and its cause, to spot it faster next time.

A is one cause you can check, like "the tip is wrong", not "something's broken".

ጥያቄ

A friend says your bill splitter gives the wrong share. What do you do first?

A wrong result

Lesson 1.4's f"{x=}" is the fastest check there is. Predict what it prints here:

ውጤቱን ገምቱ

Decide before you look. Guessing wrong is how this sticks.

total = "1850"
print(total)
print(f"{total=}")
Pick the output

Python prints

1850
total='1850'

With =, the f-string shows the name, an equals sign, and the value's repr (lesson 6.1), so a string keeps its quotes. That's how you spot text where you expected a number.

print(total) hides that total is text; f"{total=}" doesn't. Now a real bug in lesson 1.7's bill splitter, a wrong result with no error:

bill = 1850
tip_percent = 10
people = 3
tip = bill * tip_percent / 100
share = bill + tip / people
print(f"Each person: {share:.2f} birr")

In the editor, press Escape then Tab to move on.

Follow the steps, and do each check in the code box as you go:

  • Reproduce. The values in the code are the failing input; it's wrong every run.
  • Read. Expected 678.33 (lesson 1.7); got 1,911.67, more than the whole bill.
  • Guess. "The tip is wrong."
  • Check. Add print(f"{tip=}") under line 4 and run. It prints tip=185.0, which is right. A wrong guess is still progress: line 4 is cleared.
  • Guess again. "The share line is wrong."
  • Check. Add print(f"{tip / people=}") and run: tip / people=61.666666666666664, and 1850 + 61.67 is 1,911.67. Confirmed: / happens before + (lesson 1.2), so line 5 divides only the tip.
  • Fix one thing. Line 5 becomes share = (bill + tip) / people: 678.33. Remove the checks.
  • Remember. "When a total looks too big, check the order of operations."

Here's what happens when you change two things at once:

A bug that raises an error

With an error, reading comes first. Run this:

def split(total, people):
    return total / people

people = input("Number of people: ")
print(split(2035, people))

In the editor, press Escape then Tab to move on.

One answer per line, given to input() in order.

It fails every time with 3 as input, so it's reproduced. Read the last line: TypeError: unsupported operand type(s) for /: 'int' and 'str', and above it: line 2, in split, total / people. One of them is a str. Guess: people. Check: add print(f"{people=}") under line 4; it shows people='3', quotes and all, because input() always returns text (lesson 1.5). Fix one thing: line 4 becomes people = int(input("Number of people: ")).

Stuck? Explain the code aloud, line by line, even to a rubber duck: rubber duck debugging. Saying what each line does shows you the one that doesn't.

On a computer: breakpoints

A pauses a program at one line. In VS Code (with the Python extension), click left of a line number for a red dot, then Run > Start Debugging. It stops there, the Variables panel shows every name, Step Over runs one line, and Continue runs on.

Or put breakpoint() in your code and run the file in a terminal:

bill.py
total = 0
for price in [250, 30, 45]:
    breakpoint()
    total = total + price
print(total)

It stops at a (Pdb) prompt. p total, price prints values, n runs the next line, and c continues until the next breakpoint(), here the next time round the loop:

Output
> /home/hana/bill.py(3)<module>()
-> breakpoint()
(Pdb) p total, price
(0, 250)
(Pdb) n
> /home/hana/bill.py(4)<module>()
-> total = total + price
(Pdb) c
> /home/hana/bill.py(3)<module>()
-> breakpoint()
(Pdb) p total, price
(250, 30)

To stop early, type q; Python asks Quit anyway? [y/n], and y ends the program.

መልመጃ

Debug challenge

This should print the average of three exam results, but it has two bugs: one error and one wrong result. Use the six steps; the hints are in the solution.

Output
Average: 82.3

Your code

scores = [72, 85, 90]
total = 0
for score in scores:
    total = score
average = total / len(score)
print(f"Average: {average:.1f}")

In the editor, press Escape then Tab to move on.

መፍትሄውን አሳይ

This is one way to solve it, not the only one. If yours prints the same thing, it works.

scores = [72, 85, 90]
total = 0
for score in scores:
    # Bug 2 (wrong result, seen once bug 1 is fixed): the average was 30.0.
    # f"{total=}" after the loop shows total=90: total = score kept only
    # the last score. A running total adds: total + score.
    total = total + score
# Bug 1 (error): TypeError: object of type 'int' has no len(). score is one number;
# the list is scores.
average = total / len(scores)
print(f"Average: {average:.1f}")

ዋና ዋና ነጥቦች

  • Debug with a process: reproduce, read, guess one cause, check it, fix one thing, remember.
  • f"{x=}" shows a name and its repr, so text shows its quotes.
  • For an error, read the traceback from the bottom; for a wrong result, say exactly what you got and what you expected.
  • Change one thing per run, and undo a change that didn't help.
  • On a computer, breakpoints pause a program so you can look at every name.