Operators and Expressions
An expression is any piece of code that produces a value. 5 + 3 is an expression — it produces 8. "Hello " + "World" is an expression — it produces "Hello World". Operators are the symbols (+, -, ==, and, and others) that combine values into expressions.
Arithmetic operators
Run it, then change the two numbers and run it again — try to predict each output before you see it.
// and % trip up almost everyone at first, so it's worth sitting with them: 7 // 3 asks "how many whole times does 3 fit into 7?" (twice), and 7 % 3 asks "what's left over after that?" (1, since 3×2=6 and 7−6=1). This exact pair — floor division and modulo — is how real programs check things like "is this number even?" (n % 2 == 0) or convert a total number of seconds into minutes and seconds.
+ and * work on strings too, not just numbers
print("Hello " + "World") # "Hello World" — concatenation, not addition
print("ha" * 3) # "hahaha" — repetition
The same + symbol means something entirely different depending on what it's applied to — adding two numbers versus joining two pieces of text. This is a real, deliberate design choice in Python (called operator overloading — you'll see the real mechanism behind it in Week 8), not an accident. * between a string and a number repeats the string that many times — genuinely useful for quick formatting, like printing a horizontal divider: print("-" * 20).
Comparison operators
These always produce a boolean — True or False:
print(5 == 5) # True — equal to (note: TWO equals signs, not one)
print(5 != 3) # True — not equal to
print(5 > 3) # True — greater than
print(5 < 3) # False — less than
print(5 >= 5) # True — greater than or equal to
print(5 <= 3) # False — less than or equal to
The single most common beginner mistake in all of Python is writing x = 5 when you meant x == 5. A single = assigns a value to a variable. A double == compares two values and gives you back True or False. They do completely different things, and Python will not warn you if you use the wrong one in a place where both are technically legal — this is worth genuinely memorizing now.
Python also allows a real, genuinely elegant shorthand for a range check — chained comparisons:
age = 25
print(18 <= age <= 65) # True — reads almost like real English, and IS valid Python
Boolean (logical) operators
These combine multiple True/False values:
and requires every condition to be true. or only requires one. not simply flips a boolean. Real programs lean on this constantly — "let them in if they're an adult AND they have ID" is exactly age >= 18 and has_id. Try changing has_id to False above and re-running — watch how only one of the three outputs actually changes.
Operator precedence
Just like in math, Python evaluates ** before *//, before +/-, before comparisons, before and/or. When in doubt, use parentheses — (age >= 18) and has_id behaves identically to the version without parentheses here, but is easier for a human to read at a glance, and that readability genuinely matters once your code gets more complex.
This week's practical exercise
Work out, on paper or in your head, an expression that checks whether a year is a leap year using only what you've learned so far: a year is a leap year if it's divisible by 4, EXCEPT century years (divisible by 100) UNLESS they're also divisible by 400. Check your expression by hand against 2024 (leap), 1900 (not a leap year — divisible by 100 but not 400), and 2000 (leap — divisible by 400). Then try it for real in the runnable box above. This is real logic used in real calendar software, not a toy problem.
Further reading
- Python's official operator precedence table — the complete, authoritative reference
- Python's built-in types and their operators — covers exactly which operators work on which types