8.1 Sequence and Selection: if, else, Chained and Nested Conditions
Key Takeaways
- Every algorithm can be built from three constructs: sequence (steps in order), selection (choosing a path with if/else), and iteration (repeating with loops).
- In an if / else if chain, conditions are tested from the top, and only the first true branch runs; checking score ≥ 70 before score ≥ 90 makes the "A" branch unreachable.
- A nested if runs its inner test only when the outer test is true, which is equivalent to joining the two conditions with and.
- ETS pseudocode closes each selection with end if, and its indentation is significant, so an else belongs to the if it lines up with.
- In C-family languages, a switch case without break falls through into the next case.
What this competency asks
ETS asks you to understand the three basic constructs used in programming: sequence, selection, and iteration. Besides tracing code, finding inputs for given outputs, describing a segment's purpose, and supplying missing code, you should be able to:
- Identify the three constructs when used in code.
- Identify which constructs are needed to implement given functionality.
- Convert code that does not use iteration into equivalent code that does (Section 8.2).
The discussion questions add: trace code that uses selection (if, if/else, switch, case) and convert from one type of selection to another.
The three constructs
| Construct | Meaning | Recognize it by |
|---|---|---|
| Sequence | Statements run one after another, in order | Consecutive statements with no branching |
| Selection | The program chooses which statements to run based on a condition | if, else, switch/case |
| Iteration | Statements repeat while or until a condition holds | for, while, do … while, repeat … until |
Which constructs does a task need? Ask two questions:
- Does the program make a decision? If so, it needs selection.
- Does it repeat an action an unknown or large number of times? If so, it needs iteration.
Every program uses sequence. "Print the larger of two numbers" needs sequence and selection. "Print the numbers 1 to 100" needs iteration. "Count the passing scores in a list" needs all three: a loop over the list and an if for each score.
One-way and two-way selection
if ( temperature > 100 )
print "Warning: overheating"
end if
if ( balance ≥ amount )
balance ← balance - amount
else
print "Insufficient funds"
end if
A one-way if may do nothing. An if … else always runs exactly one of its two blocks.
Chained selection: order matters
When there are several mutually exclusive cases, nest the next if inside the else:
if ( score ≥ 90 )
grade ← "A"
else
if ( score ≥ 80 )
grade ← "B"
else
if ( score ≥ 70 )
grade ← "C"
else
grade ← "F"
end if
end if
end if
The tests run top to bottom, and the first true test wins. With score ← 85, the first test fails, the second succeeds, and grade becomes "B"; the remaining tests never run.
Shadowed conditions. Reverse the order and the logic breaks:
if ( score ≥ 70 )
grade ← "C" // 85 and 95 both land here
else
if ( score ≥ 80 )
grade ← "B" // unreachable: any score ≥ 80 was already ≥ 70
end if
end if
For lower-bound tests (≥), check the largest threshold first. For upper-bound tests (<), check the smallest threshold first. Alternatively, use explicit ranges, as in ( score ≥ 80 ) and ( score < 90 ).
Nested selection
A nested if is tested only when the enclosing condition is true:
int x ← 7
String msg ← ""
if ( x % 2 == 0 )
msg ← "even"
else
if ( x > 5 )
msg ← "big odd"
end if
msg ← msg + "!"
end if
print msg
x is odd, so the else block runs. Inside it, 7 > 5 is true, so msg becomes "big odd". Then msg ← msg + "!" runs regardless of that inner test, because it sits in the else block, not inside the inner if. The output is big odd!. Indentation and end if tell you exactly where each statement belongs.
Why end if matters: the dangling else
In languages that allow an if without braces, such as C and Java, an else binds to the nearest unmatched if, whatever the indentation suggests:
if (x > 0)
if (y > 0)
System.out.println("both");
else
System.out.println("x not positive"); // actually pairs with if (y > 0)
With x = −3, nothing prints. The else belongs to the inner if, which is never reached. ETS pseudocode avoids this ambiguity: indentation and end if are significant, so an else belongs to the if it lines up with. When you trace code on the test, follow the end if markers. In Java or C, use braces.
Converting between forms of selection
Nested ifs to a compound condition. An outer test and an inner test that must both pass are equivalent to and:
if ( ( loggedIn ) and ( isAdmin ) )
showAdminPanel ( )
end if
Guard clauses. A deeply nested chain of checks can often be flattened by handling failure cases first and returning early. This makes the main path easier to read.
switch/case to if/else. Many languages offer a switch statement that compares one value against constants:
switch (day) {
case 1: label = "Mon"; break;
case 2: label = "Tue"; break;
default: label = "Other";
}
Equivalent ETS-style selection:
if ( day == 1 )
label ← "Mon"
else
if ( day == 2 )
label ← "Tue"
else
label ← "Other"
end if
end if
In C, C++, and Java, leaving out break makes execution fall through into the next case. Sometimes this is intentional (grouping cases), but often it is a bug.
Common selection pitfalls
- Assignment instead of comparison: use
==to compare. In C,if (x = 5)assigns 5 and is always true. - Boundary errors:
age < 18versusage ≤ 18changes the result for exactly one value, 18. Test values at, just below, and just above each boundary (Section 10.3). - Floating-point equality: avoid
==with computed doubles; compare within a tolerance. - Impossible conditions:
( x < 10 ) and ( x > 20 )can never be true. - Missing
else: a variable assigned in only some branches may keep an old value. ETS's sample test-case question turns on exactly this: a code segment meant to store the largest of three numbers assigns nothing in one branch.
What is the value of grade after this code runs with score ← 85?
if ( score ≥ 70 )
grade ← "C"
else
if ( score ≥ 80 )
grade ← "B"
else
if ( score ≥ 90 )
grade ← "A"
else
grade ← "F"
end if
end if
end if
What is printed?
int x ← 7
String msg ← ""
if ( x % 2 == 0 )
msg ← "even"
else
if ( x > 5 )
msg ← "big odd"
end if
msg ← msg + "!"
end if
print msg
In Java, what is the value of label after this code runs when day is 1?
switch (day) {
case 1: label = "Mon";
case 2: label = "Tue"; break;
default: label = "Other";
}