In Part 1 your programs ran top to bottom, every line, every time. Real programs do not work like that. They check a condition and take one path or another: is the password correct, is the basket empty, is the score high enough for a distinction. This lesson gives your code that ability. You will learn the full set of Python operators, how the language decides what counts as true, and the three tools for branching: the classic if, elif, and else ladder, the conditional expression for one-liners, and the modern match statement introduced in Python 3.10.
This is also the lesson where Python's most famous feature stops being trivia and becomes grammar you use: indentation. Every branching construct creates a block, and in Python a block is defined by how far its lines are indented. Get comfortable with that here and the rest of the course, where blocks nest inside functions inside classes, will feel natural instead of fussy.
What you will learn in Part 2
- Arithmetic, assignment, and comparison operators, including chained comparisons
- Boolean logic with and, or, and not, plus short-circuit evaluation
- Truthiness: what Python treats as true and false beyond True and False
- How indentation defines blocks, precisely and without exceptions
- Branching with if, elif, and else, and one-line conditional expressions
- Structural pattern matching with match and case
Note
Before you start
You should be comfortable with variables, the core types, and f-strings from Part 1. Every example below runs in the playground further down the page, so keep it open in a second tab if you like to experiment as you read.
1. Arithmetic and assignment operators, completed
Part 1 introduced the arithmetic operators in passing; here is the complete picture. Addition, subtraction, and multiplication behave as expected. Division with a single slash always produces a float, even when the answer is whole, because Python refuses to silently throw away precision. The double slash performs floor division, rounding down to the nearest whole number, and the percent sign gives the remainder of that division. Two asterisks raise to a power. The remainder operator is the unsung hero of this set: checking whether a number is even, cycling through a fixed range, and the classic FizzBuzz interview question all hang off it.
print(17 / 5) # 3.4 true division, always float
print(17 // 5) # 3 floor division
print(17 % 5) # 2 remainder
print(17 % 2) # 1 odd number, remainder 1; even numbers give 0
print(3 ** 4) # 81 power
# Augmented assignment rewrites the variable in place
score = 10
score += 5 # same as score = score + 5
score *= 2 # same as score = score * 2
print(score) # 30
The augmented assignment operators, +=, -=, *=, and friends, are pure convenience, but you will see them in every Python file ever written, so make them automatic now. One more operator family worth meeting early: strings respond to + and * too. Adding two strings glues them together, and multiplying a string by an integer repeats it. Python will not, however, add a string to a number; as you learned the hard way in Part 1, it raises a TypeError and tells you exactly why.
2. Comparisons, and a Python party trick
Comparison operators ask questions about values and always answer with a boolean. You have equality ==, inequality !=, and the four orderings <, <=, >, >=. They work on numbers, on strings (alphabetical order, with all capitals sorting before all lowercase letters), and on most things you will meet later. The double equals deserves respect: confusing it with single equals assignment is the classic beginner bug, though Python at least refuses to let you assign inside an if condition, turning the mistake into a visible error instead of a silent one.
age = 19
print(age == 19) # True
print(age != 21) # True
print("apple" < "banana") # True, alphabetical
# Chained comparisons read like math
print(18 <= age < 65) # True: age is between 18 and 64
That last line is the party trick. Most languages force you to write age >= 18 and age < 65. Python lets you chain comparisons exactly the way mathematics does, and the chained form is both shorter and harder to get wrong. Use it whenever you are checking that a value sits in a range.
3. Boolean logic and the idea of truthiness
Conditions combine with three keywords: and, or, and not. An and expression is true only when both sides are true; an or expression is true when at least one side is; not flips its operand. Python evaluates these lazily, a behavior called short-circuit evaluation: in a and b, if a is already false, b is never even looked at, and in a or b, if a is true, b is skipped. This is not just an optimization. Code like balance > 0 and price / balance < 0.5 relies on it: when the balance is zero, the dangerous division on the right never runs.
Python extends true and false beyond the two boolean values, and the rule is worth memorizing once because it never changes. The number zero, the empty string, the empty list, the empty dictionary, and None all count as false in a condition. Everything else counts as true. Pythonic code leans on this constantly: if name: reads as if a name was provided, and if not items: reads as if the list is empty. You will write both of those exact lines hundreds of times in your career.
name = ""
items = [1, 2, 3]
if not name:
print("No name given") # runs: empty string is falsy
if items:
print(f"{len(items)} items") # runs: non-empty list is truthy
logged_in = True
is_admin = False
print(logged_in and is_admin) # False
print(logged_in or is_admin) # True
print(not is_admin) # True
Checkpoint
What does bool("False") evaluate to?
4. Indentation: how Python defines a block
Now the grammar that makes branching possible. A block in Python is a group of statements that belong to a header line, and membership is declared by indentation. The header ends with a colon, and every line indented one level below it belongs to it. The block ends at the first line that returns to the old indentation. The universal convention is four spaces per level, and every serious editor inserts them when you press Tab. The only real rule is consistency: mixing tabs and spaces in one file is an error, and changing indent width mid-file is a readability crime.
If you have programmed elsewhere, this replaces curly braces, and after a day you will not miss them. If Python is your first language, you have it easiest of all: the visual structure you would naturally use to keep code tidy is simply the law. Either way, when Python complains about an IndentationError or an unexpected indent, it is telling you the shape of your code does not match your intent, and the fix is always to line the block up properly.
5. if, elif, and else
The if statement evaluates a condition and runs its block only when the condition is truthy. An optional else block catches the other case. Between them you can stack any number of elif branches, short for else if, which are tested in order until one matches. Exactly one branch of the ladder runs, ever, and the order of the elifs therefore matters: put the most specific tests first. Here is a complete, realistic example, the grade boundary logic used by roughly every school on earth.
score = 73
if score >= 75:
grade = "A"
elif score >= 65:
grade = "B"
elif score >= 50:
grade = "C"
elif score >= 35:
grade = "S"
else:
grade = "F"
print(f"Score {score} earns grade {grade}") # Score 73 earns grade B
Walk the ladder with score 73. The first test fails because 73 is below 75. The second test succeeds, grade becomes B, and the rest of the ladder is skipped entirely, which is why the later, looser conditions never get a chance to overwrite the answer. If you reversed the order and tested score >= 35 first, every passing score would land on S. When a ladder misbehaves, simulate it by hand exactly like this, top to bottom, and the bug almost always reveals itself in seconds.
For tiny choices, Python offers a conditional expression that fits on one line: value_if_true if condition else value_if_false. It shines for simple assignments like label = "even" if n % 2 == 0 else "odd" and becomes unreadable the moment you nest it, so treat it as seasoning, not as a meal.
6. The match statement
Python 3.10 added match, and it is the right tool when you are comparing one value against a series of specific shapes rather than testing arbitrary conditions. The value after match is compared against each case in order; the first pattern that fits wins, an underscore serves as the catch-all default, and you can attach an extra condition to any case with if. Where an if ladder asks many unrelated questions, a match reads like a menu.
command = "help"
match command:
case "start":
print("Starting the engine")
case "stop" | "halt": # either word matches
print("Stopping")
case "help":
print("Available: start, stop, help")
case _:
print(f"Unknown command: {command}")
match can do far more than compare strings; it can destructure tuples, lists, and dictionaries, and later in the series you will see it unpack structured data in one elegant motion. For now, use it whenever an if ladder would consist entirely of x == something tests, and stick with if for everything else. Both are idiomatic; choosing between them is about which one reads better at the call site.
Checkpoint
In an if/elif/else ladder, how many branches execute?
7. Practice: a tax bracket calculator
Time to combine everything: comparisons, boolean logic, a ladder, and f-strings from Part 1. The playground below implements a simplified progressive tax calculation. Run it, then do the exercises in the comments: they ask you to add a bracket, guard against negative input with a truthiness check, and convert one decision to a conditional expression. Every change you make and verify is worth ten you only read about.
Notice how the negative-income guard wraps the whole calculation, with the ladder indented one level deeper inside the else. Nesting like this is normal and healthy up to two or three levels. Beyond that, code becomes hard to follow, and the professional fix is to restructure, usually by returning early from a function, a technique that will make complete sense after Part 4.
! Common mistakes to avoid
-
✕Writing if score = 100: and getting a SyntaxError.
✓Assignment is =, comparison is ==. Python refuses to assign inside a condition precisely to catch this classic slip.
-
✕Forgetting the colon at the end of if, elif, or else lines.
✓Every block header in Python ends with a colon. The error message points at the line; the fix is one keystroke.
-
✕Ordering elif tests from loosest to strictest, so the first loose test swallows everything.
✓Order the ladder from most specific to least specific, and trace one sample value through it by hand to confirm.
-
✕Testing if answer == "yes" or "y": and finding it is always true.
✓That parses as (answer == "yes") or ("y"), and a non-empty string is truthy. Write answer in ("yes", "y") instead.
? Frequently asked questions
Is there a switch statement in Python? +
match, added in Python 3.10, fills that role and goes further with structural patterns. Before 3.10 the idiom was an if/elif ladder or a dictionary lookup, both of which you will still meet in older code.
Why four spaces and not tabs? +
Four spaces is the convention from PEP 8, the official style guide, and the default in every modern editor. What actually matters is consistency within a file; mixing tabs and spaces is a syntax error.
Can I put an if on one line? +
Two ways: the conditional expression (x if cond else y) for choosing a value, and a single-statement suite like if ready: launch(). The first is idiomatic; the second is legal but frowned on outside quick scripts.
Does Python have && and || like other languages? +
No, Python spells them and, or, and not. If you type && you get a SyntaxError; the words are one of the reasons Python conditions read so close to English.
8. Recap and what comes next
Your programs can now think: full arithmetic and comparison operators, chained comparisons, boolean logic with short-circuiting, truthiness, blocks defined by indentation, the if/elif/else ladder, conditional expressions, and match. These tools appear in every single lesson from here to the end of the series, which is exactly why they got a full lesson to themselves.
Decisions alone are not enough; programs earn their keep by repeating work. Part 3, Python loops and flow control covers for, while, break, continue, and the loop patterns that power everything from multiplication tables to data pipelines. The Operators, Decision Making, and Flow Control lessons in the Learn Python app below mirror this material with extra quizzes when you want more reps, and the full syllabus lives on the series hub.
Pro tip
When a condition confuses you, print it. The line print(income <= 500_000, rate) costs nothing and shows the actual booleans your ladder is seeing, which beats staring at code and guessing every time.
Practice on the go
Learn Python, the free Android app
Every topic in this series lives in the app too: bite-size lessons, runnable examples, quizzes, mini projects, and an offline Python playground that runs on your phone.
Comments
0No comments yet. Be the first to share your thoughts.