Python Operators and Precedence
Objective 1.4 asks you to choose operators adequate to the problem, and in practice that means predicting what an expression evaluates to. There are only four facts behind most of the questions: `/` always produces a float, `//` floors towards negative infinity, `**` groups right to left and binds tighter than unary minus, and `and`/`or` return one of their operands rather than a boolean. Everything else is a precedence table you can reason from.
Language Fundamentals Guide 7 of 26 Beginner
- Python3.14.4
- OSUbuntu 26.04 LTS
- pip25.1.1
- TimeAbout 18 min
- Reviewed23 August 2026
Written against the versions above. Nothing in this guide has changed since Python 3.0. `/` producing a float and `//` being a separate operator are *the* Python 3 change here, so any material showing `3 / 2` as 1 is Python 2 and should be discarded entirely.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| RUNNER01 | 192.168.0.27 | Ubuntu 26.04 LTS | Python 3.14.4 - the only machine this path needs | 2 Core | 4 GB | 50 GB |
Before you start
- guide 6 - you should know
boolis anint. - Nothing else.
-
The two divisions, and the remainder
This is the highest-yield fact in the objective. Python has two division operators and they differ in return type as well as in result.
/is true division and always returns a float, even when the division is exact.//is floor division and returns anintonly if both operands are ints.Work out all seven lines before playing this.
bash Example session cat > ~/py/divs.py <<'PY'print("4 / 2 =", 4 / 2, type(4 / 2).__name__)print("4 // 2 =", 4 // 2, type(4 // 2).__name__)print("4.0 // 2=", 4.0 // 2, type(4.0 // 2).__name__)print("-7 // 2 =", -7 // 2)print("7 % 3 =", 7 % 3, " -7 % 3 =", -7 % 3, " 7 % -3 =", 7 % -3)print("7.5 % 2 =", 7.5 % 2)print("divmod(7, 2) =", divmod(7, 2))PYpython3 ~/py/divs.py4 / 2 = 2.0 float4 // 2 = 2 int4.0 // 2= 2.0 float-7 // 2 = -47 % 3 = 1 -7 % 3 = 2 7 % -3 = -27.5 % 2 = 1.5divmod(7, 2) = (3, 1)Expected result
4 / 2is2.0and a float;4 // 2is2and an int;4.0 // 2is2.0.Success conditionYou can predict both the value and the type of any division.
-
Exponentiation groups right to left
is the only arithmetic operator in Python that is right-associative:23 2 is2(3 2), not(23) ** 2. Every other arithmetic operator groups left to right.It also binds tighter than unary minus, which is where the second surprise comes from.
bash Example session cat > ~/py/power.py <<'PY'print("2 ** 3 ** 2 =", 2 ** 3 ** 2)print("(2 ** 3) ** 2 =", (2 ** 3) ** 2)print("-2 ** 2 =", -2 ** 2)print("(-2) ** 2 =", (-2) ** 2)print("2 ** -1 =", 2 ** -1)PYpython3 ~/py/power.py2 ** 3 ** 2 = 512(2 ** 3) ** 2 = 64-2 ** 2 = -4(-2) ** 2 = 42 ** -1 = 0.5Expected result512 and 64 - two different answers - then -4 against 4, and 0.5.
Success conditionYou can bracket a chained exponent correctly without guessing.
-
Precedence, in the only order worth memorising
The full table has fifteen levels. These are the ones questions are built on, highest first:
| Level | Operators | Groups | |---|---|---| | 1 |
| right to left** | | 2 |+x,-x,~x(unary) | right to left | | 3 |*,/,//,%| left to right | | 4 |+,-(binary) | left to right | | 5 |<<,>>| left to right | | 6 |&| left to right | | 7 |^| left to right | | 8 |\|| left to right | | 9 | comparisons,in,is| chained | | 10 |not| right to left | | 11 |and| left to right | | 12 |or| left to right |Four consequences to hold:
**beats unary minus;*and/beat+and-; bitwise operators bind looser than arithmetic but tighter than comparison, soa & b == cmeansa & (b == c); andnotbinds tighter thanand, which binds tighter thanor.bash Example session python3 -c 'print(2 + 3 * 4, (2 + 3) * 4, 10 - 4 - 3, 2 * 3 % 4)'14 20 3 2Expected result
14 20 3 2.Success conditionYou can evaluate a mixed expression by precedence rather than left to right.
-
Comparison, and the chaining Python allows
The comparison operators are
==,!=,<,>,<=,>=. They returnTrueorFalse, and Python lets you chain them the way mathematics does -1 < 2 < 3is legal and means what it looks like.bash Example session python3 -c 'print(1 < 2 < 3, 3 > 2 > 1, 1 < 2 > 3, 1 == 1.0)'True True False TrueExpected result
True True False True.Success conditionYou can read a chained comparison and know it is not comparing booleans.
-
and, or, not - and what they actually return
andandordo not return booleans. They return one of their operands, chosen by truthiness, and they short-circuit - the right-hand side is not evaluated when the left already decides the answer.The third line below is the proof:
1 / 0would raise, and does not.bash Example session cat > ~/py/logic.py <<'PY'print(0 or "fallback")print("a" and "b")print(0 and 1 / 0)print(not 0, not "", not "x")PYpython3 ~/py/logic.pyfallbackb0True True FalseExpected result
fallback,b,0, thenTrue True False.Success conditionYou can predict which operand an
and/orexpression returns. -
Bitwise operators
Six of them:
&(and),|(or),^(xor),~(not),<<and>>(shifts). They work on the individual bits of integers, and they are a distinct group from the logical operators -&is notand.0b1100is 12 and0b1010is 10;bin()is used on the results so the bits stay visible.bash Example session cat > ~/py/bits.py <<'PY'a, b = 0b1100, 0b1010print("a & b =", bin(a & b))print("a | b =", bin(a | b))print("a ^ b =", bin(a ^ b))print("~5 =", ~5)print("5 << 2=", 5 << 2, " 20 >> 2 =", 20 >> 2)PYpython3 ~/py/bits.pya & b = 0b1000a | b = 0b1110a ^ b = 0b110~5 = -65 << 2= 20 20 >> 2 = 5Expected result
0b1000,0b1110,0b110, then-6, then20 5.Success conditionYou can compute a bitwise result by hand and check it.
-
Shorthand assignment
Every binary operator has a compound assignment form:
+=,-=,*=,/=,//=,%=,**=, and the bitwise ones too.x += 5meansx = x + 5.They are not merely shorthand for readability - they are examined as their own syntax, including on strings.
bash Example session cat > ~/py/shorthand.py <<'PY'x = 10x += 5print(x)x //= 4print(x)x **= 2print(x)s = "ab"s *= 3print(s)PYpython3 ~/py/shorthand.py1539abababExpected result15, then 3, then 9, then
ababab.Success conditionYou can trace a variable through a run of compound assignments.
-
Operators on strings, and the one that is missing
Objective 1.4 explicitly includes string operators. Three of them work:
+concatenates,*repeats, andin/not intest for a substring.What does not work is instructive.
bash Example session python3 -c 'print("ab" + "cd", "ab" * 3, "b" in "abc", "z" not in "abc")'abcd ababab True Truepython3 -c 'print("ab" - "a")'Traceback (most recent call last): File "<string>", line 1, in <module> print("ab" - "a") ~~~~~^~~~~TypeError: unsupported operand type(s) for -: 'str' and 'str'[exit 1]Expected result
abcd ababab True True, then aTypeError.Success conditionYou know which arithmetic operators strings accept.
-
What the exam does with this objective
Objective 1.4 shares 18% of PCEP with the rest of block 1, and it is where the "what does this print?" questions concentrate. The recurring shapes:
Type of a division.
4 / 2is2.0, a float. Always.Floor division with a negative.
-7 // 2is -4.A chained exponent.
2 3 2is 512.Unary minus against an exponent.
-2 ** 2is -4.What
orreturns. An operand, not a boolean.~n.-n - 1.A run of compound assignments. Trace them in order; do not shortcut.
The one technique worth practising is bracketing an expression on paper by precedence before evaluating it. Every trap above disappears once the brackets are explicit.
guide 8 finishes objective 1.4 with the conversion half.
bash rm -f ~/py/divs.py ~/py/power.py ~/py/logic.py ~/py/bits.py ~/py/shorthand.py && ls -A ~/pyExpected resultAn empty scratch directory.
Success conditionYou can bracket and evaluate any expression the objective can produce.
Troubleshooting
-7 // 2gives -4 and you expected -3.Why:
//floors towards negative infinity; it does not truncate towards zero.Fix:Use
int(-7 / 2)for truncation - that gives -3. Ormath.trunc(). But learn the floor behaviour, because that is what the exam asks about.TypeError: unsupported operand type(s).Why: An operator that does not exist for those types - subtracting strings, multiplying two strings, adding a string to a number.
Fix:Convert explicitly.
"5" + 5fails;int("5") + 5and"5" + str(5)both work and mean different things.2 3 2is 512 and you expected 64.Why:
**is right-associative - the only arithmetic operator in Python that is.Fix:Bracket it:
(2 3) 2if that is what you meant. Every other arithmetic operator groups left to right.a & b == cgives an unexpected result.Why:
&binds tighter than arithmetic but looser than==, so this isa & (b == c).Fix:Bracket bitwise comparisons explicitly:
(a & b) == c. This trips people who assume bitwise operators sit with the arithmetic ones.x++is a syntax error.Why: Python has no increment or decrement operators.
Fix:Use
x += 1.++xparses but means unary plus twice and changes nothing.