Software Design & Development · Implementation

SDD6 — Records and Arrays of Records

📅 Thu 18 Jun 2026 · P3+P4 (double)
~120 minutes
Learning intentions
Success criteria
Warm up — recap from SDD5
Answer all three questions, then check your answers.
Question 1
In SDD5, what must be true about parallel arrays for the same index to reliably refer to the same item across every array?
Question 2
In SDD5, what is the name for the numeric position used to access a specific value inside an array?
Question 3
What is the term (from SDD5) for a single value stored inside an array, accessed via its index?

Key vocabulary

Record
A single structured variable that groups several related fields together to describe one item.
Field
One named piece of data stored inside a record, such as a name, price, or stock level.
Array of records
A list containing several records, where each element of the list is itself a complete record for one item.
Attribute
One named field belonging to a record, accessed using dot notation, e.g. record.stock.
@dataclass
A Python decorator that turns a class into a reusable template for a record, defining its field names and types once.

Grouping related data with records

What is a record?

SDD5 stored related attributes in separate parallel arrays, linked only by a shared index. A record takes a different approach: it groups every field describing one item — a name, a price, a stock level — into a single structured variable. In Python, a record is implemented using the @dataclass decorator, which defines a reusable template — a class — describing a record's field names once. For example, a template Item with fields name, price, and stock can then be used to create Item("Chocolate", 75, 30): one record, a single variable holding three related fields about one item, rather than three separate array elements spread across three different arrays.

Why use records instead of parallel arrays?

Because all of a record's fields live inside one structured variable, they can never become misaligned with each other in the way parallel arrays can. There is no risk of one field's array becoming a different length, or falling out of order relative to another — the fields are inseparably bundled together as a single item. This makes records the safer choice once a problem involves more than one or two attributes per item, which is exactly why records and arrays of records are named separately from parallel arrays in the Higher specification.

Declaring records and arrays of records in Python

Before defining a record template, the dataclass decorator must be imported: from dataclasses import dataclass. A record template is then written as a class, with the @dataclass decorator placed directly above it, and each field listed on its own line with a type hint, for example name: str. Once the template exists, individual records are created by calling the template's name with the field values in order, e.g. Item("Chocolate", 75, 30). An array of records is simply a list containing several such objects — one per item, in order. Every record in the list is built from the same template, so code written to process one record (for example, reading its price field) works consistently for every record in the list.

Traversing an array of records with an index

An array of records is traversed with a fixed loop in exactly the same way as a 1D array or parallel arrays: a single index variable, such as i, is used to select which record to work with — itemRecords[i]. Once a specific record has been selected using the list index, its individual fields are then accessed using dot notation, for example itemRecords[i].price. Both the index and the field name are needed together — the index picks the item, and the field name picks which piece of data about that item to read or change. This same double-lookup pattern is exactly what the standard algorithms in SDD15 rely on when they search or process arrays of records.

Worked examples

Example 1 — Defining a template and declaring a single record
1
Scenario: the same tuck shop item from SDD5, now stored as one record instead of three parallel array elements.
from dataclasses import dataclass

@dataclass
class Item:
    name: str
    price: int
    stock: int

tuckShopItem = Item("Chocolate", 75, 30)
2
Each field is accessed using dot notation:
print(tuckShopItem.name, tuckShopItem.price, tuckShopItem.stock)
This prints Chocolate 75 30 — all three facts about one item, read from a single structured variable rather than three separate arrays.
Example 2 — Declaring and traversing an array of records
1
The full tuck shop stock list, as an array of records, all built from the same Item template:
itemRecords = [
    Item("Crisps", 60, 24),
    Item("Juice", 90, 15),
    Item("Chocolate", 75, 30),
    Item("Water", 50, 40)
]
2
A fixed loop uses one index, i, to select each record in turn, then dot notation to read its data:
for i in range(len(itemRecords)):
    print(itemRecords[i].name, "costs", itemRecords[i].price, "pence, stock:", itemRecords[i].stock)
At i = 2, itemRecords[2] selects the Chocolate record, and itemRecords[2].price and itemRecords[2].stock read 75 and 30 from inside that same record — compare this with SDD5, where the same two facts came from two entirely separate arrays.
itemRecords[0]
nameCrisps
price60
stock24
itemRecords[1]
nameJuice
price90
stock15
itemRecords[2]
nameChocolate
price75
stock30
itemRecords[3]
nameWater
price50
stock40
Example 3 — Updating a field, and tracing a running total
1
A sale reduces the Chocolate record's stock by one, changing only that one record:
itemRecords[2].stock = itemRecords[2].stock - 1
Before: itemRecords[2].stock is 30. After this line runs, it becomes 29 — and no other record is affected, because each record's fields are entirely self-contained.
2
Separately, a fixed loop can total the stock across every record, the same way SDD5 totalled a parallel array:
totalStock = 0
for i in range(len(itemRecords)):
    totalStock = totalStock + itemRecords[i].stock
print(totalStock)
3
Using the original stock values (24, 15, 30, 40), tracing the loop: 0+24=24, 24+15=39, 39+30=69, 69+40=109.
The final printed value is 109 — the same total as SDD5's parallel array version, confirming both structures can represent identical data, just organised differently.
Now you try
A school library stores its books as an array of records, using a Book template with fields title, author, dueDate:
bookRecords = [Book("Wasp Factory", "Iain Banks", "12 Jul"), Book("Room", "Emma Donoghue", "15 Jul")]

Write a fixed loop that prints, for every book, a line in the form <title> by <author> — due <dueDate>.
⚠️ Common mistakes — examiner feedback
📝 Exam tip

When asked to describe or explain why records are used, always state that a record groups every field for one item into a single structured variable, so those fields can never become out of sync with each other — this is the specific advantage over parallel arrays, and examiners look for that comparison to be made explicitly, not just a description of what a record is. Examiners' own record pseudocode accesses fields by name in exactly this dot-notation style, so fluency with record.fieldName transfers directly to how exam answers are marked.

Task Set A — Core questions

Task Set A — Core questions
Work through all questions, then check your answers.
Question 1
What term describes a single structured variable that groups multiple related fields together to describe one item?
Question 2
How does an array of records differ from parallel arrays?
Question 3
Using record = Item("Chocolate", 75, 30), where Item has fields name, price, stock in that order, what is the value of record.price?
Question 4
Which of the following correctly accesses the stock field of the third record (index 2) in a list called itemRecords?
Question 5
Which statement about records is correct?
Question 6
Using the four records with stock values 24, 15, 30, and 40, and the fixed loop for i in range(len(itemRecords)): totalStock = totalStock + itemRecords[i].stock starting with totalStock = 0, what is the final value of totalStock?
Question 7
Explain why grouping name, price, and stock into a single record for each item avoids the synchronisation risk that exists with parallel arrays (SDD5). (3 marks)
Question 8
Write Python code that defines a Book record template (using @dataclass) with fields title and author, creates a list of two records, bookRecords, for "Wasp Factory" by "Iain Banks" and "Room" by "Emma Donoghue" — then uses a fixed loop to print each title with its author in the form <title> by <author>.
from dataclasses import dataclass

@dataclass
class Book:
    title: str
    author: str

bookRecords = [
    Book("Wasp Factory", "Iain Banks"),
    Book("Room", "Emma Donoghue")
]

for i in range(len(bookRecords)):
    print(bookRecords[i].title, "by", bookRecords[i].author)
Question 9
Using itemRecords[2] = Item("Chocolate", 75, 30), what is the value of itemRecords[2].stock after running itemRecords[2].stock = itemRecords[2].stock - 1?
Question 10
Describe how a fixed loop uses both a list index and a field name together to read data from an array of records. (3 marks)

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
In SDD5 you identified one advantage and one disadvantage of parallel arrays compared to records. Now that you have implemented records in Python, suggest one situation where parallel arrays might still be preferred over records.
Extension 2
A Book record template has fields title, author, and dueDate. A pupil accidentally writes bookRecords[i].Title (capital T) instead of bookRecords[i].title. Explain what would happen when this code runs, and why this is a particularly easy mistake to make.
Extension 3
SDD15 will use standard algorithms (like linear search) on arrays of records instead of plain 1D arrays. Suggest what would need to change in a linear search algorithm to search a list of records for a particular title, compared to searching a plain 1D array of titles.
📁 File this in OneNote under:
Higher Computing Science → Software Design & Development → SDD6
📌 Teacher notes — not for pupils

Double period. This lesson deliberately reuses SDD5's exact tuck shop scenario and figures (same names, prices, stock, and the 109 total) so pupils can directly compare the two structures on identical data rather than learning a new scenario from scratch.

Suggested timing: 10 min warm-up + vocab · 25 min notes + examples 1–2 (live-code alongside slides, explicitly pointing out where this differs from the SDD5 version on screen) · 15 min example 3 (field update + running total trace) · 10 min "now you try" · 45 min Task Set A · remaining time Task Set B / homework.

Key misconception: pupils often try to access a field with square brackets (itemRecords[2]["price"]) out of habit from arrays generally — reinforce "index first, then dot, then field name" as a fixed rule, and use the record-card visual to physically point at "which card, then which row". Also flag the from dataclasses import dataclass import line explicitly — a missed import is a common early-lesson stumbling block that produces a confusing NameError: name 'dataclass' is not defined on the decorator line.

SQA command words covered: describe, explain, implement, trace.

Extension suggestion: Extension 3 previews SDD15 directly — worth flagging to stronger pupils that this is genuinely rehearsing a skill they will need again, not just an abstract exercise.

Implementation note (5 Jul 2026): this lesson was switched from dictionary-based records to @dataclass-based records after the fact, to match the department's other Higher class and because the SQA's own 2024 QP marking instructions model record field access with dot notation (e.g. allRecipes[n].ingredient), not dictionary brackets. SDD7 and SDD8 were updated to match in the same pass.