SDD15 — Standard Algorithms with Arrays of Records
- I can adapt linear search, minimum, maximum, and count-occurrences to work on an array of records
- I can explain why these algorithms must compare a specific field of each record, rather than the record as a whole
- I can write a linear search that compares a named field (e.g.
.name) of each record to a target - I can adapt the minimum/maximum algorithms to compare a named field (e.g.
.stock,.price) of each record - I can adapt count-occurrences to count how many records satisfy a condition on a named field
- I can explain that all four algorithms keep the same overall algorithmic shape, while linear search and conditional count mainly change the tested expression and minimum/maximum require coordinated index tracking to retrieve the whole record
stockLevels = [30, 45, 20, 15, 60, 18], what is the minimum value?for loop that checks every element, unlike linear search?Key vocabulary
.stock), rather than comparing the whole record.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.
Worked examples
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")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.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)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.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).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.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)< 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 (==).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?
- Comparing the whole record instead of one field.
records[position] < records[smallestIndex]is not a valid comparison between twoItemobjects — a specific field, such as.stock, must be named explicitly. - Tracking the field value instead of the index. If only the smallest stock number itself is stored, rather than its index, the matching record's other fields (name, price) can no longer be retrieved afterwards.
- Either rewriting everything or changing too little. All four algorithms retain their overall shape. Linear search and conditional count mainly change the tested expression, but a record-based minimum/maximum must consistently initialise an index at
0, compare through that index, update it withposition, and return it. - Assuming count-occurrences only checks for equality. Swapping
==for a condition like<or>is a valid, common variation — the algorithm still counts how many elements satisfy the test, just not strict equality. - Using the wrong field for the wrong question. "Which item is cheapest?" needs
.price; "which item needs restocking soonest?" needs.stock— always check exactly which field a question is asking about.
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
itemRecords array, at what index is the record with .name equal to "Flapjack"?.stock value?.price value?stock < 20?if records[position] < records[smallestIndex]: to find the minimum-stock record. What is wrong with this?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
countOccurrences (checking for an exact match) and this lesson's countLowStock (checking a condition). (3 marks)linearSearchRecords(itemRecords, "Kale") return, given "Kale" does not appear in the array?Task Set B — Extension
stock < 20) — combining a condition with a minimum-finding algorithm.findMinStockRecord or countLowStock should specifically include.Higher Computing Science → Software Design & Development → SDD15
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.