GCSE Computer Science Paper 2: Computational Thinking, Algorithms and Programming
A full length original paper covering computational thinking, algorithms, searching and sorting, programming fundamentals, robust programs, Boolean logic and IDEs.
Exam timer
Sit this to the clock. Working under time pressure is a separate skill from knowing the content, and it is the one most students never practise.
Instructions
- Answer every question.
- The marks tell you how many creditworthy points are wanted.
- No calculator is permitted.
- You may answer programming questions in OCR reference language, Python or another high level language, but be consistent within each answer. Show your trace tables in full, because method marks are awarded for the working.
Questions
Write a full answer to every question, then mark the whole paper at the end. Marking as you go teaches you far less.
- LA sequence of steps or instructions
- LIn a specific order, to solve a problem or complete a task
An algorithm is a sequence of unambiguous instructions, arranged in a specific order, which solves a problem or completes a task. It must be complete, so no step is missing, and finite, so that it eventually stops.
- LAbstraction is removing detail that is not relevant to the problem
- LOnly the information needed to solve the problem is kept
- LGives examples of removed detail such as scenery or station buildings
- LIdentifies what is retained such as stations, connections and journey times
Abstraction is the process of removing detail that is not relevant to the problem being solved, so that only the information genuinely needed remains and the problem becomes simpler and quicker to solve. In a program finding the quickest route between two railway stations, details such as what the stations look like, the type of train used on each service, the weather and the number of passengers would all be removed, because none of them affect which sequence of connections is fastest. What would be retained is the set of stations, which stations connect directly to which others, and the journey time for each connection, which turns a complex real network into a simple set of points and weighted links that a routing algorithm can process.
- LIdentifies that the condition is true when i is a multiple of 3
- LShows total becoming 3 when i is 3
- LShows total becoming 9 when i is 6
- LShows count reaching 2
- LStates the output is 9 then 2
The loop runs with i taking the values 1 to 6. The condition i MOD 3 equals 0 is true only when i is 3 and when i is 6. When i is 3, total becomes 0 plus 3 which is 3, and count becomes 1. When i is 6, total becomes 3 plus 6 which is 9, and count becomes 2. For all other values of i the condition is false and neither variable changes. The final output is therefore 9 followed by 2.
- LThe middle item is examined first, which is 16
- L23 is greater than 16, so the lower half is discarded
- LThe middle of the remaining items is examined, which is 42
- L23 is less than 42, so the upper half is discarded, leaving 23 which is found
Binary search begins by examining the middle item of the list, which is 16. The target 23 is greater than 16, so it cannot lie in the lower half, and everything from 4 up to and including 16 is discarded, leaving 23, 42 and 50. The middle of that remaining section is 42. The target 23 is less than 42, so the upper half is discarded, leaving only 23. That item is examined, it matches the target, and the search stops after three comparisons rather than the five a linear search would have required.
- LAfter pass 1 the list is [4, 7, 2, 9]
- LAfter pass 2 the list is [4, 2, 7, 9]
- LAfter pass 3 the list is [2, 4, 7, 9]
- LA further pass makes no swaps, showing the list is sorted
Pass 1: comparing 9 and 4 gives a swap to [4, 9, 7, 2]; comparing 9 and 7 gives a swap to [4, 7, 9, 2]; comparing 9 and 2 gives a swap to [4, 7, 2, 9]. Pass 2: comparing 4 and 7 gives no swap; comparing 7 and 2 gives a swap to [4, 2, 7, 9]; comparing 7 and 9 gives no swap. Pass 3: comparing 4 and 2 gives a swap to [2, 4, 7, 9]; the remaining comparisons give no swaps. A fourth pass makes no swaps at all, which tells the algorithm the list is fully sorted.
- LMerge sort is much faster on large lists
- LBecause it repeatedly halves the problem rather than repeatedly passing through the whole list
- LMerge sort uses more memory
- LBecause the sub lists have to be stored during the merging process
The advantage of merge sort is speed on large lists. It uses divide and conquer, repeatedly splitting the list in half until each part contains a single item and then merging the sorted parts back together, which requires far fewer comparisons than bubble sort's repeated passes through the entire list and, importantly, gives consistent performance regardless of how disordered the starting data is. The disadvantage is memory. Merge sort has to create and hold the sub lists it produces while dividing and merging, so it requires additional memory roughly proportional to the size of the list, whereas bubble sort sorts in place using only a single temporary variable and therefore needs almost no extra memory at all.
- LDeclares an array or list to hold the values
- LUses a count controlled loop that runs 10 times
- LReads input and converts it to a number
- LStores each value and maintains a running total
- LFinds the largest by initialising from the first element and comparing
- LOutputs the largest and the average
numbers = [] total = 0 for i in range(10): value = int(input("Enter a number: ")) numbers.append(value) total = total + value largest = numbers[0] for n in numbers: if n > largest: largest = n print("Largest:", largest) print("Average:", total / 10) The loop runs exactly ten times, reading each number, converting it from the text that input returns into an integer, storing it in the array and adding it to a running total. The largest is found by initialising the variable to the first element rather than to zero, which matters because the numbers could all be negative, and then comparing each value against it. The average is the total divided by ten.
- LA variable's value can change while the program runs
- LA constant's value is fixed once set and cannot be changed
- LA reason such as preventing accidental change or only needing to edit one line
A variable is a named memory location whose value can be changed at any point while the program is running, such as a score that increases during a game. A constant is given a value once and that value cannot be altered afterwards, such as a VAT rate or the maximum number of players. A constant is used because it prevents the value being changed accidentally elsewhere in the program, and because if the value ever does need updating it appears in only one place so a single line has to be edited rather than every occurrence being found.
- LIncludes normal data within the range
- LIncludes boundary data at the edge of the accepted range
- LIncludes boundary data just outside the accepted range
- LIncludes erroneous data of the wrong type
- LStates the type of each piece of data
- LStates an expected result for every test
Test 1 uses the value 14, which is normal data comfortably inside the range, and the expected result is that it is accepted. Test 2 uses the value 11, which is boundary data at the lower edge of the accepted range, and the expected result is that it is accepted because the range is inclusive. Test 3 uses the value 19, which is boundary data just outside the upper edge, and the expected result is that it is rejected with an error message asking the user to try again. Test 4 uses the entry abc, which is erroneous data of the wrong type entirely, and the expected result is that the program rejects it with a clear message rather than crashing when it attempts to convert text into a number. A fifth useful test would be the value 10, checking the lower boundary from outside, since an error at one end of a range does not guarantee an error at the other.
- LA syntax error breaks the rules of the programming language
- LThe program will not run at all until it is corrected
- LA logic error means the program runs but produces the wrong result
- LGives valid examples such as a missing bracket and a wrong operator
A syntax error is a mistake in the way the code is written, such as a missing colon at the end of an if statement or an unclosed bracket, and because the code breaks the rules of the language the program will not run at all until it is fixed. A logic error is different: the code is perfectly valid and the program runs without complaint, but the instructions do not do what the programmer intended, so the output is wrong. An example is writing total = total minus price when calculating a shopping basket, or using a greater than sign where greater than or equal to was needed, which produces the wrong answer only at the boundary value. Logic errors are more dangerous because nothing alerts the programmer to them and they can only be found by careful testing.
- LLists all eight input combinations
- LIncludes an intermediate column for A OR B
- LIncludes an intermediate column for NOT C
- LQ is 0 whenever C is 1
- LQ is 1 for the combinations 010, 100 and 110
There are eight input combinations, counted in binary from 000 to 111. The intermediate column A OR B is 0 only when both A and B are 0, and 1 otherwise. The intermediate column NOT C is 1 whenever C is 0 and 0 whenever C is 1. Q is the AND of those two columns, so Q is 1 only when at least one of A and B is 1 and C is 0. Q is therefore 1 for the input combinations 010, 100 and 110, and 0 for the other five combinations, namely 000, 001, 011, 101 and 111.
- LA compiler translates the whole program before it is run
- LAn interpreter translates and executes one line at a time as the program runs
- LA compiler reports all errors together at the end of translation
- LAn interpreter stops at the first error it encounters
A compiler translates the entire source program into machine code in one operation before it is run, producing an executable file that can then be distributed and run without the compiler or the source. An interpreter translates and executes the program one statement at a time, every time it is run, so both the source code and the interpreter are needed. The second difference is how errors are reported. A compiler attempts to translate the whole program and then presents all the errors it found together, which can be a long list. An interpreter stops as soon as it reaches the first error and reports that one immediately, which makes locating and fixing problems during development considerably easier.
- LAn editor with syntax highlighting
- LWhich makes structure visible and typing errors stand out
- LError diagnostics identifying the line and type of error
- LOr debugging tools such as breakpoints allowing variables to be inspected
The first feature is the editor with syntax highlighting, which colours keywords, strings and comments differently. This makes the structure of the code immediately visible and causes typing errors to stand out, since a misspelled keyword loses its colour and an unclosed quotation mark turns the rest of the line into a string. The second feature is error diagnostics combined with debugging tools. Error diagnostics report the line number and the type of any error found, which means the programmer can go straight to the problem instead of searching. Debugging tools such as breakpoints pause the program at a chosen line so the values held in variables can be inspected, and stepping runs one line at a time so the flow can be watched, which is the only reliable way to find logic errors.
- LUsers may enter data of the wrong type or outside a sensible range
- LWithout validation the program may crash
- LOr produce incorrect results from meaningless data
- LValidation checks the input is acceptable and allows the user to try again
Input validation is needed because a user may enter something the program cannot sensibly use, whether by accident or deliberately. They might type letters instead of digits, enter a negative mark, enter a value above 100, or leave the field blank. Without validation the program would attempt to use that input directly, and converting text into a number would cause it to crash, while a mark of 500 would produce a meaningless average that the program would report as though it were correct. Validation applies a type check to confirm a whole number was entered and a range check to confirm it lies between 0 and 100 inclusive, rejecting anything that fails with a clear message so the user can correct it, which makes the program robust rather than fragile.
- LA function returns a value to the code that called it
- LA procedure carries out a task without returning a value
- LBenefit: code is written once and can be called many times
- LSo a change only has to be made in one place, or each part can be tested separately
A function is a subroutine that returns a value to the part of the program that called it, so its result can be assigned to a variable or used in a further calculation. A procedure carries out a task, such as displaying a menu, but does not return any value. The main benefit of using subroutines of either kind is that code needed in several places is written once and simply called wherever it is required, so the program is shorter and, more importantly, any correction or change is made in a single place rather than being repeated in every copy. Subroutines also make a program much easier to test, because each one performs a single well defined task that can be checked independently until it is known to work.
- LA for loop repeats a known number of times
- LA while loop repeats while a condition remains true
- LA situation for a for loop such as processing every item in a list of known length
- LA situation for a while loop such as validating input until it is acceptable
A for loop repeats a known, fixed number of times, decided before the loop begins, or once for each item in a collection. A while loop repeats for as long as its condition remains true, so the number of iterations is not known in advance and depends on what happens while the program runs. A for loop would be the correct choice for calculating the total of an array of thirty marks, because the number of repetitions is known from the length of the array. A while loop would be the correct choice for repeatedly asking a user to enter a valid password, because there is no way to know in advance how many attempts they will need.
- LDecomposition means breaking a large problem into smaller sub problems
- LEach sub problem is easier to understand and solve
- LGives a valid sub problem such as searching for a book
- LGives a second valid sub problem such as issuing or returning a book
- LStates a benefit such as parts being testable separately or by different people
Decomposition means breaking a large complex problem down into smaller sub problems, each of which is small enough to be understood and solved on its own. For a school library system, one sub problem would be searching the catalogue for a book by title, author or subject. A second would be issuing a book, which involves recording who has borrowed it and calculating the due date. Further sub problems would include returning a book and clearing the loan, calculating and recording overdue fines, adding new stock to the catalogue and producing reports for the librarian. Breaking the problem down this way means each part can be written and tested independently, different people can work on separate parts at the same time, and a fault can be traced to one small section rather than searched for across the whole program.
- LBinary search requires the data to be sorted
- LIt works by discarding half the list based on a comparison with the middle item
- LOn unsorted data that assumption is invalid so the result would be wrong
- LThe list would have to be sorted first, which itself takes time
A binary search cannot be used because it requires the data to be in sorted order. The algorithm compares the target with the middle item and then discards the entire half of the list in which the target cannot lie, and this reasoning is only valid if the list is ordered. On unsorted data there is no guarantee that the target is not in the half being discarded, so the search would frequently report that an item is absent when it is actually present. To use a binary search the list would first have to be sorted, which itself takes time. Whether that is worthwhile depends on how often the list is searched: sorting once and then performing many fast binary searches is a clear gain, but sorting 5000 names in order to perform a single search would take longer than simply scanning the list once.
This is an original paper written to match the structure, question style, command words and mark allocation of the real OCR J277/02 style assessment. 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 provided on the exam papers page.