Software Design & Development · Implementation

SDD7 — Functions and Procedures

📅 Mon 22 Jun 2026 · P1+P2 (double)
~120 minutes
Learning intentions
Success criteria
Warm up — recap from SDD6
Answer all three questions, then check your answers.
Question 1
In SDD6, what term describes a single structured variable that groups multiple related fields together to describe one item?
Question 2
Using itemRecords[2] = Item("Chocolate", 75, 30), what field name would you write after the dot to access the price?
Question 3
Why are records generally safer than parallel arrays once an item has several attributes?

Key vocabulary

Sub-program
A named, reusable block of code, defined by its name and arguments, that is either a function or a procedure.
Function
A sub-program that calculates and returns a value, so it can be used inside an expression, condition, or assignment.
Procedure
A sub-program that performs an action, such as printing or updating data, but does not return a value.
Argument
A piece of data passed into a sub-program when it is called, matching the sub-program's defined inputs.
Return statement
The line inside a function (return in Python) that sends a value back to the code that called it.

Organising code with sub-programs

What is a sub-program?

A sub-program is a named, reusable block of code that can be called from elsewhere in a program, rather than being written out repeatedly. Every sub-program is defined by two things: its name, used to call it, and its arguments — the inputs it accepts, listed inside brackets when it is defined and when it is called. The Higher specification splits sub-programs into exactly two kinds: functions and procedures, distinguished by one thing only — whether or not they return a value.

Splitting a program into sub-programs also mirrors the iterative development process from SDD1: each sub-program can be designed, written, and tested as its own small unit, rather than tackling an entire problem as one long, unbroken block of code. A well-chosen sub-program can also be reused — called several times, with different arguments, instead of the same logic being copied and pasted throughout a program. This is exactly the kind of modular structure the mini-projects in SDD19 and SDD20 will ask you to build.

Functions: sub-programs that return a value

A function calculates something and sends the result back to whatever code called it, using a return statement. Because a function produces a value, it can be used directly inside an expression: assigned to a variable, used inside a condition, or passed straight into another calculation, for example stockTotal = calculateTotalStock(itemRecords). A function without a return statement does not actually return anything meaningful — in Python, it silently returns None, even if it performs calculations internally. It is also worth noting that a return statement immediately ends the function — any code written after it inside the same function will never run.

Procedures: sub-programs that perform an action

A procedure performs an action — printing something to the screen, updating a record, saving data — but does not hand back a value for use elsewhere in the program. Procedures are called as a statement on their own line, not used inside an expression: printItemDetails(itemRecords) is a complete, valid line by itself, whereas trying to write total = printItemDetails(itemRecords) + 5 would fail to behave sensibly, since there is no numeric value to add to. Procedures can still take arguments; having inputs is not what separates a function from a procedure. The only distinguishing feature is whether a value is returned.

Naming and calling sub-programs

A sub-program's name should describe what it does clearly and specifically — vague names such as doStuff or process make code harder to read and undermine the "efficient use of coding constructs" criterion tested later at evaluation (SDD18). A good name usually reflects whether the sub-program is a function or a procedure too: calculateTotalStock and isAffordable both suggest a value comes back, while printItemDetails clearly signals an action rather than a result. When a sub-program is called, the arguments given in the call are matched, in order, to the inputs the sub-program was defined to accept. SDD8 covers exactly how this matching works, using the more precise terms formal and actual parameters — this lesson only needs the general idea that a sub-program's name and its arguments together define how it is used.

Function vs procedure — the same tuck shop data, two different jobs

Function — returns a value
Calculates the total stock and sends the result back with return, so it can be stored in a variable.
def calculateTotalStock(records):
    total = 0
    for i in range(len(records)):
        total = total + records[i].stock
    return total

stockTotal = calculateTotalStock(itemRecords)
Procedure — performs an action
Prints every record's details to the screen, but does not send anything back.
def printItemDetails(records):
    for i in range(len(records)):
        print(records[i].name, "costs",
              records[i].price, "pence, stock:",
              records[i].stock)

printItemDetails(itemRecords)

Worked examples

Example 1 — A function that returns an accumulated value
1
Using the SDD6 tuck shop records, a function totals the stock across every record and returns the result:
def calculateTotalStock(records):
    total = 0
    for i in range(len(records)):
        total = total + records[i].stock
    return total

stockTotal = calculateTotalStock(itemRecords)
print(stockTotal)
2
Because return total sends the value back, stockTotal can now be used anywhere else in the program — printed, compared, or passed into another calculation.
Using stock values 24, 15, 30, 40, the function returns 109 — this is a function, because it produces and returns a value.
Example 2 — A procedure that performs an action
1
A procedure prints every record's details, but has no return statement:
def printItemDetails(records):
    for i in range(len(records)):
        print(records[i].name, "costs", records[i].price, "pence, stock:", records[i].stock)

printItemDetails(itemRecords)
2
If a pupil mistakenly tries to capture a "result" from this procedure: result = printItemDetails(itemRecords), then print(result) — what happens?
The four lines of item details print as normal (the procedure still runs), but result is None, because printItemDetails has no return statement — this is exactly what makes it a procedure, not a function.
Example 3 — A function with two arguments, used inside a condition
1
A function checks whether a price is within budget, taking two arguments:
def isAffordable(price, budget):
    return price <= budget

if isAffordable(75, 100):
    print("Chocolate is affordable")
2
Because isAffordable returns a Boolean value, it can be used directly inside the if condition — this is only possible because it is a function, not a procedure.
Tracing: price = 75, budget = 100, 75 <= 100 is True, so the condition passes and "Chocolate is affordable" is printed.
Now you try
Using a single tuck shop record such as Item("Chocolate", 75, 30):

Write a function called isInStock that takes one argument, record, and returns True if record.stock is greater than 0, otherwise False.
⚠️ Common mistakes — examiner feedback
📝 Exam tip

When asked to describe or distinguish between a function and a procedure, always state the distinction explicitly: a function returns a value and can be used inside an expression; a procedure performs an action and does not return a value. Simply describing what each one "does" without naming this specific difference will not gain full marks.

Task Set A — Core questions

Task Set A — Core questions
Work through all questions, then check your answers.
Question 1
What SQA term is used for a named, reusable block of code that is either a function or a procedure?
Question 2
Which statement correctly distinguishes a function from a procedure?
Question 3
def calculateTotalStock(records):
    total = 0
    for i in range(len(records)):
        total = total + records[i].stock
    return total
Calling calculateTotalStock(itemRecords) on records with stock values 24, 15, 30, and 40 — what value is returned?
Question 4
A pupil writes result = printItemDetails(itemRecords) then print(result), where printItemDetails has no return statement. What happens?
Question 5
Which statement about arguments is correct?
Question 6
Using def isAffordable(price, budget): return price <= budget, what does isAffordable(90, 80) evaluate to?
Question 7
Explain why calculateTotalStock is a function but printItemDetails is a procedure, referring to what each one does with its result. (3 marks)
Question 8
Write a Python function called isInStock that takes one argument, record, and returns True if record.stock is greater than 0, otherwise False.
def isInStock(record):
    return record.stock > 0
Question 9
A function is defined but has no return statement anywhere inside it. What value does calling that function actually produce in Python?
Question 10
Describe what is meant by a sub-program being "defined by its name and arguments". (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
SDD8 will introduce formal and actual parameters as more precise vocabulary for a sub-program's inputs. Suggest why "argument" alone might not be precise enough once a program starts passing data between many different sub-programs.
Extension 2
A pupil writes a sub-program that both prints a message to the screen and returns a value. Is this good practice? Suggest one reason why keeping functions and procedures each doing only one job is usually considered better design.
Extension 3
SDD19's mini-project will require you to design a modular program built from several functions and procedures. Suggest one factor you should consider when deciding whether a particular piece of logic should become a function or a procedure.
📁 File this in OneNote under:
Higher Computing Science → Software Design & Development → SDD7
📌 Teacher notes — not for pupils

Double period. This lesson continues reusing the SDD5/SDD6 tuck shop scenario and figures (same records, same 109 stock total) — the function/procedure examples are built directly on top of SDD6's itemRecords, so pupils see immediate continuity rather than a new dataset.

Suggested timing: 10 min warm-up + vocab · 20 min notes + compare-panels (live-code both definitions side by side, running each to show the difference in the shell) · 20 min examples 1–3 · 10 min "now you try" · 45 min Task Set A · remaining time Task Set B / homework.

Key misconception: pupils very often try to "use" a procedure's return value, since Python does not stop them from writing result = someProcedure(...) — deliberately demonstrate this live (example 2) and show result printing as None, since seeing the error is more memorable than being told about it.

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

Extension suggestion: Extension 1 deliberately sets up SDD8's formal/actual parameter vocabulary — worth a brief verbal preview at the end of the lesson so the terms aren't completely new next time.

Implementation note (5 Jul 2026): this lesson was switched from dictionary-based records to @dataclass-based records after the fact, to match SDD6's updated implementation (see SDD6 teacher notes for the full rationale). Field access throughout is now dot notation (records[i].stock) rather than bracket/key notation.