SDD18 — Evaluation Criteria
- I can name and define the five criteria used to evaluate a completed program
- I can apply each of the five criteria to a piece of code, judging whether it meets that criterion
- I can define fitness for purpose, efficient use of coding constructs, usability, maintainability, and robustness
- I can evaluate a specific program or function against each of these five criteria individually
- I can suggest specific improvements a program could make against one or more evaluation criteria
Key vocabulary
Evaluating a finished program
Why evaluation is its own separate stage
A program that has passed every test in its test plan (SDD16) and has had its bugs found and fixed through debugging (SDD17) is working — but "working" and "good" are not automatically the same thing. Evaluation is the final stage of the analysis→design→implementation→testing→evaluation cycle, and asks a broader question than testing does: not just "does this specific test case pass," but "is this a genuinely well-built program overall?" Higher recognises five distinct, named criteria for answering that question.
Fitness for purpose
Fitness for purpose asks whether the program actually does what it was designed to do, judged directly against the functional requirements identified back in SDD2's analysis stage. This is the most fundamental criterion — a program can be efficient, easy to use, and robust, and still fail this criterion entirely if it simply doesn't do what was originally asked of it.
Efficient use of coding constructs
This criterion asks whether the program uses appropriate, economical language features to solve its problem, rather than unnecessarily wasteful or convoluted alternatives. Using a fully appropriate standard algorithm (SDD13–15) where one exists, rather than reinventing something more complicated, is a direct example of this criterion in practice.
Usability
Usability asks whether the program is easy for its intended end-user — not the programmer — to actually use: clear prompts, sensible input handling, and understandable output and feedback all contribute to this. A program can be perfectly correct internally and still score poorly here if a real user would find it confusing or unclear to interact with.
Maintainability
Maintainability asks whether the code itself is easy for a programmer — possibly not the original author, and possibly the same programmer returning to it much later — to read, understand, and safely change. Meaningful variable and function names, sensible use of comments, and a clear modular structure (SDD7's functions and procedures) all directly support this criterion.
Robustness
Robustness asks whether the program continues to behave sensibly when faced with unexpected, invalid, or edge-case situations, rather than crashing outright. This connects directly back to SDD16's erroneous test data and SDD15's edge-case discussion (an empty array, a boundary value) — a robust program anticipates these situations rather than being caught out by them.
Worked examples
findMinimum should return the smallest value in a given array.smallest to array[0], was confirmed in SDD14 to correctly return 15 for stockLevels. The originally-buggy version (initialising to 0) does not meet this requirement — SDD16/17 confirmed it incorrectly returns 0.stockLevels:
def findMinimum(array):
smallest = array[0]
for i in range(1, len(array)):
if array[i] < smallest:
smallest = array[i]
return smallest
def findMinimumInefficient(array):
sortedArray = sorted(array)
return sortedArray[0]15 for stockLevels — both are fit for purpose. But findMinimumInefficient sorts the entire array just to read off its first element, doing far more work than necessary to answer a question that only ever needed a single pass through the data.findMinimum is the more efficient use of coding constructs — it solves the problem with the minimum necessary work, using the standard algorithm designed specifically for this task (SDD14), rather than a more roundabout, comparatively wasteful alternative.printItemDetails procedure:def f(r):
print(r.n)
print(r.p)
print(r.s)
# Prints a tuck shop item's
# details clearly for the end-user
def printItemDetails(item):
print("Name:", item.name)
print("Price:", item.price, "p")
print("Stock:", item.stock)
f, r, n) and unlabelled output are poor for maintainability (unclear to any programmer other than perhaps the one who just wrote it) and poor for usability (an end-user sees three unlabelled numbers with no indication what each one means). The right version's descriptive names, comment, and labelled output score much better on both criteria.
calculateChange(amountPaid, price) against all five criteria at once:| Criterion | Judgement |
|---|---|
| Fitness for purpose | Met — correctly returns 25 for calculateChange(100, 75), confirmed by an actual Python run. |
| Efficient use of coding constructs | Met — a single subtraction is the minimal, appropriate operation for this task. |
| Usability | Partial — the function itself has no direct user interaction; usability would depend on how its result is displayed to a till operator. |
| Maintainability | Met — clearly named parameters (amountPaid, price) make its purpose immediately obvious. |
| Robustness | Partial — calculateChange(50, 75) returns -25 without crashing (confirmed by an actual Python run), but whether negative change should be specifically handled depends on unstated functional requirements (SDD16). |
findMinimum crashes with an IndexError if given an empty array, since array[0] doesn't exist. Which evaluation criterion does this most directly affect, and why?
- Treating "it runs" as automatically fit for purpose. Fitness for purpose is judged against specific functional requirements — a program that runs but produces wrong results (a logic error) is not fit for purpose.
- Confusing usability with maintainability. Usability is about the end-user's experience; maintainability is about a programmer's ability to read and modify the code later. Clear variable names help maintainability specifically, not usability directly.
- Giving vague, unspecific evaluations. "The code is good" is not an evaluation — each criterion needs a specific judgement tied to specific evidence (e.g. "this uses a single-pass algorithm, so it is efficient").
- Forgetting robustness applies to more than just crashes. A program that doesn't crash but silently produces a nonsensical result on invalid input (e.g. negative change) has also failed to be fully robust.
- Assuming a criterion can only be "met" or "not met". As Example 4 shows, some evaluations are genuinely partial or depend on unstated requirements — this ambiguity itself is worth stating explicitly, not resolved arbitrarily.
When evaluating a program, always name the specific criterion being addressed and tie the judgement to concrete evidence from the code or its behaviour — a generic comment about code "being good" or "working well" earns little credit. If a question gives you a piece of code, look for evidence relevant to all five criteria, not just the one or two that seem most obvious at first glance.
Task Set A — Core questions
findMinimumBuggy runs without crashing but returns the wrong result (0 instead of 15). Which criterion does it fail most directly?findMinimumInefficient (which sorts the array first) is a weaker example of "efficient use of coding constructs" than findMinimum, even though both return the correct result. (3 marks)calculateChange(50, 75) returns -25 without crashing. Which of the five criteria is this result relevant to?findMinimum's robustness, and explain which criterion it targets. (3 marks)Task Set B — Extension
Higher Computing Science → Software Design & Development → SDD18
Single period. Final lesson before the two mini-projects (SDD19/20) — this is the last purely "content" lesson of the whole SDD unit; everything from here on applies what's already been taught.
Suggested timing: 5 min warm-up + vocab · 15 min notes + criteria-grid walkthrough · 20 min examples 1–4 (Example 4's full checklist table is the pedagogical centrepiece — consider working through it live as a class rather than just reading it) · 5 min "now you try" · remainder Task Set A; Task Set B as homework/extension.
Key misconception: pupils very reliably conflate usability and maintainability, since both sound like generic "good code" qualities — Example 3's side-by-side comparison exists specifically to make the distinction concrete (one is about the end-user, the other about a future programmer).
Deliberately reuses functions and bugs already established across the whole course (SDD7's printItemDetails, SDD8's calculateChange, SDD14/16/17's findMinimum) rather than introducing new code — the point of this lesson is applying a new lens to already-familiar material, not learning new syntax.
SQA command words covered: define, explain, evaluate, justify.