O-Level Computer Science // Paper 2

Pseudocode: the complete notes

Everything Cambridge O-Level pseudocode asks of you, in one place: data types, operators, selection, every loop, arrays, strings, functions, files, SQL, and fully worked 15-mark questions. Read it once, then use it as a reference right up to the exam.

16 sections· 40+ worked snippets· By Arj

Pseudocode is how you plan a program before you write real code. It uses plain, structured English with a fixed set of keywords so that any programmer can read your logic and turn it into any language. In your Paper 2 exam it is tested directly: you read it, trace it, correct it, and write your own. These notes follow the Cambridge conventions exactly, so the keywords and layout you see here are the ones that earn marks.

01Data Types & Variables

Choosing the right type is the first decision in any program because it tells the computer how much memory to reserve and what operations are allowed. Every piece of data you store has a type, and picking the wrong one is a common way to lose easy marks.

INTEGER
Whole numbers only, no decimals.
55, 23, -8, 0, 105
REAL
Decimal (floating-point) numbers.
23.4, 3.142, 55.0
STRING
Any text inside double quotes.
"Ali", "35", "TRUE"
CHAR
A single character in single quotes.
'a', 'M', '?', '1'
BOOLEAN
Only two possible values.
TRUE, FALSE
Common trap
"35" is a STRING, not an INTEGER. The quotes make it text, so you cannot do arithmetic on it until it is converted. Likewise 'A' (single quotes) is a CHAR, while "A" (double quotes) is a one-letter STRING.

Declaring variables

Use DECLARE to tell the program a variable exists, and give it a type, before you use it. The pattern is always DECLARE name : TYPE.

Pseudocode
DECLARE Colour : STRING
DECLARE Age    : INTEGER
DECLARE Price  : REAL
DECLARE Flag   : BOOLEAN
DECLARE Grade  : CHAR

Assigning values

Use the assignment arrow to put a value into a variable. Read it as "gets" or "is set to". Constants are fixed with CONSTANT and can never be reassigned.

Pseudocode
Colour ← "red"
Age    ← 18
Price  ← 9.99
Flag   ← FALSE
Grade  ← 'A'

CONSTANT Pi ← 3.142   // fixed, cannot change
Pi ← 3.14159          // ERROR: cannot reassign a constant

INPUT and OUTPUT

INPUT reads a value the user types and stores it in a variable. OUTPUT displays text, variables, or both together separated by commas.

Pseudocode
OUTPUT "Enter your name"     // shows a prompt on screen
INPUT  Name                  // waits for the user to type
OUTPUT "Hello, ", Name       // text and variable together
OutputEnter your name Ayesha Hello, Ayesha
Exam tip
Examiners accept both and = for assignment in written answers, but the arrow is safest because it can never be confused with the comparison =. Always DECLARE a variable before its first use if the question mentions declarations.
02Operators & Expressions

Operators are the verbs of pseudocode: they combine values to produce new ones or to make decisions. They fall into three groups, arithmetic, comparison, and logical, and knowing exactly what each returns keeps your conditions correct.

OperatorMeaningExampleResult
+Addition7 + 310
-Subtraction7 - 34
*Multiplication7 * 321
/Division (real result)7 / 23.5
DIVInteger division (drops decimal)7 DIV 23
MODRemainder after division7 MOD 21
=Equal tox = 5TRUE / FALSE
<>Not equal tox <> 5TRUE / FALSE
> < >= <=ComparisonsAge >= 18TRUE / FALSE
ANDBoth conditions must be TRUEx > 0 AND x < 10TRUE / FALSE
ORAt least one must be TRUEx = 0 OR x = 1TRUE / FALSE
NOTInverts a BooleanNOT FlagTRUE / FALSE
&Join (concatenate) strings"Hi " & Name"Hi Ali"
The MOD trick
To test whether a number is even, use Num MOD 2 = 0. To test divisibility by any n, use Num MOD n = 0. Pairing DIV and MOD also splits a number: 37 DIV 10 = 3 (tens) and 37 MOD 10 = 7 (units).

Order of operations

Pseudocode follows normal maths precedence. Brackets first, then * / DIV MOD, then + -, then comparisons, then logical operators. When in doubt, add brackets to make your intention obvious to the examiner.

Pseudocode
Result ← 2 + 3 * 4          // 14, not 20
Result ← (2 + 3) * 4        // 20, brackets force the add first
Valid  ← Age >= 13 AND Age <= 19  // TRUE only for a teenager
03Strings & Built-in Functions

String questions appear often because handling text well shows real understanding. Cambridge gives you a small set of built-in functions, and memorising exactly what each returns is worth easy marks. Note that string positions start at 1 in Cambridge pseudocode.

FunctionWhat it doesExampleResult
LENGTH(s)Number of characters in sLENGTH("Hello")5
SUBSTRING(s,p,n)n characters from position pSUBSTRING("Computer",1,4)"Comp"
UCASE(s)Converts to upper caseUCASE("hi")"HI"
LCASE(s)Converts to lower caseLCASE("Hi")"hi"
ROUND(x,n)Rounds x to n decimal placesROUND(3.146,2)3.15
INT(x)Whole-number part of xINT(7.9)7
RANDOM()Random real from 0 to 1RANDOM()0.42...

Worked string example: initials

This takes a first and last name and builds initials such as "A.J". It uses SUBSTRING to grab the first letter of each and & to join everything.

Pseudocode
OUTPUT "Enter first name"
INPUT  First
OUTPUT "Enter last name"
INPUT  Last
Initials ← SUBSTRING(First, 1, 1) & "." & SUBSTRING(Last, 1, 1)
OUTPUT UCASE(Initials)
OutputEnter first name Arjun Enter last name Javaid A.J

Counting characters in a word

A classic task: loop through every position and count how many times a target letter appears. Notice how LENGTH sets the loop limit.

Pseudocode
OUTPUT "Enter a word"
INPUT  Word
Count ← 0
FOR Index ← 1 TO LENGTH(Word)
    IF SUBSTRING(Word, Index, 1) = 'a' THEN
        Count ← Count + 1
    ENDIF
NEXT Index
OUTPUT "Letter a appears ", Count, " times"
Good to know
To compare text without worrying about capitals, convert both sides first: IF UCASE(Answer) = "YES" accepts "yes", "Yes", and "YES" all at once.
04IF / ELSE Statements

Selection is how a program makes decisions, and IF is the most-used structure in the whole course. It runs one block of code when a condition is TRUE and, optionally, another when it is FALSE.

Basic structure

Pseudocode
IF Age >= 18 THEN
    OUTPUT "Eligible to vote"
ELSE
    OUTPUT "Not eligible"
ENDIF

Nested IF (ELSE IF chain)

When there are more than two outcomes, chain conditions with ELSE IF. The program checks each in order and runs the first one that is TRUE, then skips the rest.

Pseudocode
IF Hours > 50 THEN
    OUTPUT "Overtime bonus"
ELSE IF Hours > 30 THEN
    OUTPUT "Normal salary"
ELSE
    OUTPUT "Salary deducted"
ENDIF
Two easy marks to lose
Always close with ENDIF written as one word. And order your conditions from most specific to least: once Hours > 50 is caught, the chain stops, so the second test only needs Hours > 30.

Practice questions

Q1
Q1. Take a temperature as input. Output "Too hot" if it is above 40, otherwise "Pleasant weather".
Solution
Pseudocode
OUTPUT "Enter temperature"
INPUT  Temperature
IF Temperature > 40 THEN
    OUTPUT "Too hot"
ELSE
    OUTPUT "Pleasant weather"
ENDIF
Q2
Q2. Take two numbers. If the first is greater, output it times 3. If the second is greater, output it times 5. If they are equal, output their sum.
Solution
Pseudocode
OUTPUT "Enter first number"
INPUT  Num1
OUTPUT "Enter second number"
INPUT  Num2
IF Num1 > Num2 THEN
    OUTPUT Num1 * 3
ELSE IF Num2 > Num1 THEN
    OUTPUT Num2 * 5
ELSE
    OUTPUT Num1 + Num2
ENDIF
05CASE OF Statement

When one variable can take many specific values, a long ELSE IF chain becomes hard to read. CASE OF is the clean alternative: it matches a single variable against a list of values and runs the matching branch. Use OTHERWISE to catch anything unexpected.

General structure
CASE OF Variable
    Value1 : OUTPUT "..."
    Value2 : OUTPUT "..."
    Value3 : OUTPUT "..."
    OTHERWISE : OUTPUT "Invalid input"
ENDCASE

Example: simple calculator

Pseudocode
OUTPUT "Enter two numbers"
INPUT  Num1, Num2
OUTPUT "Enter operator (+, -, *, /)"
INPUT  Operator
CASE OF Operator
    '+' : OUTPUT Num1 + Num2
    '-' : OUTPUT Num1 - Num2
    '*' : OUTPUT Num1 * Num2
    '/' : OUTPUT Num1 / Num2
    OTHERWISE : OUTPUT "Invalid operator"
ENDCASE

Example: grade to points

Pseudocode
OUTPUT "Enter grade (A/B/C/D/F)"
INPUT  Grade
CASE OF Grade
    'A' : OUTPUT "4.0 points"
    'B' : OUTPUT "3.0 points"
    'C' : OUTPUT "2.0 points"
    'D' : OUTPUT "1.0 points"
    'F' : OUTPUT "0.0 points"
    OTHERWISE : OUTPUT "Invalid grade"
ENDCASE
When CASE beats IF
Use CASE OF when you are comparing one variable to fixed, separate values (a menu choice, a single letter, a month number). Use IF when the test involves ranges or more than one variable, because CASE cannot test > or < in standard Cambridge pseudocode.
06FOR Loop (Count-Controlled)

A FOR loop repeats a block a known number of times, so reach for it whenever you can say up front "do this exactly N times". A counter variable is created, increased automatically each pass, and the loop ends after the final value.

When to use it
Choose a FOR loop when the number of repetitions is fixed and known before the loop starts, for example processing all 10 elements of an array.
General structure
FOR Index ← 1 TO 10
    // code here runs 10 times
NEXT Index

// Counting down with STEP
FOR Index ← 10 TO 1 STEP -1
    OUTPUT Index
NEXT Index

// Even numbers only with STEP 2
FOR Index ← 2 TO 20 STEP 2
    OUTPUT Index
NEXT Index

Practice: sum and average of 20 numbers

Pseudocode
Sum ← 0
FOR Index ← 1 TO 20
    OUTPUT "Enter a number"
    INPUT  Num
    Sum ← Sum + Num
NEXT Index
OUTPUT "Sum: ", Sum
OUTPUT "Average: ", Sum / 20

Practice: 7-day temperature monitor

This combines a FOR loop with selection and three counters, a pattern that appears again and again in exams.

Pseudocode
HotDays  ← 0
NiceDays ← 0
ColdDays ← 0
FOR Index ← 1 TO 7
    OUTPUT "Enter temperature for day ", Index
    INPUT  Temp
    IF Temp > 30 THEN
        HotDays ← HotDays + 1
    ELSE IF Temp >= 20 THEN
        NiceDays ← NiceDays + 1
    ELSE
        ColdDays ← ColdDays + 1
    ENDIF
NEXT Index
OUTPUT "Hot days:  ", HotDays
OUTPUT "Nice days: ", NiceDays
OUTPUT "Cold days: ", ColdDays
07WHILE Loop (Pre-Condition)

A WHILE loop repeats as long as a condition stays TRUE, which makes it the right choice when you do not know in advance how many passes are needed. Because the test comes first, the body may run zero times if the condition starts FALSE.

When to use it
Use WHILE when the number of repetitions is unknown and depends on something inside the loop, and when it is valid for the loop to run no times at all.
General structure
Index ← 1
WHILE Index <= 10
    OUTPUT Index
    Index ← Index + 1
ENDWHILE

Example: sum until the user enters 0

Pseudocode
Sum ← 0
OUTPUT "Enter a number (0 to stop)"
INPUT  Num
WHILE Num <> 0
    Sum ← Sum + Num
    OUTPUT "Enter a number (0 to stop)"
    INPUT  Num
ENDWHILE
OUTPUT "Total: ", Sum
Read the first value before the loop
This is the "priming read" pattern: get one input before WHILE, then get the next input at the end of the body. It lets the loop test the value the user just typed, including the stop value 0.

Example: password login (3 attempts)

Pseudocode
Flag  ← FALSE
Tries ← 3
WHILE Flag = FALSE AND Tries > 0
    OUTPUT "Attempts remaining: ", Tries
    OUTPUT "Enter password"
    INPUT  Password
    IF Password = "hello123" THEN
        Flag ← TRUE
    ENDIF
    Tries ← Tries - 1
ENDWHILE
IF Flag = TRUE THEN
    OUTPUT "Access granted"
ELSE
    OUTPUT "Access denied"
ENDIF

Example: factorial (5! = 120)

Pseudocode
OUTPUT "Enter a number"
INPUT  Num
Index     ← 1
Factorial ← 1
WHILE Index <= Num
    Factorial ← Factorial * Index
    Index     ← Index + 1
ENDWHILE
OUTPUT "Factorial: ", Factorial
08REPEAT UNTIL Loop (Post-Condition)

REPEAT UNTIL runs the body first and checks the condition afterwards, so it always executes at least once. That makes it the natural fit for input validation, where you must ask for a value before you can judge whether it is acceptable.

WHILE pre-condition

Checks the condition BEFORE running. May run zero times. Loops WHILE the condition is TRUE.

REPEAT UNTIL post-condition

Checks the condition AFTER running. Always runs at least once. Loops UNTIL the condition becomes TRUE.

Input validation

Pseudocode
// keep asking until a valid month is entered
REPEAT
    OUTPUT "Enter month (1-12)"
    INPUT  Month
UNTIL Month >= 1 AND Month <= 12

Example: even and odd sums (1 to 10)

Pseudocode
OddSum  ← 0
EvenSum ← 0
Index   ← 1
REPEAT
    IF Index MOD 2 = 0 THEN
        EvenSum ← EvenSum + Index
    ELSE
        OddSum  ← OddSum + Index
    ENDIF
    Index ← Index + 1
UNTIL Index > 10
OUTPUT "Even sum: ", EvenSum
OUTPUT "Odd sum:  ", OddSum
OutputEven sum: 30 Odd sum: 25
09Totalling, Counting & Validation

Most Paper 2 answers are built from three small, reusable patterns. Learn them as templates and you can assemble almost any question quickly and correctly. They matter because examiners reward the technique, not just the final answer.

Totalling and counting

A total variable starts at 0 and grows by a value each pass. A counter starts at 0 and grows by 1 each time something is true. Almost every "find the average" or "how many" task uses one or both.

Pseudocode
Total ← 0
Count ← 0
FOR Index ← 1 TO 30
    INPUT Mark
    Total ← Total + Mark          // running total
    IF Mark >= 50 THEN
        Count ← Count + 1       // count the passes
    ENDIF
NEXT Index
OUTPUT "Average: ", Total / 30
OUTPUT "Number passing: ", Count

Finding highest and lowest

Set the tracker to the first value (or a safe extreme), then compare every later value against it. Never start "highest" at 0, because that fails if all values are negative.

Pseudocode
INPUT Num
Highest ← Num
Lowest  ← Num
FOR Index ← 2 TO 10
    INPUT Num
    IF Num > Highest THEN Highest ← Num ENDIF
    IF Num < Lowest  THEN Lowest  ← Num ENDIF
NEXT Index
OUTPUT "Highest: ", Highest, "  Lowest: ", Lowest

Range check vs length check

Validation confirms data is sensible before the program uses it. The two most-tested kinds are a range check (a number inside limits) and a length check (a string of the right size).

Pseudocode
// Range check: percentage 0 to 100
REPEAT
    OUTPUT "Enter percentage (0-100)"
    INPUT  Percent
UNTIL Percent >= 0 AND Percent <= 100

// Length check: PIN must be exactly 4 characters
REPEAT
    OUTPUT "Enter a 4-digit PIN"
    INPUT  Pin
UNTIL LENGTH(Pin) = 4
When to use each check
Reach for a range check on any number that has natural limits (age, month, percentage, score). Reach for a length check on codes and identifiers that must be a fixed size (PIN, phone number, product code). Serious systems layer both, plus a type check and a presence check.
101D Arrays

An array lets you store many values of the same type under one name, which is essential once you are handling lists of data such as scores or names. Each value sits at a numbered position called an index, and you reach it with Name[index].

Declaring, assigning, accessing

Pseudocode
// 10 integers, indexed 1 to 10
DECLARE Scores : ARRAY[1:10] OF INTEGER

// assign directly
Scores[1] ← 85
Scores[2] ← 92

// fill every element with 0
FOR Index ← 1 TO 10
    Scores[Index] ← 0
NEXT Index

// take input into the array
FOR Index ← 1 TO 10
    OUTPUT "Enter score"
    INPUT  Scores[Index]
NEXT Index

Linear search (efficient)

A linear search checks elements one by one. The efficient version stops the moment it finds the value, instead of scanning to the end for nothing.

Pseudocode
FUNCTION LinearSearch(ValToFind : INTEGER) RETURNS BOOLEAN
    Found ← FALSE
    Index ← 1
    REPEAT
        IF Scores[Index] = ValToFind THEN
            Found ← TRUE
        ELSE
            Index ← Index + 1
        ENDIF
    UNTIL Index > 10 OR Found = TRUE
    RETURN Found
ENDFUNCTION
Why the OR matters
The loop ends on either of two conditions: the item is found, or the index runs off the end of the array. Putting Found = TRUE in the UNTIL is what makes the search stop early.

Find the largest value

Pseudocode
DECLARE Values : ARRAY[1:5] OF INTEGER
FOR Index ← 1 TO 5
    OUTPUT "Enter a value"
    INPUT  Values[Index]
NEXT Index

Largest ← Values[1]           // start with the first element
FOR Index ← 2 TO 5
    IF Values[Index] > Largest THEN
        Largest ← Values[Index]
    ENDIF
NEXT Index
OUTPUT "Largest value: ", Largest

Bubble sort (efficient)

Bubble sort repeatedly compares neighbours and swaps them if they are out of order, so the largest value "bubbles" to the end each pass. The efficient version stops early once a full pass makes no swaps.

Pseudocode
// sorts Scores[1:10] into ascending order
UpperBound ← 10
REPEAT
    UpperBound ← UpperBound - 1
    Swap ← FALSE
    FOR Index ← 1 TO UpperBound
        IF Scores[Index] > Scores[Index + 1] THEN
            Temp ← Scores[Index]
            Scores[Index] ← Scores[Index + 1]
            Scores[Index + 1] ← Temp
            Swap ← TRUE
        ENDIF
    NEXT Index
UNTIL UpperBound = 1 OR Swap = FALSE
Exam tip
You must know the three swap lines by heart: save one value in a Temp, copy the neighbour across, then drop Temp into the neighbour's old slot. Skipping Temp and writing A ← B then B ← A loses both values.
112D Arrays

A 2D array is a table of rows and columns, perfect for grids, timetables, or one record per row. You need two indexes to reach a single cell: Array[row, column]. Nested loops are how you visit every cell.

Declaring and accessing

Pseudocode
// 5 students, 3 columns (e.g. three subject marks)
DECLARE Marks : ARRAY[1:5, 1:3] OF INTEGER
Marks[1, 1] ← 85   // student 1, subject 1
Marks[2, 3] ← 70   // student 2, subject 3

Input and output with nested loops

The outer loop moves down the rows, and for each row the inner loop sweeps across the columns. Change the inner loop and the outer stays put.

Pseudocode
// taking input
FOR Row ← 1 TO 5
    FOR Col ← 1 TO 3
        OUTPUT "Enter mark for student ", Row, " subject ", Col
        INPUT  Marks[Row, Col]
    NEXT Col
NEXT Row

// outputting values
FOR Row ← 1 TO 5
    FOR Col ← 1 TO 3
        OUTPUT Marks[Row, Col]
    NEXT Col
NEXT Row

StudentData: search by ID, output name

A very common exam shape: a table where column 1 holds an ID and column 2 holds a name. Search the ID column, then read across to the name.

Pseudocode // StudentData[1:1000, 1:2], col1 = ID, col2 = Name
OUTPUT "Enter the student ID"
INPUT  Id
Found ← FALSE
Row   ← 1
REPEAT
    IF StudentData[Row, 1] = Id THEN
        Found ← TRUE
    ELSE
        Row ← Row + 1
    ENDIF
UNTIL Row > 1000 OR Found = TRUE
IF Found = TRUE THEN
    OUTPUT "Name: ", StudentData[Row, 2]
ELSE
    OUTPUT "ID not found"
ENDIF
12Procedures & Functions

Subroutines let you name a block of code once and reuse it, which keeps programs short and readable. Cambridge splits them into two kinds, and telling them apart is a guaranteed exam question.

FUNCTION returns a value

Takes parameters, does work, and hands back one result with RETURN. You store or use that result, e.g. g ← GradeCalc(...).

PROCEDURE no return

Takes parameters and performs an action such as printing, but returns nothing. You call it as a statement on its own line.

FUNCTION: grade calculator

Pseudocode
FUNCTION GradeCalc(M1 : INTEGER, M2 : INTEGER, M3 : INTEGER) RETURNS CHAR
    Total   ← M1 + M2 + M3
    Percent ← Total / 3
    IF Percent >= 90 THEN
        Grade ← 'A'
    ELSE IF Percent >= 80 THEN
        Grade ← 'B'
    ELSE IF Percent >= 70 THEN
        Grade ← 'C'
    ELSE IF Percent >= 60 THEN
        Grade ← 'D'
    ELSE
        Grade ← 'F'
    ENDIF
    RETURN Grade
ENDFUNCTION

// calling the function
OUTPUT "Enter marks for 3 subjects"
INPUT  S1, S2, S3
Result ← GradeCalc(S1, S2, S3)
OUTPUT "Your grade is: ", Result

PROCEDURE: draw a triangle of stars

Pseudocode
PROCEDURE DrawTriangle(Size : INTEGER)
    FOR Row ← 1 TO Size
        FOR Col ← 1 TO Row
            OUTPUT "*"
        NEXT Col
        OUTPUT ""   // move to a new line
    NEXT Row
ENDPROCEDURE

// calling the procedure
CALL DrawTriangle(5)   // prints a 5-row triangle
Parameters vs arguments
The names in the header (Size, M1) are parameters. The real values you pass when calling (5, S1) are arguments. State clearly which is which if a question asks, and remember Cambridge uses CALL before a procedure name.
13File Handling

Files let a program store data permanently, so information survives after the program closes. Without files, everything held in variables is lost the moment the program ends. Cambridge pseudocode has two modes: READ and WRITE.

Open it, then close it
Always OPENFILE before reading or writing, and always CLOSEFILE when finished. Forgetting to close a file is one of the most common ways to drop a mark in this topic.

Writing to a file

Pseudocode
OPENFILE "data.txt" FOR WRITE
WRITEFILE "data.txt", "This is line one"
WRITEFILE "data.txt", "This is line two"
CLOSEFILE "data.txt"

Reading until end of file

EOF("file") returns TRUE once the last line has been read, so a WHILE loop over NOT EOF reads every line without needing to know how many there are.

Pseudocode
OPENFILE "data.txt" FOR READ
WHILE NOT EOF("data.txt")
    READFILE "data.txt", OneLine
    OUTPUT   OneLine
ENDWHILE
CLOSEFILE "data.txt"

Example: split scores into high / medium / low files

This reads one source file and writes each score to one of three destination files based on its value, a realistic task that combines files, a loop, and selection.

Pseudocode
OPENFILE "exam_scores.txt" FOR READ
OPENFILE "high.txt"   FOR WRITE
OPENFILE "medium.txt" FOR WRITE
OPENFILE "low.txt"    FOR WRITE
WHILE NOT EOF("exam_scores.txt")
    READFILE "exam_scores.txt", Score
    IF Score >= 80 THEN
        WRITEFILE "high.txt", Score
    ELSE IF Score >= 50 THEN
        WRITEFILE "medium.txt", Score
    ELSE
        WRITEFILE "low.txt", Score
    ENDIF
ENDWHILE
CLOSEFILE "exam_scores.txt"
CLOSEFILE "high.txt"
CLOSEFILE "medium.txt"
CLOSEFILE "low.txt"
14SQL: Database Queries

SQL (Structured Query Language) pulls data out of a database table. It is a small part of the syllabus but a reliable source of marks, because the whole topic rests on just four keywords used in a fixed order.

KeywordWhat it doesRequired?
SELECTChoose which columns to show. Use * for all.Always
FROMWhich table to read from.Always
WHEREFilter the rows on a condition.Optional
ORDER BYSort the results, ASC low to high or DESC high to low.Optional

Examples

SQL // table STUDENT: StudentID, FirstName, LastName, YearGroup, Score, Grade, HouseColour
-- Show all data
SELECT * FROM STUDENT

-- Year 11 students scoring above 70, highest score first
SELECT FirstName, LastName, Score
FROM   STUDENT
WHERE  YearGroup = 11 AND Score > 70
ORDER BY Score DESC

-- Everyone in house Blue, sorted by surname A to Z
SELECT FirstName, LastName
FROM   STUDENT
WHERE  HouseColour = 'Blue'
ORDER BY LastName ASC

-- All grade A students
SELECT *
FROM   STUDENT
WHERE  Grade = 'A'
Exam tip: quotes cost marks
Text values like 'Blue' go in single quotes. Numbers like 70 do not. Getting this wrong is an easy mark to lose, and so is forgetting that SELECT lists columns while WHERE filters rows.
15Worked 15-Mark Exam Questions
How to approach a long question
Treat the requirements as a checklist. Add a comment in your code for each requirement so the examiner can see it is covered. Aim to include validation, a loop, an array, and output with meaningful messages, because these are where the marks live.

Question 1: cricket league points system

Twelve clubs. Track wins, draws, and losses. Points are Win = 12, Draw = 5, Loss = 0. Find and output the club or clubs with the most points.

Full solution
// Step 1: input and validate number of matches (max 22)
REPEAT
    OUTPUT "Enter number of matches played (max 22)"
    INPUT  Matches
UNTIL Matches >= 1 AND Matches <= 22

// Step 2: input club names and results, validated
FOR Index ← 1 TO 12
    OUTPUT "Enter name of club ", Index
    INPUT  Clubs[Index]
    REPEAT
        OUTPUT "Enter matches won, drawn, lost"
        INPUT  Won, Drawn, Lost
        IF (Won + Drawn + Lost) <> Matches THEN
            OUTPUT "Error: totals must add up to ", Matches
        ENDIF
    UNTIL (Won + Drawn + Lost) = Matches
    Statistics[Index, 1] ← Won
    Statistics[Index, 2] ← Drawn
    Statistics[Index, 3] ← Lost
    // Step 3: calculate points
    Points[Index] ← (Won * 12) + (Drawn * 5)
NEXT Index

// Step 4: find the highest points total
Highest ← -1
FOR Index ← 1 TO 12
    IF Points[Index] > Highest THEN
        Highest ← Points[Index]
    ENDIF
NEXT Index

// Step 5: output every club on the highest points (handles ties)
FOR Index ← 1 TO 12
    IF Points[Index] = Highest THEN
        OUTPUT "Winner: ", Clubs[Index]
        OUTPUT "Wins:   ", Statistics[Index, 1]
        OUTPUT "Points: ", Highest
    ENDIF
NEXT Index

Question 2: grid treasure hunt game

A 5 by 5 grid. Place 'X' at a random cell that is not [1,1]. The player starts at [1,1] and has 10 moves to reach X using W, A, S, D. Validate moves so the player cannot leave the grid.

Full solution
// Step 1: fill the grid with empty strings
FOR Row ← 1 TO 5
    FOR Col ← 1 TO 5
        Grid[Row, Col] ← ""
    NEXT Col
NEXT Row

// Step 2: place 'X' at a random cell, but not [1,1]
REPEAT
    Xrow ← INT(RANDOM() * 5) + 1
    Xcol ← INT(RANDOM() * 5) + 1
UNTIL Xrow <> 1 OR Xcol <> 1
Grid[Xrow, Xcol] ← 'X'

// Step 3: set up the player and move counter
PlayerRow ← 1
PlayerCol ← 1
MoveCount ← 0
Win       ← FALSE

// Step 4: game loop, up to 10 moves
REPEAT
    OUTPUT "Position [", PlayerRow, ",", PlayerCol, "]  Moves left: ", 10 - MoveCount
    OUTPUT "W=Up S=Down A=Left D=Right"
    INPUT  Move
    Move  ← UCASE(Move)
    Error ← FALSE
    TempR ← PlayerRow
    TempC ← PlayerCol
    CASE OF Move
        'W' : TempR ← PlayerRow - 1
        'S' : TempR ← PlayerRow + 1
        'A' : TempC ← PlayerCol - 1
        'D' : TempC ← PlayerCol + 1
        OTHERWISE : Error ← TRUE
    ENDCASE
    // validate the move stays inside the grid
    IF TempR < 1 OR TempR > 5 OR TempC < 1 OR TempC > 5 THEN
        Error ← TRUE
        OUTPUT "Move out of bounds, try again"
    ENDIF
    IF Error = FALSE THEN
        PlayerRow ← TempR
        PlayerCol ← TempC
        MoveCount ← MoveCount + 1
    ENDIF
    // check for a win
    IF Grid[PlayerRow, PlayerCol] = 'X' THEN
        Win ← TRUE
        OUTPUT "You win! Found it in ", MoveCount, " moves."
    ENDIF
UNTIL Win = TRUE OR MoveCount = 10

IF Win = FALSE THEN
    OUTPUT "You lose. The X was at [", Xrow, ",", Xcol, "]"
ENDIF
16Exam Technique & Common Traps

Two students can write the same logic and score differently. The difference is usually technique: closing every structure, naming things clearly, and reading the question properly. This section collects the habits that turn a good answer into a full-mark one.

Close every structure with its partner

Each opening keyword has a matching closer. Miss one and the marker cannot follow your logic. Memorise these pairs.

Opens withCloses with
IFENDIF
CASE OFENDCASE
FORNEXT
WHILEENDWHILE
REPEATUNTIL
PROCEDUREENDPROCEDURE
FUNCTIONENDFUNCTION

Trace tables: show your working

When a question says "complete the trace table", run the code by hand and write down each variable every time it changes. Take this snippet and its trace.

Pseudocode
Total ← 0
FOR Index ← 1 TO 3
    Total ← Total + Index
NEXT Index
OUTPUT Total
IndexTotalOutput
11
23
366

The mistakes that cost marks most often

  • Writing END IF as two words, or forgetting ENDWHILE and NEXT entirely.
  • Using = for both assignment and comparison in a way that confuses the reader. Prefer for assignment.
  • Starting Highest at 0 instead of the first data value, which breaks with negative data.
  • Forgetting the second INPUT inside a WHILE loop, causing an endless loop on the same value.
  • Missing CLOSEFILE, or opening a file for the wrong mode.
  • Putting numbers in quotes, or text without quotes, in SQL and CASE branches.
  • Not initialising a total or counter to 0 before the loop.

A reliable answer plan

  1. Read the whole question and underline every separate requirement.
  2. Declare and initialise your variables and arrays first.
  3. Deal with input and validation before any processing.
  4. Write the loop or logic, adding a comment per requirement.
  5. Output results with clear, labelled messages, not bare numbers.
  6. Trace your own code with one sample input to check it works.
Final reminder
Consistent, well-indented pseudocode with matching keywords reads like clean code, and markers reward clarity. If you are unsure of a rare keyword, describe the step plainly in structured English rather than inventing syntax.
Ready to turn this into real code?
Every pattern here maps straight onto Python. Follow the step-by-step tutorial and start writing programs that actually run.
Start the Python tutorial
painlessprogramming.com · making the hardest CS concepts click

Stop wrestling with confusion.

Join thousands of students mastering Computer Science without the academic jargon.

From syntax to systems. We break down the hardest ideas in computer science so you can actually build things.

© 2026 Painless Programming. Built for students.
Scroll to Top