AQA programming practice: read, repair, extend and test
Read requirements and predict outputs before running code. Repair one boundary fault, preserve existing validation, then extend the report and record test evidence.
Content owner: Michael Print · Written for A-Level learners · Checked against official specifications
Explore the idea
Predict, modify and test an unfamiliar program
Use an original score-report task. Record an expected result before checking a boundary change; the fixed model validates rows and applies the selected threshold.
The idea to start with
The original task loads ID,score text rows, validates them, and reports accepted scores at or above a threshold. Valid IDs are one uppercase letter followed by two digits; scores are decimal integers from 0 to 100. The first valid occurrence of an ID is kept.
The starter deliberately uses > where the requirement says >=. Keep the solution closed, predict the boundary case, then run the supplied tests. This is independent practice, not an AQA skeleton, past-paper task or mark scheme.
AQA 7517 · 4.1 programming; 4.13 systematic problem solving; Paper 1 practice
Before you start
Useful foundations
Python functions, lists, files and exception handling
Normal, boundary and invalid test data
By the end, you should be able to
Read an unfamiliar program and connect functions to requirements.
Predict outputs before execution and repair a threshold boundary fault.
Design independent normal/boundary/invalid tests and retain regressions.
Extend input/reporting behaviour and record relevant code and output evidence.
Original practice files
Read TASK.txt first. Keep the solution closed while attempting the starter. These plain-text files run locally in your chosen Python environment.
AQA: original Python task for reading, repairing, extending and testing an unfamiliar program. It does not reproduce a supplied skeleton or assert equivalence across every supported language. Test files and expected outcomes are original.
Shared foundations and optional extensions are labelled separately; this page does not claim complete coverage of the qualification.
Read a complete, bounded task
Read a complete, bounded task
Ignore blank lines. Reject a row with the wrong field count or ID format; reject a non-integer or out-of-range score; reject a repeated accepted ID. Preserve accepted rows in their source order and report those whose score is at least the minimum.
The supplied scores.csv contains valid scores 72, 0, 100 and 60 plus two invalid scores and one malformed row. At minimum 60, expected qualifying IDs are A11, C13 and F16. Predict this independently before inspecting actual output.
Inspect the program before modifying it
Inspect the program before modifying it
parse_rows handles format, range and uniqueness; report handles threshold validation and filtering. The file-reading/writing block catches task-file errors. Keeping the pure transformation separate makes it testable without repeatedly changing files.
Copy score_report_starter.py to score_report.py to use the tests against the starter. Read the TODO instructions in TASK.txt. The solution file uses the same name, so keep its copy separate until you have attempted the repair.
Choose tests that distinguish the bug
Choose tests that distinguish the bug
A score of 72 at threshold 60 passes both > and >=, so it cannot distinguish them. A score exactly 60 is the boundary that exposes the defect. Include 59, 60 and 61 for the comparison, alongside 0 and 100 for validation.
Retain tests for duplicate IDs, malformed records, nonnumeric scores, empty text and invalid thresholds. Expected results belong in the test plan before execution; a screenshot of output alone does not establish correctness.
Independent expectations before running the starter
Test
Expected
F16,60 at minimum 60
Included
B12,59 at minimum 60
Accepted but not qualifying
D14,101
Rejected: score
Second valid A11 record
Rejected: duplicate
Empty file
No rows; no row-validation errors
Extend and transfer the skill
Extend and transfer the skill
Add an interactive threshold input that accepts only an integer from 0 to 100 and reprompts after invalid text. Keep that input loop outside report so the existing pure-function tests still run. Test empty input, text, −1, 0, 100 and 101.
A second variation sorts qualifying rows by descending score and then ID for equal scores. Test a tie and ensure original accepted rows are not silently reordered. Explain the changed requirements and run old tests as regressions after each small modification.
Reference implementation and evidence
After attempting the task, compare the solution with the requirements and test results. AQA permits several programming languages; this resource supplies Python practice and does not establish equivalent language-specific depth for Java, C# or VB.Net.
Use relevant program extracts and labelled expected/actual results to explain a repair. Consult your examination year's instructions for the on-screen response format. Avoid copying all console text without identifying which requirement each test supports.
Original score-report reference implementationPython
"""Original practice task: validate rows, then report scores >= minimum."""
import re
from pathlib import Path
def parse_rows(text):
accepted, rejected, seen = [], [], set()
for number, raw in enumerate(text.splitlines(), 1):
if not raw.strip():
continue
fields = raw.strip().split(',')
if len(fields) != 2 or not re.fullmatch(r'[A-Z][0-9]{2}', fields[0]):
rejected.append((number, 'format'))
continue
identifier, score_text = fields
if not re.fullmatch(r'[0-9]+', score_text) or not 0 <= int(score_text) <= 100:
rejected.append((number, 'score'))
continue
if identifier in seen:
rejected.append((number, 'duplicate'))
continue
seen.add(identifier)
accepted.append((identifier, int(score_text)))
return accepted, rejected
def report(text, minimum=60):
if type(minimum) is not int or not 0 <= minimum <= 100:
raise ValueError('minimum must be an integer from 0 to 100')
accepted, rejected = parse_rows(text)
rows = [(identifier, score) for identifier, score in accepted if score >= minimum]
return rows, rejected
if __name__ == '__main__':
try:
source = Path('scores.csv').read_text(encoding='utf-8')
rows, rejected = report(source)
Path('report.csv').write_text(''.join(f'{key},{score}\n' for key, score in rows), encoding='utf-8')
print(f'{len(rows)} qualifying rows; rejected: {rejected}')
except (OSError, UnicodeError) as error:
print(f'Cannot read/write task files: {error}')
Repair the equality boundary without breaking validation
Worked example
Repair the equality boundary without breaking validation
Requirement: include accepted score 60 at threshold 60. Expected qualifying row: ('F16',60).
The starter's > comparison excludes it. Change only the filter to >=, retaining ID/range/duplicate checks.
The reference fixture then reports A11:72, C13:100 and F16:60. It rejects line 4 for score 101, line 5 for abc and line 7 for malformed format.
Run all five supplied test methods, then create an additional tie test for the sorting extension. A passing baseline does not prove an untested extension.
Common mix-up: Any normal test will reveal a boundary faultCommon mix-up: Actual output can serve as its own expected result
Original A-Level practice
4 original questions total 14 marks. Attempt each before opening the independently written indicative marking guidance.
Question 1
3 marks
For minimum 60 and rows A11,59; B12,60; C13,61, state which rows qualify and identify the one that distinguishes > from >=.
Show solution and marking guidance+
Indicative answer
B12 and C13 qualify.
A11 is valid but below the minimum.
B12 at equality distinguishes the two comparisons.
Question 2
4 marks
A file contains A11,72; A11,80; B12,101; C13,text. Under the declared rules, give accepted and rejected records.
Show solution and marking guidance+
Indicative answer
Accept A11 with score 72.
Reject the second A11 as duplicate.
Reject B12 because 101 is out of range.
Reject C13 because text is not an integer score.
Question 3
4 marks
Describe a safe threshold-input extension and supply one normal, one boundary and one invalid test with expected outcomes.
Show solution and marking guidance+
Indicative answer
Convert validated text and require integer 0–100, reprompting on error outside the pure report function.
Normal input 60: accepted as 60.
Boundary 0 or 100: accepted.
Invalid abc, −1 or 101: rejected with reprompt.
Question 4
3 marks
Specify how to sort qualifying records by descending score with ascending ID ties, and how to verify that change independently.
Show solution and marking guidance+
Indicative answer
Use a key such as (-score, identifier) over a new sorted result list.
Test equal scores with IDs in reverse input order and predict ascending ID order.
Retain filtering/validation regression tests and check the original accepted list has not been mutated.
Specification and references
This guide addresses AQA 7517 4.1 programming; 4.13 systematic problem solving; Paper 1 practice. Check your examination year and the complete specification for the assessment scope.
These are independently written explanations and practice questions. CompSciTutoring.co.uk is not affiliated with or endorsed by an examination board. The marking guidance is indicative; always check the syllabus for your examination year.