Skip to the page
Year 11 Β· Computer Science Β· Spring 2 – Summer 1 Β· Final revision and the exams

Last full Paper 2

Exam practicePresent β–Ά

What this lesson covers

7.4 Standard methods of solution

Cambridge IGCSE Computer Science 0478 Β· Topic 7: Algorithm design and problem-solving Β· Paper 2

7.9 Writing and amending algorithms

Cambridge IGCSE Computer Science 0478 Β· Topic 7: Algorithm design and problem-solving Β· Paper 2

9.3 SQL: SELECT, FROM, WHERE, AND, OR

Cambridge IGCSE Computer Science 0478 Β· Topic 9: Databases Β· Paper 2

You will learn to

  • Complete a full Paper 2 in 1 hour 45 minutes, using the timing plan.
  • Correct every lost mark using the mark scheme in the corrections lesson.
  • Describe what to bring and what to do on the exam day.

Success criteria

  • I can start the scenario question by my planned clock time.
  • I can write a full-mark correction for every question where I lost marks.
  • I can list what goes in my pencil case and what stays outside the exam room.
The syllabus points for these sections
  • Write totalling and counting in pseudocode and Python.
  • Find the maximum, minimum and average of a set of values.
  • Write and trace a linear search.
  • Write and trace a bubble sort.
  • Count the comparisons a bubble sort makes.
  • Write algorithms precisely, with the exact comparison the problem needs.
  • Amend a given algorithm to do a new job.
  • Plan and answer a 15-mark scenario question.
  • Explain how the scenario question is marked.
  • Explain what each part of a SELECT query does.
  • Use comparison operators in a WHERE condition.
  • Combine conditions with AND and OR.
  • Predict the exact output of a query.

Key words

Say each word, then read what it means. Every one is in the glossary too.

Algorithm
A precise, ordered set of steps that solves a problem.
Program development life cycle
The four stages of making a program: analysis, design, coding and testing.
Structure diagram
A top-down diagram that shows how a system is split into sub-systems.
Pseudocode
A structured, code-like way of writing an algorithm that is not tied to one language.
Totalling
Adding values into a running total, for example Total ← Total + Value.
Counting
Adding 1 to a counter each time something happens.
Linear search
Checking each item in a list in turn until the target is found or the list ends.
Bubble sort
Sorting by comparing neighbouring items and swapping them if they are in the wrong order, pass after pass.
Validation
An automatic check that data is sensible and follows the rules before it is accepted.
Check digit
An extra digit calculated from the other digits, used to catch typing errors.
Trace table
A table used in a dry run to record the value of each variable as an algorithm runs.
Database
An organised, structured store of data that a computer can search and sort.
Table
A grid of data made of rows (records) and columns (fields).
Field
One column of a table; it holds one item of data about every record, such as Minutes.
Record
One row of a table; it holds all the data about one thing, such as one bike hire.
Field name
The heading at the top of a column, such as HireID; it is not a record.
Data type
The kind of data a field can hold, such as integer, real or Boolean.
Text / alphanumeric
A data type for letters, digits and symbols, such as a name or a phone number.
Boolean
A data type with only two possible values, TRUE or FALSE.
Integer
A data type for whole numbers, such as 55.
Real
A data type for numbers with a decimal part, such as 5.50.
Date/time
A data type for a date, a time, or both, such as 05/03/2026.
SQL
Structured Query Language: the language used to ask a database for data.
Query
A question to the database, written in SQL, that returns matching data.
ORDER BY
The SQL clause that sorts the output, ascending (ASC) or descending (DESC).
COUNT
An SQL function that counts how many records meet a condition.

The explanation

Read it here, or open the study page below to go one step at a time with things to try.

The day before

Check the date, the time and the room of each paper.

  • Two black or dark blue pens.
  • A pencil, a ruler and an eraser for diagrams and logic circuits.
  • A simple watch. Smartwatches are not allowed.
  • No calculator. It is not allowed in either Computer Science paper.
β˜…Remember

Sleep is part of revision. A tired brain recalls less. Stop revising early and go to bed.

In the exam room

  1. Read the instructions on the front cover.
  2. Write your clock times for the paper on the front page.
  3. For each question: underline the command word and circle the marks.
  4. Answer every question. A blank always scores zero.
  5. In the last 10 minutes, check: working, units, trace tables, and starred questions.
!Watch out

Phones and smartwatches must be handed in before you enter the room. Having one on you can lead to disqualification.

7.4 Standard methods of solution

Totalling and counting

Totalling means adding values into a running total: `Total ← Total + Value`.

Counting means adding 1 each time something happens: `Count ← Count + 1`.

Both variables must start at 0 before the loop.

e.g.Example
Marks 34, 48, 21, 40, 15, 45. Pass mark 25. Total: 0 β†’ 34 β†’ 82 β†’ 103 β†’ 143 β†’ 158 β†’ 203 PassCount: 34 yes (1), 48 yes (2), 21 no, 40 yes (3), 15 no, 45 yes (4) Output: Total: 203, Number of passes: 4
DECLARE Marks : ARRAY[1:6] OF INTEGER
DECLARE Index : INTEGER
DECLARE Total : INTEGER
DECLARE PassCount : INTEGER
// Marks already holds 34, 48, 21, 40, 15, 45
Total ← 0
PassCount ← 0
FOR Index ← 1 TO 6
  Total ← Total + Marks[Index]
  IF Marks[Index] >= 25
    THEN
      PassCount ← PassCount + 1
  ENDIF
NEXT Index
OUTPUT "Total: ", Total
OUTPUT "Number of passes: ", PassCount
marks = [34, 48, 21, 40, 15, 45]
total = 0
pass_count = 0
for index in range(6):
    total = total + marks[index]
    if marks[index] >= 25:
        pass_count = pass_count + 1
print("Total:", total)
print("Number of passes:", pass_count)
!Watch out

Setting Total to 0 inside the loop is a classic error. The total is wiped each time round, so only the last value is kept.

Finding the maximum and minimum

To find the maximum (largest), keep a variable `Highest`. Compare each value with it. If the value is bigger, it becomes the new `Highest`.

The minimum (smallest) works the same way with `Lowest` and `<`.

Start `Highest` at the smallest possible value and `Lowest` at the largest possible value. Another safe way is to start both at the first item.

e.g.Example
Marks out of 50: 34, 48, 21, 40, 15, 45. Highest: 0 β†’ 34 β†’ 48 (21, 40, 15, 45 are not bigger than 48) Lowest: 50 β†’ 34 β†’ 21 β†’ 15 (40, 45 are not smaller than 15) Output: Highest: 48, Lowest: 15
DECLARE Marks : ARRAY[1:6] OF INTEGER
DECLARE Index : INTEGER
DECLARE Highest : INTEGER
DECLARE Lowest : INTEGER
// Marks already holds 34, 48, 21, 40, 15, 45 (each out of 50)
Highest ← 0
Lowest ← 50
FOR Index ← 1 TO 6
  IF Marks[Index] > Highest
    THEN
      Highest ← Marks[Index]
  ENDIF
  IF Marks[Index] < Lowest
    THEN
      Lowest ← Marks[Index]
  ENDIF
NEXT Index
OUTPUT "Highest: ", Highest
OUTPUT "Lowest: ", Lowest
marks = [34, 48, 21, 40, 15, 45]
highest = 0
lowest = 50
for index in range(6):
    if marks[index] > highest:
        highest = marks[index]
    if marks[index] < lowest:
        lowest = marks[index]
print("Highest:", highest)
print("Lowest:", lowest)
!Watch out

If Lowest starts at 0, no mark is ever smaller, so the answer is wrong. Start Lowest at the top of the range (50 here) or at the first value.

Finding the average

The average (mean) is the total divided by how many values there are.

First total the values in a loop. Then divide once, after the loop.

The answer is usually not a whole number, so store it as `REAL`. Use `ROUND` to give a set number of decimal places.

e.g.Example
Marks 34, 48, 21, 40, 15, 45. Total = 203. Count = 6. Average = 203 Γ· 6 = 33.8333… Rounded to 2 decimal places: 33.83
DECLARE Marks : ARRAY[1:6] OF INTEGER
DECLARE Index : INTEGER
DECLARE Total : INTEGER
DECLARE Average : REAL
// Marks already holds 34, 48, 21, 40, 15, 45
Total ← 0
FOR Index ← 1 TO 6
  Total ← Total + Marks[Index]
NEXT Index
Average ← Total / 6
OUTPUT "Average: ", ROUND(Average, 2)
marks = [34, 48, 21, 40, 15, 45]
total = 0
for index in range(6):
    total = total + marks[index]
average = total / 6
print("Average:", round(average, 2))
!Watch out

Do not divide inside the loop. Also check the count is not 0 before dividing, or the program crashes.

Linear search

A linear search looks for a value by checking each item in a list, one at a time, from the start.

It stops when it finds the item, or when it reaches the end of the list.

Try it: the toy's list holds numbers, not names. Type 22 (the last item), press Search for it, then Run all. Then try 99, which is not there. Count the comparisons each time.

e.g.Example
List: Lucia, Hugo, Martina, Pablo, Sofia, Leo. Target: Pablo. Position 1: Lucia β‰  Pablo Position 2: Hugo β‰  Pablo Position 3: Martina β‰  Pablo Position 4: Pablo = Pablo β†’ Found ← TRUE Output: Pablo found at position 4 (4 comparisons) Target Ana: all 6 compared, none match β†’ Ana is not in the list
DECLARE Names : ARRAY[1:6] OF STRING
DECLARE Target : STRING
DECLARE Index : INTEGER
DECLARE Found : BOOLEAN
// Names already holds Lucia, Hugo, Martina, Pablo, Sofia, Leo
OUTPUT "Which name do you want to find? "
INPUT Target
Found ← FALSE
Index ← 1
WHILE Found = FALSE AND Index <= 6 DO
  IF Names[Index] = Target
    THEN
      Found ← TRUE
    ELSE
      Index ← Index + 1
  ENDIF
ENDWHILE
IF Found = TRUE
  THEN
    OUTPUT Target, " found at position ", Index
  ELSE
    OUTPUT Target, " is not in the list"
ENDIF
names = ["Lucia", "Hugo", "Martina", "Pablo", "Sofia", "Leo"]
target = input("Which name do you want to find? ")
found = False
index = 0
while found == False and index < 6:
    if names[index] == target:
        found = True
    else:
        index = index + 1
if found == True:
    print(target, "found at position", index + 1)
else:
    print(target, "is not in the list")
?Why?

A linear search works on any list, sorted or not. The cost is time: a list of 1000 names can need 1000 comparisons.

!Watch out

The `Found` flag stops the loop early. Without it the search carries on to the end even after the name is found.

There is something to try for this step in the IGCSE library.

Bubble sort

A bubble sort puts a list in order. It compares each pair of neighbours. If they are in the wrong order, it swaps them.

One trip through the list is a pass. After each pass the largest unsorted value has 'bubbled' to the end.

It stops when a pass makes no swaps. The toy uses a longer list: 6, 2, 9, 4, 7, 1, 5. Press Reset, then Step one comparison at a time. Watch the 9 move to the end in pass 1.

PassList after the passComparisonsSwaps
Start7, 3, 9, 2, 5
13, 7, 2, 5, 943
23, 2, 5, 7, 932
32, 3, 5, 7, 921
42, 3, 5, 7, 910 β†’ stop
DECLARE Numbers : ARRAY[1:5] OF INTEGER
DECLARE Top : INTEGER
DECLARE Index : INTEGER
DECLARE Temp : INTEGER
DECLARE Swap : BOOLEAN
Numbers[1] ← 7
Numbers[2] ← 3
Numbers[3] ← 9
Numbers[4] ← 2
Numbers[5] ← 5
Top ← 5
REPEAT
  Swap ← FALSE
  FOR Index ← 1 TO Top - 1
    IF Numbers[Index] > Numbers[Index + 1]
      THEN
        Temp ← Numbers[Index]
        Numbers[Index] ← Numbers[Index + 1]
        Numbers[Index + 1] ← Temp
        Swap ← TRUE
    ENDIF
  NEXT Index
  Top ← Top - 1
UNTIL Swap = FALSE OR Top = 1
# Python has no REPEAT ... UNTIL, so a WHILE loop is used
numbers = [7, 3, 9, 2, 5]
top = 5
swap = True
while swap == True and top > 1:
    swap = False
    for index in range(top - 1):
        if numbers[index] > numbers[index + 1]:
            temp = numbers[index]
            numbers[index] = numbers[index + 1]
            numbers[index + 1] = temp
            swap = True
    top = top - 1
print(numbers)
?Why?

The swap uses `Temp` because `A ← B` then `B ← A` would lose A's value. `Temp` keeps a copy. `Top` goes down by 1 each pass because the end of the list is already sorted.

!Watch out

The loop runs to `Top - 1`, not `Top`. The last comparison is item `Top - 1` with item `Top`. Going to `Top` would compare with an item past the end.

There is something to try for this step in the IGCSE library.

How many comparisons? (extra)

This formula is not in the syllabus. It is useful for understanding why bubble sort is slow for long lists.

In the worst case every pass is needed. With n items, pass 1 makes n βˆ’ 1 comparisons, pass 2 makes n βˆ’ 2, and so on down to 1.

Adding these gives n(n βˆ’ 1) Γ· 2. Double the list and the work goes up about four times.

e.g.Example
n = 5: (5 Γ— 4) Γ· 2 = 10 comparisons. Check: 4 + 3 + 2 + 1 = 10. This matches the table above. n = 30 (a class): (30 Γ— 29) Γ· 2 = 435 n = 1000: (1000 Γ— 999) Γ· 2 = 499 500
?Why?

This shows why a sort that is fine for a class list is too slow for a million customers. Faster sorts exist, but they are not in this course.

7.9 Writing and amending algorithms

Be precise, and amend with care

An algorithm must say exactly what to do. 'More than 50' is `> 50`. '50 or more' is `>= 50`. These give different results for 50.

Set every total, counter, highest and lowest to a start value before the loop. Use meaningful names like `PassCount`, not `x`, and `//` comments.

An amend question asks you to change a given algorithm. Find the line that controls the behaviour and change only that line.

Example: to make the bubble sort give descending order (largest first), change `>` to `<` in the comparison.

Words in the questionPseudocode
over 18 / more than 18`Age > 18`
18 or over / at least 18`Age >= 18`
under 18 / less than 18`Age < 18`
between 1 and 21 inclusive`Days >= 1 AND Days <= 21`
not equal to -1`Value <> -1`
e.g.Example
7, 3, 9, 2, 5 sorted with the amended line: Output: 9, 7, 5, 3, 2
// Original: sorts into ascending order (smallest first)
IF Numbers[Index] > Numbers[Index + 1]

// Amended: sorts into descending order (largest first)
IF Numbers[Index] < Numbers[Index + 1]
numbers = [7, 3, 9, 2, 5]
top = 5
swap = True
while swap == True and top > 1:
    swap = False
    for index in range(top - 1):
        # amended: < instead of > gives descending order
        if numbers[index] < numbers[index + 1]:
            temp = numbers[index]
            numbers[index] = numbers[index + 1]
            numbers[index + 1] = temp
            swap = True
    top = top - 1
print(numbers)
?Why?

Rewriting the whole algorithm wastes time and can add new errors. The examiner is looking for the one or two key changes.

!Watch out

`Days >= 1 AND <= 21` is wrong. Write the variable on both sides: `Days >= 1 AND Days <= 21`.

The 15-mark scenario question: plan first

The last question on Paper 2 is a scenario worth 15 marks. Allow about 30 minutes. You may answer in pseudocode, Python, Visual Basic or Java.

Read the scenario twice. Underline every task. Make a numbered checklist and tick each item as you code it.

Sample scenario: a teacher records three tests for each of 30 students. Each test is out of 50. Names are already in `StudentName[1:30]`.

e.g.Example
Tasks in the sample scenario: 1. Input three marks per student and store them in StudentMark[1:30, 1:3]. 2. Validate each mark: 0 to 50. 3. Calculate and store each student's total in StudentTotal[1:30]. 4. Calculate each student's average, rounded to 1 decimal place. 5. Output each name with total and average. 6. Count and output the students with a total of 120 or more (a merit). 7. Output the class average total and the name of the student with the highest total. All inputs and outputs need suitable messages.
?Why?

Marks are given for meeting each requirement. A checklist stops you forgetting one, which is the most common way to lose marks here.

Model answer in pseudocode and Python

The model answer uses two nested `FOR` loops: one for students, one for tests. It reuses validation, totalling, counting, maximum and average.

Read the comments. They say what each part does, which also earns marks.

Python lists start at index 0, so the Python loops use `range(30)` and `range(3)`.

The first Python line is a stand-in for the names, so the program can run. In the exam you do not write it, because the names are already stored.

e.g.Example
If one student scores 45, 40 and 38: Total = 45 + 40 + 38 = 123. Average = 123 Γ· 3 = 41.0 123 >= 120, so MeritCount goes up by 1. If 123 is more than TopTotal, TopTotal becomes 123 and TopStudent becomes this student's index. Python sample run: Enter mark for test 1 for Student 1: 55 Error: a mark must be from 0 to 50. Enter it again: 31
// StudentName[1:30] already holds the 30 names
DECLARE StudentName : ARRAY[1:30] OF STRING
DECLARE StudentMark : ARRAY[1:30, 1:3] OF INTEGER
DECLARE StudentTotal : ARRAY[1:30] OF INTEGER
DECLARE Student : INTEGER
DECLARE Test : INTEGER
DECLARE Mark : INTEGER
DECLARE Total : INTEGER
DECLARE Average : REAL
DECLARE ClassTotal : INTEGER
DECLARE MeritCount : INTEGER
DECLARE TopTotal : INTEGER
DECLARE TopStudent : INTEGER

// set the class totals and counters to their start values
ClassTotal ← 0
MeritCount ← 0
TopTotal ← -1
TopStudent ← 1

FOR Student ← 1 TO 30
  Total ← 0
  FOR Test ← 1 TO 3
    // input one mark and validate it with a range check (0 to 50)
    OUTPUT "Enter mark for test ", Test, " for ", StudentName[Student]
    INPUT Mark
    WHILE Mark < 0 OR Mark > 50 DO
      OUTPUT "Error: a mark must be from 0 to 50. Enter it again"
      INPUT Mark
    ENDWHILE
    // store the valid mark and add it to this student's total
    StudentMark[Student, Test] ← Mark
    Total ← Total + Mark
  NEXT Test
  // store the total, work out the average and output the results
  StudentTotal[Student] ← Total
  Average ← ROUND(Total / 3, 1)
  OUTPUT StudentName[Student], " Total: ", Total, " Average: ", Average
  ClassTotal ← ClassTotal + Total
  // a total of 120 or more earns a merit
  IF Total >= 120
    THEN
      MeritCount ← MeritCount + 1
  ENDIF
  // remember the highest total so far and whose it is
  IF Total > TopTotal
    THEN
      TopTotal ← Total
      TopStudent ← Student
  ENDIF
NEXT Student

// whole-class results
OUTPUT "Class average total: ", ROUND(ClassTotal / 30, 1)
OUTPUT "Number of merits: ", MeritCount
OUTPUT "Highest total: ", StudentName[TopStudent], " with ", TopTotal
# The question says the names are already stored.
# This line is a stand-in so the program can run.
student_name = ["Student " + str(n) for n in range(1, 31)]
student_mark = [[0, 0, 0] for row in range(30)]
student_total = [0] * 30

# set the class totals and counters to their start values
class_total = 0
merit_count = 0
top_total = -1
top_student = 0

for student in range(30):
    total = 0
    for test in range(3):
        # input one mark and validate it with a range check (0 to 50)
        mark = int(input("Enter mark for test " + str(test + 1) + " for " + student_name[student] + ": "))
        while mark < 0 or mark > 50:
            mark = int(input("Error: a mark must be from 0 to 50. Enter it again: "))
        # store the valid mark and add it to this student's total
        student_mark[student][test] = mark
        total = total + mark
    # store the total, work out the average and output the results
    student_total[student] = total
    average = round(total / 3, 1)
    print(student_name[student], "Total:", total, "Average:", average)
    class_total = class_total + total
    # a total of 120 or more earns a merit
    if total >= 120:
        merit_count = merit_count + 1
    # remember the highest total so far and whose it is
    if total > top_total:
        top_total = total
        top_student = student

# whole-class results
print("Class average total:", round(class_total / 30, 1))
print("Number of merits:", merit_count)
print("Highest total:", student_name[top_student], "with", top_total)
?Why?

The Python version was run with 90 test marks, including invalid ones, to check it works. In Python, `round(total / 3, 1)` keeps one decimal place; `//` would cut off the decimals.

!Watch out

Store values in the arrays the question names. Calculating the total but not storing it in StudentTotal loses marks.

How the 15 marks are awarded

Recent mark schemes use levels, not one mark per line. AO2 (applying techniques and data structures) gives up to 9 marks. AO3 (comments, identifiers, logic and accuracy) gives up to 6 marks.

The examiner reads the whole answer and picks the band that fits best. Minor syntax errors are ignored if the logic is clear.

BandAO2: techniques and data structures (9)AO3: comments, names, accuracy (6)
Top7–9: all tasks covered with the right techniques; arrays store all the data5–6: fully commented, meaningful names, logical and accurate, meets all requirements
Middle4–6: some techniques suit the problem; some data stored correctly3–4: some comments, most names sensible, most requirements attempted
Low1–3: at least one technique used; some data stored, not well1–2: no useful comments, some sensible names, at least one requirement attempted
e.g.Example
The model answer reaches the top bands because it: - inputs with messages and validates every mark (input, iteration, selection) - stores marks in the 2D array and totals in StudentTotal (data structures) - uses totalling, counting, maximum, average and ROUND - outputs every result with a message - has a comment for every section and meaningful names like MeritCount
?Why?

Because marks come in bands, a working answer to every task beats a perfect answer to half of them. Attempt every requirement, even if one part is rough.

9.3 SQL: SELECT, FROM, WHERE, AND, OR

The shape of a query

SQL (Structured Query Language) is the language used to ask a database for data. A question written in SQL is called a query.

`SELECT` lists the fields you want to see. `FROM` names the table. `WHERE` gives the condition a record must meet.

The output is a new, smaller table. It has only the chosen fields, and only the records that meet the condition.

SymbolMeaningExample
=equal toStation = 'Sol'
<>not equal toBikeType <> 'E'
>greater thanMinutes > 30
<less thanCost < 1.00
>=greater than or equal toMinutes >= 30
<=less than or equal toCost <= 2.00
SELECT HireID, Station
FROM BikeHire
WHERE Minutes > 30;
?Why?

Text values go inside single quotes, like `'Sol'`, so SQL knows where the text starts and ends. Numbers and TRUE/FALSE have no quotes.

Predicting output: one condition

Use the same three moves every time. First, filter: go down the table and tick each record that meets the WHERE condition.

Second, pick columns: keep only the fields named after SELECT, in the order they are listed.

Third, sort, if there is an ORDER BY. With no ORDER BY, keep the records in table order.

HireIDMinutes
H0240
H0555
H0842
e.g.Example
Filter: Minutes > 30 H01 25 βœ— Β· H02 40 βœ“ Β· H03 12 βœ— Β· H04 18 βœ— H05 55 βœ“ Β· H06 30 βœ— Β· H07 8 βœ— Β· H08 42 βœ“ Pick columns HireID and Minutes. The output is in the table below.
SELECT HireID, Minutes
FROM BikeHire
WHERE Minutes > 30;
!Watch out

H06 has exactly 30 minutes. 30 is not greater than 30, so H06 is not in the output. Read `>` and `>=` very carefully.

AND: both conditions must be true

AND joins two conditions. A record is shown only if both conditions are true.

AND makes the output smaller, because each record has to pass two tests.

HireIDCost
H012.50
H084.20
e.g.Example
Records at Sol: H01 (E), H04 (M), H08 (E) H01: Sol βœ“ and E βœ“ β†’ shown H04: Sol βœ“ and M βœ— β†’ not shown H08: Sol βœ“ and E βœ“ β†’ shown
SELECT HireID, Cost
FROM BikeHire
WHERE Station = 'Sol' AND BikeType = 'E';

OR: at least one condition must be true

OR joins two conditions. A record is shown if either condition is true, or both.

OR makes the output bigger, because a record has two chances to pass.

Write the full condition on both sides of OR. The field name must appear twice.

HireIDStation
H02Retiro
H03Atocha
H06Retiro
H07Atocha
SELECT HireID, Station
FROM BikeHire
WHERE Station = 'Retiro' OR Station = 'Atocha';
!Watch out

`WHERE Station = 'Retiro' OR 'Atocha'` is wrong and loses the mark. Each side of OR must be a complete condition: `Station = 'Atocha'`.

Study it

Open the study page and go one step at a time.

Check yourself

One question at a time. The reason shows after each answer.

Saved on this device.