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.
Last updated: September 2026

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

ConstructMeaningRecognize it by
SequenceStatements run one after another, in orderConsecutive statements with no branching
SelectionThe program chooses which statements to run based on a conditionif, else, switch/case
IterationStatements repeat while or until a condition holdsfor, while, do … while, repeat … until

Which constructs does a task need? Ask two questions:

  1. Does the program make a decision? If so, it needs selection.
  2. 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 < 18 versus age ≤ 18 changes 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.
Test Your Knowledge

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

A
B
C
D
Test Your Knowledge

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

A
B
C
D
Test Your Knowledge

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";
}

A
B
C
D