Time left2:00:00 Answered 0 of 6 75 marks
Pearson Edexcel 1CP2/02 2 hours 75 marks Full length paper

GCSE Computer Science Paper 2: Application of Computational Thinking

A full length 1CP2/02 onscreen paper in Python 3: complete a temperature converter, fix the logic errors in a grading program, then write a rainfall report, a Caesar cipher, a gym report that reads and writes files, and the subprograms for a sports day.

Instructions

Time allowed
2 hours
Total marks
75
Calculator
You do not need a calculator.
  • 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.
  • Each question gives you a code file to amend. Write your answers in Python 3.
  • Use the Run button to test your program. In the real exam you would save each file as, for example, Q01FINISHED.py.
  • Read each question to the end before you start. Run your program on the example in the question, and on values at the edges, before you move on. Every program is marked by running it.

Questions

Answer every question, then finish the paper to have it marked. Marking as you go teaches you far less.

75 marks
1Open Q01.py. The program converts a temperature from Celsius to Fahrenheit.Amend the code to:take a temperature in Celsius as a real number inputconvert it to Fahrenheit, using F = C x 9 / 5 + 32display the temperature in Fahrenheit, with a messagedisplay Freezing if the temperature is 0 Celsius or below.7 marks
Q01.py

Mark scheme0 / 7
  • LTakes the temperature as an input
  • LConverts the input to a real number, so 21.5 is accepted
  • LConverts correctly: 100 Celsius is 212 Fahrenheit
  • LConverts correctly with a fraction: 21.5 Celsius is 70.7 Fahrenheit
  • LDisplays the Fahrenheit temperature with a message
  • LDisplays Freezing for 0 Celsius and below
  • LDoes not display Freezing above 0 Celsius
A program that scores full marks

float() accepts a real number. The condition uses <= so that exactly 0 counts as freezing.

Python
# Convert a temperature from Celsius to Fahrenheit

celsius = 0.0
fahrenheit = 0.0

celsius = float(input("Enter a temperature in Celsius: "))
fahrenheit = celsius * 9 / 5 + 32
print("The temperature in Fahrenheit is", fahrenheit)
if celsius <= 0:
    print("Freezing")
Marked exactly against the mark scheme. Change it only if an examiner would accept your answer.
2Open Q02.py. The program should grade the test marks of five students and then display how many passed. The grades are:a mark below 0 or above 50: Invalid mark40 to 50: Distinction30 to 39: Merit20 to 29: Passbelow 20: FailA student passes with a Pass, Merit or Distinction. The code contains logic errors. Amend the code to fix them.8 marks
Q02.py

Mark scheme0 / 8
  • LGrades five students
  • LDisplays Invalid mark for a mark below 0
  • LDisplays Invalid mark for a mark above 50
  • LGives a Distinction for exactly 40
  • LGives a Pass, not a Merit, for 20 to 29
  • LStill gives Merit for 30 to 39 and Fail below 20
  • LCounts the passes: 3 for 45, 35, 25, 15 and 5
  • LDoes not count an invalid mark as a pass
A program that scores full marks

Four fixes: range(5) grades five students, or replaces and because no mark is both below 0 and above 50, >= 40 includes 40, and the third grade is Pass.

Python
# Grade the test marks of five students and count how many passed

passed = 0

for student in range(5):
    mark = int(input("Enter a mark out of 50: "))
    if (mark < 0) or (mark > 50):
        print("Invalid mark")
    elif (mark >= 40):
        print("Distinction")
        passed = passed + 1
    elif (mark >= 30):
        print("Merit")
        passed = passed + 1
    elif (mark >= 20):
        print("Pass")
        passed = passed + 1
    else:
        print("Fail")

print("Number passed:", passed)
Marked exactly against the mark scheme. Change it only if an examiner would accept your answer.
3Open Q03.py. A weather station records the rainfall in millimetres each day for a week.Write a program that:takes the rainfall for each of the seven days as a real number inputrejects a negative reading and keeps asking until the reading is validstores the readings in the list rainfalldisplays the total rainfall and the average daily rainfall, rounded to 1 decimal placedisplays the highest daily rainfall and the day it fell ondisplays the number of dry days, days with 0 mm of raindisplays Wet week if the total is more than 50 mm, otherwise Dry week.Your output must follow the format of the example below.15 marks

Example output for the readings 0, 12.5, 3, 0, 20, 8.5 and 0

Total: 44.0 mm
Average: 6.3 mm
Highest: 20.0 mm on Friday
Dry days: 3
Dry week
Q03.py

Mark scheme0 / 15
  • LTakes seven readings as real numbers: total 62.5 for the second week
  • LAccepts a reading of 0: total 44.0 for the example
  • LRejects a negative reading
  • LKeeps asking until the reading is valid
  • LDisplays the average rounded to 1 decimal place: 6.3
  • LDisplays the correct average for other readings: 8.9
  • LDisplays the highest rainfall: 20.0
  • LDisplays the day of the highest rainfall: Friday
  • LFinds the highest when it falls on the last day
  • LFinds the highest when it falls on the first day
  • LCounts the dry days: 3
  • LCounts no dry days when every day had rain
  • LDisplays Wet week when the total is more than 50 mm
  • LDisplays Dry week when the total is exactly 50 mm
  • LDisplays the four results in the order and format shown
A program that scores full marks

Validate each reading with a while loop before appending it. One pass through the list can then add up the total, track the highest reading and its day, and count the zeros.

Python
# Weekly rainfall report

days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
rainfall = []

for day in days:
    reading = float(input("Rainfall on " + day + " in mm: "))
    while reading < 0:
        print("Rainfall cannot be negative")
        reading = float(input("Rainfall on " + day + " in mm: "))
    rainfall.append(reading)

total = 0.0
highest = rainfall[0]
highestDay = days[0]
dryDays = 0
for index in range(len(rainfall)):
    total = total + rainfall[index]
    if rainfall[index] > highest:
        highest = rainfall[index]
        highestDay = days[index]
    if rainfall[index] == 0:
        dryDays = dryDays + 1
average = round(total / len(rainfall), 1)

print("Total:", total, "mm")
print("Average:", average, "mm")
print("Highest:", highest, "mm on", highestDay)
print("Dry days:", dryDays)
if total > 50:
    print("Wet week")
else:
    print("Dry week")
Marked exactly against the mark scheme. Change it only if an examiner would accept your answer.
4Open Q04.py. A Caesar cipher replaces each letter with the letter a fixed number of places further along the alphabet, wrapping round from Z to A.Write a program that:asks whether to encrypt or decrypt, and keeps asking until E or D is entered, in either caseasks for the messageasks for the shift, and keeps asking until it is a whole number from 1 to 25encrypts or decrypts the message: letters keep their case, and every other character, such as a space, a digit or punctuation, is left unchangeddisplays the result.For example, encrypting Hello World with a shift of 3 gives Khoor Zruog.15 marks
Q04.py

Mark scheme0 / 15
  • LEncrypts a lower case message
  • LKeeps upper case letters in upper case
  • LWraps round from z to a
  • LWraps round from Z to A
  • LKeeps the case of each letter in a mixed message
  • LLeaves spaces unchanged
  • LLeaves digits and punctuation unchanged
  • LDecrypts a message
  • LDecrypts with wrapping round from a to z
  • LAccepts e or d in lower case
  • LKeeps asking until E or D is entered
  • LRejects a shift of 0 and asks again
  • LRejects a shift of 26 and asks again
  • LAccepts a shift of 25
  • LKeeps asking until the shift is valid, however many times
A program that scores full marks

ord() and chr() convert between letters and codes. Taking the position in the alphabet, adding the shift and using % 26 wraps round in both directions; decrypting is encrypting with the shift made negative.

Python
# Caesar cipher

choice = input("Encrypt or decrypt (E/D)? ").upper()
while choice != "E" and choice != "D":
    choice = input("Please enter E or D: ").upper()

message = input("Enter the message: ")

shift = int(input("Enter a shift from 1 to 25: "))
while shift < 1 or shift > 25:
    shift = int(input("The shift must be from 1 to 25: "))

if choice == "D":
    shift = -shift

result = ""
for character in message:
    if "A" <= character <= "Z":
        result = result + chr((ord(character) - ord("A") + shift) % 26 + ord("A"))
    elif "a" <= character <= "z":
        result = result + chr((ord(character) - ord("a") + shift) % 26 + ord("a"))
    else:
        result = result + character

print("Result:", result)
Marked exactly against the mark scheme. Change it only if an examiner would accept your answer.
5Open Q05.py. Each line of the text file members.txt holds a gym member's name, age and number of visits this month, separated by commas, as shown below.Write a program that reads the file and:displays the number of membersdisplays the name of the member with the most visitsdisplays the average age of the members, rounded to 1 decimal placewrites the name of every member with fewer than 5 visits to a new file, reminders.txt, one name per line. The file must be created even if no names are written.displays how many names were written.Your output must follow the format of the example below.15 marks

members.txt

Asha,34,12
Ben,19,3
Cara,45,20
Dev,27,0
Emi,52,4
Finn,38,9

Example output for this file

Members: 6
Most visits: Cara
Average age: 35.8
Reminders written: 3
Q05.py

Mark scheme0 / 15
  • LReads every line of the file: 6 members
  • LCounts the members in a different file: 4
  • LFinds the member with the most visits: Cara
  • LFinds the most visits when it is a later member: Yara
  • LFinds the most visits when it is the first member: Omar
  • LCompares visits as numbers, not as text: 10 is more than 9
  • LCalculates the average age: 35.8
  • LRounds the average age to 1 decimal place: 34.3
  • LCreates the file reminders.txt
  • LWrites every member with fewer than 5 visits
  • LWrites no member with 5 or more visits, so Quin, with exactly 5, is left out
  • LWrites one name per line, with nothing else
  • LDisplays how many names were written: 3
  • LDisplays the count for a different file: 1
  • LDisplays the results in the order and format shown
A program that scores full marks

Read the file a line at a time, strip the newline and split on commas, converting the age and visits to integers so they compare as numbers. Open reminders.txt for writing before the loop, so it is created even when nothing is written.

Python
# Gym members report

count = 0
totalAge = 0
mostVisits = -1
mostName = ""
written = 0

reminders = open("reminders.txt", "w")
members = open("members.txt", "r")
for line in members:
    parts = line.strip().split(",")
    name = parts[0]
    age = int(parts[1])
    visits = int(parts[2])
    count = count + 1
    totalAge = totalAge + age
    if visits > mostVisits:
        mostVisits = visits
        mostName = name
    if visits < 5:
        reminders.write(name + "\n")
        written = written + 1
members.close()
reminders.close()

print("Members:", count)
print("Most visits:", mostName)
print("Average age:", round(totalAge / count, 1))
print("Reminders written:", written)
Marked exactly against the mark scheme. Change it only if an examiner would accept your answer.
6Open Q06.py. The results of a race on sports day are stored in a two-dimensional list. Each record holds a runner's name, house and time in seconds.Complete the subprograms fastest, houseCount, averageTime and points, following the comments in the code. Then complete the main program so that it displays the name of the fastest runner, then the average time for each of the houses Red, Blue and Green, using the subprograms.15 marks
Q06.py

Mark scheme0 / 15
  • Lfastest returns Dee for the results given
  • Lfastest works when the fastest runner is first
  • Lfastest works when the fastest runner is last
  • LhouseCount returns 2 for Red
  • LhouseCount returns 0 for a house with no runners
  • LaverageTime returns 13.85 for Red
  • LaverageTime returns 14.35 for Blue
  • LaverageTime rounds to 2 decimal places
  • LaverageTime returns 0 for a house with no runners
  • Lpoints gives 10, 8 and 6 for the first three places
  • Lpoints gives 3 for 4th, 5th and 6th place
  • Lpoints gives 0 for any other position
  • LThe main program displays the fastest runner
  • LThe main program displays the average time for each house
  • LThe main program uses the subprograms rather than repeating their code
A program that scores full marks

Each subprogram loops through the records once. averageTime checks for an empty house first, so it never divides by zero, and rounds only the final answer.

Python
# Sports day results
# Each record holds a runner's name, house and time in seconds

results = [
    ["Ava", "Red", 14.2],
    ["Ben", "Blue", 13.8],
    ["Cal", "Green", 15.1],
    ["Dee", "Red", 13.5],
    ["Eli", "Blue", 14.9],
    ["Fay", "Green", 13.9]
]


def fastest(records):
    best = records[0]
    for record in records:
        if record[2] < best[2]:
            best = record
    return best[0]


def houseCount(records, house):
    count = 0
    for record in records:
        if record[1] == house:
            count = count + 1
    return count


def averageTime(records, house):
    if houseCount(records, house) == 0:
        return 0
    total = 0
    for record in records:
        if record[1] == house:
            total = total + record[2]
    return round(total / houseCount(records, house), 2)


def points(position):
    if position == 1:
        return 10
    elif position == 2:
        return 8
    elif position == 3:
        return 6
    elif position >= 4 and position <= 6:
        return 3
    else:
        return 0


print("Fastest runner:", fastest(results))
for house in ["Red", "Blue", "Green"]:
    print(house, "average time:", averageTime(results, house))
Marked exactly against the mark scheme. Change it only if an examiner would accept your answer.
Machine mark 0 / 75
About this paper

This is an original paper modelled on the real Pearson Edexcel 1CP2/02 past papers: the same structure, the same balance of topics, the same command words and mark tariffs, 75 marks in 2 hours, 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.