You are viewing a free preview of this lesson.
Subscribe to unlock all 4 lessons in this course and every other course on LearningBro.
Paper 1 of the AQA A-Level Computer Science exam places heavy emphasis on your ability to read, trace, write, and debug code. This lesson covers the specific techniques you need to excel at code-tracing questions, write effective solutions in AQA pseudo-code or a named programming language, approach algorithm design questions systematically, and avoid the common mistakes that cost students marks. Tracing is a transferable discipline: the same line-by-line, variable-by-variable rigour that wins trace-table marks is exactly the habit that lets you debug your own code in the on-screen exam and in your NEA. We will treat tracing not as a chore but as the lens through which you understand every algorithm — because a student who can reliably predict what code does is a student who can reliably write code that does what they intend.
This is a Paper 1 technique lesson at heart, but its reach extends across the specification:
So while the worked examples below are framed around on-screen Paper 1, the discipline they teach pays off everywhere code appears.
Code tracing is the process of manually following the execution of a program, tracking the values of variables at each step. It is a fundamental skill tested extensively on Paper 1 and is also essential for debugging your NEA project.
| Reason | Detail |
|---|---|
| Direct marks | Trace table questions appear on almost every Paper 1 paper, typically worth 4–8 marks |
| Indirect value | Understanding how code executes helps you write better code and spot errors |
| Debugging skill | Trace tables are the most reliable method for finding logic errors |
| Full marks or nothing | Trace tables are often marked right-or-wrong — partial credit is limited if you make an early error that cascades |
A trace table has one column for each variable in the program (plus an output column if the program produces output) and one row for each step that changes a variable's value.
Step-by-step method:
Consider the following code:
x = 5
y = 3
WHILE x > 0
y = y + x
x = x - 2
ENDWHILE
OUTPUT y
| Step | x | y | Output |
|---|---|---|---|
| 1 | 5 | 3 | |
| 2 (loop check: 5 > 0 = TRUE) | |||
| 3 | 8 | ||
| 4 | 3 | ||
| 5 (loop check: 3 > 0 = TRUE) | |||
| 6 | 11 | ||
| 7 | 1 | ||
| 8 (loop check: 1 > 0 = TRUE) | |||
| 9 | 12 | ||
| 10 | -1 | ||
| 11 (loop check: -1 > 0 = FALSE) | |||
| 12 | 12 |
Exam Tip: The most common error in trace tables is getting loop conditions wrong. Always re-evaluate the condition at the start of each iteration. Pay particular attention to
<vs<=,>vs>=, and off-by-one errors.
Nested loops with an array are where most candidates lose trace-table marks, so trace one slowly. Consider this AQA-style pseudo-code that performs a single outer pass of a bubble-style comparison over an array a:
a <- [4, 2, 5, 1]
n <- 4
FOR i <- 0 TO n - 2
IF a[i] > a[i + 1] THEN
temp <- a[i]
a[i] <- a[i + 1]
a[i + 1] <- temp
ENDIF
ENDFOR
OUTPUT a
The disciplined approach is to give every array element its own column and write a new value only when a swap actually changes it. Note that a[i] > a[i + 1] is a comparison, not an assignment, so it never changes the array on its own.
| i | a[0] | a[1] | a[2] | a[3] | Condition a[i] > a[i+1] | Action |
|---|---|---|---|---|---|---|
| start | 4 | 2 | 5 | 1 | — | initial values |
| 0 | 2 | 4 | 5 | 1 | 4 > 2 = TRUE | swap a[0], a[1] |
| 1 | 4 > 5 = FALSE | no swap | ||||
| 2 | 1 | 5 | 5 > 1 = TRUE | swap a[2], a[3] | ||
| end | 2 | 4 | 1 | 5 | loop ends (i would be 3 > n-2) | OUTPUT [2, 4, 1, 5] |
Three things to notice, each of which is a common slip in the exam: (1) the loop runs for i = 0, 1, 2 only, because the condition compares a[i] with a[i + 1] and i must stop at n - 2 = 2; an off-by-one here would read past the end of the array. (2) When the condition is FALSE (the i = 1 row) nothing changes, but you should still show the row so the examiner sees you evaluated the condition. (3) After one outer pass the array is not fully sorted — [2, 4, 1, 5] still has the 1 out of place — which is exactly why a real bubble sort repeats the pass; do not "tidy up" the output to the sorted answer the question did not ask for.
Exam Tip: Give every array element its own column from the start. Trying to track a four-element array in a single "a" column is how candidates lose the thread on swaps. One column per element, one row per loop iteration, and show the condition you evaluated.
| Pitfall | How to Avoid It |
|---|---|
| Forgetting to initialise variables | Always write the initial values in the first row |
| Off-by-one errors in loops | Check the loop condition before every iteration, not just at the start |
Confusing = and == | = is assignment, == is comparison. In a trace table, x = x + 1 changes x; x == 5 tests x |
| Ignoring integer division | 7 DIV 2 gives 3, not 3.5. AQA pseudo-code uses DIV for integer division and MOD for modulus |
| Mishandling nested loops | Trace the inner loop completely for each iteration of the outer loop |
| Not tracking function calls | When a function is called, trace into the function body, then return to the calling point |
| Forgetting scope | Local variables in a function do not exist outside that function |
AQA has a specific pseudo-code syntax defined in their specification. While you can answer programming questions in any language (Python, Java, C#, VB.NET, etc.), you must be able to read and understand AQA pseudo-code because exam questions will use it.
| Construct | AQA Pseudo-Code | Python Equivalent |
|---|---|---|
| Assignment | x <- 5 | x = 5 |
| Output | OUTPUT x | print(x) |
| Input | x <- USERINPUT | x = input() |
| If statement | IF x > 5 THEN ... ELSE ... ENDIF | if x > 5: ... else: ... |
| For loop | FOR i <- 1 TO 10 ... ENDFOR | for i in range(1, 11): |
| While loop | WHILE x > 0 ... ENDWHILE | while x > 0: |
| Repeat until | REPEAT ... UNTIL x > 0 | No direct equivalent (use while True with break) |
| Subroutine | SUBROUTINE name(params) ... ENDSUBROUTINE | def name(params): |
| Return | RETURN value | return value |
| Integer division | x DIV y | x // y |
| Modulus | x MOD y | x % y |
| String length | LEN(s) | len(s) |
| Substring | SUBSTRING(pos, length, s) | s[pos:pos+length] |
| Array access | a[i] | a[i] |
| Record | RECORD name ... ENDRECORD | class or named tuple |
Key Point: You can write your answers in Python, Java, C#, VB.NET, or AQA pseudo-code. However, you MUST be able to read AQA pseudo-code because questions will present code in this format. Familiarise yourself with the AQA pseudo-code reference in the specification appendix.
When writing code in exam answers, clarity is paramount:
| Principle | Detail |
|---|---|
| Use meaningful variable names | total, count, studentName — not x, y, z (unless they are clearly mathematical) |
| Indent consistently | Even in handwritten answers (Paper 2), indentation shows structure |
| Comment where necessary | Brief comments explaining your logic can earn marks and help examiners follow your thinking |
| Handle edge cases | Think about empty inputs, boundary values, and error conditions |
| Use appropriate data types | Show the examiner you understand the difference between integers, floats, strings, and Booleans |
AQA tests three programming paradigms. You must understand when each is appropriate and be able to write code in at least two of them.
| Feature | Detail |
|---|---|
| Definition | Programs structured as a sequence of instructions, using subroutines (procedures and functions) to organise code |
| Key concepts | Sequence, selection, iteration, subroutines, parameters, local/global variables |
| When tested | Most code-writing questions on Paper 1 expect procedural solutions unless OOP is specifically requested |
| Exam approach | Write clear functions with well-named parameters; avoid excessive use of global variables |
| Feature | Detail |
|---|---|
| Definition | Programs structured around objects that encapsulate data (attributes) and behaviour (methods) |
| Key concepts | Classes, objects, instantiation, encapsulation, inheritance, polymorphism, overriding, aggregation, composition |
| When tested | Specific OOP questions ask you to design class hierarchies, write class definitions, or explain OOP principles |
| Exam approach | Know the definitions precisely; be able to write class definitions with constructors, attributes, and methods; understand inheritance hierarchies |
| Feature | Detail |
|---|---|
| Definition | Programs structured as the evaluation of mathematical functions, avoiding mutable state and side effects |
| Key concepts | First-class functions, higher-order functions, map, filter, fold/reduce, partial application, function composition, immutability |
| When tested | Section 4.12 questions on Paper 2; questions asking you to rewrite procedural code in a functional style |
| Exam approach | Know how to use map, filter, and fold/reduce; understand partial application; be able to explain why immutability is beneficial |
Exam Tip: OOP and functional programming questions often ask you to explain the advantages of the paradigm. Prepare concise, technically precise explanations. For OOP: reusability, maintainability, encapsulation hides complexity. For functional: no side effects, easier to test and parallelise, more predictable behaviour.
Algorithm design questions ask you to create a solution to a problem. These are among the highest-mark questions on Paper 1.
Dry running means executing your algorithm by hand with sample data to verify it works correctly. This is a critical skill both for checking your own answers and for exam questions that ask you to trace algorithms.
How to dry run effectively:
Exam Tip: If a question asks you to "show the state of the array after each pass" of a sorting algorithm, you must show every intermediate state — not just the final sorted result. Skipping steps loses marks.
Some Paper 1 questions present code containing deliberate errors and ask you to identify and correct them.
Subscribe to continue reading
Get full access to this lesson and all 4 lessons in this course.