2.1 Syntax, types and control flow
Checked against the Python 3 documentation, August 2026
What this is and why it exists
This is the floor of the language: values, conditions and loops, enough to write a script that reads input, decides and prints. Everything after this module — pandas, PyTorch, agent frameworks — is these same constructs wearing better clothes, so time spent here is not preparation for the real work, it is the real work in its smallest form.
The vocabulary
- Value and type — every value has a type, and the type decides what operations are legal on it.
- int, float — whole numbers and decimals; floats are approximations, which matters more than beginners expect.
- str — text, immutable: every operation that looks like editing a string produces a new one.
- bool —
TrueorFalse. - None — the absence of a value; not zero, not an empty string, its own thing.
- Truthiness — whether a value counts as true in a condition, even when it is not a bool.
- Statement and expression — an expression produces a value, a statement does something.
- Block — the indented lines belonging to an
if, a loop or a function; indentation is syntax in Python, not decoration.
The mental model
Python evaluates expressions and executes statements, and the shape of your program is the indentation. That last point is worth taking seriously rather than resenting: the visual structure and the actual structure cannot disagree, which removes a whole family of bugs that other languages allow.
Conditions are where the interesting behaviour lives, because Python does not require a bool. Any value can be tested, and the rule is precise — the documentation lists most of the built-in objects considered false as "constants defined to be false: None and False", "zero of any numeric type", and "empty sequences and collections: '', (), [], {}, set(), range(0)". Everything else is true.
That is convenient and it is the module's first trap. if results: reads as "if we got results", and it is false for an empty list — which is usually what you meant — and also false for None, and also false for 0. So a function that returns a count of zero, or a value that has not arrived yet, takes the same path as one that failed. When you mean "did this succeed", test the thing you mean: if results is not None: or if len(results) > 0:. The general rule is to use truthiness for containers where empty and absent should behave alike, and to be explicit everywhere else.
Comparison chaining is a small piece of syntax worth knowing because it reads exactly as mathematics does: 0 <= score <= 100 means both comparisons, evaluated once each. And == compares values while is compares identity — two lists with the same contents are equal but not identical, and is should be reserved for None, True and False, where identity is what you actually mean.
Loops come in two kinds and one uncommon extra. for walks over something that can be walked over. while repeats until a condition stops being true. break leaves a loop immediately and continue skips to the next round. Then the piece that surprises people: a loop can have an else. The documentation is exact — "if the loop finishes without executing the break, the else clause executes", and "in either kind of loop, the else clause is not executed if the loop was terminated by a break". Read it as "and nothing was found", which is exactly the search pattern it exists for.
In code
Checked against the Python tutorial and the built-in types reference.
scores = [88, 42, 95]
if not scores:
print("no scores at all")
elif len(scores) < 3:
print("not enough to judge")
else:
print(f"average {sum(scores) / len(scores):.1f}")
for score in scores:
if 0 <= score <= 100:
continue
print(f"impossible score: {score}")
break
else:
print("every score is in range")
total = 0
i = 0
while i < len(scores):
total += scores[i]
i += 1Note the for-else at work: the message prints only when no break happened. And note that the while loop is the clumsier way to do the same thing — in Python, if you find yourself managing an index by hand, there is almost always a for that reads better.
What you should now be able to explain or do
Write a hundred-line script that reads something, decides something and prints something. List the values Python considers false without looking. Say what goes wrong with if results: when the answer is legitimately zero, and write the explicit test instead. Read 0 <= score <= 100 aloud and say how many comparisons happen. Explain when is is right and when == is. Use for-else for a search and say what stops the else from running.
Check yourself
Which values are false in Python?
None and False, zero of any numeric type, and empty sequences and collections — the empty string, tuple, list, dict, set and an empty range. Everything else is true.
A function returns the number of errors found, and you write if errors:. What is the bug?
Zero errors is false, which is what you wanted — but so is None, if the function failed and returned nothing. Success with zero and outright failure take the same path. Test what you actually mean.
What is the difference between == and is?
== compares values; is compares identity — whether they are the same object. Two equal lists are not the same object. Reserve is for None, True and False.
When does the else on a for loop run?
When the loop finished without a break. It is the "and nothing was found" path of a search, which is why it looks strange until you see it used for one.
Why is Python's indentation being syntax an advantage rather than a nuisance?
Because the structure you see and the structure the interpreter uses cannot disagree. In languages where they can, they eventually do.
Go deeper
We haven't checked most of these for screen reader use yet.
Using a screen reader? 1 resource
- Getting Started with Python · Coding In Blind (Joel Dodson) · Docswritten for screen reader users
Back to Syntax, types and control flow: work through the checklist