B2.3.1 · Programming constructs
Sequence: order is part of the logic
A program can run from start to finish without a single error message and still be completely wrong, because the lines were valid on their own but ran in the wrong order.
Explainer
Flat-pack shelf instructions matter for the same reason: attach the back panel before the two side panels are screwed on, and there's now no way to reach the screw holes it was supposed to cover. Every individual step, taken alone, was still a valid thing to do. Doing them in the wrong order is what breaks the shelf.
A sequence is the simplest of the three fundamental programming constructs: a list of instructions a computer executes one at a time, in exactly the order they are written, each one finishing before the next begins.
Sequence is one of three constructs that control which instruction runs next, and this subtopic covers all three separately:
Sequence (this page): every line runs once, in the order written. Selection: the program chooses one path over another based on a condition. Iteration: a set of instructions repeats, possibly many times. A real program is built almost entirely out of these three, combined.
Explainer
The impact of instruction order on functionality
Swapping two lines never crashes a program by itself, both lines are still perfectly legal code. What changes is the state each line acts on: a later line reads whatever the earlier lines left behind, so moving a line changes what it actually operates on.
Consider total = total + fee then total = total * discount, versus the same two lines swapped. In the first order, the discount applies to the fee as well as the price. In the second, the discount applies to the price only, and the fee is added afterward at full value. Nothing about either line is wrong in isolation, only their relationship to each other has changed.
Explainer
Three ways bad sequencing shows up
The guide names three concrete symptoms of a sequencing mistake. Each of the three worked examples below shows one of these actually happening.
Incorrect output. The program runs to completion with no error at all, but the value it produces is wrong, because an instruction ran before (or after) the state it needed was in place.
Infinite loop. A loop's exit condition depends on some line updating a value each pass. If that update sits in the wrong place, sometimes even one indentation level off, the condition can never become false and the loop never ends.
Deadlock. Two parts of a program each hold a resource the other one needs, and each is sequenced to wait for the other before continuing. Neither one ever proceeds.
Worked example
A raffle kiosk, two orders, two totals
A school fun-fair raffle kiosk sells a $5 ticket bundle. Members get a 20% discount, and every sale adds a fixed $1 booking fee. The two lines that apply the discount and the fee are simple, correct code on their own, run them in a different order and the kiosk quietly charges the wrong amount.
Step 1. Intended order: discount the ticket price first, then add the fixed fee. The fee is a flat charge, it should never be affected by the member discount.
Step 2. That order gives $5.00. $5 × 0.8 = $4, then + $1 fee = $5. The fee was charged in full, exactly as intended.
Step 3. Same two lines, swapped: fee added first, then the discount. Nothing else in the program changed.
Step 4. That order gives $4.80, silently. $5 + $1 = $6, then × 0.8 = $4.80. The discount now also reduces the booking fee, which was never supposed to happen. Both versions ran without any error, and both produced a real total, only one of them is the total the kiosk actually meant to charge.
Try it yourself
Run both orderings
The intended order is loaded below. Comment out those two lines and uncomment the swapped pair underneath to see the $4.80 total for yourself, then try a different discount or fee to see the gap change.
Running in offline fallback mode. The full Python engine couldn't load (blocked school network, or no internet), so this console switched automatically to a small hand-written engine. It supports this page's arithmetic and print statements, but it isn't full Python.
Worked example
A misplaced line turns a loop infinite
This code is shown, not run live: an infinite loop would freeze this page's Python engine exactly as it would freeze a real program running it, that is the whole point of the example. Trace it by hand instead.
Wrong: the decrement is inside a condition that's never true for this stock level.
stock = 3 while stock > 0: print("Ticket sold, stock now", stock) if stock > 5: stock = stock - 1
| Pass | stock > 0? | stock > 5? | stock after this pass |
|---|---|---|---|
| 1 | True (3 > 0) | False (3 > 5) | 3, unchanged |
| 2 | True (3 > 0) | False (3 > 5) | 3, unchanged |
| 3, 4, 5… | always True | always False | always 3 |
stock starts at 3 and the condition that would decrease it, stock > 5, can never be true while stock stays at 3 or below. The loop's own exit test, stock > 0, is therefore permanently true. The loop never ends.
Right: the decrement runs on every pass, unconditionally.
stock = 3 while stock > 0: print("Ticket sold, stock now", stock) stock = stock - 1
Now every pass genuinely moves stock closer to 0: 3, 2, 1, 0, then the exit test finally becomes false and the loop stops. The fix wasn't a new line of code, it was moving one existing line out from inside the if.
Worked example
Two kiosks, each waiting on the other
The raffle stall shares one laptop (for typing in member numbers) and one printer (for the receipt) between two checkout points. Picture this: Chloe at Checkout A picks up the laptop first, then reaches for the printer. At that exact moment, Lachlan at Checkout B has already picked up the printer, and now reaches for the laptop. Chloe won't let go of the laptop until she's used the printer. Lachlan won't let go of the printer until he's used the laptop. Neither of them is ever going to get both.
In code, "picking up" a shared device is written as lock(device), and "putting it back down" is unlock(device). While a checkout holds the lock on a device, no other checkout is allowed to touch it, exactly like Chloe physically holding the laptop.
Wrong: the two checkouts pick the devices up in different orders.
# Checkout A (Chloe) lock(laptop) lock(printer) issue_receipt() unlock(printer) unlock(laptop) # Checkout B (Lachlan), running at the same time lock(printer) lock(laptop) issue_receipt() unlock(laptop) unlock(printer)
If Chloe picks up the laptop right as Lachlan picks up the printer, Chloe is now stuck waiting for the printer, which Lachlan is holding, and Lachlan is stuck waiting for the laptop, which Chloe is holding. Each is waiting on the one thing the other refuses to put down. Neither can ever finish: a genuine deadlock.
Right: both checkouts pick the devices up in the same fixed order.
# Both Checkout A and Checkout B, every time
lock(laptop)
lock(printer)
issue_receipt()
unlock(printer)
unlock(laptop)
Whichever checkout reaches the laptop first now genuinely goes first, the other one simply waits its turn for the laptop before it ever reaches for the printer. Chloe and Lachlan can no longer both be holding the one thing the other needs, so the standoff can't happen.
Fixing the lock order is an example of deadlock prevention: designing the system so the circular wait can't occur in the first place. An operating system managing many real processes has three further strategies for the cases prevention doesn't cover: avoidance (only granting a resource request if the system can guarantee every process can still finish), detection (periodically checking for stuck processes), and recovery (stopping or reallocating to break a cycle that's already happened). Those four strategies are covered in full later in this course (A1.3.5, the operating system's role in managing multitasking and resource allocation).
Check your understanding
A kiosk program adds a $1 booking fee to a $5 ticket, then applies a 20% member discount to that new total. What total does it print, and is that the intended sequencing?
Common mistake
RecurringWhen asked to explain why a program's output is wrong, a vague answer like "there's an error in the code" is not enough to earn the mark. The command word is construct or explain, either way the answer has to name the specific instruction and state what it does wrong relative to the others around it, not just that something, somewhere, is broken.
The same slip shows up with infinite loops: naming "the loop" as the problem, rather than the one specific line whose position stops the exit condition from ever changing.
What the vague version looks like: "The total is wrong because the code is in the wrong order." Correctly spots that ordering is the cause, names no actual line.
What it should say: "The fee is added before the discount is applied, so the discount is calculated on price + fee instead of on price alone, which is why the fee itself ends up discounted." Names the two specific lines and states exactly what changes between them.
Revision questions
Past-paper style. Write an answer, then reveal the marking points and mark yourself.
[2]State what is meant by a "sequence" as a programming construct.
Marking points
评分要点
- Sequence is the construct where statements are carried out one after another in the exact order they are written.
- It is one of the three control constructs, alongside selection and iteration.
- 顺序是语句按写下的确切顺序一条接一条执行的构造。
- 它是三种控制构造之一,另两种是选择和迭代。
[3]Explain why applying a fixed fee before a percentage discount produces a different total to applying the fee after the discount.
Marking points
评分要点
- Applying a fixed fee first adds it to the price, then the percentage discount is taken off the larger total, which also reduces the fee.
- Applying the discount first reduces only the original price, then the full fixed fee is added on top.
- The two orders act on different amounts, so they give different totals.
- 先加固定费用会把它加到价格上,然后百分比折扣从更大的总额中扣除,这也把费用打了折。
- 先打折只减少原始价格,然后把完整的固定费用加在上面。
- 两种顺序作用于不同的金额,所以给出不同的总额。
[4]A loop's stopping condition never becomes false. Explain, referring to instruction order, how this can happen even though every individual line of the loop is valid code.
Marking points
评分要点
- A loop ends only when the statement that moves its control variable toward the stopping condition actually runs.
- If that update statement is placed where it is skipped (for example after a branch that always exits, or inside a block that never executes), the control variable never changes.
- So the stopping condition stays true forever and the loop does not end, even though each individual line is valid.
- The fix is to reorder the statements so the update runs on every iteration.
- 只有当把控制变量推向停止条件的语句真正运行时,循环才结束。
- 如果那条更新语句被放在会被跳过的地方(例如在一个总是退出的分支之后,或在一个从不执行的块内),控制变量就永不改变。
- 于是停止条件永远为真,循环不结束,即便每一行本身都有效。
- 修正是重排语句,使更新在每次迭代都运行。
Flashcards
Active recall for this statement’s key terms.
Keep this statement’s practice with you
Free account: unlock every revision question and flashcard for B2.3.1, and every other IB CS 2027 statement.