Software Design & Development · Applied Cycle

SDD19 — Mini-project 1: Modular Program

📅 Mon 28 Sep 2026 · P1+P2 (double)
~120 minutes
Learning intentions
Success criteria
Warm up — recap across the whole cycle
Answer all three questions, then check your answers.
Question 1
What term describes a variable listed in a function's own definition, e.g. def calculateAverage(scores):?
Question 2
Name one of the three categories of test data a comprehensive test plan should include (normal, extreme, or ______).
Question 3
Which evaluation criterion asks whether a program handles unexpected or invalid input without crashing?

Key vocabulary

Modular program
A program broken into separate functions and procedures, each with a single clear responsibility, rather than one long unbroken block of code.
Functional requirement
A specific statement of what a program must do, identified during analysis, in terms of its inputs, processes, and outputs.
Structure diagram
A design diagram showing a program's top-level design — which sub-programs exist and what data flows between them — before any code is written.
Standard algorithm
A well-known, reusable pattern for solving a common problem, such as linear search or finding a maximum value.
Test plan
A structured record of test cases, test data, expected results, and actual results, used to check functional requirements are met.
Evaluation
Judging a finished program against fitness for purpose, efficient use of coding constructs, usability, maintainability, and robustness.

Building a modular program — the full cycle

Why this lesson is different

Every lesson so far has taught one skill in isolation: one data structure, one construct, one algorithm, one testing idea. This lesson is different — it asks you to run the whole cycle, analysis through evaluation, on one small original problem, exactly as the assignment (Task 1, 25 marks) will require in February–March 2027. The problem is deliberately scoped: it uses functions, procedures, parameter passing, and one standard algorithm — but no arrays of records and no file handling, which are saved for SDD20's second mini-project. Keeping the scope narrow here means the cycle itself, not the data structures, is what gets rehearsed first.

1
Analysis
Identify what the program must do
2
Design
Plan the structure before coding
3
Implementation
Write the functions and procedures
4
Testing
Check requirements are actually met
5
Evaluation
Judge the finished program

The problem for this lesson

A teacher wants a small program to summarise a class's quiz scores (each out of 100), stored in a single 1D array. The program should calculate the average score, find the highest score, and display a summary — this is deliberately similar in shape to SDD13/14's standard algorithms, but now built as a complete, tested, evaluated modular program rather than a single isolated function.

Stage 1 — Analysis

Analysis identifies the functional requirements before any design or code exists. For this problem: the program must store a set of quiz scores in an array; calculate the average of those scores; find the highest score in the array; and display a clear summary of both results. Each of these becomes a specific requirement that later testing (Stage 4) will need to trace back to — a program that does something extra, or misses one of these four, has not met its functional requirements.

Stage 2 — Design

Design plans the program's shape before implementation. The top-level design for this problem has one main routine calling three sub-programs: calculateAverage (a function, since it returns a value), findHighestScore (a function, returning both the value and its index), and displayResults (a procedure, since it only outputs — it returns nothing). Data flows into the two functions (the scores array) and their results flow into the procedure as parameters. Sketching this on paper first, as a structure diagram or simple pseudocode outline, is what stops a pupil from realising halfway through coding that a value they need in displayResults was never actually passed to it.

Stage 3 — Implementation

Implementation turns the design into working code. calculateAverage reuses SDD7's function pattern (returns a value); findHighestScore reuses SDD14's find-maximum standard algorithm, extended to also track the index of the highest value, not just the value itself; displayResults reuses SDD7's procedure pattern, receiving the average and highest score as actual parameters passed in from the two functions. This is exactly the combination the SQA spec groups together as "computational constructs" (SDD7–SDD12) plus "algorithm specification" (SDD13–SDD15) — this lesson is where those two strands are first required to work together in one program.

Stage 4 — Testing

Testing checks the implemented program against the Stage 1 functional requirements using a structured test plan, not just a single quick run. A complete test plan for this problem needs at least one normal case (a typical mixed set of scores), at least one extreme case (a boundary value, such as the lowest or highest possible score, or every score being identical), and at least one erroneous case (such as an empty array) — mirroring SDD16's three test data categories exactly, now applied to a whole program rather than one function studied on its own.

Stage 5 — Evaluation

Evaluation judges the finished, tested program against all five SDD18 criteria together: does it do what was required (fitness for purpose); does it use appropriate constructs, such as the standard maximum-finding algorithm rather than something more roundabout (efficiency); is its output clear to the teacher using it (usability); are its functions and procedures clearly named and easy to follow (maintainability); and does it cope with situations like an empty array without crashing (robustness). Running this full checklist against a whole modular program, rather than a single isolated function as in SDD18, is genuine rehearsal for the assignment's own evaluation requirement.

Worked examples

Example 1 — Analysis: identifying the functional requirements
1
The stated problem: "A teacher wants a program to summarise a class's quiz scores: calculate the average, find the highest score, and display a summary."
Functional requirements extracted:
  • FR1 — Store a set of quiz scores in a 1D array
  • FR2 — Calculate the average of the scores
  • FR3 — Find the highest score in the array
  • FR4 — Display a summary showing the average and the highest score
Example 2 — Design: structure and pseudocode
1
Top-level design: main calls calculateAverage(scores) → returns average; main calls findHighestScore(scores) → returns highestValue and highestIndex; main calls displayResults(scores, average, highestValue, highestIndex) → no return value.
Pseudocode outline:
1. SET scores TO [62, 78, 45, 91, 55, 70]
2. CALL calculateAverage(scores) storing result in average
3. CALL findHighestScore(scores) storing results in highestValue, highestIndex
4. CALL displayResults(scores, average, highestValue, highestIndex)
Example 3 — Implementation: functions, procedure, and one standard algorithm
1
examScores = [62, 78, 45, 91, 55, 70]

def calculateAverage(scores):
    total = 0
    for i in range(len(scores)):
        total = total + scores[i]
    average = total / len(scores)
    return average

def findHighestScore(scores):
    highestValue = scores[0]
    highestIndex = 0
    for i in range(1, len(scores)):
        if scores[i] > highestValue:
            highestValue = scores[i]
            highestIndex = i
    return highestValue, highestIndex

def displayResults(scores, average, highestValue, highestIndex):
    print("Number of scores:", len(scores))
    print("Average score:", round(average, 1))
    print("Highest score:", highestValue, "(quiz", highestIndex + 1, ")")
Confirmed by an actual Python run: calculateAverage(examScores)66.833..., displayed rounded as 66.8; findHighestScore(examScores)(91, 3), displayed as "Highest score: 91 (quiz 4)". findHighestScore is SDD14's find-maximum algorithm, extended to also return the index — this is the one standard algorithm this mini-project requires. Note how average, highestValue, and highestIndex are passed as actual parameters into displayResults, exactly as planned in Example 2's design.
Example 4 — Testing: a test plan for the whole program
1
A test plan traces each test case back to a Stage 1 functional requirement:
Test dataTypeExpected resultActual resultPass/fail
[62, 78, 45, 91, 55, 70]NormalAverage 66.8, highest 91 (quiz 4)Average 66.8, highest 91 (quiz 4)Pass
[70, 70, 70, 70]Extreme — all identicalAverage 70.0, highest 70 (quiz 1)Average 70.0, highest 70 (quiz 1)Pass
[0, 100, 50]Extreme — boundary valuesAverage 50.0, highest 100 (quiz 2)Average 50.0, highest 100 (quiz 2)Pass
[] (empty array)ErroneousA clear message, no crashZeroDivisionError: division by zeroFail
Confirmed against an actual Python run: all three non-empty cases produce exactly the expected average and highest score. The empty-array case fails — calculateAverage([]) divides by len(scores), which is 0, raising ZeroDivisionError rather than handling the situation gracefully. This failing test case is exactly what Stage 5's robustness evaluation will need to address.
Example 5 — Evaluation: judging the finished program
1
Applying all five SDD18 criteria to the tested program above:
CriterionJudgement
Fitness for purposeMet — all four functional requirements (FR1–FR4) are satisfied for every non-empty test case.
Efficient use of coding constructsMet — uses the standard single-pass maximum-finding algorithm (SDD14) rather than sorting or another roundabout method.
UsabilityMetdisplayResults labels every value clearly rather than printing bare numbers.
MaintainabilityMet — descriptive function and variable names throughout make each sub-program's purpose clear without needing comments to explain it.
RobustnessPartial — Example 4's test plan shows the program crashes on an empty array; this would need to be fixed (e.g. checking len(scores) == 0 before dividing) before the program could be considered fully robust.
Now you try
The test plan above found that an empty array causes a crash. Suggest a specific change to calculateAverage that would fix this, and name the evaluation criterion it improves.
⚠️ Common mistakes — examiner feedback
📝 Exam tip

Assignment- and exam-style questions on a modular program often use the command words "identify", "design", "implement", "test", and "evaluate" together across different parts of the same question. Answer each part using the vocabulary and structure of that specific stage — a design answer should describe structure/data flow, not jump ahead to Python code, and an evaluation answer should name a specific criterion, not just say whether the program "works".

Task Set A — Core questions

Task Set A — Core questions
Work through all questions, then check your answers.
Question 1
In Example 3's code, is calculateAverage a function or a procedure?
Question 2
In Example 3's code, is displayResults a function or a procedure?
Question 3
Which standard algorithm from SDD13/14 does findHighestScore reuse?
Question 4
Given examScores = [62, 78, 45, 91, 55, 70], what does calculateAverage(examScores) return, rounded to 1 decimal place?
Question 5
Given the same array, what does findHighestScore(examScores) return?
Question 6
Which test data category does [] (an empty array) belong to in the test plan?
Question 7
Explain why the empty-array test case fails, and which evaluation criterion this result is most relevant to. (3 marks)
Question 8
Explain how designing the structure diagram before coding helps avoid a specific implementation mistake with displayResults's parameters. (3 marks)
Write a function calculateLowestScore(scores) that returns the lowest score in the array, reusing the find-minimum standard algorithm from SDD14, extended (like findHighestScore) to also return its index.
Question 9
Summarise how you would evaluate this whole program against all five SDD18 criteria, and identify which one is not yet fully met. (4 marks)
Question 10
Explain the connection between Stage 1's functional requirements and Stage 4's test plan. (3 marks)

Task Set B — Extension

Task Set B — Extension · Beyond the specification
Longer written answers — no auto-check. Discuss your answers with your teacher.
Extension 1
Suggest what would need to change at each of the five stages if this same problem were extended to load quiz scores from a CSV file and store each pupil's name and score as a record, as SDD20 will require.
Extension 2
Suggest one additional test case that isn't already in Example 4's test plan, and explain what specific risk it would help rule out.
Extension 3
Suggest how this lesson's five-stage structure compares to what the actual assignment (Task 1) will require, and which stage might need the most additional practice.
📁 File this in OneNote under:
Higher Computing Science → Software Design & Development → SDD19
📌 Teacher notes — not for pupils

Double period — this lesson deliberately runs the full cycle in one sitting rather than splitting stages across separate lessons, since the assignment itself works this way under time pressure.

Suggested timing: 5 min warm-up + vocab · 10 min stage-flow overview + notes · 35 min working through Examples 1–5 as a class, ideally with pupils attempting each stage's output before it's revealed (e.g. pause before showing Example 1's extracted requirements and have pupils write their own first) · 5 min "now you try" · remainder Task Set A; Task Set B as homework/extension.

Scope is deliberately narrower than SDD20: no arrays of records, no file handling. This keeps the five-stage cycle itself as the learning focus rather than adding new data-structure or file-handling complexity at the same time — those are saved for SDD20's second, closer-to-assignment mini-project.

The empty-array robustness failure in Example 4/5 is a deliberately real, Python-verified failure (not a contrived teaching device) — worth letting pupils discover it by actually running the code against [] themselves if time and equipment allow, rather than just reading the test plan's stated result.

SQA command words covered: identify, design, implement, test, evaluate — all five stage-specific command words in one lesson.