GCSE Computer Science Paper 2 B: Computational Thinking, Algorithms and Programming
A full length J277/02 paper: searching and sorting, data types, operators and trace tables, Boolean logic, validation and testing in Section A, then a cinema ticketing program to design, write and refine in Section B.
Instructions
- Time allowed
- 1 hour 30 minutes
- Total marks
- 80
- Sections
- Section A, 50 marks; Section B, 30 marks
- Calculator
- No calculator is permitted.
- Answer all the questions.
- The number of marks for each question is shown in brackets. Use it as a guide to how much to write.
- The clock at the top counts down from the real time allowed. When it reaches zero the paper is locked and marked, as it would be collected in the exam hall.
- Section B questions ask for programs. Write them in Python so they can be run and marked here. In the real exam you may also use OCR Exam Reference Language.
- OCR advises about 50 minutes on Section A and about 40 minutes on Section B.
- In Section B read the whole scenario first. Test each program with the Run button before you move on, using the example values in the question.
Questions
Answer every question, then finish the paper to have it marked. Marking as you go teaches you far less.
Section A 50 marks
Answer all the questions in this section.
| Abstraction | Decomposition | |
|---|---|---|
| Breaking the job of building a game into designing levels, writing the physics and creating the sound | ||
| Storing a player only as a position, a health value and a score |
Tick one box in each row.
- LBreaking the job of building a game into designing levels, writing the physics and creating the sound: Decomposition
- LStoring a player only as a position, a health value and a score: Abstraction
Splitting a problem into parts is decomposition. Keeping only the details that matter is abstraction.
| Comparison | Item checked |
|---|---|
| 1 | |
| 2 | |
| 3 |
- L25
- L40
- L52
With indexes 0 to 8, the middle is index 4, which is 25. 52 is larger, so the search continues in indexes 5 to 8, whose middle is index 6, 40. 52 is larger again, so it continues in 7 to 8, whose middle is index 7, which holds 52.
- LIt works on an unsorted list (or is simpler to write)
A linear search works on a list in any order, whereas a binary search only works on a sorted list.
| Position 0 | Position 1 | Position 2 | Position 3 | Position 4 |
|---|---|---|---|---|
- L2, 6, 4 in positions 0 to 2: 2, 6, 4
- L1, 9 in positions 3 and 4: 1, 9
6 and 2 swap, 6 and 9 stay, 9 and 4 swap, 9 and 1 swap: 2, 6, 4, 1, 9. The largest value has moved to the end.
- LThe list is split repeatedly until each sublist holds one item
- LPairs of sublists are merged in order: 2, 6 and 4, 9
- LThe two sorted lists are merged by comparing their first items, giving 2, 4, 6, 9
The list is split in half, then in half again, until there are four lists of one item: 6, 2, 9 and 4. Neighbouring lists are merged in order, giving 2, 6 and 4, 9. Those two lists are then merged by repeatedly comparing their front items and taking the smaller, giving 2, 4, 6, 9.
| Integer | Real | Boolean | Character | String | |
|---|---|---|---|---|---|
| The number of students in a class | |||||
| The price of a ticket in pounds | |||||
| Whether a seat is booked | |||||
| A form group, such as 10B | |||||
| A single grade, such as A |
Tick one box in each row.
- LThe number of students in a class: Integer
- LThe price of a ticket in pounds: Real
- LWhether a seat is booked: Boolean
- LA form group, such as 10B: String
- LA single grade, such as A: Character
Whole numbers are integers, money is real, yes or no is Boolean, 10B is a string because it has more than one character, and a single letter is a character.
- L2
- L3
- L16
17 divided by 5 is 3 remainder 2, so MOD gives 2 and DIV gives 3. 2 to the power 4 is 16.
Tick one box.
- LC age = int(userAge)
int() casts a string to an integer.
total = 0
for i = 1 to 3
total = total + i * 2
next i
print(total)| i | total |
|---|---|
| 1 | |
| 2 | |
| 3 | |
| output |
- L2
- L6
- L12
- L12
Each pass adds i x 2: 0 + 2 = 2, 2 + 4 = 6, 6 + 6 = 12, and 12 is printed.
- LA local variable can only be used inside the subroutine where it is declared
- LA global variable can be used anywhere in the program
A local variable is declared inside a subroutine and can only be used there; it disappears when the subroutine ends. A global variable is declared in the main program and can be used anywhere in it.
| A | B | C | P |
|---|---|---|---|
| 0 | 0 | 0 | |
| 0 | 0 | 1 | |
| 0 | 1 | 0 | |
| 0 | 1 | 1 | |
| 1 | 0 | 0 | |
| 1 | 0 | 1 | |
| 1 | 1 | 0 | |
| 1 | 1 | 1 |
- LRows 1 and 2: 1, 0
- LRows 3 and 4: 1, 0
- LRows 5 and 6: 1, 0
- LRows 7 and 8: 1, 1
P is 1 whenever C is 0. When C is 1, P is only 1 if A and B are both 1, which is the last row.
Tick one box.
- LA AND
AND needs both inputs to be 1.
- LS AND (D OR W)
Q = S AND (D OR W). The brackets matter: without them S AND D OR W would sound whenever a window opened.
- L1
1 AND 0 is 0, NOT 0 is 1, and 1 OR 0 is 1.
| Range check | Presence check | Length check | Format check | |
|---|---|---|---|---|
| A password must have at least 8 characters | ||||
| A postcode must match the pattern of letters and digits | ||||
| An age must be between 0 and 120 | ||||
| A username cannot be left blank |
Tick one box in each row.
- LA password must have at least 8 characters: Length check
- LA postcode must match the pattern of letters and digits: Format check
- LAn age must be between 0 and 120: Range check
- LA username cannot be left blank: Presence check
Minimum characters is a length check, a pattern is a format check, limits are a range check, and not blank is a presence check.
- LDesigning a program to anticipate misuse and handle unexpected input, so it does not crash or behave wrongly
- LExample: input validation or input sanitisation
- LExample: authentication, such as usernames and passwords, or maintainable code with comments and naming
Defensive design means planning for misuse: anticipating how users might enter unexpected or malicious data and making sure the program copes rather than crashing or giving wrong results. Examples are validating every input, and authentication so only allowed users can use the program.
| Normal | Boundary | Invalid | Erroneous | |
|---|---|---|---|---|
| 5 | ||||
| 10 | ||||
| 11 | ||||
| ten |
Tick one box in each row.
- L5: Normal
- L10: Boundary
- L11: Invalid
- Lten: Erroneous
5 is typical valid data, 10 is at the edge of the range, 11 is the right type but out of range, and ten is the wrong type of data.
| Compiler | Interpreter | |
|---|---|---|
| Translates the whole program at once into an executable file | ||
| Translates and runs one line at a time | ||
| Reports every error after translating the whole program | ||
| Stops at the first error it meets |
Tick one box in each row.
- L1 mark for both: Translates the whole program at once into an executable file: Compiler; Translates and runs one line at a time: Interpreter
- L1 mark for both: Reports every error after translating the whole program: Compiler; Stops at the first error it meets: Interpreter
A compiler translates everything first and produces an executable; an interpreter translates and runs line by line.
- LError diagnostics that show where errors are and what they are
- LThese point the programmer straight to the line to fix
- LA debugger with breakpoints or stepping, or a variable watch
- LThis lets the programmer pause the program and see the values of variables to find logic errors
Error diagnostics highlight the line where a syntax error is and say what is wrong, so the programmer goes straight to it. Breakpoints pause the running program at a chosen line, so the programmer can step through it line by line and watch the variables change, which is how logic errors are found.
Section B 30 marks
A cinema uses a program to sell tickets. Answer all the questions in this section. Write your programs in Python.
def ticketPrice(age):
# return the price of one ticket for a person of this age
pass
- LReturns 5.50 for anyone under 16, including 15
- LReturns 8.00 for ages 16 to 64, including both ends
- LReturns 6.00 for 65 and over, including 65
- LReturns the price rather than printing it
Check the bands in order with if, elif and else, using < 16 and < 65 so that 16 and 65 fall in the right band.
def ticketPrice(age):
if age < 16:
return 5.50
elif age < 65:
return 8.00
else:
return 6.00def ticketPrice(age):
if age < 16:
return 5.50
elif age < 65:
return 8.00
else:
return 6.00
# Write the rest of the program below
- LAsks for the number of tickets and one age per ticket
- LRejects a number of tickets below 1 and asks again
- LRejects a number above 10 and asks again
- LUses a loop to repeat the validation
- LUses ticketPrice to find each person's price
- LOutputs the correct total for a mixed group, 19.5 for ages 10, 30 and 70
Validate with a while loop, then loop once per ticket, adding ticketPrice(age) to a running total.
def ticketPrice(age):
if age < 16:
return 5.50
elif age < 65:
return 8.00
else:
return 6.00
tickets = int(input("How many tickets? "))
while tickets < 1 or tickets > 10:
tickets = int(input("Enter a number from 1 to 10: "))
total = 0
for i in range(tickets):
age = int(input("Age: "))
total = total + ticketPrice(age)
print("Total cost:", total)01 def discount(total, members):
02 if members > 4:
03 total = total * 0.9
04 return totalTick one box.
- LB 02
Line 02 uses > 4, so a group of exactly 4 misses out. It should be >= 4.
- Lif members >= 4:
if members >= 4:
seats = [["B", "F", "F", "B"],
["F", "F", "B", "B"],
["B", "B", "B", "F"]]- LB
- LF
Row 0, seat 3 is the last item of the first row, B. Row 2, seat 3 is the last item of the last row, F.
def countFree(seats):
# return how many items are "F"
pass
- LDefines countFree with one parameter
- LReturns 5 for the seat plan above
- LReturns 0 when every seat is booked
- LWorks for a seat plan of any size
Two nested loops visit every seat, counting those that hold F.
def countFree(seats):
free = 0
for row in seats:
for seat in row:
if seat == "F":
free = free + 1
return freedef bookSeat(seats, row, seat):
# book the seat if it is free
pass
- LDefines bookSeat with three parameters
- LChanges a free seat to B
- LPrints Booked when the seat was free
- LPrints Already taken, and leaves a booked seat unchanged
Check the seat first. Only a free seat is changed; a booked one just gets the message.
def bookSeat(seats, row, seat):
if seats[row][seat] == "F":
seats[row][seat] = "B"
print("Booked")
else:
print("Already taken")- LThe list is held in RAM, so it is lost when the program closes or the power fails
- LA file is kept in secondary storage, so the bookings can be loaded again later
The 2D list only exists in RAM while the program runs, so every booking would be lost when the program closes or the computer restarts. Saving it to a file on secondary storage keeps the bookings permanently, so they can be loaded the next time the program starts.
- LAn input: the member's ID or name
- LA second input: the number of tickets bought, now or in total
- LAn output: the number of free tickets earned (or a message saying so)
Inputs: the member's ID, and the number of tickets they have bought. Output: the number of free tickets they have earned.
def freeTickets(bought):
# one free ticket for every 10 bought
pass
- LReturns 2 for 25 tickets bought
- LReturns 0 for 9 and 1 for 10, so the tenth ticket counts
- LWorks for any number, such as 100 and 0
Integer division by 10, DIV in OCR Exam Reference Language, // in Python, counts the complete tens.
def freeTickets(bought):
return bought // 10This is an original paper modelled on the real OCR J277/02 past papers: the same structure, the same balance of topics, the same command words and mark tariffs, 80 marks in 1 hour 30 minutes, exactly as the real paper allows. It is not a past paper. Real past papers are the copyright of the exam board and cannot be republished here, so links to the official papers on the board's own site are on the exam papers page.