Python with AI Tutorial · Chapter 46 of 48
To debug Python code with AI you first read the traceback yourself, isolate the failing line, then paste the error and the surrounding code into an assistant with enough context for a precise answer. This chapter covers how tracebacks are structured, the eight error messages you will meet most often, the prompt that gets useful fixes, and the two classic tools that still matter: print() and pdb.
Read the traceback from the bottom up
A traceback lists the chain of calls that led to the error. The last line names the exception and the message; the block above it shows the file and line where it happened; earlier blocks show who called that code. Start at the bottom, then walk up until you reach a line you wrote.
def average(values):
return sum(values) / len(values)
monthly = {"Jan": [1200, 980], "Feb": []}
for month, sales in monthly.items():
print(month, average(sales))
Output:
Jan 1090.0
Traceback (most recent call last):
File "report.py", line 6, in <module>
print(month, average(sales))
File "report.py", line 2, in average
return sum(values) / len(values)
ZeroDivisionError: division by zero
Reading upward: the division failed inside average (line 2), which was called from line 6 while processing February, whose list is empty. The bug is in the data, and the fix is a guard: return sum(values) / len(values) if values else 0.
The 8 most common error messages
Most beginner errors fall into a handful of types. Learn to recognise them and half of your debugging becomes instant.
| Error | Typical message | Usual cause | Check first |
|---|---|---|---|
| SyntaxError | invalid syntax / was never closed | Missing colon, bracket or quote | The line before the one reported |
| IndentationError | unexpected indent | Mixed tabs and spaces, wrong nesting | Editor set to 4 spaces |
| NameError | name ‘df’ is not defined | Typo, or used before assignment | Spelling and execution order |
| TypeError | can’t multiply sequence by non-int | Wrong type, often a string that should be a number | type(variable) |
| ValueError | could not convert string to float: ‘1,250’ | Right type, unacceptable value | The exact input value |
| KeyError | ‘revenue’ | Dictionary or DataFrame key does not exist | .keys() or df.columns |
| IndexError | list index out of range | Position beyond the last element | len() and zero-based counting |
| ModuleNotFoundError | No module named ‘openpyxl’ | Not installed in this environment | Which interpreter and venv is active |
Two close relatives: AttributeError ('str' object has no attribute 'append') means the object is not the type you thought, and FileNotFoundError almost always means the working directory is not where the file is.
Reproduce the error in three lines
Before asking anyone, human or AI, shrink the problem. A TypeError buried in a 200-line report script usually reduces to one operation on one value.
price = "1,250"
try:
total = price * 1.18
except TypeError as e:
print("TypeError:", e)
price = float(price.replace(",", ""))
print(round(price * 1.18, 2))
Output: TypeError: can't multiply sequence by non-int of type 'float' 1475.0
How to paste an error into an AI assistant
The quality of the fix depends on the context you provide. Give five things: what you were trying to do, the complete traceback (not just the last line), the ten or so lines around the failing one, a sample of the data, and your Python and library versions. Ask for the cause first and the fix second, so you learn something and can judge the answer.
Use this template every time; fill in the brackets.
I am running Python 3.12 with pandas 2.x on Windows. Goal: [one sentence]. Here is the full traceback: [paste traceback] Here is the code around the failing line: [paste 10-15 lines] Sample of the data: [paste 3 rows or the dict] Explain the cause in two sentences, then show the minimal fix. Do not rewrite the whole script.
Ask why, not only what
An assistant will happily wrap your code in try/except and call it fixed. That hides bugs. A KeyError on a column name, for example, is usually a capitalisation mismatch that you should correct at the source rather than catch.
row = {"Region": "North", "Revenue": 46200}
print(list(row.keys()))
print(row.get("revenue", "missing key"))
print(row["Revenue"])
Output: ['Region', 'Revenue'] missing key 46200
print() debugging done well
The humble print is still the fastest tool for small scripts. Use the {name=} f-string form, which prints the expression and its value, and prefer zip(..., strict=True) so length mismatches fail loudly instead of silently dropping data.
units = [4, 10, 25]
prices = [1100, 250]
for u, p in zip(units, prices, strict=True):
print(f"{u=} {p=} {u * p=}")
Output:
u=4 p=1100 u * p=4400
u=10 p=250 u * p=2500
Traceback (most recent call last):
File "check.py", line 3, in <module>
for u, p in zip(units, prices, strict=True):
ValueError: zip() argument 2 is shorter than argument 1
Without strict=True the loop would stop after two rows and the third order would vanish from your report without a word.
Step through code with pdb
Put breakpoint() on any line and Python pauses there in the built-in debugger. The commands you need on day one are p (print a value), n (next line), s (step into a call), l (list code), c (continue) and q (quit).
def margin(revenue, cost):
breakpoint()
return (revenue - cost) / revenue
print(round(margin(5000, 3200), 2))
Output: > margin.py(3)margin() -> return (revenue - cost) / revenue (Pdb) p revenue, cost (5000, 3200) (Pdb) c 0.36
In VS Code the same thing is a red dot in the gutter and F5; the variables pane shows every value without typing p.
Turn a bug you just fixed into a test so it cannot come back.
This Python function had a bug: it crashed with ZeroDivisionError when the list was empty. Here is the fixed version: [paste function]. Write three pytest test functions for it: a normal case, the empty-list case, and a single-value case. Use realistic sales numbers and keep each test under 4 lines.
A debugging routine
- Read the last line of the traceback and name the error type.
- Find the topmost frame in your own file and look at that line.
- Print or inspect the values involved; check their types.
- Reproduce in three lines.
- Fix, rerun, then paste the reproduction into an AI only if you are still stuck, using the template above.
Common mistakes
- Pasting only "it doesn’t work" or the last line of the error into the assistant.
- Accepting a
try/except: passthat hides the problem. - Fixing the line the traceback points to when the real cause is the data created earlier.
- Running
pip installinto a different Python than the one executing the script. - Not reading the fix before running it against production files.
Exercise
This function crashes. Read the traceback, name the error type and fix it so it returns 413.0.
def total_with_vat(amounts):
total = 0
for a in amounts:
total += a
return total * 1.18
print(total_with_vat(["100", "250"]))
Show answer
The error is TypeError: unsupported operand type(s) for +=: 'int' and 'str': the amounts arrive as strings. Convert them where they are used.
def total_with_vat(amounts):
total = 0
for a in amounts:
total += float(a)
return round(total * 1.18, 2)
print(total_with_vat(["100", "250"]))
Output: 413.0
Related chapters
FAQ
Can AI debug Python code for me completely?
It can explain most errors and propose fixes quickly, but it cannot see your data or run your program. You still have to reproduce the problem, supply context and verify the fix.
What is the most common Python error for beginners?
TypeError and NameError top the list: numbers stored as strings, and variables misspelled or used before they exist. SyntaxError from a missing colon or bracket is a close third.
Should I use pdb or print statements?
Use print for quick checks in short scripts and pdb or the VS Code debugger when you need to inspect several variables or step through a loop. Both are worth knowing.
Working with spreadsheets too? Ready-made Excel, Google Sheets and Power BI templates are at NextGenTemplates.com.
Chapter 46 of 48 · Python with AI: all 48 chapters



