System design
Structure charts, data flow diagrams, designing data, algorithms and the user interface, and printing a structure chart with recursion.
Do this lesson in the simulatorAnalysis said what the system must do. Design decides how, before any code is written. A design is a plan other people can check and build from: the modules and how they fit together, the data and where it flows, the algorithms, and what the user will see. At GCSE you decomposed problems and drew flowcharts (F4.4 and F5.2); at A level you need the diagrams that describe a whole system.
What a design contains
AQA lists the parts a design should plan:
- the data structures for the data model: records, arrays, files or database tables, with their fields, types and validation;
- the algorithms, in pseudocode or flowcharts, for the parts that are not obvious;
- a modular structure: which subroutines or classes there are, and what each one is given and returns;
- the human user interface: screens, controls, messages and feedback.
A design should also include the test plan, since the success criteria already say what must be tested. And like analysis, design can be iterative: an agile team designs a little for each iteration.
Top-down design and structure charts
Top-down design (also called stepwise refinement) starts with the whole problem as one module and breaks it into sub-modules, then breaks those down, until each module is small enough to write and test on its own. A structure chart draws the result as a hierarchy.
Reading a structure chart:
- Each box is a module; lines join a module to the modules it calls.
- Modules on the same level are usually called from left to right.
- Data couples, small arrows with an open circle, show the data passed down as parameters or up as return values. A filled circle is a control flag, such as
found. - A chart shows structure, not order of steps or loops: that is what pseudocode and flowcharts are for.
The benefits are the benefits of modular design: each module can be written, tested and fixed on its own, by different people, and reused; the chart shows the team who owns which part.
Data flow diagrams
A data flow diagram (DFD) shows how data moves through a system, ignoring the order of steps and the code. It has four symbols:
| Symbol | Meaning | Example |
|---|---|---|
| Rectangle | an external entity: a person or system outside, which sends or receives data | office staff, teacher |
| Rounded box, numbered | a process that changes data | 1 Plan delivery |
| Open-ended box, numbered | a data store where data is kept | D1 Delivery log |
| Labelled arrow | a data flow | route, delivery record |
Two rules catch most mistakes: every data flow must start or end at a process (data cannot move from one store to another, or from a person straight into a store, without a process), and every process must have at least one flow in and one flow out. The DFD is also the first place a data protection problem shows up: the delivery log is a data store holding personal data (lesson A14.7).
Designing the data
For each data structure, a design gives the fields, their data types, and the validation each needs. For a delivery record:
| Field | Type | Validation |
|---|---|---|
| delivery_id | integer | unique, created by the system |
| room | string | lookup: must be a room in the map |
| weight_g | integer | range: 1 to 1000 |
| sent_at | date/time | set by the system |
| arrived | Boolean |
A design this precise turns straight into code. Each row of the table becomes one check:
ROOMS = {"A1", "B12", "C3", "C4"} # from the map: the lookup check
def validate_delivery(room, weight_g):
problems = []
if room not in ROOMS:
problems.append(f"room {room!r} is not on the map")
if not isinstance(weight_g, int) or not 1 <= weight_g <= 1000:
problems.append(f"weight {weight_g!r} must be a whole number from 1 to 1000")
return problems
for room, weight in [("C3", 450), ("D9", 450), ("B12", 1500), ("A1", "heavy")]:
print(room, weight, validate_delivery(room, weight) or "valid")
Designing the interface
The user interface is designed with its users in mind. Good interface design:
- is consistent: the same action looks and works the same everywhere;
- gives feedback: every action has a visible result (the robot's LED changes when it accepts a parcel);
- prevents errors: choose a room from a list rather than typing it;
- is accessible: readable text, sufficient colour contrast, and never colour alone to carry meaning (the robot beeps as well as turning green, for users who cannot tell red from green);
- suits the users and the setting: large buttons for a screen used standing up in a busy office.
Designs are often shown as annotated sketches or wireframes, and tested on users as prototypes.
Designing the algorithms
The algorithms for each module are written in pseudocode or drawn as flowcharts, detailed enough for someone else to code them. The design for check gap might be:
SUBROUTINE check_gap(target)
gap ← distance()
RETURN gap ≥ target - 2 AND gap ≤ target + 2
ENDSUBROUTINE
Writing algorithms first lets them be checked with a trace table before time is spent on code.
Task: print the structure chart
chart is a dictionary describing a structure chart: each key is a module name (a string), and its value is the list of that module's sub-modules, in left-to-right order. A module that is not a key has no sub-modules.
Write a recursive procedure show(module, depth) that prints the module's name after 2 * depth spaces, then calls itself for each of the module's sub-modules with depth + 1. Call it as show("delivery robot", 0).
While it runs, count every module printed and collect the leaves (modules with no sub-modules) in the order they are printed. After the chart, print modules: <n> and then leaves: <names>, with the names separated by ,. The robot stays still.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
chart = {
"delivery robot": ["plan route", "drive route", "report"],
"plan route": ["read map", "shortest path"],
"drive route": ["drive leg", "check gap"],
"drive leg": ["set motors", "read heading"],
"report": ["format message", "send message"],
}
Challenges
- Draw a data flow diagram for a system where students book a robot for a lesson and a technician gets a daily list of bookings.
- Change
showso it also prints each module's depth in brackets, and printsdepth of chart: <n>at the end. - The robot's screen shows errors in red text only. Give two changes that make it accessible, and say which users each helps.