JD

CAB201 Programming Principles – Selection & Iteration

Introduction to Selection & Iteration

  • Fundamental control–flow tools that let a program “decide” (selection) or “repeat” (iteration)

  • Real–world metaphor introduced with the “egg preparation” steps that grew from a single-path recipe to:

    • Add a quality check (selection → throw away rotten egg vs cook)

    • Add a repetition over all eggs in a box (iteration)

  • Lecture scope

    • Selection keywords: if, else, else if, switch

    • Iteration keywords: while, do-while, for

    • Robust testing with both valid & invalid data

Braces and Code Blocks

  • Curly braces {} group statements into a block; languages with C-style syntax (C, C++, C#, Java, etc.) rely on them

{
    // This is a code block
    int x = 10;
}
  • Nesting rules determine scope

    • Variables declared in an inner block are invisible outside it

    • Re-declaring a name in an inner block that is already declared in an outer block is illegal

  • Readability conventions

    • Sometimes braces are used for compatibility, sometimes to enable specific scoping, sometimes simply for clarity

  • Example of scope error

int i1 = 1;
  {
      int j1 = 2;
  }
  Console.WriteLine(j1); // ERROR – j1 out of scope

Boolean Type and Operations

  • Keyword: bool (system type ext{System.Boolean}, size 1 byte)

bool isValid = true;
bool hasPermission = false;
  • Only two legal literal values: true and false (case–insensitive when read as text)

  • Relational operators: <, >, <=, >=, ==, !=

    • Produce a Boolean result, e.g. 7 >= 3 \rightarrow \text{true}

int a = 5, b = 10;
bool isEqual = (a == b); // isEqual is false
bool isGreater = (b > a);  // isGreater is true
  • Logical operators (binary): AND (&&, &), OR (||, |), XOR ^; unary NOT !

    • Truth table snapshot: both operands true → AND true, OR true, XOR false

bool p = true, q = false;
bool andResult = p && q; // andResult is false
bool orResult = p || q;  // orResult is true
bool notP = !p;          // notP is false
  • Conversion / I/O

string s = Console.ReadLine();
  bool b1 = Convert.ToBoolean(s); // or Boolean.Parse(s)
  Console.WriteLine(b1);
  • Importance: completes the set of primitive types; cornerstone of selection constructs

Selection – If Statement

  • Purpose

    • Take a different execution path once (simple if) or twice (if + else)

    • Guard against invalid states/data

  • Syntax

if (CONDITION) {
      // STATEMENTS
  }
  // or single-statement form without braces
  if (CONDITION) STATEMENT;
  • Example task – “Perfect day proposal”

    • Constant ext{PERFECT}=24 °C

    • Compare user-entered temperature

    • Single-path variant (only act when perfect) and dual-path variant (else → “Better luck tomorrow.”)

int temperature = 24;
const int PERFECT = 24;

if (temperature == PERFECT) {
    Console.WriteLine("It's a perfect day!");
}

if (temperature == PERFECT) {
    Console.WriteLine("Perfect!");
} else {
    Console.WriteLine("Better luck tomorrow.");
}
  • Idioms & anti-idioms

    • Use Boolean variable directly: if(isPerfect) not if(isPerfect==true)

    • Empty statement after condition: if(!isPerfect); executes nothing – almost always an error

  • Logical negation patterns

if (temperature != PERFECT) {...}
  // VS logically equivalent but verbose
  if (!(temperature == PERFECT)) {...}

Testing If Statements

  • Adopt software-engineering pipeline (Waterfall model) – devise test plan in analysis/design phase

  • Typical test categories

    • Normal values

    • Boundary values (just above/below threshold)

    • Equivalence (exact threshold)

  • Test-case table example for “hot day ≥ 30 °C”

    ID

    Type

    Input

    Expected


    3

    Boundary

    31

    Phwoar! Hot day

    • else supplies an alternative path

if (score >= 90) {
    Console.WriteLine("Excellent");
} else if (score >= 70) {
    Console.WriteLine("Good");
} else {
    Console.WriteLine("Needs improvement");
}
- **else if** provides multiple mutually-exclusive branches
- Ordering matters – first true condition wins; ensure comparisons go from most specific to most general to avoid “shadowing” cases
- Temperature classification exercise (Hot/Warm/Perfect…)
    - Constants: HOT=30,\,WARM=25,… etc.
    - Testing revealed bug when order was incorrect (`temperature &gt;= WARM` placed before `&gt;= HOT`)

- Take-home: Flexibility vs complexity; requirement of exhaustive tests

Nested If Statements

  • An if inside another if for multi-dimension decisions

    • Example: Temperature (>20) AND windiness

int temp = 25;
bool isWindy = true;

if (temp > 20) {
    if (isWindy) {
        Console.WriteLine("It's warm but windy!");
    } else {
        Console.WriteLine("It's warm and calm.");
    }
} else {
    Console.WriteLine("It's not warm enough.");
}
  • Readability trade-off—as complexity grows, an else-if ladder or even switch often clearer

  • Avoid deep nesting as shown in the “VERY confusing code. Don’t do it!” slide

  • Best used when second condition only relevant after first one passes/fails

Switch Statement

  • Multi-way selection for discrete integral-like values (numeric, char, string, bool)

  • Structure

switch(expr) {
          case C1: ... break;
          case C2: // no statements → fall-through
          case C3: ... break;
          default: ... break;
      }
  • “Quarter of AFL game” example: 1\rightarrow first quarter … default → error

int quarter = 2;
switch (quarter) {
    case 1:
        Console.WriteLine("First quarter");
        break;
    case 2:
        Console.WriteLine("Second quarter");
        break;
    case 3:
    case 4: // Fall-through: Same action for Q3 and Q4
        Console.WriteLine("Second half");
        break;
    default:
        Console.WriteLine("Invalid quarter");
        break;
}
  • Fall-through technique: stack multiple case labels above one body

  • Non-integral notes

    • Floats allowed (with suffix, e.g. 3.14f) but seldom recommended

    • Strings: beware of typos and culture-specific comparisons (“hell” vs “hello”)

    • Booleans: legal but conventional if/else clearer

  • Comparison with if/else (summary slide)

    • if supports full relational operators and ranges

    • switch only equality but often more readable for many discrete options

Selection Comparison Table (recap)

  • Both structures give multiple paths

  • Key differences

    • Condition types & operator set

    • Mechanisms for “else” path (else vs default)

    • switch enables intentional fall-through

Iteration Overview

  • Definition: executing a block repeatedly until a condition terminates

  • Real-world cues (Lisa eating apples, store owner counting sales)

  • Two big families

    1. Condition-controlled loopswhile, do-while

    2. Counter-controlled loopsfor

While Loop

  • Syntax: while(CONDITION){ BODY }

  • Pre-test: body may execute zero times

  • Typical architecture

    • Control variable declared outside, updated inside body

int count = 0;
while (count < 5) {
    Console.WriteLine($"Count is {count}");
    count++;
}
  • Apple-eating examples

    • Unknown number of apples; ask “Are you hungry?” until answer false

    • Variant with daily limit – compound condition numApples < MAXAPPLES

  • Test-case design same triad: equivalence, boundary, normal

  • Take-home: Use when repeat count unknown; think of it as “repeating if”

Do-While Loop

  • Post-test loop – body executes at least once

  • Syntax ends with semicolon: do{...} while(cond);

int num = 0;
do {
    Console.WriteLine("Enter a number greater than 0:");
    num = Convert.ToInt32(Console.ReadLine());
} while (num <= 0);
Console.WriteLine($"You entered: {num}");
  • Apple task guaranteeing one apple/day

  • Risks: off-by-one errors if the “at least once” property is unintended

For Loop

  • Ideal when repeat count known or easily derivable

  • Header packs init, condition, change in one line ⇒ easy auditing

for(int i=0; i<MAX; i++)
for (int i = 1; i <= 5; i++) {
    Console.WriteLine($"Iteration {i}");
}
  • Control variable scope

    • Declared in header → limited to loop, can reuse same name in later loops

    • Declared outside if its value needed afterwards

  • Variants

    • Count down for(i=MAX;i>MIN;i--)

    • Char iteration for(char c='a'; c<='j'; c++)

  • Case study: summing apple sales over n days (user-supplied)

    • Control var: day index d, condition d < numDays, change d++

  • Warning: rewriting a clear for as while spreads change far from condition, increasing bug risk

Iteration Nuances – break, continue, infinite loops

  • break – exit entire loop immediately; common for sentinel or error escape

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break; // Exits the loop when i is 5
    }
    Console.WriteLine(i);
}
  • continue – skip rest of current iteration, jump to condition check

for (int i = 0; i < 5; i++) {
    if (i == 2) {
        continue; // Skips printing 2, moves to next iteration
    }
    Console.WriteLine(i);
}
  • Infinite loop patterns

    • Explicit while(true) or for(;;)

    • Missing update of control variable; braces omission in single-line loops causing logic leak

  • Example safe sentinel: echo input until user types “exit” → inside infinite loop with break

  • Good testing & code reviews are antidotes to accidental infinite loops

Handling Invalid Data

  • Real programs must reject/handle unacceptable inputs (e.g. negative apples or day counts)

  • Technique stack:

    1. Guard with if before loop start (e.g. numDays<0 → abort via return)

    2. Inside loop, embed a validation sub-loop (do-while) to re-prompt until valid

  • Design rationale slide: choose loop type based on need to ask at least once vs zero-times possibility

  • Comprehensive test plans cover both invalid and valid scenarios; Gradescope etc. grade on this

Testing Strategies (across Selection & Iteration)

  • Categories: Normal, Boundary, Equivalence, Invalid

  • Always draft test table before coding, update when requirements or code change

  • Passing all visible test cases does not guarantee absence of hidden bugs ⇒ reason about logic

Quick Summary / Take-Home Cheat-Sheet

  • Boolean type with relational & logical ops underpins all decision logic

  • Selection options

    • Simple fork: if/else

    • Multi-branch discrete: switch

    • Multi-condition range: else if ladder

    • Carefully test branch order & completeness

  • Iteration options

    • for when repeat count known \rightarrow header shows init+cond+change

    • while when count unknown, may execute 0 times

    • do-while when body must run once minimum

  • Guard against invalid data with early if checks + inner validation loops

  • Debug aids

    • Extensive test tables (normal/boundary/invalid)

    • Avoid deep nesting; prefer clear, flat structures

    • Watch for missing brace or update – classic infinite-loop source

  • Principle: DRY (Don’t Repeat Yourself) – loops replace copy-pasted blocks; selection removes redundant paths