All subjects · Computer Science · WCP04 Advanced Practical Programming and Problem-solving
Designing programs: decomposition, modularity and scope
Edexcel IAL Computer Science · WCP04 Advanced Practical Programming and Problem-solving
Unit 4 marks reward programs that are well designed, not just ones that work. Design means splitting the problem sensibly, keeping each part focused, controlling what each part can change, and choosing efficient structures.
Decompose, then choose structures
- Break the problem into sub-problems, each solved by a named subprogram:
load_scores(),median_score(),print_leaderboard(). - Plan clear logic for each part (pseudocode or a flowchart) before coding.
- Choose variables, constants, data types and structures that fit the data: a dictionary for look-ups by name, a list for ordered items, a set for membership tests, a class for records with behaviour.
- Choose the construct that fits: a for loop for a known count, while for an unknown count, match/case for many fixed options.
Modularity and separation of concerns
- Modularity: build the program from blocks (subprograms, classes, modules and files) that can be written, tested and reused separately. Use built-in subprograms and libraries rather than rewriting them.
- Separation of concerns: each part does one job. Keep input, processing and output apart: a function that calculates a total should return it, not print it, so it can be tested and reused.
- Fitness for purpose: the program does what the user needs, no more and no less. The exam warns you not to add functionality that was not asked for.
Side effects and scope
A side effect is any change a subprogram makes outside itself: altering a list passed in, changing a global variable, printing or writing a file. Minimise them so each part is predictable. Lists are passed by reference, so changing one inside a function changes the caller's list.
def add_bonus_in_place(scores, bonus):
for i in range(len(scores)):
scores[i] = scores[i] + bonus # side effect: changes the caller's list
return scores
def add_bonus(scores, bonus):
return [s + bonus for s in scores] # no side effect: returns a new list
marks = [60, 72, 85]
boosted = add_bonus(marks, 5)
print(marks, boosted)
add_bonus_in_place(marks, 5)
print(marks)Output:
[60, 72, 85] [65, 77, 90]
[65, 77, 90]Scope: a variable created inside a function is local to it. Use global only when unavoidable; pass values in and return results instead.
total = 0
def add_global(x):
global total # avoid where possible
total = total + x
def add_pure(current, x):
return current + x
add_global(5)
print(total, add_pure(total, 5), total)Output:
5 10 5Efficiency
- Avoid repeated work: calculate a value once and store it, rather than recomputing it inside a loop.
- Choose structures that suit the operation:
x in a_setis fast however large the set;x in a_listchecks each item. - Use library functions such as
sorted(),sum()andmax(), which are tested and efficient. - Do not optimise at the cost of clarity when the data is small.
banned = ["spam", "scam", "fake", "fraud"]
banned_set = set(banned)
words = "this is not spam or a scam".split()
print([w for w in words if w in banned_set])Output:
['spam', 'scam']Worked example
A program reads diving scores, calculates totals and prints a table, all in one 60-line block of code. Suggest a better design.
- Decompose into `load_dives(filename)` (input), `dive_score(judge_scores, difficulty)` (processing, returns a number), `rank(totals)` (processing, returns a sorted list) and `show_table(ranking)` (output).
- Keep the original data unchanged: processing functions return new values instead of modifying their inputs.
- Use named constants for fixed values such as the number of judges.
- Each function can now be tested on its own with known data.
Answer: Separate input, processing and output into focused functions with parameters and return values, and no hidden side effects.
Check yourself
- What does this program print?
```python
def double_all(nums):
for i in range(len(nums)):
nums[i] = nums[i] * 2
data = [1, 2, 3]
double_all(data)
print(data)
```
Show answer
[2, 4, 6]. The function changes the list it was given, and that is the same list object as data, so the caller sees the change: `[2, 4, 6]`
- What does this program print?
```python
def doubled(nums):
return [n * 2 for n in nums]
data = [1, 2, 3]
new = doubled(data)
print(data, new)
```
Show answer
[1, 2, 3] [2, 4, 6]. The function builds and returns a new list, so data is unchanged. Output: `[1, 2, 3] [2, 4, 6]`
- What does this program print?
```python
total = 0
def add_global(x):
global total # avoid where possible
total = total + x
def add_pure(current, x):
return current + x
add_global(5)
add_global(3)
print(total, add_pure(total, 10))
```
Show answer
8 18. add_global changes the global total: 5 then 8. add_pure returns 8 + 10 without changing total. Output: `8 18`
- Which function design best follows separation of concerns?
- `def average(scores): print(sum(scores) / len(scores))`
- `def average(): scores = input(); print(...)`
- `def average(scores): return sum(scores) / len(scores)`, with printing done by the caller
- One function that reads the file, calculates every statistic and prints them
Show answer
`def average(scores): return sum(scores) / len(scores)`, with printing done by the caller. A function that only calculates and returns its result can be tested and reused; input and output are handled elsewhere.
- Which of these is a side effect of a function?
- It appends an item to a list that was passed in as an argument
- It returns a new list
- It creates a local variable
- It calls another pure function
Show answer
It appends an item to a list that was passed in as an argument. Changing a mutable argument alters data outside the function.
- A loop checks 50 000 product codes against a list of 20 000 valid codes. What change makes it most efficient?
- Sort the product codes
- Use a while loop instead of a for loop
- Convert the valid codes to a set once, before the loop
- Print each code as it is checked
Show answer
Convert the valid codes to a set once, before the loop. Set membership is fast regardless of size; list membership checks items one by one.
- An exam question asks you to add a function that calculates a median. You also add a menu and colour output. What is the problem?
- The program now does more than was asked, which the instructions say not to do
- Menus are not allowed in Python
- Colour output always crashes
- There is no problem; extra features earn extra marks
Show answer
The program now does more than was asked, which the instructions say not to do. Fitness for purpose: meet the requirement exactly. The Unit 4 instructions say not to add functionality beyond what is asked.
Sources
- Pearson Edexcel International Advanced Subsidiary/Advanced Level in Computer Science specification, Issue 1 (March 2026)
- Pearson Edexcel IAL Computer Science Unit 4 Programming Language Subset (PLS)
- Pearson Edexcel IAL Computer Science sample assessment materials (Unit 3 and Unit 4)
Last updated 8 November 2026. Spotted a mistake? Tell us.