Output Puzzles: Operators, Division and Truthiness
40 min · Intermediate
Need help? Ask a tutor on WhatsApp (opens in a new tab)Output rounds give you a few lines of Python and ask what prints. Most traps come from a small set of rules: how // and % treat negatives, how floats are stored, which values count as false, and when and / or stop early. Learn the rules, then trace line by line.
Division, modulo and rounding
Floor division (//) divides and rounds the result down to the nearest whole number below it. For negative results this is further from zero, so -7 // 2 is -4, not -3.
Python has two division operators. / always gives a float. // rounds down toward minus infinity, not toward zero.
print(7 // 2, -7 // 2)print(-7 % 3, 7 % -3)print(round(2.5), round(3.5))The result of % takes the sign of the right-hand number, so a == (a // b) * b + a % b always holds.
Example 1 · Negative numbers and the division identity
a, b = -17, 5q, r = a // b, a % bprint(q, r)print(q * b + r == a)print(divmod(a, b))-4 3 True (-4, 3)
What this code does
//rounds down, so -17 // 5 is -4, not -3.- The remainder is then 3, so that -4 * 5 + 3 gives back -17.
divmodreturns both parts in one call.
This prints 3 -4, then 2 -2, then 2 4. round() sends exact halves to the nearest even number, so 2.5 becomes 2.
Floats are approximate
Python stores a float in binary, and most decimals such as 0.1 have no exact binary form. Small errors appear when you add them.
print(0.1 + 0.2)print(0.1 + 0.2 == 0.3)print(2 ** 100)Integers are different. An int has no size limit, so 2 ** 100 is exact and never overflows.
Example 2 · Floats and exact cents
price = 0.1 + 0.2print(price == 0.3, round(price, 2) == 0.3)cents = 10 + 20print(cents == 30)False True True
What this code does
- The raw float sum is slightly above 0.3, so
==fails. - Rounding to 2 places or using whole cents gives a reliable comparison.
The first line prints 0.30000000000000004, the second False. Compare money in whole cents, or use round() before comparing.
Truthiness
Truthiness is whether Python treats a value as true or false in a condition. 0, 0.0, "", [], {}, () and None are falsy; nearly all other values are truthy, even the string "False".
Every object can be used in an if. Zero, empty collections, empty strings and None are false. Almost everything else is true.
print(bool(0), bool(""), bool([]))print(bool("False"), bool([0]), bool(None))Example 3 · A default with or
def display_name(nickname, username): return nickname or username or "guest"
print(display_name("", "asha_k"))print(display_name("", ""))print(display_name("Ash", "asha_k"))asha_k guest Ash
What this code does
orreturns the first truthy value, so empty strings are skipped.- This is a common way to supply a default, but it also skips a valid
0.
The first line prints False False False, the second True True False. A list holding 0 is not empty, so it is truthy.
Short-circuiting with and, or
Short-circuit evaluation means and / or stop at the first operand that decides the result. The remaining operands are never evaluated, so any calls inside them never run.
and and or do not return True or False. They return one of their operands and stop as soon as the answer is known.
print(0 or "" or "guest")print(5 and 0 and 9)print(1 < 2 < 3)Example 4 · Skipped calls
log = []
def check(name, result): log.append(name) return result
check("a", False) and check("b", True)check("c", True) or check("d", True)print(log)['a', 'c']
What this code does
check("b")never runs becauseFalse and ...is already false.check("d")never runs becauseTrue or ...is already true.
or returns the first truthy operand (guest). and returns the first falsy one (0). 1 < 2 < 3 means 1 < 2 and 2 < 3, so it is True.
Next step
Check your understanding
12 quick questions