Numbers and arithmetic

Numbers show up in almost every program you write. A shopping cart totals a price. A game updates a score. A script counts how many times something happened. Python gives you arithmetic operators that work like paper maths, plus a few more that are worth knowing from the start.
The operators
The four operators from maths (+, -, *, /) work exactly as you would expect. Python adds three more that you will use constantly: integer division, remainder, and exponentiation.
price = 12.99
quantity = 3
print(price * quantity) # 38.97
print(price + 2) # 14.99
print(price - 1.00) # 11.99| Operator | Name | Example | Result |
|---|---|---|---|
+ | Addition | 5 + 3 | 8 |
- | Subtraction | 5 - 3 | 2 |
* | Multiplication | 5 * 3 | 15 |
/ | Division | 5 / 3 | 1.6666... |
// | Integer division | 5 // 3 | 1 |
% | Remainder | 5 % 3 | 2 |
** | Exponentiation | 5 ** 3 | 125 |
+, -, *, / behave like paper maths. The three extras are worth learning early: // divides down to a whole number, % hands you the remainder, and ** raises to a power. I reach for % more than I ever expected to. Division: / vs //
/ always gives you the exact decimal result, even if the answer is a whole number. // drops the fractional part and floors toward negative infinity. For positive numbers that means cutting the decimal, but for negatives it steps one further from zero:
10 / 2 # 5.0 (always float, even when it divides evenly)
10 / 3 # 3.3333333333333335
10 // 3 # 3
7 // 2 # 3
-7 // 2 # -4 (floors toward negative infinity, not toward zero)You will mostly use // with positive numbers. Keep the negative behavior in mind for when they show up.
/ always hands back a decimal, even when it divides evenly: 4 / 2 is 2.0. // drops the fractional part, but watch the negatives: -7 // 2 is -4, not -3, because it floors instead of chopping. Caught me out the first time I did it. The remainder operator %
% gives you what is left over after integer division. If 10 // 3 is 3 (because 3 goes into 10 three times), then 10 % 3 is 1 (because 3 × 3 = 9, and 10 - 9 = 1). The most common use is checking whether a number is even or odd.
10 % 3 # 1
10 % 2 # 0 (divides evenly)
10 % 7 # 3
6 % 2 # 0 (even)
7 % 2 # 1 (odd)% is the leftover after integer division. 10 % 3 is 1 because 3 fits into 10 three times with 1 to spare. You will mostly meet it as the even/odd check: n % 2 is 0 for even, 1 for odd. Exponentiation **
** raises a number to a power. Use two asterisks, not the ^ symbol (which means something else in Python):
2 ** 10 # 1024
3 ** 3 # 27
9 ** 0.5 # 3.0 (square root: raise to the power of 0.5)** raises a number to a power, so 2 ** 10 is 1024. A fractional power gives you a root: 9 ** 0.5 is 3.0. The one trap is the symbol, use **, not ^, which does something unrelated in Python. Operator precedence
Python follows the standard maths order: exponentiation first, then multiplication and division, then addition and subtraction. When you are unsure, use parentheses. They make the intention clear and cost nothing:
2 + 3 * 4 # 14, not 20
2 ** 3 + 1 # 9, not 512
10 - 4 / 2 # 8.0, not 3.0
(2 + 3) * 4 # 20
10 / (2 + 3) # 2.0How int and float interact
Python has a consistent rule: / always returns a decimal, even 4 / 2 gives 2.0. Any operation mixing an integer and a decimal also gives a decimal. When you need a whole number, use // or convert with int().
4 / 2 # 2.0 (float, always)
4 // 2 # 2 (int)
4 + 2 # 6 (int)
4 + 2.0 # 6.0 (float)
4 * 0.5 # 2.0 (float)/ always gives a decimal, so 4 / 2 is 2.0, not 2. Mix a whole number with a decimal anywhere and you get a decimal out. When you need a whole number, reach for // or wrap it in int(). Float precision
There is a gotcha that surprises almost everyone at some point:
0.1 + 0.2 # 0.30000000000000004That tiny error is not a Python bug. Computers store decimal numbers in binary, and some values like 0.1 cannot be represented exactly. It is similar to how 1/3 cannot be written exactly in decimal. For most everyday calculations it does not matter. For displaying money, round() or the :.2f format specifier will keep the output tidy.
0.1 have no exact binary form, so 0.1 + 0.2 comes out as 0.30000000000000004. It isn't a Python bug, every language does this. For everyday output, round() or :.2f keeps it tidy. Readable number literals
Python lets you put underscores in number literals to make large numbers more readable. Python ignores them completely; they are there for you:
population = 8_100_000_000
distance_km = 384_400
pi_approx = 3.141_592_6538_100_000_000 is the same value as 8100000000. Python ignores them entirely, they're there for your eyes, not the interpreter. Useful built-in functions
abs()
abs() returns the absolute value: always positive, regardless of the sign of the input. Use it when you care about how far a number is from zero, not which direction.
abs(-5) # 5
abs(3.7) # 3.7
abs(-0.5) # 0.5abs() strips the sign and hands back the positive size: abs(-5) is 5, abs(3.7) is 3.7. Reach for it when you care how far a number is from zero, not which direction it leans. round()
round() rounds to the nearest integer by default. Pass a second argument to keep a specific number of decimal places:
round(3.7) # 4
round(3.2) # 3
round(3.14159, 2) # 3.14One thing worth knowing: round(2.5) gives 2, not 3. Python rounds to the nearest even number when a value is exactly halfway between two options.
round(x) goes to the nearest whole number, round(x, n) keeps n decimal places. The surprise: a value sitting exactly halfway rounds to the nearest even number, so round(2.5) is 2, not 3. divmod()
divmod() gives you both the quotient and the remainder in a single call. It returns a pair of values, a tuple (covered in the Tuples and sets chapter), that you can assign to two names at once:
divmod(10, 3) # (3, 1): quotient 3, remainder 1
divmod(7, 2) # (3, 1)
divmod(9, 3) # (3, 0)
quotient, remainder = divmod(10, 3)
print(quotient) # 3
print(remainder) # 1divmod(a, b) hands back the quotient and the remainder together: divmod(10, 3) is (3, 1). You can unpack both at once with quotient, remainder = divmod(10, 3). In practice
A tip calculator:
bill = 45.50
tip_rate = 0.18
tip = round(bill * tip_rate, 2)
total = round(bill + tip, 2)
print(f"Bill: ${bill}")
print(f"Tip: ${tip}")
print(f"Total: ${total}")round() keeps the output looking like money rather than a long run of decimal places.

