Learn
7.1.2 | DESIGN, CODING AND ITERATIVE TESTING
01 | FROM AN IDEA TO A WORKING SOLUTION
You know what the school club needs: record bookings, prevent duplicates and stop accepting students when all places are taken. Knowing the goal is a good start, but the computer still needs precise instructions.
Think about building a model bridge. You establish what it must support, plan its structure, build it and test it. Software development also connects understanding, planning, making and checking.
The syllabus names four stages: analysis, design, coding and testing. Analysis identifies the problem and requirements. Design plans a solution. Coding implements that plan in a programming language. Testing checks its behaviour using suitable data.
This lesson follows the club example through those stages. You do not need to know Python already: the small code example is explained one line at a time.
02 | DESIGN: PLAN HOW THE SOLUTION WILL WORK
Design turns the requirements into a plan for the solution. It includes decisions about the tasks, the information each task needs and the order in which actions and decisions occur.
Start by breaking the booking system into smaller parts: accept a request, check it, record an accepted booking, display a result and save data for later use. This is decomposition, meaning dividing a problem into manageable parts.
A structure diagram can show these parts and how they fit together. It describes the organisation of the system; it does not necessarily show the order of execution.
We will concentrate on one part: checking a booking request. The saving feature is still a requirement for the complete system, but it is outside this small worked component. Developing one component makes it easier to understand its behaviour before combining it with others.
03 | WHAT IS AN ALGORITHM?
An algorithm is a precise sequence of steps for completing a task. A recipe is a useful everyday comparison, but a computer needs the steps to be much less ambiguous than “add a little” or “cook until it looks right”.
For the booking checker, “check whether it is okay” is not enough. We must explain what makes a request acceptable. A student must not already be booked, and the accepted booking count must be smaller than capacity.
Our plan is to receive an identifier, check for a duplicate, check capacity, and then either reject the request or record it. After acceptance, we calculate and display the remaining places.
A step such as displaying success must come after the decision to accept. Showing “Booking accepted” before checking capacity would give the user misleading information. The order of steps is part of the design.
04 | TWO WAYS TO REPRESENT THE PLAN
A flowchart represents steps and decisions using symbols and arrows. A process is normally shown in a rectangle; a decision in a diamond; input/output in a parallelogram; and start/end in a terminator symbol. The arrows show the direction of control flow.
Pseudocode is a structured written description of an algorithm. It uses instructions such as INPUT, OUTPUT and IF, without requiring the exact syntax of a particular programming language.
Both help us reason about a solution before coding. A flowchart makes branching paths visible. Pseudocode lets us write detailed steps in a compact form. Neither should leave important decisions to the reader’s imagination.
The following boxes outline the booking decisions; they are a reading guide, not a substitute for the standard flowchart symbols used in an exam.
RECEIVE STUDENT IDENTIFIER
Get the request to check.
↓
ALREADY BOOKED?
Yes: reject duplicate and finish.
No: continue to the capacity check.
↓ For a new identifier
CLUB FULL?
Yes: reject request and finish.
No: add the identifier and display remaining places.
05 | READ A SMALL PSEUDOCODE DESIGN
To practise one decision first, suppose the request has already passed the duplicate check. BookingCount means the number of accepted bookings and Capacity is the maximum allowed. This is only the capacity-check part of the complete design.
IF BookingCount < Capacity THEN
BookingCount ← BookingCount + 1
Remaining ← Capacity - BookingCount
OUTPUT "Booking accepted"
OUTPUT Remaining
ELSE
OUTPUT "Club full"
ENDIFIF introduces a decision. The condition BookingCount < Capacity asks whether the count is smaller than capacity. If it is true, there is room; otherwise the ELSE branch rejects the request.
The arrow ← means assignment: calculate the value on the right and store it using the name on the left. Increasing the count happens only when the request is accepted.
The messages inside quotation marks are literal text. The name Remaining refers to a calculated value. ENDIF marks the end of the decision.
Here, increasing the count represents the capacity decision only. The full component must also retain the accepted identifier so that later duplicate checks can work.
06 | CODING: MAKE THE DESIGN EXECUTABLE
Coding means writing the solution as instructions in a programming language. A language has rules called syntax, just as written English has conventions about sentence structure and punctuation.
Python uses if, elif and else for decisions. A colon introduces each branch, and indentation shows which instructions belong to that branch. Pseudocode uses different conventions, so you cannot simply assume its text will run as Python.
The next example checks one booking request. It starts with a capacity of 3 and two accepted identifiers. It keeps the bookings in memory while it runs; it does not implement saving and loading, or the complete application.
capacity = 3
booked_ids = ["S104", "S205"]
student_id = input("Enter student identifier: ")
if student_id in booked_ids:
print("Already booked")
elif len(booked_ids) >= capacity:
print("Club full")
else:
booked_ids.append(student_id)
remaining = capacity - len(booked_ids)
print("Booking accepted")
print("Places remaining:", remaining)Try entering S306, S104 and S407 in separate runs. Because the program restarts with the same two bookings each time, each run is a fresh starting situation. To test a full club, change the initial list to contain three identifiers.
07 | UNDERSTAND THE CODE ONE LINE AT A TIME
capacity = 3 gives the maximum number of places a name. A variable is a named place for a value that can be used by the program. The equals sign in Python assigns a value; it does not ask a comparison question here.
booked_ids is a list, a collection of items kept together. Its initial items are the text identifiers S104 and S205. input() displays a prompt and receives the identifier typed by the user.
The first condition uses in to ask whether the identifier already appears in the list. If it does, the program displays the duplicate message and skips the later branches.
len(booked_ids) counts the list’s items. The next condition asks whether this count is greater than or equal to capacity. If so, the club is full. Otherwise append() adds the new identifier, and the remaining-place calculation uses the updated list.
For this small example, assume identifiers are valid and entered consistently. Checking identifier format or treating lowercase and uppercase as equivalent would need additional agreed rules and code.
08 | TEST WITH A PURPOSE
Testing means running a solution with chosen data and checking its behaviour against the requirements. A test case describes a particular situation to check, including the starting state, input and expected result.
A program producing output is not enough evidence that it works. We need to know whether that output and any changes to data are correct. For the full-club case, rejection is expected and the booking collection must stay unchanged.
| Starting bookings (capacity 3) | Input | Expected result |
|---|---|---|
| S104, S205 | S306 | Accept; list contains three identifiers; 0 places remain. |
| S104, S205 | S104 | Reject duplicate; list unchanged; 1 place still remains. |
| S104, S205, S306 | S407 | Reject full club; list unchanged; 0 places still remain. |
For each row, start with the stated booking list. Otherwise an accepted request in one test might change the starting point for the next test and make the result difficult to interpret.
The expected result is worked out from the requirements before running the test. The actual result is what the program really does. Comparing them lets you decide whether that test passes or fails.
09 | A PROGRAM CAN RUN AND STILL BE WRONG
Imagine the capacity condition in the Python example is accidentally written as len(booked_ids) > capacity. It checks whether the club is already beyond capacity, rather than whether capacity has been reached.
With capacity 3 and three accepted bookings, the comparison 3 > 3 is false. The program enters the acceptance branch and adds a fourth student. It runs without crashing, but it breaks the overbooking requirement.
This is a logic error: the instructions are valid for the language but produce the wrong behaviour. A test with only two bookings would miss this error because both the correct and incorrect conditions allow another booking.
The correction is >=, meaning greater than or equal to. The full-club test is valuable because it checks the exact point where the decision should change.
Predict the incorrect remaining-place output
After adding the fourth identifier, the program calculates 3 − 4 = −1. A negative number of remaining places is another visible sign that the capacity rule failed.
10 | DEBUGGING AND THE DIFFERENT KINDS OF ERROR
Debugging is finding the cause of an error and correcting it. Testing can reveal a problem; debugging investigates why it happened.
A syntax error breaks the language’s rules, such as omitting the colon after a Python if condition. The program cannot execute normally until it is corrected.
A runtime error occurs during execution, such as trying to divide a value by zero. A logic error gives unintended behaviour even though the affected instructions can execute, such as the incorrect capacity comparison.
Read error messages, follow the relevant instructions and inspect values at the failing decision. For our overbooking bug, recording the count, capacity and condition result shows exactly why the rejection branch was skipped.
Changing unrelated lines at random makes it harder to know what solved the problem. A useful correction is linked to a cause you can explain.
11 | ITERATIVE TESTING: CHECK, IMPROVE AND CHECK AGAIN
Iterative means repeated in cycles. During coding, you implement a small part, test it, use the result to make a correction or improvement, and then test again.
For the club checker, first test an available place. Then test a duplicate. Then test a full club. If the full-club test reveals the wrong comparison, correct it and rerun that test to check the fix.
Next, rerun the available-place and duplicate tests. A change that fixes one situation can accidentally break another. Checking previously working behaviour after a change is called regression testing.
This does not mean repeating exactly the same easy input until you feel confident. Each test should provide evidence about a requirement or a possible failure. Different starting states and inputs reveal different paths through the program.
The syllabus includes iterative testing during coding and testing with test data as a development stage. Testing can happen throughout development as well as on the assembled solution.
12 | KEEP EVIDENCE AND REVISIT THE RIGHT STAGE
A simple test record helps you see what has been checked and what remains unresolved.
| Version and test | Expected | Actual observation | Outcome |
|---|---|---|---|
| Buggy version: full club, new ID | Reject; retain 3 bookings | Accepts; stores 4 bookings | Fail |
| Corrected version: same full-club test | Reject; retain 3 bookings | Rejects; retains 3 bookings | Pass |
| Corrected version: available-place test | Accept; store third booking | Accepts; shows 0 remaining | Pass |
The actual results shown here illustrate the buggy version and a corrected version; record your own observations when you run a program.
Sometimes the fix belongs in the code, as with the incorrect comparison. Sometimes the algorithm itself is incomplete, so the design must change. If staff reveal that students may book several different sessions, return to analysis: the earlier requirements and model are no longer sufficient.
After individual components work, test them together. A checker that works by itself does not prove that saving, loading and reporting also work correctly. The complete application must be checked against the complete set of requirements.
13 | EXPLAIN THE PROCESS CLEARLY
When asked to describe design, explain that it plans the solution, including its smaller components and algorithms, using tools such as structure diagrams, flowcharts and pseudocode.
When asked to explain iterative testing, connect actions and reasons: “The programmer tests a small component during development, so errors can be identified early. After correcting an error, they rerun the failing test and previously passed tests to check the correction and detect unintended effects.”
Avoid saying that a program is correct because it ran once. One successful booking does not check duplicates, full capacity or stored data. The strength of the evidence depends on what your tests actually cover.
You have now followed a requirement through planning, implementation, a failure, a correction and retesting. That connection is the foundation for the more detailed algorithm and programming lessons ahead.