Booleans and Decision Pitfalls
Introduction: Using Boolean Values as Conditions
Welcome back to Making Decisions in Python! We can guard a block with if, offer an alternative with else, and line up several alternatives with elif.
Let's pause on something we have been doing without naming it. Every condition we have written so far, score >= 90, name == "Ada", or age < 18, was a comparison that produced True or False before Python decided anything. A comparison's result can also be stored in a variable and used later as a condition.
More generally, Python tests the truth value of any expression, so a condition does not have to produce a bool. In this course, we will focus on comparisons, logical expressions, and Boolean variables.
This unit has two goals. First, we will use Boolean variables directly as conditions. Second, we will untangle two structural pitfalls that catch nearly every beginner: stacked if blocks that all run, and an if accidentally nested inside another one.
Storing a Condition in a Boolean Variable
As you may recall, a comparison produces a Boolean that we can store like any other value. Let's do exactly that:
Here is what happens on each line:
Line 1stores the number35intemperature.Line 2evaluatestemperature > 30, which is35 > 30, soTrue; that result is stored inis_hot.
The variable is_hot now holds a plain True: no comparison remains, just the answer. Notice the name we chose. Names such as is_hot, is_ready, or has_access read like yes-or-no questions, which document what is being tested rather than leaving a reader to decode the arithmetic behind it.
Using the Boolean Variable Directly as a Condition
Since is_hot already holds a Boolean, we can hand it straight to if:
Python looks up is_hot, finds True, and runs the indented block:
We deliberately did not write if is_hot == True:. That version works, but it asks a redundant question: comparing True to True to get True again. if is_hot: says the same thing with less noise, and the payoff grows when a condition is long or reused: we compute it once, give it a clear name, then test that name wherever we need it.
Pitfall 1: Several Separate if Blocks Can All Run
Now to the first pitfall. Let's score a quiz with two checks written one after another:
Let's trace the interpreter with points set to 100:
- It tests
100 >= 50, which isTrue, so it printsYou passed. - The first block ends. The second
ifis not attached to it, soPythonsimply continues and tests100 >= 100, alsoTrue, and printsPerfect score!
Two if statements at the same indentation level are two independent decisions, each evaluated on its own. Depending on the data, zero, one, or both blocks may run.
Comparing With an if/elif Chain: One Decision, One Winner
Let's now ask a similar question, but as a single if/elif chain, keeping points at 100:
Python tests 100 >= 100, finds True, prints Top tier, and skips the rest of the chain; the elif is never even evaluated, though 100 >= 50 would have been True too:
Same value, different structure, different result: the stacked version printed two lines, while the chain printed one. A handy rule of thumb: use separate if blocks when the checks are unrelated facts that can all be true at once, and use a chain when the cases are alternatives and only one should win.
Reading the Full Program and Its Output
Let's put every piece together and read the file top to bottom:
Four lines appear, one per block that ran:
Stay hydrated. comes from the Boolean-variable test, You passed. and Perfect score! come from the two independent if blocks, and Top tier comes from the chain. The blank lines and comments carry no meaning for Python, but they show us at a glance where one decision ends and the next begins.
Pitfall 2: Accidentally Nesting One if Inside Another
The second pitfall is subtler because the code still runs. Let's take our two independent checks and indent the second one by mistake:
Indentation alone changed the meaning: the second if is now a statement inside the first block, so it is only tested when points >= 50 is True. With points = 100, the bug hides perfectly since both messages still appear. Now let's set points = 100 aside and try points = 30:
30 >= 50isFalse, so the whole outer block is skipped.- The inner
ifis never reached, so30 >= 100is never tested.
Nothing prints, which is correct here. But imagine if the inner condition were points >= 10: it is True, yet its message would still never appear.
Spotting and Fixing Indentation Mistakes
These bugs are quiet, so a short checklist helps us catch them. This side-by-side sketch makes the three structures easier to compare:
- Line up every independent
ifat the same column; a stray four spaces is the whole bug. - Ask, "Should this check happen no matter what?" If yes, it belongs side by side; if it only makes sense once the first condition holds, nesting is correct.
- Test with a value that makes the outer condition
False, since that is the only case where nesting and side-by-side behave differently.
Here is the repaired version, with both if keywords starting at column one again:
Now the second check runs regardless of the first, so You scored some points. prints even though the passing check failed.
Conclusion and Next Steps
Let's collect the takeaways. Python tests the truth value of the expression after if or elif, so a Boolean variable such as is_hot can be tested directly with if is_hot:, no == True required. Two if statements at the same indentation level are independent decisions, and both may run. An if/elif chain is a single decision that runs at most one branch. And indentation, nothing else, decides whether an if sits inside another block or beside it.
Congratulations on mastering these decision-making tools! We can now write programs that choose among many paths using if, else, elif, comparisons, and named Boolean conditions, and we can read a block's indentation to predict exactly what will run.
Let's put it all to the test: in the practices ahead, you will name a condition and test it directly, watch two stacked if blocks both fire, fold them into a chain that picks a single winner, and rescue a program from one misplaced indent.
