All GCSE 2 40 min read 10 question quiz 16 exam marks

Arrays, Records and Files

One and two dimensional arrays, records, and text files: the three ways a GCSE program holds a lot of data, with the lists, dictionaries and files that do the work in Python.

One dimensional arrays

An array is a numbered row of boxes that all hold the same type of data. In the exam you declare one with a fixed size, and the first box is number 0:

OCR reference language
array scores[5]
scores[0] = 12
scores[1] = 18
scores[4] = 7

Python has no fixed-size array. A list does the same job and can also grow, so when you write an exam answer in Python, behave like an array: make the list the right size at the start, and do not use append or insert.

Python
# array scores[5]
scores = [0] * 5
scores[0] = 12
scores[1] = 18
scores[4] = 7
print(scores)             # [12, 18, 0, 0, 7]
print(len(scores))        # 5

The positions of a five box array are 0, 1, 2, 3 and 4. Asking for a position that does not exist is an error:

Python
# raises: IndexError
scores = [12, 18, 0, 0, 7]
print(scores[5])

Going through an array

Use the index when the position matters, and the value when it does not.

Python
scores = [12, 18, 0, 0, 7]

for i in range(len(scores)):
    print("Position", i, "holds", scores[i])

for score in scores:
    print(score)

The array algorithms the exam keeps asking for

Every one of these is a loop with something carried from one pass to the next. Learn the shape of each.

Python
marks = [56, 71, 38, 90, 64]

total = 0
for mark in marks:
    total = total + mark
average = total / len(marks)
print(total, average)                       # 319 63.8

highest = marks[0]
position = 0
for i in range(1, len(marks)):
    if marks[i] > highest:
        highest = marks[i]
        position = i
print(highest, "at position", position)     # 90 at position 3

passes = 0
for mark in marks:
    if mark >= 50:
        passes = passes + 1
print(passes, "passed")                     # 4 passed

Notice that highest starts as the first item, not as 0. Starting at 0 fails if every value is negative, and starting at the first item is always right.

Linear search

Check every item in turn. Return its position when found, and only say "not found" after the whole array has been checked.

Python
def find(names, target):
    for i in range(len(names)):
        if names[i] == target:
            return i
    return -1

names = ["Asha", "Ben", "Chloe", "Dev"]
print(find(names, "Chloe"))     # 2
print(find(names, "Zoe"))       # -1
The return -1 goes outside the loop

If it sits inside the loop, in an else branch, the function gives up after the first item that does not match.

Parallel arrays

Two arrays can describe the same set of things, if the box at one position in one array belongs with the box at the same position in the other.

Python
names = ["Asha", "Ben", "Chloe", "Dev"]
marks = [56, 71, 38, 90]

best = 0
for i in range(1, len(marks)):
    if marks[i] > marks[best]:
        best = i
print(names[best], "scored", marks[best])     # Dev scored 90

They only stay in step if every change is made to both. Sort one array on its own and the names no longer match the marks. That fragility is the reason records exist.

A list is a row of numbered lockersA list drawn as a row of numbered lockers, with the code that changes it. The list scores starts with five values, 72, 85, 90, 64 and 78, in lockers numbered from 0. The call append of 88 adds a new locker on the end, so the list now has six items. The assignment scores, bracket, 1, bracket, equals 99 replaces what was in locker 1, the 85, with 99. Reading scores bracket 2 opens locker 2 and finds 90, and len of scores is 6, so the last index is 5, one less than the length. The program prints 90 and 6.lists.py1scores = [72, 85, 90, 64, 78]2scores.append(88)3scores[1] = 994print(scores[2], len(scores))output90 6the item at index 2, then the length720991902643784885appendchangedscores[2]len(scores) is 6, so the last index is 51234
  1. The list holds its items in order, and the first locker is number 0.
  2. append() puts a new item on the end, so the list grows.
  3. Assign to an index to replace what is there. The old value is gone.
  4. scores[2] opens locker 2. len(scores) counts the lockers, so the last index is one less.
Index from 0, and remember the last index is len minus 1.

Two dimensional arrays

A two dimensional array is a table: rows and columns. OCR writes the row first and the column second, grid[1,2]. Python uses a list of lists, so the same box is grid[1][2].

OCR reference language
array grid[3,4]
grid[1,2] = 9
Python
# array grid[3,4]: 3 rows, 4 columns
grid = [[0] * 4 for row in range(3)]
grid[1][2] = 9
print(grid)               # [[0, 0, 0, 0], [0, 0, 9, 0], [0, 0, 0, 0]]
Arrays and gridsTwo arrays. A one dimensional array called scores holds 12, 18, 0, 0 and 7 in positions 0 to 4, and scores at position 2 holds 0. There is no position 5. A two dimensional array called grid has three rows and four columns, all zero except one nine, in row 1, column 2, which is written grid, one, two, with the row index first and the column index second.One dimensional arrayTwo dimensional array120181020374positionscores[2]holds 0, the third boxPositions run from 0 to 4,so scores[5] does not exist.0123column000001009020000rowgrid[1][2]row 1, then column 2Rows first, then columns.
A grid is a list of rows. The first index picks the row, the second the box in it.
Never build the grid as [[0] * 4] * 3

That does not make three rows. It makes three names for one row, so changing a box in one row changes it in all of them.

Python
wrong = [[0] * 4] * 3
wrong[1][2] = 9
print(wrong)              # [[0, 0, 9, 0], [0, 0, 9, 0], [0, 0, 9, 0]]

Going through a table

An outer loop for the rows, and an inner loop for the columns. The inner loop runs all the way round for every single pass of the outer one.

Python
marks = [
    [56, 61, 70],
    [72, 68, 75],
    [38, 45, 40],
    [90, 85, 94],
]

for row in range(len(marks)):
    total = 0
    for col in range(len(marks[row])):
        total = total + marks[row][col]
    print("Student", row, "average", round(total / 3, 1))

The total is set to 0 inside the outer loop, so each student starts afresh. Move that line above the outer loop and every student's total includes the one before.

To go down the columns instead, swap the loops, and the outer loop is now the column:

Python
marks = [
    [56, 61, 70],
    [72, 68, 75],
    [38, 45, 40],
    [90, 85, 94],
]

for col in range(3):
    best = 0
    for row in range(4):
        if marks[row][col] > best:
            best = marks[row][col]
    print("Best in test", col, "is", best)

A board game

Noughts and crosses is a 3 by 3 array of characters. Checking a row is one comparison:

Python
board = [["X", "X", "X"],
         ["O", "X", "O"],
         [" ", "O", " "]]

for row in range(3):
    if board[row][0] == board[row][1] == board[row][2] == "X":
        print("X wins on row", row)
Rows first, then columns

marks[row][col]. The first index picks a list inside the big list, and the second picks an item inside that list. If you are unsure which is which, draw the table and write the row and column numbers round the outside before you write any code.

Records

An array holds many items of one type. A record holds the facts about one thing, and those facts can be of different types. Each fact is a field.

OCR reference language
record Student
    name : string
    age : integer
    passed : Boolean
endrecord

Python has no record type at this level. A dictionary does the job, with the field names as keys.

Python
student = {"name": "Asha", "age": 15, "passed": True}
print(student["name"], student["age"])      # Asha 15
student["age"] = 16
print(student)             # {'name': 'Asha', 'age': 16, 'passed': True}

An array of records

A list of dictionaries is a table where each row is one record. This is the structure behind nearly every real program that stores people, products or scores.

Python
students = [
    {"name": "Asha", "age": 15, "mark": 56},
    {"name": "Ben", "age": 16, "mark": 71},
    {"name": "Chloe", "age": 15, "mark": 38},
]

for s in students:
    print(s["name"], "is", s["age"], "and scored", s["mark"])

print(students[1]["name"])          # Ben, the second record

for s in students:
    if s["mark"] < 50:
        print(s["name"], "needs a resit")      # Chloe needs a resit

A class gives a record named, checked fields. It is more than the GCSE needs, but it is how larger programs do it:

Python
from dataclasses import dataclass

@dataclass
class Student:
    name: str
    age: int
    passed: bool

asha = Student("Asha", 15, True)
print(asha.name, asha.age)      # Asha 15
print(asha)                     # Student(name='Asha', age=15, passed=True)

Why records beat parallel arrays

Parallel arraysArray of records
Keeping items togetherOnly by discipline, one index at a timeThe record moves as one unit
SortingEvery array has to be swapped in stepSwap whole records
Adding a fieldA new array and new code everywhereA new key
Resemblance to a databaseLittleA table: record is a row, field is a column
A record is a row of a database table

When you reach SQL in a later topic, the table is the array, each row is a record, and each column is a field. The ideas are the same.

Text files

Variables vanish when a program ends. A file keeps data after it does. The exam uses text files: lines of characters, read and written one at a time.

OCR reference languagePython
newFile("scores.txt")open("scores.txt", "w")
myFile = open("scores.txt")file = open("scores.txt")
myFile.readLine()file.readline() or for line in file
myFile.endOfFile()the for line in file loop ends by itself
myFile.writeLine("text")file.write("text\n")
myFile.close()file.close()

writeLine adds the end of line for you. Python's write does not, so you add \n yourself.

Open modes

ModeDoesIf the file already exists
"r"Read onlyReads it. Error if it does not exist
"w"WriteErases everything and starts again
"a"AppendKeeps it and adds to the end
Python
file = open("scores.txt", "w")
file.write("Asha,56\n")
file.write("Ben,71\n")
file.write("Chloe,38\n")
file.close()

file = open("scores.txt", "r")
for line in file:
    print(line.strip())
file.close()

Each line read from a file still has its \n on the end. strip() takes it off. Forget it and every printed line is followed by a blank one, and a number read this way carries a newline into every comparison.

Files in the browser

When you press Run on this page the file is created in a small private disk that lives in your browser tab. It disappears when you close the tab, so write it and read it back in the same program, as these examples do.

Reading records from a file

Each line is one record and the commas separate the fields. split(",") cuts a line into a list, and everything read from a file is text, so a number must be cast.

Python
file = open("scores.txt", "w")
file.write("Asha,56\nBen,71\nChloe,38\n")
file.close()

students = []
file = open("scores.txt")
for line in file:
    name, mark = line.strip().split(",")
    students.append({"name": name, "mark": int(mark)})
file.close()

total = 0
for s in students:
    total = total + s["mark"]
print(students[0])                    # {'name': 'Asha', 'mark': 56}
print("Average", total / len(students))      # Average 55.0

Closing for you

The with statement closes the file when its block ends, even if something goes wrong inside it, so you cannot forget.

Python
with open("log.txt", "w") as file:
    file.write("first\n")

with open("log.txt", "a") as file:
    file.write("second\n")

with open("log.txt") as file:
    first = file.readline()
    rest = file.readlines()
print(repr(first), rest)           # 'first\n' ['second\n']

A file that is not there

Python
try:
    file = open("missing.txt")
except FileNotFoundError:
    print("That file does not exist yet")
Closing the file is a mark

If a question says "write a program that reads a file", the mark scheme has a separate mark for closing it. Either call close() or use with.

Reading, writing and appending to a text fileThree ways to open a text file, one card each. Opening with mode r reads the file: the program looks at the lines, nothing in the file changes, and it is an error if the file does not exist. Opening with mode w writes: it creates the file if it is missing, but if it exists everything in it is erased first, so a file that held two lines ends up holding only the new line. Opening with mode a appends: the new line is added to the end and the old lines are kept. The code below uses the with statement, which closes the file automatically, and writes the line Tia comma 51 followed by a newline character. Always close a file, because unwritten data may stay in a buffer and never reach the disk."r" readbeforeAsha,42Tom,37"w" writebeforeAsha,42Tom,37"a" appendbeforeAsha,42Tom,37programreads each linethe file is not changederror if it does not existTia,51erases what was therecreates the file if missingAsha,42Tom,37Tia,51adds to the endkeeps what was theresave.py1with open("scores.txt", "a") as f:2    f.write("Tia,51\n")with closes the file for you\n starts a new linea is safer than w for addingalways close a file, or the last lines may never reach the disk1234
  1. r reads. The file is only looked at, and it must already exist.
  2. w writes. Everything already in the file is erased first.
  3. a appends. New lines go on the end and the old ones are kept.
  4. with closes the file for you, and \n ends a line.
If you mean to add to a file, open it with a. Opening it with w by mistake wipes it.

Key terms you must be able to define

Array
A fixed size, numbered collection of items that are all the same data type, indexed from 0.
Index
The number that identifies one item in an array. The first is 0.
Two dimensional array
An array of arrays, organised as rows and columns, accessed with two indexes.
Record
A collection of related fields, which may be different data types, describing one thing.
Field
One named item of data inside a record, such as name or age.
Parallel arrays
Two or more arrays where the items at the same index belong together.
Linear search
Checking each item in turn from the start until the one wanted is found or the end is reached.
Text file
A file of characters organised in lines, read and written by a program one line at a time.
Append mode
Opening a file so that new data is added to the end and existing data is kept.

Flashcards

Say the definition out loud before you flip the card. Retrieving it from memory is what builds recall, reading it again is not.

DefineArray
AnswerA fixed size, numbered collection of items that are all the same data type, indexed from 0.
DefineIndex
AnswerThe number that identifies one item in an array. The first is 0.
DefineTwo dimensional array
AnswerAn array of arrays, organised as rows and columns, accessed with two indexes.
DefineRecord
AnswerA collection of related fields, which may be different data types, describing one thing.
DefineField
AnswerOne named item of data inside a record, such as name or age.
DefineParallel arrays
AnswerTwo or more arrays where the items at the same index belong together.
DefineLinear search
AnswerChecking each item in turn from the start until the one wanted is found or the end is reached.
DefineText file
AnswerA file of characters organised in lines, read and written by a program one line at a time.

Reach the top grade on this topic

Marks on data structure questions are awarded for the shape of the loop and for the details that beginners drop.

  • Start a maximum or minimum at the first item of the array, never at zero
  • Reset a running total inside the outer loop of a two dimensional array
  • Put the not found result after the loop, never inside it
  • Cast every value read from a file, and strip the newline from every line
  • Close every file you open, or use with, and say which mode you want and why

Mistakes that cost marks here

Avoid these
  • Treating positions as starting at 1, so the last item is one position out of range.
  • Starting a highest value at 0, which fails when the values are all negative.
  • Opening a file in write mode to add a line, which erases everything already in it.
  • Swapping the row and column indexes in a two dimensional array.
  • Forgetting to cast a value read from a file, so that 56 is added as text.
Fun fact

A 1 megabyte text file of names and marks is about the same size as a single photograph from an old phone, yet it can hold more than fifty thousand records. Text is a very compact way to store data.

Knowledge check

0 of 10 answered
1What is the index of the first item in an array?
2names = ["Ann", "Bo", "Cy"]. What happens when names[3] runs?
3Which line builds a 3 row by 4 column grid of zeros with three separate rows?
4In OCR reference language grid[1,2] is row 1, column 2. How is it written in Python?
5Two parallel arrays hold names and marks. What makes them work?
6What is a record?
7Which file mode erases the existing contents of the file?
8A line read from a file is "Asha,56\n". Which method removes the newline?
9students is a list of dictionaries. Which expression is the mark of the third student?
10What is the main advantage of using with open(...) as file?
Score 0 / 10

Exam-style questions

Five written questions in the style of the real paper. Write a full answer, then let the marker check it against the mark scheme.

16 marks
1Give two differences between an array and a record.2 marks
Give

Mark scheme0 / 2
  • LAn array holds items that are all the same data type, a record can hold different data types
  • LAn array is accessed by a numeric index, a record by the name of a field
  • LAn array holds many values of one kind, a record holds the facts about one item
Model answer

An array stores a number of items that must all be the same data type and each is found by its numeric position. A record stores a set of related fields about one thing, and the fields can be different data types, such as a string for a name and an integer for an age, each found by the name of the field.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
2A two dimensional array named marks stores the results of 5 students in 3 tests, one student on each row. Write a program that outputs the total of each student's three marks.4 marks
Write

Mark scheme0 / 4
  • LOuter loop that repeats once for each of the 5 students
  • LSets the total to 0 inside the outer loop, before the inner loop
  • LInner loop over the 3 tests adding marks[student][test] to the total
  • LOutputs the total after the inner loop, once per student
Model answer

The outer loop picks a student, the inner loop adds up that student's three tests, and the total is printed once the inner loop has finished.

Python
marks = [[56, 61, 70], [72, 68, 75], [38, 45, 40], [90, 85, 94], [60, 60, 62]]   # given in the question

for student in range(5):
    total = 0
    for test in range(3):
        total = total + marks[student][test]
    print(total)
The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
3A text file called scores.txt holds one whole number on each line. Write a program that reads the file and outputs the highest number in it.4 marks
Write

Mark scheme0 / 4
  • LOpens the file for reading and closes it
  • LReads each line using a loop until the end of the file
  • LConverts each line to an integer
  • LCompares with the highest so far, updates it, and outputs it after the loop
Model answer

Everything read from a file is text, so each line is cast to an integer before it is compared. The highest value is output once the whole file has been read.

Python
file = open("scores.txt", "w")        # set up the file the question describes
file.write("56\n71\n38\n90\n64\n")
file.close()

file = open("scores.txt", "r")
highest = int(file.readline())
for line in file:
    number = int(line)
    if number > highest:
        highest = number
file.close()
print(highest)
The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
4A program stores student names in one array and their marks in a second array. Describe one problem with parallel arrays and explain how using records solves it.3 marks
Describe

Mark scheme0 / 3
  • LThe arrays are only linked by position
  • LIf one array is changed or sorted and the other is not, the data no longer matches
  • LA record keeps all the fields for one student together so they cannot separate
Model answer

In parallel arrays the only thing connecting a name to a mark is that they sit at the same index. If the names are sorted or one item is deleted but the marks array is not changed in the same way, the data goes out of step and a mark is attached to the wrong student. With a record, the name and the mark are fields of one record, so they are always kept together and move as one unit.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
5Describe the difference between opening a file in write mode and in append mode.3 marks
Describe

Mark scheme0 / 3
  • LWrite mode replaces any existing contents of the file
  • LAppend mode keeps the existing contents
  • LAppend mode adds new data to the end of the file
Model answer

Opening a file in write mode removes everything that was already stored in it and starts again from an empty file, so only the newly written data remains. Opening it in append mode keeps everything that is already there, and any new data is added after it, at the end of the file.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
Machine mark 0 / 16