Requirements & pseudocode: design before code
420-302-VA · WEEK 5 · FALL 2026

Stage 3 of 6 · Theory, pen ready · about 30 minutes

Pseudocode

Requirements say what; pseudocode sketches how. It is logic written in structured plain language: exact about the order of steps, the decisions and the loops, and deliberately silent about syntax. It is where you find your design's flaws while they still cost pencil lead.

What pseudocode is

Pseudocode is a description of an algorithm precise enough to translate into any programming language and informal enough to write at a whiteboard. It has no official standard, and that is by design: textbooks, exams and teams each fix their own conventions, then apply them consistently. What every convention shares is the structured part: the same three shapes that structured programming showed are sufficient for any algorithm, sequence (one step after another), selection (IF/ELSE), and repetition (loops). That result, one of computer science's foundational ideas, is why the small construct table below covers everything you will ever design; the Wikipedia article on structured programming tells the history, dramatic 1968 letter included.

Two things pseudocode is not:

  • Not vague code. "Deal with the button somehow" is not pseudocode; it postpones the only decision that matters. Pseudocode is exact about logic: which condition, checked when, doing what.
  • Not Python with the colons removed. If your pseudocode says button.wait_for_press(), you are writing code and calling it design. Pseudocode says wait until the button is pressed and lets the translation choose the call.

This course's conventions

Used in the hubs, expected on the midterm, recommended for your project documents. Keywords in capitals, indentation for blocks (the habit Python already taught you), one step per line:

KeywordMeaning
SET x TO valueAssignment
IF condition THEN ... ELSE ... END IFSelection; ELSE IF chains allowed
WHILE condition ... END WHILECondition-controlled loop; LOOP FOREVER for the deliberate infinite loop
FOR each item IN collection ... END FORCount- or collection-controlled loop
FUNCTION name(parameters) ... RETURN valueA named recipe
INPUT ... / OUTPUT ...Reading from and reporting to the outside world
WAIT ... / WAIT UNTIL ...Time passing or an event arriving (this course's addition, for hardware)
# commentA note to the reader, ignored by the "machine"

Other sources use ENDIF, REPEAT ... UNTIL, arrows for assignment, or French keywords; all are fine. The only rule with teeth: pick a convention and hold it, because inconsistent pseudocode cannot be traced.

The construct map

Every keyword above lands on a Week 4 construct, which is why the translation step at the end is nearly mechanical, and why Python was advertised as reading like pseudocode:

PseudocodePython
SET count TO 0count = 0
IF temperature > 30 THEN ... ELSE ...if temperature > 30: ... else: ...
WHILE count < 5 / LOOP FOREVERwhile count < 5: / while True:
FOR each n IN 0 to 4for n in range(5):
FUNCTION flash(duration) ... RETURNdef flash(duration): ... return
OUTPUT "blink", nprint(f"blink {n}")
WAIT 0.5 secondssleep(0.5)
WAIT UNTIL button is pressedbutton.wait_for_press()
SET t0 TO current timet0 = monotonic()

Stepwise refinement

Nobody writes twenty exact lines from a blank page. Designs descend through levels, each one checkable before the next:

Four descending boxes: the goal in one sentence, coarse steps in about five lines, detailed traceable pseudocode, and finally Python that runs. Each level is checked against the requirements before descending. Goal · one sentence "a reaction-time game on the LED and button" Coarse steps · about five lines ready → random wait → light → measure press → report → repeat Detailed pseudocode · every decision explicit false starts handled, variables named, traceable line by line Python · runs on the Pi a near-mechanical translation, verified against R1 to R6
Descend one level at a time. Each level answers "does this still satisfy the requirements?" before earning more detail. Discovering a flaw one level up always costs less than one level down.

The coarse level for the timer, checked against the spec: ready → random wait → light → measure press → report → repeat. And immediately the spec earns its keep: R4 is nowhere in those steps. Where do false starts fit? Inside "random wait", which is not a plain wait at all but a watchful one. That discovery, made in five lines of coarse steps, is the design catching a bug that improvised code would have met as a rewrite.

The reaction timer, designed

The detailed level, satisfying R1 to R4 and R6. Read it against the spec table, requirement by requirement:

LOOP FOREVER                                        # R6: rounds continue until Ctrl+C
    turn LED off                                    # R1
    OUTPUT "Get ready..."                           # R1
    SET delay TO random number between 2.0 and 5.0  # R2
    SET waited TO 0
    SET false_start TO false
    WHILE waited < delay                            # the watchful wait
        IF button is pressed THEN
            SET false_start TO true
            EXIT WHILE                              # leave the wait early
        END IF
        WAIT 0.01 seconds
        SET waited TO waited + 0.01
    END WHILE
    IF false_start THEN                             # R4
        OUTPUT "FALSE START"
        WAIT UNTIL button is released
        continue to next round
    END IF
    turn LED on                                     # R2 completed
    SET t0 TO current time
    WAIT UNTIL button is pressed                    # R3
    SET reaction TO (current time - t0) in ms
    turn LED off
    OUTPUT "Reaction:", reaction, "ms"              # R3
    WAIT UNTIL button is released
END LOOP

Notice the design decisions the pseudocode makes visible, exactly the ones worth debating with a partner before coding: the wait polls every 0.01 s (a design answer to R5's accuracy); a flag variable (false_start) carries a fact out of the loop to the decision after it, a pattern you will reuse constantly; and both exits wait for the button's release, without which one long press would bleed into the next round, an edge case R6's "new round" wording forces you to confront on paper.

Trace tables: run it on paper

A trace table (also called a desk check or dry run) executes a design by hand: one row per step actually taken, one column per variable, plus condition results and output. It is the standard exam technique for a reason: it separates what the text says from what you meant, and the bug always lives in that gap. Trace the false-start path, pretending the button is pressed at 0.02 s into a 3.0 s delay:

StepLinedelaywaitedfalse_startCondition?Output
1turn LED off · OUTPUT––––Get ready...
2SET delay / waited / false_start3.00false––
3WHILE waited < delay3.00false0 < 3.0 → true, enter–
4IF button is pressed3.00falsefalse → skip–
5WAIT · SET waited3.00.01false––
6loop again · IF button is pressed3.00.01falsetrue (pressed at 0.02 s)–
7SET false_start · EXIT WHILE3.00.01true––
8IF false_start3.00.01truetrue → enterFALSE START
9WAIT UNTIL released · next round––––Get ready...

Nine rows, and R4 is proven, on paper, before any Python exists: no time was reported, the message appeared, a new round began. Now trace the version without the flag, where the false-start OUTPUT sits inside the WHILE: the table shows the loop resuming after the press, the LED still lighting, the round not restarting. The trace table catches in two minutes what the bench would have turned into twenty of confused rewiring. On the midterm, expect to trace given pseudocode exactly like this; practice material is on the Resources page.

Pseudocode smells

SmellExampleThe fix
Hand-waving"handle the button correctly"Name the condition and the action: which press, detected when, doing what
Secret PythonButton(27, bounce_time=0.05)Back up one level: "wait until button is pressed (debounced)"; the call belongs in the translation
Level mixing"initialize hardware" next to "SET waited TO waited + 0.01"Refine evenly; a coarse line among detailed ones hides exactly the logic you needed to check
Untraceable loopWHILE with a condition no line ever changesEvery loop needs a line that moves it toward exit (or an explicit EXIT); the trace table exposes this in three rows
Orphan logicA branch no requirement asked forEither a requirement is missing (add it) or the branch is (delete it); spec and design must trace to each other

Checklist for this stage

Check yourself

Why is pseudocode kept free of real syntax like wait_for_press()?
Because design decisions and implementation decisions should be reviewable separately. Syntax smuggles a how into the sketch, hides the logic behind an API name, and makes the design unreadable to anyone who does not know that library.
What are the three structured-programming shapes, and why do they matter?
Sequence, selection and repetition. Structured programming established they suffice for any algorithm, which is why a small keyword set (SET, IF, WHILE, FOR, FUNCTION) can express every design you will ever write.
What job does the false_start flag do that nothing else in the design does?
It carries a fact discovered inside the loop (the early press) out to the decision after the loop. Without it, the information dies when the loop exits, and the code after cannot distinguish "delay elapsed" from "pressed early".
In a trace table, what exactly goes in each row?
The line actually executed next, the value of every tracked variable after it, the result of any condition evaluated, and any output produced. You trace what the text says, mechanically, not what the author intended.
Your WHILE loop traces forever. Which smell is this and what is the repair?
Untraceable loop: no line inside changes the condition (or reaches an EXIT). Add the line that moves it toward exit, here SET waited TO waited + 0.01, or an explicit exit on an event.
Why did the design wait for the button's release before the next round?
Edge case: a press outlasting the report would still be "pressed" when the new round's watchful wait begins, triggering an instant false start. R6's "begin a new round" forced the question; the release wait is the answer, found on paper.