LANG·I Language Chapter 1 of 65
First program, first bug
A chapter kept as a logbook: we write our first lines of Python, do sums, break things and learn to read the machine’s complaints. We begin with a program from 1843 that already had a bug in it.
Language
- 01 First program you are here
- 02 Variables
- 03 Conditions
- 04 Loops
- 05 Functions
- 06 Lists
- 07 Strings
- 08 Dictionaries
- 09 Recursion
- 10 Functions as values
- 11 Errors and tests
- 12 Objects
Builds on: 00 · What a program can do
What you will take away
- print text and numbers, and use Python as a calculator
- read an error message from the bottom up and find the line where things broke
- tell an error Python shouts about from one it keeps quiet about
At the end of the last chapter we promised red text. It will turn up on this very page, more than once. To take the fright out of it, we’ll borrow a habit from the engineers who ran the first computing machines: whatever goes wrong goes into a logbook. This chapter is kept that way, entry by entry.
At the bottom of the page you have a logbook of your own. It fills itself in: every error you run into in this chapter’s cells lands there with the time and the line number. By the end of the chapter it will surely hold a few entries, and that is a good sign.
Entry one. 1843: a bug in the first program
Below are the first seven operations of Lovelace’s program. The engine’s columns are labeled $V_1, V_2, \ldots$; today we would call them variables. The program computes the Bernoulli number for $n = 4$, and its first operations prepare the fraction $-\frac12 \cdot \frac{2n-1}{2n+1}$. Press “Step” and watch the numbers move from column to column.
In the fourth operation the dividend and the divisor are swapped: the table says $V_5 \div V_4$, which is $\frac{2n+1}{2n-1}$, when $V_4 \div V_5$ is needed. Had the engine been built, it would not have noticed. It would obediently have divided nine by seven instead of seven by nine and carried on with the wrong number without skipping a beat.
It looks like a misprint: in the next column of the same table, where the expected result is written out, the fraction is correct. But a machine doesn’t read explanations; it carries out the table. The lesson of the first entry: a machine does what is written, not what you meant.
Entry two. The machine speaks
Our machine, luckily, has been built, and it understands Python. The simplest Python program asks the machine to say something:
The word print is a command, and the parentheses hold what it should print. Text goes in quotes, double or single, as long as they match at both ends: that is how Python knows where the text begins and ends. Programmers call text in quotes a string.
There can be many commands. Python carries them out from top to bottom, line after line, the way you read this page. Press “Steps” under the next program and follow Python as it goes.
In the second command print got several values separated by commas and printed them on one line with spaces between. The 4 there has no quotes, and to Python it is a number. We’ll trip over that difference soon.
Entry three. The calculator
Python does arithmetic better than a calculator: with whole numbers it never loses a digit. The signs are the familiar ones: +, -, * (times), / (divided by), ** (power). There are two more that a calculator doesn’t have: //, integer division (how many times one number goes into another), and %, the remainder.
The fractional part comes after a point, 3.5, never after a comma: in Python a comma separates values, as in print("Two", "three", 4). Write print(3,5) and Python prints two numbers, three and five.
The order of operations is the one you learned at school: powers first, then multiplication and division, then addition and subtraction; parentheses change the order. Test yourself.
What does print(2 + 3 * 4 ** 2) print?
The power first: $4^2 = 16$. Then the multiplication: $3 \cdot 16 = 48$. Then the addition: $2 + 48 = 50$. Check it in the machine below, which shows every step.
+ - * / // % **. The machine shows the order in which Python works it out.Try 2 ** 3 ** 2 and -2 ** 2 in the order machine. Both answers trip people up: powers are worked out from right to left (first $3^2 = 9$, then $2^9 = 512$), and a minus in front of a number binds less tightly than a power, so -2 ** 2 is $-(2^2) = -4$. When in doubt, add parentheses: spare ones cost nothing.
Entry four. Red text
Time to break something on purpose. In this program a quote is never closed. Run it.
Python didn’t even start running the program: it couldn’t read it. This is a SyntaxError, a breach of the language’s grammar, like a sentence that a typo has turned into nonsense. Python shows the line where it stumbled and puts a ^ under it. The line is highlighted in the code as well.
One rule will save you a lot of time: if everything looks right in the line that’s marked, look at the line before it. Python marks the place where it stopped understanding the text, and the mistake may be earlier. When a parenthesis is left open, Python 3.13 usually says so plainly, '(' was never closed, and shows the line where it was opened. Before version 3.10, Python noticed it only on the next line, once it realized the expression had never ended.
Hunting for errors is called debugging. Our bugs don’t usually fly, but they are caught the same way: find the spot where the machine broke, and think about why.
Entry five. Anatomy of a traceback
Not every error shows up when you read the code. Sometimes a program is written correctly, Python starts running it, and halfway through it stumbles. Then it prints a traceback, a report of where the program stopped and why.
The first two lines ran, and you can see their result in the output. On the third the program crashed. You read an error message from the bottom up: the last line says what happened, the lines above say where.
Here are the errors you’ll meet most often early on. There’s no need to learn them by heart. It is enough to know that each has a name and the name tells you where to look.
| Error | What happened | Example |
|---|---|---|
SyntaxError | The program breaks the language’s grammar | print("a) |
IndentationError | An extra or missing indent at the start of a line | print(1) |
NameError | Python doesn’t know the name: a typo, or it doesn’t exist yet | prnt(1) |
TypeError | The operation doesn’t fit the types: text plus a number | "year " + 1843 |
ZeroDivisionError | Division by zero | 1 / 0 |
The sneakiest of all is the TypeError from adding a string and a number. To Python, "1843" in quotes and 1843 without them are different things: the first is four characters, the second a number. Python refuses to add them because it can’t tell what you want: two pieces of text glued together, or two numbers added up. More about types in the next chapter.
Entry six. An error Python keeps quiet about
Red text is good news: the machine has found a problem and pointed straight at it. It is worse when a program runs without a single complaint and gives the wrong answer. Lovelace’s bug was of that kind: the engine would calmly have computed the wrong number.
Here is a program meant to find the average of two numbers, 4 and 6. The answer is obviously 5. Run it.
Python printed 7.0 without the slightest embarrassment. It did what was written: following the order of operations, it first divided b by two and then added a. Fix the program yourself; you already know how.
There will be no traceback here. What helps is the habit of checking the answer on an example you know in advance: the average of four and six should be five, the minutes in a day 1440. In Chapter 11 this habit becomes a tool, automated tests. The server that checks this course’s tasks works the same way: it runs your program on examples whose answers are known.
Your logbook
Here is what has piled up in your logbook while you were reading. Below are five broken programs. Each is broken in its own way: Python will point out four of the problems itself, and one you’ll have to find without its help. While you fix them, the logbook will grow.
The program should print Hello, world!, but Python can’t even read it.
Look at where the string begins and where it should end.
The closing quote is missing: print("Hello, world!").
The program should print Hello, Ada.
The last line of the traceback names a name Python doesn’t know. Compare it with the name in the first line.
Two letters of the name are swapped: nmae instead of name. There will be no Did you mean here, as there was in the traceback for greting: in a short name, two swapped letters are already too big a difference for Python, and you have to compare the names yourself.
The program should print Ada's program was published in 1843.
Python won’t add text to a number. How can you print several values on one line without gluing them with a plus?
Remember print("Two", "three", 4): commas.
The simplest fix is a comma: print("Ada's program was published in", year); print puts in the space itself. You can also turn the number into text with str(year), which the next chapter explains.
The program should print two lines: Start and End.
Spaces at the start of a line aren’t decoration to Python. Where are they out of place here?
The second line begins with four spaces. In Python an indent means “this line is nested inside the command before it,” and print can’t have anything nested in it. Remove the spaces. You’ll find out what indents are for in Chapter 3.
The program should print the number of minutes in a day. Python doesn’t complain about anything, but the answer is wrong.
How many minutes are there in an hour?
An hour has 60 minutes, not 6: print(24 * 60) prints 1440. Mistakes like this are found only by checking the answer against something you know in advance.
What next
So far our programs are like a barrel organ: they play the same tune every time. They don’t keep what they’ve computed for later, and they never ask anyone anything. For a program to remember a number or find out your name, values need names. And here the first trick is waiting for us: a name in Python doesn’t work the way it seems to. That is Chapter 2.