Software Design & Development · Implementation

SDD11 — File Handling: Reading

📅 Mon 7 Sep 2026 · P1+P2 (double)
~120 minutes
Learning intentions
Success criteria
📥 Files for this lesson

Download these into the same PyCharm project folder as your .py file before working through the examples and Task Set A — the code in this lesson expects notice.txt and tuckshop.csv to already exist alongside it.

Warm up — recap from SDD10
Answer all three questions, then check your answers.
Question 1
Which pre-defined function converts a floating-point number to an integer by truncating it, rather than rounding it?
Question 2
What is the value of "Higher Computing".split(" ")?
Question 3
What is the value of 23 % 5?

Key vocabulary

File handling
Reading data from, or writing data to, a file stored outside the program, so data survives after the program ends.
Sequential file
A file whose contents are accessed in order, from the beginning to the end, rather than jumping to a specific position.
CSV (comma-separated values)
A plain text file format that stores tabular data, with each line one record and each field separated by a comma.
Delimiter
The character used to mark where one piece of data ends and the next begins — a comma in a CSV file, a newline between lines.
.strip()
A string method that removes whitespace (including newline characters) from the start and end of a string.

Reading data from a file

Why use file handling at all?

Every program built so far in this course has stored its data only in variables and arrays — the moment the program stops running, that data is gone. File handling solves this by reading data from, or writing data to, a file stored outside the program, so it survives between one run and the next. This lesson covers reading; SDD12 covers writing. Higher only requires sequential file access, meaning a file's contents are read in order from the beginning, not jumped to at a specific position.

Opening, reading, and closing a file

Three pre-defined functions/methods handle the basic lifecycle of reading a file. open(filename, mode) opens a file and returns a file object that the rest of the code works with; the mode "r" means read. Calling .read() on that file object returns the entire contents of the file as one single string — including any newline characters that separated the original lines. Finally, .close() releases the file once the program is finished with it. Forgetting to close a file can leave it locked or cause data not to be saved properly when writing (SDD12) — always close what was opened.

From one big string to individual lines

.read() returns everything as a single string, with each original line separated by a newline character, "\n". To work with the data one line at a time, that whole string must be broken apart using split("\n") — the pre-defined function met in SDD10, used here with a newline as the delimiter instead of a space. This turns one long string into a list, with each item in the list being one line (one record) from the file.

From one line to individual fields — reading CSV data

A CSV file stores several fields on each line, separated by commas — for example Chocolate,75,30 stores a name, a price, and a stock level as one line. Once split("\n") has produced a list of individual lines, split(",") is applied again, this time to each individual line, to break it into its separate fields. This is why reading a CSV file typically needs split() used twice, with two different delimiters: once for the whole file (splitting on "\n" to get lines), and once per line (splitting on "," to get fields).

Converting fields after reading them

Every single value produced by split() is a string — even a field that looks like a whole number, such as "75", is read as the text characters 7 and 5, not the number 75. Any field that needs to be used as a number (added, compared, or used in a calculation) must be explicitly converted using int() (SDD10) before it can be used that way. Skipping this step doesn't raise an error immediately — Python will happily let two string fields be joined with + — but the result is string concatenation, not addition, producing a wrong answer that runs without complaint.

Cleaning up with .strip()

If a file ends with a newline character (which most text editors add automatically), splitting the whole file's text on "\n" produces one extra, empty item at the end of the list. Similarly, the very last field on a line can end up with a trailing "\n" still attached to it if .read()'s result isn't cleaned up first. Calling .strip() on the whole file's text, before splitting it into lines, removes this leading/trailing whitespace and prevents both problems.

1
Open the file
file = open("tuckshop.csv", "r") — opens the file in read mode and returns a file object.
2
Read and clean the contents
fileText = file.read().strip() — reads the whole file as one string, then removes any trailing newline.
3
Split into lines, then split each line into fields
lines = fileText.split("\n") then, for each line, fields = line.split(",") — two separate delimiters, two separate steps.
4
Convert and store each field
Numeric fields are converted with int() before being stored, e.g. as an Item record.
5
Close the file
file.close() — always close a file once the program is finished reading from it.

Worked examples

Example 1 — Reading a plain text file
1
A file notice.txt contains one line of text: Tuck shop closes early on Fridays.
file = open("notice.txt", "r")
noticeText = file.read()
file.close()
2
open() returns a file object in read mode; .read() loads the entire file's contents into noticeText as one string; .close() releases the file.
noticeText is "Tuck shop closes early on Fridays" — a single string, ready to be printed or processed further.
Example 2 — Splitting a CSV file into lines and fields
1
tuckshop.csv contains five lines, one per item:
Chocolate,75,30
Crisps,63,45
Juice,90,20
Flapjack,110,15
Sweets,50,60
2
file = open("tuckshop.csv", "r")
fileText = file.read().strip()
file.close()

lines = fileText.split("\n")
for line in lines:
    fields = line.split(",")
    print(fields)
lines has 5 items, one per row. Each fields is a 3-item list of strings, e.g. ['Chocolate', '75', '30'] — note every value, including '75' and '30', is still text, not a number.
Example 3 — Converting fields into an array of records
1
Using the same Item @dataclass from SDD6–10:
from dataclasses import dataclass

@dataclass
class Item:
    name: str
    price: int
    stock: int

itemRecords = []
2
Each line's fields are converted before being stored — fields[1] and fields[2] are passed through int(), but fields[0] (the name) is left as a string:
for line in lines:
    fields = line.split(",")
    newItem = Item(fields[0], int(fields[1]), int(fields[2]))
    itemRecords.append(newItem)
itemRecords[0] is Item(name='Chocolate', price=75, stock=30)price and stock are now genuine integers, so itemRecords[0].stock can be used directly in a calculation.
Example 4 — Using the converted data, and the int()/round() reminder
1
With all five records read and converted, a running total of stock is calculated exactly as in SDD6:
totalStock = 0
for item in itemRecords:
    totalStock = totalStock + item.stock
2
Separately, an average price is calculated from the five prices (75, 63, 90, 110, 50), then handled with both int() and round() to recall SDD10's distinction:
totalPrice = 0
for item in itemRecords:
    totalPrice = totalPrice + item.price
averagePrice = totalPrice / len(itemRecords)
totalStock is 170 (30+45+20+15+60). averagePrice is 77.6; int(averagePrice) gives 77 (truncated) while round(averagePrice) gives 78 (rounded) — neither of these calculations would have been possible if price and stock had been left as strings straight from the file.
Now you try
A line read from a CSV file is stored in the variable line, containing the text "Muffin,120,18". Write the Python code needed to split this line into its three fields and store the price as an integer in a variable called price.
⚠️ Common mistakes — examiner feedback
📝 Exam tip

When describing how to read CSV data, name the exact sequence: open, read, split on newline, split each line on comma, convert fields, close — a vague answer like "read the file and get the data out" will not gain full marks. If a question shows a field being used in a calculation, always check whether an int() conversion is missing before assuming the rest of the logic is wrong.

Task Set A — Core questions

Task Set A — Core questions
Work through all questions, then check your answers.
Question 1
Which pre-defined function opens a file and returns a file object ready to be read from?
Question 2
Which mode, passed as the second argument to open(), opens a file for reading?
Question 3
What does .read() return when called on an open file object?
Question 4
A CSV line reads "Muffin,120,18". What is the value of "Muffin,120,18".split(",")[1]?
Question 5
What type is the value "Muffin,120,18".split(",")[1], before any further conversion?
Question 6
What value does the string concatenation "75" + "30" produce, if the int() conversion is forgotten?
Question 7
Explain why reading a CSV file typically requires split() to be called twice, using two different delimiters. (3 marks)
Question 8
A file's text ends with a newline character. What happens if .strip() is not called before splitting the whole text on "\n"?
Question 9
Write Python code that opens "tuckshop.csv" for reading, reads and strips its contents, splits it into lines, then splits each line into fields and prints the resulting list of fields for every line. Remember to close the file.
file = open("tuckshop.csv", "r")
fileText = file.read().strip()
file.close()

lines = fileText.split("\n")
for line in lines:
    fields = line.split(",")
    print(fields)
Question 10
Explain why the stock field should be converted with int() immediately after being read from a CSV file, rather than left as a string until it is needed later in the program. (3 marks)

Task Set B — Extension

Task Set B — Extension · Beyond the specification
Longer written answers — no auto-check. Discuss your answers with your teacher.
Extension 1
A CSV file is supposed to have three fields per line, but one line is missing a value. Predict what happens when the code tries to access fields[2] on that line, and explain why.
Extension 2
Research Python's built-in csv module. Suggest one advantage it might have over the manual split()-based approach used in this lesson, and one reason a learner might still be taught the manual approach first.
Extension 3
SDD12 will cover writing data to a file. Suggest what you think the reverse process of this lesson's reading process might look like — what would need to happen to data before it could be written back into a CSV file in the correct format?
📁 File this in OneNote under:
Higher Computing Science → Software Design & Development → SDD11
📌 Teacher notes — not for pupils

Double period. Reviewed a colleague's equivalent teaching material (Lessons 7–8, file handling) ahead of this build — confirmed the manual double-split() approach (no csv module) and .strip()-after-.read() are both consistent with what's taught in the parallel course, so this lesson matches that convention deliberately, not by coincidence.

Suggested timing: 5 min warm-up + vocab · 25 min notes + file-flow pipeline walkthrough (run each step live in the Python shell rather than only showing static code) · 30 min examples 1–4 · 10 min "now you try" · 40 min Task Set A · Task Set B as homework/extension.

Key misconception: pupils very reliably forget that every field from split() is a string, including ones that look numeric — the silent string-concatenation bug ("75" + "30""7530") is worth demonstrating live, since it produces a plausible-looking but wrong number rather than an obvious error.

Bug to avoid repeating from the colleague's material when SDD12 (writing) is built: one worked example there concatenated a non-string dataclass field directly with + without wrapping it in str() first, which raises a TypeError — verified by actual Python execution this session. SDD12 must cast every non-string field with str() before writing it out.

SQA command words covered: explain, describe, predict, write code.