Conditional Statements and Decision Logic

Getting Started with Code · 30 min

Programming foundations · Control flow

Conditionals & decision logic

One value walks down an else-if ladder and exactly one branch runs. This page traces marks = 72 rung by rung, then writes the same four conditions in the wrong order and watches the same student get a different grade.

Walk 72 down both ladders
marks = 72one value goes into the ladder
first true wins≥90 no · ≥75 no · ≥60 yes
grade = C≥40 and else never tested

01 The idea

Ask a question, and only ask the next one if the answer was no

Code that runs straight down the page can do exactly one thing. Real programs have to choose: pass or fail, admin or student, cash or card. A conditional is how you write that choice — a question that is either true or false, and a block of code that runs only when it is true.

Once there is more than one outcome you stop writing separate questions and start writing a ladder. Ask the first question. Only if the answer is no, ask the second. That "only if" is the part that catches people out, because a rung the value never reaches cannot be right or wrong. It is simply dead code that looks alive.

An else-if ladder is tested top to bottom and stops at the first condition that is true. Every rung below it is skipped without ever being tested — so the order you write the rungs in is the logic, not a matter of style.
ConditionThe true-or-false expression that guards a branch. marks >= 60 is a condition. The branch it guards runs only when the expression evaluates to true.
BranchOne block of code guarded by a condition. Across a whole if / else-if / else chain, at most one branch ever runs — never two, no matter how many conditions happen to be true.
else-if ladderA chain of conditions tested in written order. The first true one wins and the chain exits; the rungs below it are not evaluated at all, whether they would have been true or not.

02 Hand trace

marks = 72, one rung at a time

Five grade bands: 90 and above is an A, 75 and above a B, 60 and above a C, 40 and above a D, and anything below 40 is an F. Written as a ladder with the highest band first, that is four conditions and one else. Push marks = 72 into it and follow 72 down the rungs. A rose box is a condition that was tested and came back false. A green box is the one that came back true. A plain box was never touched.

test 1≥90≥75≥60≥40else72 ≥ 90 is false → A ruled out, drop a rung
test 2≥90≥75≥60≥40else72 ≥ 75 is false → B ruled out, drop a rung
test 3≥90≥75≥60≥40else72 ≥ 60 is true → grade = "C", chain exits here
result≥90≥75≥60≥40else3 conditions tested, 2 rungs never looked at

Two numbers matter more than the answer. The first is three: only three of the four conditions were evaluated, and the else is never evaluated at all — it is simply what is left. The second is one: exactly one branch ran. The ≥40 rung is also true for 72 — the machine simply never asked it, because the chain had already exited. That is the whole mechanism, and it is why the next section can break this ladder without changing a single condition.

03 Code

Same four conditions, two orders, two grades

The trace worked because the rungs were in descending order. Put the same conditions in ascending order and every line is still legal. The program compiles, nothing crashes, no warning appears — and the answer is wrong. This is the failure mode you need to recognise on sight.

Wrong order · lowest band first

if   marks >= 40: grade = "D"   # loosest test firstelif marks >= 60: grade = "C"   # unreachableelif marks >= 75: grade = "B"   # unreachableelif marks >= 90: grade = "A"   # unreachableelse:             grade = "F"# marks = 72 -> "D"  after 1 test

Right order · highest band first

if   marks >= 90: grade = "A"   # tightest test firstelif marks >= 75: grade = "B"elif marks >= 60: grade = "C"   # 72 stops hereelif marks >= 40: grade = "D"else:             grade = "F"# marks = 72 -> "C"  after 3 tests

Order is the logic, not a style choice. Both blocks hold the same four conditions, the same else and the same five grades. Only the sequence differs. On marks = 72 the left block stops at rung 1 and answers D; the right block walks to rung 3 and answers C. Nothing else was edited.

The lower rungs are not wrong, they are unreachable. Any mark that reaches elif marks >= 60 in the left block has already failed marks >= 40, so it is under 40 and cannot possibly be 60 or more. The same argument kills rungs 3 and 4. That five-rung ladder has exactly two branches that can ever run: the first one and the else. Every passing student gets a D.

Nesting says the same thing with more room to get it wrong. You could write this as if marks >= 40: with another if marks >= 60: inside it. Nesting is the right tool when the inner question only makes sense once the outer one passed — check the file exists, then read it. When both tests sit on the same axis, keep the ladder flat: you can read the thresholds straight down the page and see at a glance whether they descend.

The other way to write a choice: switch

A switch compares one value against constant labels and jumps to the match. It cannot express a range, so it can never replace the ladder above — but it is the usual shape once you already have the grade letter. It also carries the single most famous bug in this module.

switch (grade) {                // grade = 'C', from marks = 72  case 'A': msg = "Distinction";  break;  case 'B': msg = "First class";  break;  case 'C': msg = "Second class";         // break forgotten  default:  msg = "Needs work";            // runs as well}                                // msg ends up "Needs work"

A case runs on until it hits a break. switch jumps to the matching label and then keeps executing forward, ignoring every label it passes. Our C student matches case 'C', sets "Second class", finds no break, and falls straight into default. Fall-through is deliberate only when you stack labels with no code between them — case 'A': case 'B': to give two grades one shared block. Python has no such thing; its match never falls through.

05 Cheat sheet

What gets asked about conditionals

ConstructWritten asWhat catches people
Two separate ifsif a: … if b: …Both blocks can run. As grade bands, marks = 72 sets C and then D, and the last assignment wins.
if / elseif a: … else: …Exactly one of the two runs. The else binds to the nearest unmatched if, which is why braces matter in C and Java.
else-if ladderif / elif / elseTop to bottom, first true wins, the rest are never evaluated. Order is the logic.
Nested ifif a: if b: …The inner test runs only when the outer passed. Two independent tests belong in a and b, not in two levels.
switch on one valuecase v: … break;Equality against constants only — no ranges. A missing break falls through into the next case.
Ladder with no elseif / elifZero branches can run. Whatever the branches were meant to set silently keeps its old value.
= is not ==In C and C++, if (x = 5) assigns 5 to x and then tests 5, which is non-zero, so the branch always runs. Java rejects it unless x is a boolean. Python rejects it as a syntax error.
Never == two floatsMost decimals cannot be stored exactly in binary, so 0.1 + 0.2 == 0.3 is false — the sum is 0.30000000000000004. Compare with a tolerance: abs(a - b) < 1e-9.
A case without break keeps goingIn C, C++, Java and JavaScript, execution enters at the matching label and runs forward until a break or return. Stacked labels with no code between them are the one legitimate use.

06 Where & why

Ladder, switch, or a table of data

A ladder is the most general of the three and the hardest to read once it passes about five rungs. What you buy is that any expression at all can go in a rung — ranges, two different variables, a function call. A switch cannot do that, and a lookup table cannot either.

Reach for a ladder when…

The conditions are rangesmarks >= 60 is not an equality, and a switch only matches constants. Bands, tiers and thresholds have to be a ladder.
The rungs test different thingsOne rung looks at marks, the next at attendance, the next at a flag. A switch inspects a single value; a ladder has no such limit.
First match is what you wantYou are deliberately relying on the earlier rung winning — a discount ladder where the best offer is checked first.
There are five rungs or fewerShort enough that you can read it top to bottom and check the ordering by eye. Past that, the ordering bug stops being visible.

Use something else when…

SituationBetter choiceWhy
Every rung compares the same variable to a constant — a menu choice, a status code, a day nameswitch / matchOne value against many labels reads better, and a compiler can often jump straight to the case instead of testing rungs one by one.
Each rung only maps a key to a value — grade to message, code to labelA dictionary or lookup tablemsg[grade] is one line, and adding a band means adding a row of data rather than another branch to order correctly.
The band boundaries are data an admin can changeA sorted array of (threshold, grade) pairsThe ordering is enforced by sorting the array instead of by whoever typed the rungs, and a new band needs no code change.
You are choosing between exactly two valuesA conditional expression"pass" if marks >= 40 else "fail" is one expression with no rungs to put in the wrong order.
Interviewers rarely ask you to write a ladder. They hand you one that is subtly out of order, or one with a missing break, and ask what it prints. Being able to hold one value in your head and walk it down the rungs in order is the skill actually being tested.

07 Interview questions

Say these out loud

The ladder-order question and the missing-break question are the two that actually come up. Both are read-this-code questions, not define-this-term questions.

What is the difference between an if / else-if chain and a series of separate if statements?
In an if / else-if chain at most one branch runs — the first true condition wins and the rest are never evaluated. Separate if statements are independent, so two or more of them can run on the same input. Write the grade bands as four separate ifs and marks = 72 sets grade to C and then to D, so the student ends up with a D.
Does the order of conditions in an else-if ladder matter?
Yes — the order is the logic. The ladder stops at the first true condition, so a loose condition placed above a stricter one makes the stricter one unreachable. Write the grade bands from marks >= 40 upward and every passing student gets a D, because 72 >= 40 is true and the ladder never reaches >= 60.
Walk me through what happens to marks = 72 in the grade ladder.
72 >= 90 is false, 72 >= 75 is false, 72 >= 60 is true, so grade becomes C and the chain exits. Three conditions were evaluated and one branch ran. The >= 40 rung is also true for 72, but it is never tested, and that is the point of the whole construct.
How many conditions are evaluated in the best and worst case?
One in the best case, when the first rung matches — marks = 95 costs a single test. All of them in the worst case, when the value falls through to the else: marks = 35 costs four tests, one per condition, and the else is not a test at all. So a ladder of k conditions costs up to k tests. Putting the most likely condition first saves tests, but only when the conditions cannot both be true — grade bands overlap, because 72 satisfies >= 60 and >= 40 at once, so reordering them changes the answer and is not an option.
What is short-circuit evaluation and why does it matter inside a condition?
With and, the second operand is not evaluated once the first is false; with or, it is not evaluated once the first is true. That lets you write if p is not None and p.age > 18 and know the second half never runs when p is missing. Swap the two halves and you get a crash instead, so the order inside a single condition matters for the same reason the order of rungs does.
What happens if you write = instead of == inside an if?
In C and C++ it compiles: if (x = 5) assigns 5 to x and then tests 5, which is non-zero, so the branch always runs and x is quietly overwritten. Java rejects it unless the variable is a boolean, and Python rejects it as a syntax error. Some people write the constant on the left — if (5 == x) — so the typo becomes a compile error.
Why should you never compare two floating-point numbers with ==?
Because most decimal fractions have no exact binary representation, so arithmetic leaves a tiny error. 0.1 + 0.2 == 0.3 is false — the sum is 0.30000000000000004. Compare against a tolerance instead, such as abs(a - b) < 1e-9. It bites in ladders too: a computed mark of 39.999999 fails a >= 40 test that a human would pass.
What is fall-through in a switch, and when is it useful?
A case that does not end in break or return keeps executing straight into the next case's code. Usually that is a bug: drop the break after case 'C' and a C student also runs default and gets the wrong message. It is deliberate only when you stack labels with no code between them, like case 'A': case 'B': sharing one block.
if-else ladder or switch — which do you pick and why?
A switch tests one value against constant labels, so a compiler can often build a jump table and go straight to the matching case. A ladder tests arbitrary expressions, including ranges like marks >= 60, which a switch cannot express at all. Grade bands are ranges, so they must be a ladder; a menu choice or a status code is equality on one value, so it should be a switch.
When is nesting better than a flat ladder, and when is it worse?
Nesting is right when the inner question only makes sense after the outer one passed — check the file exists, then read it. It is worse when the two tests are independent, because if a: if b: is just if a and b: with an extra level and an extra place to attach an else. More than two levels deep usually means you should invert the outer test and return early.
Can an else-if ladder run zero branches?
Yes, if there is no else and no condition is true. Nothing runs, and any variable the branches were supposed to set silently keeps its old value — which is how a grade ends up as an empty string with no error anywhere. Add an else whenever the ladder is meant to always produce a value.
When would you actually use this?
Constantly, which is exactly why it is asked. Nobody is testing whether you can define if; they hand you a ladder that is subtly out of order or a switch with a missing break and ask what it prints. The skill is reading one accurately with a single value in your head, and noticing when a rung can never be reached.

08 Practice problems

Read the ladder before you write one

For each one, pick a single value and walk it down the rungs in written order. If you cannot say which rung it stops at, the ladder is not finished yet.

Grade the wrong ladder

Easy
Take the grade ladder written from marks >= 40 upward and state exactly what it returns for 95, 72 and 35.
Follow-up
One of the three inputs already comes back correct, so a single test case would have let this bug ship.
Show the hint
Walk each value down the rungs in written order and stop at the first true one — do not read ahead.

Leap year in three rules

Easy
Write a ladder that returns true when a year is a leap year: divisible by 400 is a leap year, other centuries are not, and any other year divisible by 4 is.
Follow-up
Test year % 4 == 0 first and the year 1900 comes back as a leap year, so the order of the three rules decides the answer just like the grade bands did.
Show the hint
The most specific rule has to be tested before the most general one that would also match it.

Ticket price by age

Medium
A cinema charges nothing under 5, half price from 5 to 17, full price from 18 to 59, and a senior rate at 60 and over. Write it as one ladder, then say which price each of 5, 17, 18 and 60 pays.
Follow-up
Now write the same four bands lowest band first. That version needs an upper bound on almost every rung — say what the 5-to-17 rung has to become, and why the highest-first version needs no upper bound anywhere.
Show the hint
A rung only ever sees the values the rungs above it did not already take, so for each ordering ask what has been ruled out by the time this rung is reached.

The missing break

Medium
Given the switch from section 03 with no break after case 'C', list the message assigned for grade A, B, C and Z.
Follow-up
Only one of the four inputs is affected, and its wrong output is identical to the output for an invalid grade — so the message alone cannot tell you whether the bug fired.
Show the hint
Execution enters at the matching label and then runs forward past every later label until it meets a break.

Nesting that a single and cannot replace

Medium
Write the eligibility rule as a nested if: marks 60 or above and attendance 75 or above gives "eligible", marks 60 or above with lower attendance gives "short attendance", and anything else gives "not eligible".
Follow-up
Flattening the two tests into marks >= 60 and attendance >= 75 makes the middle message impossible, because one else now has to cover two different failures.
Show the hint
Keep the outer test separate the moment its else needs to say something different from the inner one's.

Tax slabs, not tax rates

Hard
Tax is charged in slabs: nothing on the first 250000, 5% on the part between 250000 and 500000, 20% on the part between 500000 and 1000000, and 30% on anything above 1000000. Write one ladder that turns an income into the total tax, then check it on 400000 and 1200000.
Follow-up
Multiplying the whole income by the rate of the slab it lands in is wrong for every income above 250000 — an income of 600000 owes 32500, not 120000 — so each rung has to add the tax the slabs beneath it have already produced in full.
Show the hint
Put the highest slab first, and inside each branch subtract that slab's starting point from the income before applying its rate, then add the fixed total the lower slabs come to.