print(9 * 2 + 33, 9 * (2 + 33))
print(300 / 5, 300 // 5, 6 / 3)
print(17 // 5, 17 % 5, -7 // 2, -7 % 2)
print(10 - 4 - 3, 2 ** 3 ** 2, -3 ** 2, (-3) ** 2)51 315
60.0 60 2.0
3 2 -4 1
3 512 -9 9
Before this lesson
After this lesson you can
In review. The maths and code on this page are checked by automated tests on every change, but an independent reader has not signed it off yet. Spot a mistake or a confusing step? Tell us.
The five quiz scores add up to 300, so their mean is 300 / 5. Python answers 60.0, not 60. It says that 9 * 2 + 33 is 51 but 9 * (2 + 33) is 315, and that -7 // 2 is −4, not −3. What fixed rules turn any line of arithmetic into one value, so that you can predict the answer before Python gives it?
From the last lesson
1. What are the two steps of an assignment?
Work out the right-hand side until it is one object, then bind the name on the left to that object.
2. After x = 5, y = x and x = x + 1, what are x and y, and what does x is y give?
x is 6 and y is 5, and x is y is False: x now refers to a new object.
An expression is any piece of code that Python can reduce to one value: 55, hours, or 9 * hours + 33. The last lesson’s first step of an assignment, “work out the right-hand side”, means reducing an expression.
The clearest picture of an expression is a tree. The values sit at the leaves, and each operator sits above the two values it combines. Python works from the leaves up: each operator takes the values below it and replaces itself with one new value, until a single value is left at the top.
The same three numbers, two trees. Python works out each tree from the leaves up; the vermillion number beside each operator is the value it hands upwards. Brackets change the shape of the tree, so they change the answer.
The trees settle what a line means. In 9 * 2 + 33 the * sits lower, so it happens first and gives 18, then + gives 51. The brackets in 9 * (2 + 33) push the + down the tree, so it happens first and gives 35, then * gives 315. A machine-learning model’s prediction is an expression of exactly this kind, and so is every loss it is trained to make small.
Step 1. Seven operators. Python has these operators for numbers:
| Symbol | Name | Example | Value |
|---|---|---|---|
+ |
add | 7 + 2 |
9 |
- |
subtract | 7 - 2 |
5 |
* |
multiply | 7 * 2 |
14 |
/ |
divide | 7 / 2 |
3.5 |
// |
floor divide | 7 // 2 |
3 |
% |
remainder | 7 % 2 |
1 |
** |
power | 7 ** 2 |
49 |
Step 2. The order. Without brackets, Python decides which operator sits lowest in the tree by a fixed order called precedence. ** comes first. Then a minus sign written in front of one value, as in -3. Then *, /, // and %, which share a level. Then + and -. Operators on the same level go from left to right, so 10 - 4 - 3 is 6 - 3, which is 3. The one exception is **, which goes from right to left: 2 ** 3 ** 2 is 2 ** 9, which is 512. Brackets always come first.
Ben’s squared error, one operation at a time. Each line does exactly one step of the tree, in Python’s order.
Step 3. / always gives a float. Dividing with / gives a float even when the division is exact: 300 / 5 is 60.0 and 6 / 3 is 2.0. This is why the course writes the mean of the scores as 60.0. The other operators give an int when both values are ints, and a float as soon as one of them is a float, as lesson P01.2.1 showed.
Step 4. // and % split a division into a whole part and a rest. 17 // 5 is 3, the number of whole fives in 17, and 17 % 5 is 2, what is left over. The two always fit together: \({3 \times 5 + 2 = 17}\).
Step 5. Updating a name. Adding to a running total is so common that it has a short form: total += 65 means total = total + 65. For numbers it is a rebinding, as in lesson P01.2.2: a new object holding the sum, and the name moved to it. The same short form exists for the other operators, such as -= and *=.
Step 6. Square roots and distances, with nothing imported. A square root is the power one half, so 16 ** 0.5 is 4.0. The built-in abs gives a number’s distance from zero: abs(-4) is 4, the size of Ben’s error whichever side of the prediction it falls. Lesson P01.5.1 shows math.sqrt, the library form of the square root.
For whole numbers \(a\) and \(b\) with \({b \neq 0}\), the floor division a // b is the whole number \(q\) found by working out \(a/b\) and rounding down, to the largest whole number that is not more than \(a/b\). The remainder a % b is \({r = a - q\,b}\), so that, by definition,
\[ a = q\,b + r . \]
In Python, a == (a // b) * b + a % b holds for every such pair.
Why the remainder lies between 0 and \(b\). Take \({b > 0}\). Rounding down means that \(q\) is not more than \(a/b\), and that \({q + 1}\) is more than \(a/b\). So, line by line:
\[ \begin{aligned} q &\le \frac{a}{b} < q + 1 \\ q\,b &\le a < q\,b + b \\ 0 &\le a - q\,b < b \\ 0 &\le r < b \end{aligned} \]
Line 2 multiplies every part of line 1 by \(b\), which keeps the order because \(b\) is positive. Line 3 takes \({q\,b}\) from every part. Line 4 writes \(r\) for \({a - q\,b}\). So whenever \(b\) is positive, a % b is one of \(0, 1, \dots, b - 1\), whatever the sign of \(a\). (When \(b\) is negative the remainder takes the sign of \(b\) instead; this course does not need that case.)
The order, from first to last.
| Order | Operators | Within a level |
|---|---|---|
| 1 | ( ) brackets |
innermost first |
| 2 | ** |
right to left |
| 3 | -x, a minus in front |
|
| 4 | * / // % |
left to right |
| 5 | + - |
left to right |
Lesson P01.2.4 adds the comparisons and and, or, not, which all come after these.
Work out 17 // 5 and 17 % 5, then -7 // 2 and -7 % 2, and check both pairs with \({a = q\,b + r}\).
a // b counts whole steps of \(b\) from 0 to the multiple of \(b\) at or just below \(a\), and a % b is the rest. For −7 the steps go down to −8, past −7, because −8 is the multiple of 2 at or below −7.
17 and 5. \({17 / 5 = 3.4}\), and rounding down gives \({q = 3}\). The remainder is \({r = 17 - 3 \times 5 = 2}\). Check: \({3 \times 5 + 2 = 17}\), and \({0 \le 2 < 5}\).
−7 and 2. In Python -7 // 2 means (-7) // 2, because a minus in front comes before // in the order. Now \({-7 / 2 = -3.5}\). Rounding down means towards the left of the number line, and the largest whole number that is not more than −3.5 is −4, not −3, because −3 is more than −3.5. So \({q = -4}\). The remainder is
\[ \begin{aligned} r &= -7 - (-4) \times 2 \\ &= -7 + 8 = 1 . \end{aligned} \]
Check: \({(-4) \times 2 + 1 = -8 + 1 = -7}\), and \({0 \le 1 < 2}\). On the number line, four steps of 2 go down from 0 to −8, the multiple of 2 at or below −7, and 1 more gets back up to −7.
The examples of this lesson, each checked by Python.
51 315
60.0 60 2.0
3 2 -4 1
3 512 -9 9
Now the identity \({a = q\,b + r}\), tested on the two worked pairs:
A running total of the five scores with +=, and their mean:
300 60.0
Ben’s squared error from the step frames, his error’s size, and a square root:
Machine learning uses // and % all the time. A training loop that takes the 300 examples of a data set in groups of 32, the mini-batches of lesson ML01.5.4, gets 300 // 32 full groups and 300 % 32 examples left over:
Nine full groups of 32 and a last group of 12. Dividing by zero has no answer, so print(300 / 0) stops with (copied from a run with Python 3.15; other versions word some messages a little differently):
This module’s interactive, the memory-diagram builder, lives in lesson P01.2.2. Its button x = x + 1 is the rebinding of Step 5: each press makes a new int and moves the name x.
Wrong beside right. Without brackets, / comes before + and halves only the last score.
“55 + 65 + 80 + 40 + 60 / 5 is the mean of the scores.”
/ comes before +, so only the last score is divided: 60 / 5 is 12.0, and the line adds 55, 65, 80, 40 and 12.0 to give 252.0. Put brackets round the sum, (55 + 65 + 80 + 40 + 60) / 5, to get 60.0. A wrong mean like this gives no error message at all; it is simply a wrong number.
“-7 // 2 is −3, because −3.5 rounded is −3.”
// rounds down, towards the left of the number line, so it gives −4. Cutting off the fractional part, as int(-7 / 2) does, gives −3. The two agree for positive numbers and differ for negative ones.
“-3 ** 2 is 9.”
** comes before the minus sign in front, so the line means \({-(3^2)}\), which is −9. Write (-3) ** 2 when you mean 9.
“/ gives a whole number when the division comes out exact.”
6 / 3 is 2.0, a float, every time. Use // when you want an int.
1. In what order does Python work out 2 + 3 * 4 ** 2, and what is the value?
The power first, 4 ** 2 is 16; then the product, 3 * 16 is 48; then the sum, 2 + 48 is 50.
2. What type and value does 12 / 4 give?
The float 3.0: / always gives a float.
3. What are 23 // 4 and 23 % 4, and how do they fit a = (a // b) * b + a % b?
5 and 3, and \({5 \times 4 + 3 = 23}\).
4. What are -9 // 4 and -9 % 4?
\({-9 / 4 = -2.25}\), which rounds down to −3, so -9 // 4 is −3. Then -9 % 4 is \({-9 - (-3) \times 4 = 3}\). Check: \({(-3) \times 4 + 3 = -9}\).
5. How do you take a square root in Python without importing anything?
Raise to the power 0.5: 25 ** 0.5 is 5.0.
1. ★ Work out each by hand, then say its type: 7 + 3 * 2, (7 + 3) * 2, 2 ** 3 * 2, 2 ** (3 * 2) and 20 / 4 * 2.
7 + 3 * 2: the product first, 6, then 13, an int. (7 + 3) * 2: the brackets first, 10, then 20, an int. 2 ** 3 * 2: the power first, 8, then 16, an int. 2 ** (3 * 2): the brackets first, 6, then \({2^6 = 64}\), an int. 20 / 4 * 2: / and * share a level, so left to right: 20 / 4 is 5.0, then 5.0 * 2 is 10.0, a float.
2. ★★ A training run takes 300 examples in groups of 32. How many full groups are there, and how many examples are in the last, smaller group? Then work out -300 // 32 and -300 % 32, and check them with the identity.
300 // 32 is 9, because \({9 \times 32 = 288}\) and \({10 \times 32 = 320}\) is too many. 300 % 32 is \({300 - 288 = 12}\). So there are 9 full groups and a last group of 12.
For −300: \({-300 / 32 = -9.375}\), which rounds down to −10, so -300 // 32 is −10. Then -300 % 32 is the remainder \(r\):
\[ \begin{aligned} r &= -300 - (-10) \times 32 \\ &= -300 + 320 = 20 . \end{aligned} \]
Check: \({(-10) \times 32 + 20 = -300}\), and \({0 \le 20 < 32}\).
3. ★★★ Use \({0 \le r < b}\) from the formal statement to show that a % 2 is 0 for every even whole number \(a\) and 1 for every odd one, negative numbers included.
With \({b = 2}\), the formal statement gives \({a = 2q + r}\) with \({0 \le r < 2}\), so \(r\) is 0 or 1. If \({r = 0}\), then \({a = 2q}\) is a multiple of 2, that is, even. If \({r = 1}\), then \({a = 2q + 1}\) is one more than a multiple of 2, that is, odd. Every whole number is exactly one of the two, and \(r\) is fixed by \(a\), so a % 2 is 0 exactly for the even numbers and 1 exactly for the odd ones. For example, \({-7 = 2 \times (-4) + 1}\), so -7 % 2 is 1, and −7 is odd.
An expression becomes one value, worked out from the leaves of its tree up, in a fixed order.
Brackets change the tree.
**, a minus in front, then * / // %, then + -; left to right within a level, except **./ always gives a float. // rounds down, and a == (a // b) * b + a % b.a % b lies from 0 up to \({b - 1}\), for negative a too.total += 55 is total = total + 55; x ** 0.5 is a square root; abs(x) is a distance from 0.Sources. Each was opened and checked against this lesson on 12 November 2026.
// for floor division and % for the remainder, ** for powers, and the footnote that -3**2 means -(3**2), which is −9.-1**2 is −1. Section 6.7: floor division applies the floor function to the result, the identity x == (x//y)*y + (x%y), and the sign of the remainder. Section 6.17: the precedence table, with ** grouping from right to left.x += 1 can be rewritten as x = x + 1, with a similar effect.// gives the floored quotient, rounded towards minus infinity, so (-1)//2 is −1./ is always a float; “Simple operations” gives the order **, then * / %, then + -.Next. P01.2.4 Comparisons and boolean logic adds the operators whose answer is True or False.
This lesson unlocks
P01.2.4 Comparisons and boolean logic