Programming with Objects

OOP Files and Array

Part 3 of the Paper 4 OOP chapter — the classic 'load and process' task: read records from a text file, turn each into an object, store them in a fixed array with a counter, linear-search the array, and wrap the file work in try/except so a missing file doesn't crash the program. Ends with a full library inventory exam question with mark scheme.

23.1 Introduction: From Text File to Array of Objects

Programs rarely keep their data typed into the code. Instead the data lives in a text file, and the program loads it when it runs. In OOP that means: read each record from the file, build one object from it, and collect the objects in an array so you can search and process them.

This is one of the most common Paper 4 long-answer shapes. By the end of this page you will read records into objects, store them in an array with a counter, search the array, and wrap the file work in exception handling so a missing file does not crash the program.

What this page covers
  • OOP combined with text-file processing and arrays.
  • It assumes the class basics from Part 1 and private attributes from Part 2.
TermMeaning
RecordOne item’s worth of data in a file — here, the lines (or one comma-separated line) that describe a single object.
Array of objectsA fixed-size list whose elements are objects, e.g. 30 Book objects.
CounterAn integer that tracks how many objects have actually been stored, separate from the array’s capacity.
Linear searchChecking each element of the array in turn until a match is found or the end is reached.
ExceptionAn error that happens while the program runs, such as opening a file that does not exist.
Exception handlingCode (try / except) that catches an exception so the program reports it instead of crashing.

23.2 Reading a Text File into Objects

Why are we doing this?
  • Hard-coding data is fine for a demo, but a real catalogue lives in a file.
  • The skill the exam tests is the bridge: read a record, hand its fields to a constructor, and you have an object.
  • Repeat to the end of the file and you have your whole data set as objects.
Exam tip:
  • Examiner focus: “Load records from a text file into an array of objects, using exception handling” is a standard Paper 4 long-answer worth 6 to 8 marks.
  • It blends section 20.1 (OOP) with section 20.2 (file processing and exception handling).

Start with a class for one record. Here each animal in a zoo has a name, species and age, stored as private attributes with a display method.

class Animal:
    def __init__(self, name, species, age):
        self.__name    = name      # private
        self.__species = species   # private
        self.__age     = age       # private

    def get_name(self):
        return self.__name

    def display_info(self):
        print("Name:", self.__name, "Species:", self.__species, "Age:", self.__age)

If the file stores each animal on three consecutive lines (name, species, age), read three lines, build one object, and append it to a list. strip() removes the trailing newline; int() converts the age.

zoo = []                       # list to hold Animal objects
file = open("Animals.txt", "r")
for i in range(3):             # three animals in the file
    name    = file.readline().strip()
    species = file.readline().strip()
    age     = int(file.readline().strip())
    zoo.append(Animal(name, species, age))
file.close()

for animal in zoo:
    animal.display_info()

# Animals.txt:
# Leo
# Lion
# 5
# Bella
# Elephant
# 10
# ...
Key rule To load objects: open the file, read one record, pass its fields to the constructor, append the object to the array, repeat until the end of the file, then close the file.
Exam tip:
  • Read the file format carefully.
  • Three-lines-per-record needs three readline()s; one comma-separated line per record needs one readline() then split(",").
  • Using the wrong pattern loses the reading marks.

23.3 A Fixed Object Array and a Counter

Why are we doing this?
  • Exam questions often require a fixed-size array (e.g. up to 30 objects) rather than a growable list, because the syllabus array has a set length.
  • You then need a separate counter so you know how many slots are actually used, and an initialise step that empties the array first.

Declare the array with a capacity, initialise every slot to None, and keep an integer total of how many objects are stored. Store each new object at index total, then add 1 — but stop if the array is full.

MAX = 30
book_list = [None] * MAX     # global array of up to 30 Book objects
total = 0

def initialise_array():
    global total
    for i in range(MAX):
        book_list[i] = None
    total = 0
Task — Worked Example 20.2.2B — Store a new object in the next free slot
Store a new object b in the next free slot of book_list, or print "List full".
Hint:
  • The counter total is both the next index and the count.
  • Check if total < MAX; if so store at book_list[total] and add 1; else print “List full”.
Your Turn — Your Turn 20.2.2B — Count available books
Count how many stored books in book_list have get_status() equal to "Available".
Hint:
  • Loop the first total slots and count matches.
Key rule
  • A fixed array has a capacity (its length) and a count (how many slots are filled).
  • Keep them separate: store at index count, then increase count; never write past the capacity.
Exam tip: When asked to “initialise the array”, the mark is for a loop setting every element to null/None and resetting the counter to 0 — not just declaring the array.

23.4 Linear Search and Exception Handling

Why are we doing this?
  • After loading objects you usually must find one — a linear search returns the index of a match, or -1 if there is none.
  • And because a file might be missing or corrupt, the syllabus requires exception handling around file work so the program reports the problem instead of crashing.
Exam tip: Examiner focus: Exception handling and serial/sequential/random file operations are listed in section 20.2 and are routinely combined with the OOP load task in Paper 4.

A linear search loops through the stored objects, comparing a getter's value to the target. Wrap the file open/read in try / except so a FileNotFoundError is caught.

def find_book(title_to_find):
    for i in range(total):
        if book_list[i].get_title() == title_to_find:
            return i        # found: return the index
    return -1               # not found

def load_books():
    try:
        file = open("Books.txt", "r")
        line = file.readline()
        while line != "":
            title, status = line.strip().split(",")
            store_book(Book(title, status))
            line = file.readline()
        file.close()
    except:
        print("File could not be opened.")
Task — Worked Example — find_book(title) [3 marks]
Write program code (AO3). Write a function find_book(title) that returns the index of the matching book in book_list, or -1 if not found. [3]
Hint:
  • Step 1 — loop the stored slots: range(total).
  • Step 2 — compare and return: return the index on a match.
  • Step 3 — not found: return -1 after the loop.
Your Turn — Your Turn — find_animal(name) [3 marks]
Write program code (AO3). Write a function find_animal(name) that returns the index of the matching animal in zoo (a list of total objects), or -1 if not found. [3]
Hint:
  • Identical shape; use get_name().
Key rule
  • A linear search returns the index of the first match, or -1 when nothing matches.
  • Always wrap file open and read operations in try / except so a missing or unreadable file is handled, not fatal.
Exam tip:
  • Returning -1 for “not found” matters because 0 is a valid index.
  • Code that returns 0 on failure will look like it found the first element — examiners check for a non-index sentinel such as -1.

23.5 Full Exam-Style Question

Paper 4 · OOP + files · ~14 marks
  • A library stores its catalogue in Books.txt.
  • Each line holds a title and a status separated by a comma, for example Dune,Available.

(a) Write program code to declare a class Book with private attributes Title and Status, a constructor, GetTitle(), GetStatus() and SetStatus(newStatus). [4]

(b) Declare a global array BookList for up to 30 Book objects and a procedure InitialiseArray() that sets every element to null and the counter to 0. [4]

(c) Write a procedure LoadBooks() that opens Books.txt, reads each line to the end of file, splits it into title and status, stores a new Book in the next slot (or outputs "List full"), and uses exception handling. [6]

Lab Task — Show full solution & mark scheme
Reveal the model solution and mark scheme for parts (a)–(c).
Hint:
  • (a) class Book with __init__(self, title, status) storing two private attributes; GetTitle, GetStatus, SetStatus.
  • (b) BookList = [None] * 30; total = 0; InitialiseArray loops setting every element to None and resets total.
  • (c) try: open file; while line != "": split(","); if total < MAX store Book and add 1, else print “List full”; readline; close; except: print error.

Key Points Summary

The classic Paper 4 "load and process" task: read records from a text file, turn each into an object, store them in an array, and search the array — with exception handling around the file work.
A record is one item's worth of data in a file — the lines (or one comma-separated line) that describe a single object. Each record becomes one object when loaded.
The load pattern: open the file, read one record, pass its fields to the constructor, append the object to the array, repeat until the end of the file, then close the file.
Three-lines-per-record needs three readline() calls (one per field), each with .strip(). Use int() to convert numeric fields like age.
One comma-separated line per record needs one readline() then split(",") to get the fields. Using the wrong pattern loses the reading marks.
strip() removes the trailing newline (\n) that readline() includes, plus any other leading/trailing whitespace. Always use it when reading from a file.
Exam questions often require a fixed-size array (e.g. up to 30 objects) because the syllabus array has a set length. Declare it with [None] * MAX.
A fixed array has a capacity (its length, MAX) and a count (how many slots are filled, total). Keep them separate — never write past the capacity.
Store a new object at index total, then total = total + 1 (if total < MAX, else print "List full"). The counter total is both the next free index and the count.
"Initialise the array" = a loop setting every element to None AND resetting the counter to 0 — not just declaring the array.
A linear search loops through the stored objects (range(total)), comparing a getter's value to the target, and returns the index of the first match.
A linear search returns -1 for "not found" — never 0, because 0 is a valid index (the first element). Examiners check for a non-index sentinel like -1.
Loop through range(total) in a linear search — the slots that actually contain objects. Going past total hits None slots and crashes when you call a getter.
Wrap file open and read operations in try / except so a missing or unreadable file (FileNotFoundError) is caught and reported, not fatal.
Exception handling is required by the syllabus (section 20.2) and is routinely combined with the OOP load task in Paper 4.

23.6 Practice Tasks

Fifteen exam-style tasks. Click Hint for bullet-point guidance, then Help to reveal a worked Python solution.

1Practice Task — Read three-line records into objects [5 marks]
A Student class has __init__(self, name, form, year). Students.txt stores each student on three lines (name, form, year). Read 4 students into a list and display each.
2Practice Task — Read comma-separated records into objects [5 marks]
A Book class has __init__(self, title, status). Books.txt stores one book per line as title,status (e.g. "Dune,Available"). Read all books to EOF into a list and display each.
3Practice Task — Declare a fixed array and initialise [3 marks]
Declare a global array PlayerList for up to 20 Player objects, a counter total, and an InitialiseArray() that sets every element to None and total to 0.
4Practice Task — Store in the next free slot [3 marks]
Write a procedure store_player(p) that stores p in the next free slot of PlayerList, or prints "List full".
5Practice Task — Count matching objects [3 marks]
Count how many stored books in BookList have get_status() equal to "Borrowed".
6Practice Task — Linear search by title [3 marks]
Write a function find_book(title) that returns the index of the matching book in BookList, or -1 if not found.
7Practice Task — Linear search by name [3 marks]
Write a function find_animal(name) that returns the index of the matching animal in zoo (total objects), or -1 if not found.
8Practice Task — Load with exception handling [6 marks]
Write a procedure load_books() that opens Books.txt, reads comma-separated lines to EOF, stores Book objects (or prints "List full"), and uses try/except to handle a missing file.
9Practice Task — Why return -1 not 0? [2 marks]
Explain why a linear search should return -1 (not 0) for "not found".
10Practice Task — Three-line vs comma-separated [2 marks]
A file stores each record on three lines. A student reads one line and split(","). What is wrong, and what is the fix?
11Practice Task — Initialise array marks [2 marks]
A student wrote `book_list = [None] * 30` for "initialise the array". Why does this lose marks, and what is the fix?
12Practice Task — Find and update [5 marks]
Write a procedure borrow_book(title) that finds the book by title in BookList (using find_book), and if found sets its status to "Borrowed" (using SetStatus); otherwise prints "Not found".
13Practice Task — Full class + array + load + search [12 marks]
Write a class Song (title, artist) with getters. Declare a global array SongList (MAX 50) and counter. Write InitialiseArray(), LoadSongs() (comma-separated, exception handling), and find_song(title) returning the index or -1.
14Practice Task — Pseudocode class + array [4 marks]
In Cambridge pseudocode, declare a class Book with PRIVATE Title and Status, a constructor NEW, and a PUBLIC FUNCTION GetTitle that returns the title.
15Practice Task — Exam-style: full library program [14 marks]
(a) Write a class Book with private Title and Status, constructor, GetTitle, GetStatus, SetStatus [4]. (b) Declare BookList (30) and InitialiseArray [4]. (c) Write LoadBooks with exception handling [6].

Question Bank

Answer all questions, then press Submit Quiz to see your score.

0/12 answered

Question 1Multiple Choice

A record in a text file is:

Question 2Multiple Choice

The load pattern (file to objects) is:

Question 3True / False

Three-lines-per-record needs three readline() calls; one comma-separated line per record needs one readline() then split(",").

Question 4Multiple Choice

Why use a fixed-size array with a counter in the exam?

Question 5Multiple Choice

How do you store a new object in a fixed array with a counter?

Question 6Multiple Choice

A linear search of an object array returns:

Question 7Multiple Choice

How many slots does a linear search loop through?

Question 8True / False

Exception handling (try/except) around file work prevents the program crashing on a missing file.

Question 9Multiple Choice

What does .strip() do when reading a line from a file?

Question 10Multiple Choice

What is "initialise the array" in the exam?

Question 11Multiple Choice

In the Book exam question, LoadBooks() is worth how many marks?

Question 12Multiple Choice

Why return -1 (not 0) for "not found" in a linear search?

Answer all 12 questions to enable submission.