Errors are the most useful output Python produces
Nobody writes correct code first time. Not beginners, not people with twenty years of practice. The difference between the two is almost entirely how fast they read the error and know where to look. This lesson is that skill, and it is worth more than any syntax you will learn this month.
There are two kinds of failure, and telling them apart saves you time.
Kind one: it never started
prices = [120, 340, 90
print("done") File "budget.py", line 1
prices = [120, 340, 90
^
SyntaxError: '[' was never closedA SyntaxError means Python could not read the file, so nothing ran at all. No output from earlier lines, because there were no earlier lines as far as Python is concerned.
One honest warning: for unclosed brackets and quotes, the reported line is often not where you would say the mistake is. Python keeps reading, hoping the bracket closes, and complains where it gives up. Newer Python versions point back at the opening bracket, as above. Older ones say invalid syntax on the *following* line. So when a syntax error makes no sense, look at the line above it, and count your brackets and quotes.
Kind two: it started and then hit something impossible
This is a traceback, and it has a shape worth learning. Here is a real program:
# budget.py
bills = {"food": [200, 150], "transport": [60]}
def total_for(name):
return sum(bills[name])
print(total_for("food"))
print(total_for("rent"))Running it:
350
Traceback (most recent call last):
File "budget.py", line 8, in <module>
print(total_for("rent"))
~~~~~~~~~^^^^^^^^
File "budget.py", line 5, in total_for
return sum(bills[name])
~~~~~^^^^^^
KeyError: 'rent'Read the last line first. KeyError: 'rent' is what went wrong: something asked a dict for a key called rent and there is no such key. The error type tells you the category; the bit after the colon tells you the specific value involved.
Then read upwards. The blocks above are the chain of calls that got you there, oldest at the top, most recent at the bottom, which is what "most recent call last" means in the header. The bottom block, line 5, is where the failure actually happened. The block above it, line 8, is the line that called it.
So the broken line is 5, and the reason it broke is on line 8: someone asked for "rent", which is not in bills. Fixing line 5 would be fixing the wrong thing. The squiggles and carets under the code point at the exact expression that failed, which is a real help on a long line.
Also notice: 350 printed first. The program worked until it did not. Whatever printed before the traceback did happen.
The errors you will actually meet
NameError: name 'totl' is not defined— a typo, or you used a name before creating it, or it was created inside a function.TypeError: can only concatenate str (not "int") to str— a number where text was expected, or the reverse. Very often aninput()you forgot to convert.TypeError: ... 'NoneType' ...— you used the result of a function that printed instead of returning.IndexError: list index out of range— you asked for position 3 of a 3-item list. Valid positions are 0, 1, 2.KeyError: 'rent'— the dict has no such key. Check spelling and capitals.AttributeError: 'list' object has no attribute 'split'— you called a string method on a list, or similar. The message names the type you actually had, which usually tells you what went wrong earlier.ModuleNotFoundError: No module named 'requests'— not installed, or installed into a different Python. That is lesson nine.ZeroDivisionError— you divided by a count that turned out to be zero.IndentationError/TabError— spacing is inconsistent. Pick four spaces and never mix in tabs.
How to work through one
- Read the bottom line. That is what happened.
- Find the lowest block naming *your* file. That is where.
- Look at the values, not the code. Print them just above the failing line:
print(repr(name), bills.keys()).reprshows quotes and hidden spaces thatprinthides. - Change one thing. Run again.
When you ask another person, or an AI assistant, paste the whole traceback, not just the last line. The chain of calls is usually where the answer is, and the last line alone is often unanswerable.
Try this now
Run the budget.py above exactly as written. Then change "rent" to "transport" and run again. Then delete the return from total_for and run again, and read the new error type carefully.
Before you move on