Software Design & Development · Implementation

SDD15 — Standard Algorithms with Arrays of Records

📅 Thu 17 Sep 2026 · P3+P4 (double)
~120 minutes
Learning intentions
Success criteria
Warm up — recap from SDD14
Answer all three questions, then check your answers.
Question 1
Using stockLevels = [30, 45, 20, 15, 60, 18], what is the minimum value?
Question 2
What value should a minimum-finding algorithm's running "smallest" variable be initialised to?
Question 3
Why do minimum, maximum, and count-occurrences all use a for loop that checks every element, unlike linear search?

Key vocabulary

Field-based comparison
Comparing one specific named field of each record (e.g. .stock), rather than comparing the whole record.
Record index vs record value
The position of a matching record in the array, as distinct from the record itself or one of its fields.
Conditional count
A count-occurrences variant that counts records satisfying a condition (e.g. stock < 20), not just an exact match.

The same four algorithms, one field at a time

What changes, and what doesn't

SDD13 and SDD14 built linear search, minimum, maximum, and count-occurrences against plain 1D arrays of bare values. This lesson re-runs all four algorithms against the tuck shop's itemRecords array of Item @dataclass records (SDD6–12). All four keep the same overall algorithmic shape: traverse the array, test the relevant data, update running state, and return a result. The exact adaptation is not identical for every algorithm, however. Linear search and conditional count mainly change the tested expression from a bare value such as array[position] to a named field such as records[position].stock. Minimum and maximum also need coordinated changes to their running state when the result must identify a whole record.

Linear search on a record field

Rather than searching an array of plain names for a match, linear search on records compares one field — typically .name — of each record to the target, e.g. records[index].name == target. The rest of the algorithm (the found flag, the incrementing index, the -1 sentinel for "not found") is completely unchanged from SDD13.

Minimum and maximum on a record field

Instead of comparing bare numbers, the minimum/maximum algorithms now compare a chosen numeric field of each record — for example, finding the record with the lowest stock or the record with the highest price. SDD14 safely initialised a running value from the first element, such as smallest = array[0], then compared the remaining elements from index 1. Here the equivalent safe initialisation is smallestIndex = 0: the first record is the current best record. The comparison must read through that index, for example records[position].stock < records[smallestIndex].stock; a better record makes the update store position in smallestIndex; and the function returns that index. These coordinated initialisation, comparison, update, and return changes are necessary because the whole matching record must remain retrievable, not just its field value.

Count-occurrences as a condition, not just equality

SDD14's count-occurrences checked for an exact match (array[position] == target). Applied to records, this same "running counter, check every element" shape works equally well for a condition rather than strict equality — for example, counting how many items have stock < 20 (a reorder-warning count), simply by swapping == for < in the comparison. The algorithm's shape is unchanged; only the comparison operator and what's being compared (a field, not a bare value) are different.

Why this lesson matters beyond just "more practice"

It would be easy to treat this lesson as simply repeating SDD13/14 with slightly different data, but the real point is narrower and more useful than that: recognising which parts of an already-known, already-tested pattern can stay and which must change for a new data structure. Sometimes the adaptation is chiefly one tested expression, as in linear search and conditional count. Sometimes several connected lines must change together, as in an index-tracking minimum or maximum. This is precisely the kind of transferable skill the SQA assignment (Task 1, SDD7–SDD12's parameter passing and file handling combined with SDD13–15's algorithms) rewards — adapting a standard pattern accurately rather than reinventing it or changing only part of the required state.

0
Chocolate
75p
stock 30
1
Crisps
63p
stock 45
2
Juice
90p
stock 20
3
Flapjack
110p
stock 15
4
Sweets
50p
stock 60
5
Muffin
120p
stock 18

Worked examples

Example 1 — Linear search on the .name field
1
Using the six-item itemRecords array of Item records (Chocolate, Crisps, Juice, Flapjack, Sweets, Muffin):
def linearSearchRecords(records, target):
    index = 0
    found = False
    while index < len(records) and not found:
        if records[index].name == target:
            found = True
        else:
            index = index + 1
    if found:
        return index
    else:
        return -1

result = linearSearchRecords(itemRecords, "Flapjack")
2
Compare this directly to SDD13's linearSearch: the only change is array[index] == target becoming records[index].name == target.
result is 3 — confirmed by an actual Python run. Searching for "Kale", which does not exist, correctly returns -1.
Example 2 — Minimum stock record
1
def findMinStockRecord(records):
    smallestIndex = 0
    for position in range(1, len(records)):
        if records[position].stock < records[smallestIndex].stock:
            smallestIndex = position
    return smallestIndex

minIndex = findMinStockRecord(itemRecords)
2
Note that smallestIndex — the position of the best record so far — is tracked, not the stock value itself, so the whole matching Item record can still be retrieved via records[smallestIndex] afterwards.
minIndex is 3, and itemRecords[3] is Item(name='Flapjack', price=110, stock=15) — confirmed by an actual Python run.
Example 3 — Maximum price record
1
def findMaxPriceRecord(records):
    largestIndex = 0
    for position in range(1, len(records)):
        if records[position].price > records[largestIndex].price:
            largestIndex = position
    return largestIndex

maxIndex = findMaxPriceRecord(itemRecords)
2
Identical structure to Example 2, but comparing .price instead of .stock, and > instead of < — exactly the same relationship SDD14 established between its own minimum and maximum algorithms.
maxIndex is 5, and itemRecords[5] is Item(name='Muffin', price=120, stock=18) — confirmed by an actual Python run.
Example 4 — Counting low-stock items (a condition, not equality)
1
Counting how many items need reordering, defined as stock below 20:
def countLowStock(records, threshold):
    count = 0
    for position in range(len(records)):
        if records[position].stock < threshold:
            count = count + 1
    return count

result = countLowStock(itemRecords, 20)
2
Flapjack (stock 15) and Muffin (stock 18) both have stock below 20; Juice, at exactly 20, does not satisfy < 20.
result is 2 — confirmed by an actual Python run. This is the same "running counter, check every element" shape as SDD14's countOccurrences, just with a condition (<) in place of strict equality (==).
Now you try
Adapt Example 2's findMinStockRecord pattern to instead write findMaxStockRecord, finding the index of the record with the highest stock level. What index and item does it find in itemRecords?
⚠️ Common mistakes — examiner feedback
📝 Exam tip

When adapting a standard algorithm to work on records, state explicitly which field is tested and what the running variable stores. For linear search and conditional count, the tested expression is the main change. For minimum/maximum that must identify a whole record, show the full index-tracking pattern: initialise the best index to 0, compare the chosen fields through that index, store position when a better record is found, and return the index.

Task Set A — Core questions

Task Set A — Core questions
Work through all questions, then check your answers.
Question 1
Using the six-item itemRecords array, at what index is the record with .name equal to "Flapjack"?
Question 2
Using the same array, which item has the lowest .stock value?
Question 3
Which item has the highest .price value?
Question 4
How many items have stock < 20?
Question 5
Why does a minimum-stock-record algorithm typically track the index of the best record, rather than the stock value itself?
Question 6
Explain what changes, and what stays the same, when adapting a standard algorithm from SDD13/14 to work on an array of records. (3 marks)
Question 7
A pupil writes if records[position] < records[smallestIndex]: to find the minimum-stock record. What is wrong with this?
Question 8
Write a Python function called countLowStock that takes an array of Item records and a threshold, and returns how many records have .stock below the threshold.
def countLowStock(records, threshold):
    count = 0
    for position in range(len(records)):
        if records[position].stock < threshold:
            count = count + 1
    return count
Question 9
Explain the difference between SDD14's countOccurrences (checking for an exact match) and this lesson's countLowStock (checking a condition). (3 marks)
Question 10
What does linearSearchRecords(itemRecords, "Kale") return, given "Kale" does not appear in the array?

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 how you might find the item with the lowest price among only the items with low stock (stock < 20) — combining a condition with a minimum-finding algorithm.
Extension 2
SDD16 will cover writing test plans. Suggest two edge cases that a test plan for findMinStockRecord or countLowStock should specifically include.
Extension 3
SDD19 and SDD20 will each build a complete mini-project. Suggest which of the two would be the more natural place for a program that reads records from a CSV file, runs a standard algorithm on them, and writes an updated file back out — and explain why.
📁 File this in OneNote under:
Higher Computing Science → Software Design & Development → SDD15
📌 Teacher notes — not for pupils

Single period, though content-dense (four algorithms re-run) — if the single P3 slot proves tight in practice, consider trimming Task Set A to 8 questions rather than 10, or moving Question 9/10 to a follow-up starter next lesson.

This is the pedagogical payoff lesson combining SDD6–12 (records) with SDD13/14 (algorithms) — deliberately reuses the exact itemRecords six-item array established across SDD6–12 (including the Muffin record added in SDD12), for maximum continuity.

Suggested timing: 5 min warm-up + vocab · 15 min notes · 20 min examples 1–4 · 5 min "now you try" · remainder Task Set A; Task Set B as homework/extension.

Key misconception: pupils may either rewrite each algorithm from scratch or assume every adaptation is a single-line comparison change. A side-by-side display should show that linear search and conditional count mainly change the tested expression, while SDD14's value-tracking minimum/maximum becomes coordinated index tracking in SDD15: initialise at index 0, compare through the index, update it with position, and return it.

This completes the algorithm-specification strand (SDD13–15) and the SQA content map's Implementation strand in full. SDD16 (Testing) begins the Testing/Evaluation portion of the course.

SQA command words covered: explain, write code.