✦ Python Intermediate & OOP Code quality

L2 · Concept 03 · Code Quality & Testing

Debugging Techniques
Find Bugs, Understand Errors, Fix Code with Confidence.

Learn a calm, repeatable way to find unexpected behavior, understand its cause, and verify a focused fix.

Learning goalRecognize common error types, read a traceback, inspect values, and use a breakpoint to follow Python code step by step.
01 Learn02 Work locally03 Check your understanding

Learning as a guest

Learning as a guest? Save your progress!

Create a free account to learn with Sloby AI, check your understanding, and track your progress.

The entire platform is free throughout 2026. Foundations stays free forever.

Debugging means finding a cause, not trying random fixes.

Writing code is one task. Running it shows what it actually does. Debugging begins when that behavior is unexpected: reproduce the problem, observe clues, find a cause, make a small fix, and verify the result.

Reproduce  →  Observe  →  Find the cause  →  Fix  →  Verify

1. Run the same input that shows the problem.
2. Read the error message or compare the actual result with the expected result.
3. Form a small hypothesis and inspect the relevant line or value.
4. Change only what is needed.
5. Run the program again and check for new problems.

For example, if a price is too high, do not immediately rewrite the whole calculation. First reproduce it with the same price and discount, observe the intermediate values, then check the formula that created the unexpected result.

A useful debugger changes one idea at a time. That makes it easier to tell whether a change solved the real cause or only hid a symptom.

↳

Start with evidence: An error message, a traceback, a surprising result, and a variable value are clues. Each clue narrows the part of the program worth investigating.

Three common kinds of problems
# Syntax error
if cena > 100
    print("Skupo")

# Runtime error
cena = 100
kolicina = 0
print(cena / kolicina)

# Logic error
cena = 100
popust = 20
nova_cena = cena + cena * popust / 100
print(nova_cena)

The first example has a SyntaxError because the if line needs a colon. The second raises ZeroDivisionError while running. The third program runs, but adding a discount makes the price higher: that is a logic error, so there may be no traceback at all.

Read a traceback from the bottom up
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    rezultat = 100 / 0
ZeroDivisionError: division by zero

Traceback (most recent call last) introduces the call history. The file name and line number show where Python noticed the exception. The final line names the exception and its message. In a larger program, an earlier stack frame may contain the decision that caused the bad value, so the traceback is a useful clue rather than a complete explanation.

Use print() to inspect a value
cena = 200
popust = 10

iznos_popusta = cena * popust
print("DEBUG:", iznos_popusta)

nova_cena = cena - iznos_popusta
print(nova_cena)

# Correct calculation:
iznos_popusta = cena * popust / 100

The temporary DEBUG print reveals that the discount amount is 2000 instead of 20. Dividing the percentage by 100 fixes the formula. Remove temporary DEBUG prints after the investigation so they do not become confusing output later.

Start the VS Code debugger
1. Open the Python file and choose the correct interpreter.
2. Click left of a line number to add a breakpoint.
3. Start Run and Debug or press F5.
4. If asked, choose Python File debugging with the Python extension installed.
5. The program stops before it executes the breakpoint line.

A breakpoint pauses the program at a chosen place so you can inspect its state. VS Code layouts and keyboard shortcuts can differ by operating system or settings, so the debugger toolbar buttons are always a good alternative.

Follow a discount calculation step by step
def cena_sa_popustom(cena: float, popust: float) -> float:
    iznos_popusta = cena * popust / 100
    nova_cena = cena - iznos_popusta
    return nova_cena

print(cena_sa_popustom(200, 10))

Put a breakpoint on the first line inside the function. In the Variables panel, first inspect cena and popust. Step Over executes one line without entering a called function; Step Into enters one when possible; Step Out continues until the current function returns; Continue runs to the next stop. Watch how iznos_popusta and nova_cena appear as execution moves forward.

A practical debugging strategy

  1. 1. Repeat the problemUse the same input or action that shows the error. A problem you cannot reproduce is harder to investigate.
  2. 2. Read the clueRead the traceback, error type, or actual result carefully. For a logic error, write down what result you expected instead.
  3. 3. Form a hypothesisAsk one focused question, such as “Is kolicina zero here?” or “Did I use a percentage as a whole number?”
  4. 4. Inspect the program stateAdd a temporary print() or stop at a breakpoint. Check values and the order in which lines run.
  5. 5. Make one focused change and verify itRun the same scenario again. Confirm both that the original problem is fixed and that the change did not create a new one.

Debugging habits to avoid

  • Changing many lines at onceSeveral changes can hide which one helped or introduced a new error. Keep each experiment small.
  • Reading only the last word of an errorThe exception type, file, line number, and surrounding code each add useful context.
  • Leaving debugging output in the final programTemporary prints are useful while investigating, but remove them or replace them with deliberate program output afterward.

Find Five Bugs — Debugging Challenge

Do this in VS Code

Download a small order-processing program with five deliberate problems. Investigate one clue at a time, then verify the final control values.

Download starter project
Five-bug order-processing project
debugging_five_bugs/
├── main.py
├── porudzbine.py
├── podaci.py
├── README_SR.md
└── README_EN.md

The starting program is intentionally broken. Follow the traceback and inspect values step by step; do not expect the first run to finish.

Debug the project locally

  1. Open the Python file and reproduce the issueRun the downloaded program once before changing anything. Keep the traceback or unexpected output as evidence.
  2. Choose one inspection toolUse either a temporary print() or a breakpoint, then inspect one value or one line of program flow.
↳

When debugging: python main.py Run the same example again after every focused fix.

VS Code debugger reminder

  • Use the current program stateVariables show values at the current pause point. Continue, Step Over, Step Into, and Step Out move execution in different ways.

What will happen when this code runs?

The values have types that are valid for multiplication, but are they the kinds of values this price calculation intended to use?

def ukupna_cena(cena, kolicina):
    return cena * kolicina

print(ukupna_cena("100", 3))
Choose the output

Build confidence independently

Investigate an empty grade list

Do not write a complete solution immediately. First describe how you would investigate this function and verify a safe fix.

Your goalExplain what happens for an empty list, how you would find the cause, how you would protect the function, and how you would check both empty and non-empty lists afterward.
def prosecna_ocena(ocene):
    zbir = sum(ocene)
    return zbir / len(ocene)

Work in your local VS Code folder

Progressive hints
  • Try to predict the value of len(ocene) when the list is empty.
  • Use the error type and the line that performs division as your first clues.
  • After protecting the empty case, run an example with grades too.

Ask Sloby for one guiding question about a traceback, a variable value, or a breakpoint; do not ask it to reveal the complete challenge solution.

Sloby, the Python AI Tutor mascot

Your learning mentor

Sign in to ask Sloby

Create a free account or sign in to get AI guidance while you learn.

Sign in to check your understanding

Create a free account or sign in to receive AI feedback and save your learning progress.

Python AI Tutor · Learn by understanding, not just by running code.