Exam Revision Guide

AS Level — Unit 2: Practical Programming to Solve Problems

How the paper works

Unit 2 is a 2-hour, 60-mark, on-screen practical exam split into two sections:

Section Marks What you produce
A — Analysis and Design 36 A single Word document (Section A.docx) with answers to 4 questions
B — Develop Programs 24 Python files: complete supplied code, write a new program, annotate it

This guide walks through every question slot in turn, telling you what the mark scheme rewards and giving Python templates you can rehearse until automatic.

The question types in this paper are extremely consistent year-on-year. The same mark-scheme bullets appear in 2016, 2019, 2022, 2023 and 2024. Memorising the templates on this page is the single highest-leverage thing you can do.


Section A — Analysis and Design (36 marks)

Save your answers as one Word document named Section A. Use the question numbers as headings so the examiner can locate each answer easily.

Q1(a) — Entity Relationship Diagram (~5 marks)

The 5 marks (consistent 2022–2024) break down as:

Marks What earns the mark
1 First entity table named correctly
1 Second entity table named correctly
1 Third entity table named correctly
1 Correct relationship link from entity A to entity B with the many side shown
1 Correct relationship link from entity B to entity C with the many side shown

The mark scheme literally says “must indicate many side for each mark above”. The crow’s-foot or letter M must be visible at the many end of every relationship. Miss this and you lose both relationship marks.

Method

  1. Read the scenario for entities. Phrases like “each manager can be responsible for several teams” or “a customer may have many bookings” tell you the 1:M direction directly.
  2. Draw three boxes labelled with the entity names — use the scenario’s wording, don’t invent names.
  3. Draw the relationship lines. Most relationships in this paper are 1:M (one customer makes many bookings; one booking is for one trip).
  4. Mark the many end clearly — use a crow’s foot (three lines branching) OR write M at that end and 1 at the other end. Either notation works.
  5. If asked to “include some exemplar fields” (2024 wording), add 2–3 sample fields inside each entity box, including primary keys and foreign keys.

Q1(b) — Data Structure Table (~10 marks)

Marks What earns the mark
2 Two suitable fieldnames in addition to the key field
2 Specific data types for those fields (Integer, String, Real, Boolean, Date)
1 Key field clearly indicated (asterisk, underline or column note)
2 Sensible field lengths
2–3 Validation types (one mark each for Range, Format, Presence, Length, Lookup…)
2 When two tables asked: foreign keys in linking table and primary keys in parent tables (2023 MS)

Template you can copy straight into the exam

Fieldname Key Data Type Length Validation
CustomerID PK * Integer 6 Presence check
Title String 4 Lookup: Mr, Mrs, Miss, Dr, Ms
FirstName String 25 Length check 1–25 chars
DOB Date 10 Format DD/MM/YYYY
Postcode String 8 Format LL00 0LL
Email String 40 Format: must contain @ and .
BookingID (FK) FK Integer 6 Type check (Integer)

Use at least three different validation types across your fields — Presence, Length, Range, Format, Lookup, Type check. Examiners reward variety; repeating the same validation type for every field loses marks.


Q2 — Method of Solution Justification (6 marks)

This is a banded question, not points-based. To hit Band 3 (5–6 marks) you need sustained prose, not a checklist. The mark scheme Band 3 descriptor requires “a sustained line of reasoning which is coherent, relevant, and logically structured” with “balanced discussion and justified their answer with examples” tied to the scenario.

Indicative content the MS lists (identical across 2016, 2019, 2022, 2023 and 2024)

  • Discussion of interface (CLI/GUI)
  • Data structures (arrays/files)
  • File handling (serial/random)
  • Validation (range, format, presence, length)
  • Local or global variables used
  • Ability to handle data types (string/integer/Boolean)
  • Processes required: Add, amend, delete, save, calculate (added in 2019 MS)

Band targets (from 2024 MS)

Band Marks What you need
3 5–6 Five–six detailed points, each tied to the scenario, with examples and accurate terminology
2 3–4 Three–four points with adequate reasoning
1 1–2 One–two points, superficial

Model paragraph (Python-flavoured)

Each paragraph: state your choice → justify in scenario terms → give a Python example. 2–3 sentences each. Write six of these.

“I will use a graphical user interface (GUI) built in Python with the tkinter library. Sky Balloon Park’s staff are not technical, so text boxes and buttons for TripID, Date, Time and Description give a clearer data entry experience than a command-line interface, with immediate feedback through messagebox widgets when records are saved. The form-based layout also makes it easier to add the validation in the next point.”

Python-specific phrases to bank for each point

Point Phrase
Interface “GUI built using tkinter with Entry widgets, Button widgets, Label widgets, plus messagebox for confirmations.”
Data structures “A list of records (each record a string of fixed-width fields) holds the dataset in memory; lists allow indexed iteration when searching.”
File handling “Serial text file access using open() in append mode for saving and read mode for searching. Each record is one line, padded to fixed widths with ljust(50) for reliable slicing.”
Validation “Length checks using len(), presence checks comparing against the empty string, range checks using comparisons, format checks using string methods like startswith().”
Local/global StringVar() objects declared global so all subroutines can access form fields; loop counters and match counts kept local inside each function to prevent side-effects.”
Data types “Strings for names and IDs, integers for numeric IDs converted with int(), booleans for found-flags, dates stored as strings in DD/MM/YYYY format.”

Q3 — Rotating Context Question (6–8 marks)

This slot rotates each year. You must be prepared for any of the five topics below. For 2026 the top bets are the OOP class diagram (last seen 2022) or modes of operation (last seen 2016).


Topic 3A — OOP Class Diagrams

Two question styles have appeared. Style 1 (drawing) is the more demanding one.

UML class-box notation — memorise this layout

ClassName + publicAttribute : Type − privateAttribute : Type # protectedAttribute : Type + publicMethod() : ReturnType − privateMethod(p : Type) # protectedMethod() : ReturnType + method(a : Int, b : String) : Bool Class name Attributes (state) Methods (operations) Visibility: + public − private # protected

Notation rules to memorise

  • Visibility symbols: + public, private, # protected
  • Attribute notation: visibility name : Type — e.g. +customerID : Integer
  • Method notation: visibility name(parameters) : ReturnType — e.g. +getName() : String
  • Inheritance arrow: hollow triangle pointing FROM the subclass TO the superclass. Don’t draw it backwards.

Style 1 — Draw a class diagram (2022, 7 marks)

The MS awards 1 mark per item:

Item
1 Public attribute with type, e.g. +accountNumber : Integer
2 Second public attribute with type, e.g. +transactionID : Integer
3 Public method with return type, e.g. +getAccountNumber() : Integer
4 Second public method with return type
5 Inheritance arrow (hollow triangle, subclass → superclass)
6 Private attribute with type, e.g. −amount : Real
7 Private method with parameter, e.g. −setAmount(Real)

Worked answer — Transaction → AddCredit inheritance

Transaction + accountNumber : Integer + transactionID : Integer + getAccountNumber() : Integer + getTransactionID() : Integer AddCredit − amount : Real + getAmount() : Real − setAmount(Real)

The diagram earns all 7 marks: two public attributes (accountNumber, transactionID), two public methods with return types (getAccountNumber, getTransactionID), the hollow-triangle inheritance arrow pointing from AddCredit to Transaction, one private attribute (amount), and one private method with parameter (setAmount(Real)).


Style 2 — Interpret a given class diagram (2019, 6 marks)

Questions ask: name a subclass, name a superclass, list inherited methods, list inherited attributes.

Transaction + accountNumber : Integer + transactionID : Integer + getAccountNumber() : Integer + getTransactionID() : Integer AddCredit − amount : Real + getAmount() : Real − setAmount(Real) Withdraw − amount : Real + getAmount() : Real − setAmount(Real) Transfer − toAccount : Integer + getToAccount() : Int − setToAccount(Int)
Question Answer
Name a subclass AddCredit, Withdraw or Transfer
Name the superclass Transaction
Inherited attributes of AddCredit accountNumber, transactionID
Inherited methods of AddCredit getAccountNumber(), getTransactionID()

Inheritance rule — An object of the subclass can access all of its own members plus the public (+) and protected (#) members of the superclass. It cannot access private (−) members of the superclass.

For the interpretation question, the 2019 MS says “No need for type or visibility” — when listing attributes you just need the names. For the drawing question, full UML notation is required.


Topic 3B — Modes of Operation (last seen 2016)

Suggest one suitable and one unsuitable mode and justify.

Mode Description Typical use Avoid for…
Batch processing Jobs submitted to a queue and processed together later Payroll, utility billing Customer-facing booking systems
Real-time transaction System responds immediately; data updated as it arrives Bookings, stock, kiosks (default safe answer for any customer-facing scenario)
Real-time control Continuous monitoring and reaction Flight control, missile guidance Almost always unsuitable for business scenarios
Multi-tasking / Time-sharing Multiple programs run apparently simultaneously by sharing CPU time slices General-purpose OS

Answer structure: name the suitable mode → give 2 reasons it fits → name the unsuitable mode → give 2 reasons it doesn’t.


Topic 3C — Changeover Methods (last seen 2024)

Marks: 1 per method described, 1 per advantage, 1 per disadvantage, 1 for the final justified recommendation. Total typically 7–8.

Method Advantage Disadvantage
Direct / Big Bang — old system off, new system on Cheap and quick If the new system fails there is no backup
Parallel — both systems run side-by-side Safest; outputs can be compared Expensive, doubles staff workload
Phased — introduce one function at a time Staff trained gradually Slow; the two systems must communicate during transition
Pilot — trial in one part of the organisation first Full features trialled with low risk to the whole organisation No backup for the pilot site if it fails

Topic 3D — Data Security and Integrity (last seen 2023, ~7 marks, banded)

Indicative content from the MS:

  • Standard clerical procedures (lock screens, sign in/out, secure rooms)
  • Levels of permitted access (read/write/no access by role)
  • Passwords for access to files and systems
  • Write-protect mechanisms
  • Validation (for data integrity)
  • Backup procedures (for integrity and recovery)
  • Encryption (of stored data and in transit)
  • Antivirus and firewall protection

To hit Band 3, mention 6+ points and tie each one to the specific data the scenario is storing.


Topic 3E — Access Rights for Staff Groups (last seen 2018)

Scenario names 3–4 staff groups; describe what access each should have to each table.

Level Meaning
No access Cannot see the table at all
Read only Can view but not change
Read/Write Can view, add, edit
Full / Admin Read/write/delete and modify the table structure

Justify each level by tying it to the role, e.g. “Cleaners only need to see the schedule of which units to clean, so they get read-only access to a filtered view of the Bookings table.”


Q4 — Algorithm Task (8–12 marks)

This is the most predictable question. Recent rotation: 2023 dry-run + identify constructs; 2024 dry-run + outputs for various inputs. Top 2026 bet: another 2D array dry-run, OR complete-the-binary-search (2022 style).

Style 1 — 2D array dry-run (most likely)

Method (use paper — never try to do this in your head):

  1. Draw the table with column headers i=0, i=1, i=2, i=3 across the top.
  2. Identify the loop bounds. for i = 0 to 3 runs 4 iterations (0, 1, 2, 3). for i = 1 to 4 also runs 4 iterations but indexed 1–4. Read carefully.
  3. For each iteration, calculate each row of the array. Write the value into the table cell.
  4. Watch for off-by-one. If the formula has (i+1) and i starts at 0, the first value uses 1. If i starts at 1, the first value uses 2.
  5. For follow-on output questions, treat the array as a lookup table — find the row/column from the inputs and read the value.

Worked example (2024 MS)

Algorithm: distance[i,0] = (i+1) * 1.14, distance[i,1] = (i+1) * 1.98, for i = 0 to 3.

i 0 1 2 3
distance[i,0] 1.14 2.28 3.42 4.56
distance[i,1] 1.98 3.96 5.94 7.92

Style 2 — Identify programming constructs (8 marks, 2023)

Crucial MS rule: you must NAME the line AND DESCRIBE its role in context. Naming the line alone gets zero.

Memorise these one-sentence definitions:

Construct Definition
Constant A named value set once and not changeable later (e.g. PASSENGERWEIGHT = 150)
Local variable A variable declared inside a subroutine, accessible only within that subroutine
Global variable A variable declared outside any subroutine, accessible from anywhere in the program
Self-documenting identifier A name whose meaning is obvious from itself (passengerWeight, not pw or x)
Annotation A comment line in natural language explaining the code to a human reader
Procedure calling A line that invokes another subroutine, e.g. completed = fillArray(passengers)
Parameter passing Supplying a value to a subroutine when calling it (passengers is the parameter passed in)
Return a value A subroutine sending a value back to its caller using return, e.g. return TRUE

Style 3 — Complete a binary search (8 marks, 2022)

You’re given the binary search with several lines replaced by . . . and a list of candidate lines. Memorise the complete algorithm so you can recognise the missing pieces instantly:

 1  start is integer
 2  endv is integer
 3  found is Boolean
 4  mid is integer
 5
 6  set start = 0
 7  set endv = (size of array - 1)
 8  set found = FALSE
 9
10  input searchValue
11
12  repeat
13    set mid = (start + endv) DIV 2
14    if searchValue = array[mid] then
15      set found = TRUE
16      output "Found at position", mid
17    endif
18
19    if searchValue > array[mid] then
20      set start = mid + 1
21    endif
22
23    if searchValue < array[mid] then
24      set endv = mid - 1
25    endif
26  until (found = TRUE) OR (endv < start)
27
28  if found = FALSE
29    output "searchValue not found"
30  endif
31  End

Recognition strategy for filling gaps

  • Missing declaration line → look for what’s used later (endv, found, etc.)
  • Line above set start = mid + 1 must be the comparison if searchValue > array[mid] then
  • Line above set endv = mid - 1 must be if searchValue < array[mid] then
  • The until line must include both conditions: found = TRUE OR endv < start
  • The not-found block sits outside the loop, guarded by if found = FALSE

Style 4 — Write a search or sort from scratch (older style, possible return)

Linear search

 1  found is Boolean
 2  i is integer
 3  set found = FALSE
 4  set i = 0
 5  input searchValue
 6
 7  while (i < length of array) AND (found = FALSE)
 8    if array[i] = searchValue then
 9      set found = TRUE
10      output "Found at position", i
11    endif
12    set i = i + 1
13  endwhile
14
15  if found = FALSE then
16    output "Not found"
17  endif

Bubble sort

 1  swapped is Boolean
 2  i is integer
 3  temp is integer
 4  set swapped = TRUE
 5
 6  while swapped = TRUE
 7    set swapped = FALSE
 8    for i = 0 to (length of array - 2)
 9      if array[i] > array[i+1] then
10        set temp = array[i]
11        set array[i] = array[i+1]
12        set array[i+1] = temp
13        set swapped = TRUE
14      endif
15    next i
16  endwhile

Section B — Develop Programs (24 marks, Python)

Three sub-questions on the supplied scenario files. Always: complete supplied code, create a new program, annotate. The 2025 supplied code (AZStock) confirms the format is unchanged — fixed-width 50-char fields, Save and Search/Count operations.

Q1 — Complete the Supplied Code (4–8 marks)

Open the file volunteers (or whatever name the scenario uses), read the existing code, fill in the . . . gaps. The file always contains a Save subroutine, a Search/Count subroutine, and a tkinter form. Gaps are marked with . . . in the place of names or expressions.

What the MS rewards (1 mark per corrected line)

  • Definition of storage type (e.g. the variable holding the field data)
  • Defining a data structure
  • End-if / correct indentation / closing brackets
  • Copying data into the structure (assigning padded values)
  • End of subroutine/method
  • Message confirming file saved
  • Outputting a count message
  • Outputting the number counted

The supplied code pattern (Python tkinter) — recognise this and you can fill any gap

from tkinter import *
from tkinter import messagebox

def saveRecord():
    # gap 1: read each StringVar and pad to 50 chars
    field1Save = field1Var.get()
    field1Save = field1Save.ljust(50)

    field2Save = field2Var.get()
    field2Save = field2Save.ljust(50)

    field3Save = field3Var.get()
    field3Save = field3Save.ljust(50)

    # gap 2: open file in append mode (filename in quotes)
    fileObject = open("records.txt", "a")
    fileObject.write(field1Save + field2Save + field3Save + "\n")
    fileObject.close()

    messagebox.showinfo("Saved!", "Record Saved")
    return

def countRecords():
    recordCount = 0
    countNeeded = 0

    field1Save = field1Var.get()
    field2Save = field2Var.get()
    field3Save = field3Var.get()

    # gap 3: work out how many criteria the user filled in
    if not field1Save == "":
        countNeeded += 1
    if not field2Save == "":
        countNeeded += 1
    if not field3Save == "":
        countNeeded += 1

    if countNeeded == 0:
        messagebox.showerror("Error", "Please enter something to count!")
        return

    try:
        fileObject = open("records.txt", "r")
    except IOError:
        messagebox.showerror("Error", "No file to read")
    else:
        while True:
            countGot = 0
            recordVar = fileObject.readline()
            if recordVar == "":
                fileObject.close()
                break

            # gap 4: compare each filled-in criterion with the right slice
            if field1Save in recordVar[0:50] and not field1Save == "":
                countGot += 1
            if field2Save in recordVar[50:100] and not field2Save == "":
                countGot += 1
            if field3Save in recordVar[100:150] and not field3Save == "":
                countGot += 1

            # gap 5: only count when ALL filled criteria match
            if countGot == countNeeded:
                recordCount += 1

        # gap 6: output the count in a message box
        messagebox.showinfo("Found: ", str(recordCount))
    return

How to fill the . . . gaps

Gap looks like Answer
field1Save.ljust( . . . ) 50 — standard width for every paper since 2015
open( ". . .", "a") The filename the question specifies, e.g. "pets.txt", "volunteers.txt"
Slice positions First field [0:50], second [50:100], third [100:150]
messagebox.showinfo("Found: ", str( . . . )) The counter variable, e.g. recordCount
Button(frame, text="Save", command= . . . ) The function name without parentheses, e.g. command=saveRecord

Q2 — Create a New Program (8 marks)

Standard requirement: input details → validate → save to text file → retrieve. The 2024 wording was “input pet details, perform a length check on each field, store on disk in pets.txt, confirm storage, retrieve specified pet details from disk”. Save as pets.py.

What the MS rewards (1 mark per feature, 8 features for 8 marks)

  1. Input (text boxes / Entry widgets for each field)
  2. Length check on each field (len() is sufficient)
  3. Creates a data file called pets.txt (file created if missing)
  4. Stores on disk in a text file called pets.txt
  5. Descriptive feedback that the file has been saved
  6. Retrieves data from disk
  7. Retrieves specified pet details (filtered by search criteria)
  8. HCI fit for purpose (tkinter is ideal)

Python template — copy this structure and adapt

from tkinter import *
from tkinter import messagebox
import os

FILENAME = "pets.txt"

def saveRecord():
    petID = petIDVar.get()
    name = nameVar.get()
    species = speciesVar.get()

    # Validation: length checks
    if len(petID) < 1 or len(petID) > 6:
        messagebox.showerror("Error", "PetID must be 1-6 characters")
        return
    if len(name) < 1 or len(name) > 30:
        messagebox.showerror("Error", "Name must be 1-30 characters")
        return
    if len(species) < 1 or len(species) > 20:
        messagebox.showerror("Error", "Species must be 1-20 characters")
        return

    # Pad to fixed width and save
    petID = petID.ljust(50)
    name = name.ljust(50)
    species = species.ljust(50)

    fileObject = open(FILENAME, "a")
    fileObject.write(petID + name + species + "\n")
    fileObject.close()

    messagebox.showinfo("Saved", "Pet record successfully saved")

def retrieveRecord():
    searchID = petIDVar.get().strip()
    if searchID == "":
        messagebox.showerror("Error", "Enter a PetID to search")
        return

    try:
        fileObject = open(FILENAME, "r")
    except IOError:
        messagebox.showerror("Error", "No file found")
        return

    found = False
    for record in fileObject:
        if record[0:50].strip() == searchID:
            nameVar.set(record[50:100].strip())
            speciesVar.set(record[100:150].strip())
            found = True
            messagebox.showinfo("Found", "Pet record retrieved")
            break
    fileObject.close()

    if not found:
        messagebox.showinfo("Not Found", "No matching record")

# Create file if missing
if not os.path.exists(FILENAME):
    open(FILENAME, "w").close()

# Build the form
win = Tk()
win.title("Pet Records")

petIDVar = StringVar()
nameVar = StringVar()
speciesVar = StringVar()

Label(win, text="PetID").grid(row=0, column=0, sticky=W)
Entry(win, textvariable=petIDVar).grid(row=0, column=1)

Label(win, text="Name").grid(row=1, column=0, sticky=W)
Entry(win, textvariable=nameVar).grid(row=1, column=1)

Label(win, text="Species").grid(row=2, column=0, sticky=W)
Entry(win, textvariable=speciesVar).grid(row=2, column=1)

Button(win, text="Save", command=saveRecord).grid(row=3, column=0)
Button(win, text="Retrieve", command=retrieveRecord).grid(row=3, column=1)

win.mainloop()

Validation techniques to mix in (depending on what the question asks)

Type Pattern
Length check if len(field) < 1 or len(field) > 30:
Presence check if field == "" or field.strip() == "":
Type check try: int(field) except ValueError: — catches non-numeric input
Range check if value < 0 or value > 100:
Format check if "@" not in field or "." not in field: (email pattern)
Lookup check if field not in ["Mr", "Mrs", "Miss", "Dr", "Ms"]:

Q3 — Annotate the Code (4 marks)

Use Python comments (#) and docstrings (""" """) to explain your code. The MS lists 8 routine types to comment — aim to clearly annotate at least 4–6 of them for Band 3 (4 marks).

Routine types the MS wants annotated

  • Setting up a data structure
  • Creating a new blank file
  • Copying data from screen textboxes to data structure
  • Writing of data to file
  • Retrieving data from file
  • Splitting into array / textboxes / variables
  • Looking / counting of items required
  • Validation

Band 3 (4 marks) criteria

  • Annotation covers all programming routines listed above
  • Documentation goes beyond self-documenting identifiers — explain WHY, not just WHAT
  • Uses appropriate technical terminology confidently and accurately

Good vs poor annotation

Rating Example
Poor (0–1 mark) # save the data — adds nothing the reader couldn’t see from the code
Good (gets the mark) # Pad each field with spaces to a fixed width of 50 characters using ljust() so each record on disk has the same structure, making slice-based retrieval reliable.

Python annotation template

def saveRecord():
    """Read three fields from the form, validate their lengths,
    pad each to 50 characters, append them as one line to the
    data file, and confirm to the user."""

    # --- Setting up the data structure ---
    # Each record is built from the three StringVar objects bound
    # to the form's Entry widgets.
    petID = petIDVar.get()

    # --- Validation ---
    # Length check: reject anything outside 1-6 chars and feedback
    # to the user without saving so the data file stays clean.
    if len(petID) < 1 or len(petID) > 6:
        messagebox.showerror("Error", "PetID must be 1-6 chars")
        return

    # --- Copying data into structure ---
    # Pad to fixed width so that on retrieval we can slice by
    # known character positions [0:50], [50:100], etc.
    petID = petID.ljust(50)

    # --- Writing of data to file ---
    # Append mode ("a") preserves existing records; "\n" ends
    # the record so readline() works during retrieval.
    fileObject = open(FILENAME, "a")
    fileObject.write(petID + name + species + "\n")
    fileObject.close()

    # --- User feedback ---
    messagebox.showinfo("Saved", "Pet record saved")

Exam-day strategy

Timing

Section Target Per question
Section A — 50 min (10 min buffer) Q1 ≈ 12 min, Q2 ≈ 10 min, Q3 ≈ 12 min, Q4 ≈ 16 min  
Section B — 60 min Q1 first (quick, builds confidence), then Q2 (the big one), then Q3 (annotation — easy marks)  
Last 10 minutes Save every file, re-read Section A.docx, run Python files one final time to confirm no syntax errors  

File naming — examiners are strict

  • Section A: save as Section A.docx (or the exact name the question gives)
  • Section B Q1: save the supplied file with its given name — don’t rename it
  • Section B Q2: save with the exact name the question asks (pets.py, trips.py, customers.py…). Wrong filename = potential lost marks

Final checklist before clicking submit

  • Section A document contains 4 numbered question headings
  • ERD has crow’s feet or M/1 notation on both relationships
  • Data structure table has all 5 columns and varied validation types
  • Method of solution is prose with at least 5 points tied to the scenario
  • Algorithm dry-run table is complete with every cell filled
  • Section B Q1: every . . . gap filled, code runs without error
  • Section B Q2: form opens, save creates file, retrieve loads back into the boxes
  • Section B Q3: every function has comments explaining purpose AND non-obvious steps
  • All files saved with the exact filenames specified in the question