VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Ministry of Education V3.0 Reference 363 | G3 Computing Python File Handling: Read the Record, Write the Result

University learner using a computational notebook with visibly out-of-order cell counters and restart and run icons

Did you know that a Python program can calculate the correct answer, print it on the screen and still fail a file-handling task? If the instructions require the result in output.txt, a correct console message is not the requested deliverable. File input and output teach a more durable skill: information must travel from the correct source through a correct computation to the correct destination.

Ministry of Education V3.0 Reference 363 teaches the 2027 Singapore–Cambridge SEC G3 Computing K349 skill of non-interactive file input/output with open(), read(), readline(), write() and close(). The article shows how to read an entire text file, consume records line by line, write and replace a text file, avoid exhausting a file before a second read, manage line breaks and distinguish strings from numbers. Students and tutors get original runnable practice, a twelve-stage workflow, twenty-four worked cases, safe test data and explanations tied to the official Python quick-reference guide.

This is an independent eduKateSG study guide, not an official MOE, SEAB or Cambridge examination publication. Every filename and record below is invented; do not overwrite school files or use real student records when practising. Some additional Python conveniences are explained for understanding but the official K349 syllabus and quick-reference guide govern examination scope. Code shown in a learning article should be run only in a permitted working folder.

A two-minute orientation: a file is not a keyboard prompt

Interactive input comes through input(), and console output through print(). A file-handling task instead works with named resources on storage. The program opens the file, reads stored characters, processes them, and optionally opens a separate file for output. File reading does not require a person to type each record while the program runs.

At the start of a task, draw three boxes: source file, Python transformation, destination file. Label the contents of each with an example. A program can be correct in its arithmetic but wrong if its source contains old data, if the output goes to the wrong place, or if the file is accidentally overwritten. Good computational thinking therefore checks the whole data path.

1. Read the exact official 2027 examination boundary

The K349 Module 2.3.4 outcome names the open() built-in function and read(), readline(), write() and close() methods for non-interactive file input/output. The quick-reference guide on page 15 demonstrates f = open(‘input.txt’,’r’), f.readline(), f.read(1), f.close(), and a with-open output example. These are the central techniques studied in this reference.

The full G3 Computing examination includes a lab-based Paper 2 using Python, spreadsheets and JupyterLab. A candidate is responsible for saving specified work as instructed. Understanding this assessment context helps learners take output paths and filenames seriously, rather than treating file handling as a decorative topic.

2. What open() returns

Calling open(‘input.txt’,’r’) asks Python to open a file for reading in text mode and returns a file object when successful. A variable such as f holds a reference to that file object; it does not automatically contain the entire file text. The read operation must still be performed to obtain characters.

The second argument is the mode. ‘r’ is a reading mode; ‘w’ is a writing mode that creates the file or replaces the previous file contents. If a file does not exist when a program tries to read it, an error occurs unless a suitable handling strategy is present. This guide does not rely on advanced exception handling to hide that fundamental fact.

f = open("records.txt", "r")
text = f.read()
f.close()
print(text)

3. read() consumes the remaining file contents

Calling read() without an argument obtains the remaining contents from the file’s current position, in a string. When the read starts at the beginning, that is generally the whole text. This is convenient for short files but can use substantial memory for a very large one. The selected method should suit the task and file size.

A useful exam distinction is that read() returns text, not automatically a list of records or numeric values. A file containing three visible digits ‘120’ yields the string ‘120’, and adding another number requires appropriate conversion first. Do not assume a number-looking file has already been turned into an integer.

4. read(n) reads up to n characters, not n lines

A call such as read(1) returns up to one character at the current file position. A following read(2) resumes where the first left off. For a text file containing ‘ABCDE’, the first result is ‘A’, the second is ‘BC’, and a subsequent read() obtains the remaining ‘DE’. The file is not automatically rewound between calls.

This matters in trace questions. Students sometimes imagine that read(2) always returns the first two characters, even after another read. Think of an imaginary cursor advancing through the stream. The position changes as characters are consumed. If an exercise calls read() after all text has been read, the returned string is empty.

f = open("letters.txt", "r")
a = f.read(1)
b = f.read(2)
c = f.read()
f.close()
print(a, b, c)

5. readline() obtains a line at a time

A call to readline() returns the next line of text, including a line-ending character when one is present. For a two-line file, the first call returns the first line and the second returns the next. A third call at end of file returns an empty string. A line without a final newline remains a valid line and can be returned without that character.

A newline is part of the text stream, even if it is not obvious in a screenshot. When you use print() to display a string that already ends in a newline, print() normally adds another one, potentially creating a blank line. Do not assume an extra blank display line means the file has a missing record.

6. Know the meaning of the empty string at end of file

Python uses ” as a signal that a read operation has returned no more characters at the current position. In a typical text file, an empty line is instead represented by a newline character, such as ‘\n’, and is not the same as the empty string. This distinction supports a safe line-reading loop.

For example, a while loop can ask for another line and end when the result is ”. If a learner instead ends whenever a line looks blank, a legitimate blank record might terminate processing early. In data work, distinguish a blank line inside a file from the actual end of the file.

f = open("lines.txt", "r")
line = f.readline()
while line != "":
    print(line, end="")
    line = f.readline()
f.close()

7. write() stores strings in a file

When a file is opened in text-writing mode, write() sends a string into the file. It does not automatically add a newline after each call. If code writes ‘alpha’ and then ‘beta’ without a separator, the resulting text is ‘alphabeta’. To create separate lines, include a newline character deliberately.

The return value of write() is the number of characters written in text mode, not the name of the file. In a beginner task the essential result is the stored text. A program may call write() repeatedly for several records, but the programmer must provide separators, appropriate data conversion and a correct output path.

f = open("summary.txt", "w")
f.write("Group A: 12\n")
f.write("Group B: 9\n")
f.close()

8. Writing mode can destroy previous data

Opening an existing text file with mode ‘w’ truncates its previous contents. A learner who uses the same filename for input and output may therefore erase the source before processing begins. This is not a minor formatting problem: the data used for the computation may be lost.

For practice, choose distinct invented filenames such as input_demo.txt and output_demo.txt, and work inside an approved folder. Confirm the intended destination before executing. A good programmer protects the original data and verifies that the output file was created with the content required, not simply that the program ended without an error.

9. close() finishes the file operation

Calling close() closes the file handle. For a writable text file, closing also ensures buffered output is flushed through the normal file interface. It is poor practice to depend on the program process eventually ending as the sole method of finalising a file, particularly when the specification requires a saved artefact.

If the program crashes before close() is reached, some output may not have been completed. Python’s with-open pattern is valuable because it manages closing when control leaves the block, including on an exception. Both explicit close() and the with form appear in the official quick-reference guide, making the relationship useful to understand.

with open("result.txt", "w") as f:
    f.write("Completed\n")

with open("result.txt", "r") as f:
    print(f.read())

10. Distinguish file creation from reading an existing source

Reading usually assumes that the named source already exists. Writing with mode ‘w’ can create a new file. A common student error is to open a source with ‘w’ expecting merely to make it accessible; this overwrites rather than reads. Another is to attempt write() through a handle opened in ‘r’ mode, which does not permit writing.

Ask what task the file has: supplying input, receiving output, or both under an explicitly specified workflow. A simple solution often uses one read handle and a separate write handle. This separation reduces the chance of accidental erasure and clarifies the flow of information for exam checking.

11. Read numbers as text first, then convert

Suppose a fictional input file contains the characters ’12’ on its first line. The text returned by readline() is not the integer 12; it is a string containing digits and possibly a newline. Python int() can convert a suitable numeric string, but non-numeric text will not be accepted by that conversion without further handling.

A common calculation error is treating text concatenation as addition. The strings ’12’ and ‘3’ combine as ‘123’ when concatenated, whereas the integers 12 and 3 add to 15. The program must perform the operation the task intends, with data types made explicit and invalid input addressed according to the assignment rules.

with open("numbers.txt", "r") as f:
    first = int(f.readline())
    second = int(f.readline())

total = first + second
with open("total.txt", "w") as f:
    f.write(str(total) + "\n")

12. File location and filename are parts of the requirement

A relative filename such as records.txt is interpreted relative to the program’s working directory. If the student launches code from a different folder, the program may not find the file, or may create the output in an unexpected location. The error is environmental rather than necessarily a mathematical bug.

The safe school approach is to inspect the examination working instructions, use the required folders and filenames, and check the generated files before submission. Never presume that a screenshot of a notebook output proves the correct text file exists. A deliverable has a location and a format as well as content.

13. Learn to trace reads with an imaginary cursor

For a file containing ABCDE, the starting cursor is before A. After read(2), the result is AB and the cursor is before C. After readline() on the same single-line file, the result is CDE and the cursor reaches the end. After read(), the result is ”.

When line endings exist, they are also consumed. Imagine a file with ‘A\nB’. The first readline() returns ‘A\n’; the next read() returns ‘B’. A trace table should record the exact returned string and the remaining content. Students gain more by following cursor movement than by memorising a dozen unrelated examples.

14. Design a controlled input-to-output pipeline

A robust beginner program can be divided into six parts: identify the expected file, open it safely for the required operation, read the contents, validate or convert values, perform the intended transformation, and write and verify the output. Each stage has a distinct failure mode and a distinct check.

If a total is wrong, first determine whether the source was read correctly. If the printed total is right but the output file is wrong, inspect writing, conversion, separators and destination. If the output file is missing, inspect path and mode. This diagnosis is more effective than changing the arithmetic at random.

15. Choosing read() versus readline() is a design decision

Use read() when the entire remaining text is the natural unit of input and the amount is manageable. Use readline() when the task is organised into sequential lines or when an exercise requires tracking the read position. Either method returns strings; the programmer must still interpret the data.

For an input containing a sentence, read() may be direct. For a list of one integer per line, a line-by-line loop may better match the data structure. Neither method validates the contents. An assignment that expects three records should also decide what to do if one line is absent or contains text where a number is required.

16. Non-interactive input still requires validation

A stored file is not guaranteed to be well formed. It might have missing rows, unexpected spaces, a number outside a permitted range or a changed delimiter. A task that requires valid data should define the acceptable structure and response to invalid input. K349 separately treats validation as an important programming topic.

For example, a fictional file of test scores may contain ’82’ and ‘hello’. Converting ‘hello’ directly to an integer causes an error. In an examination, follow the specified assumptions and expected behaviour. In a real application, design appropriate error handling and logging rather than silently treating invalid records as zero.

17. Keep data provenance and privacy visible

Students can practise the entire topic with fictional records. There is no need to export classmates’ names, grades or contact details to an online service. An input file should have a known origin and an appropriate purpose, and a generated output should not expose more data than the task requires.

Even a technically correct program can create a privacy problem if it writes personally identifiable records to a shared location. For school preparation, use synthetic labels and generated values. A tutor should demonstrate the mechanics, not obtain live assessment files or complete a student’s authorised practical work for them.

18. A twelve-stage Read–Transform–Verify protocol

This independent eduKateSG teaching protocol is not a marking scheme. It separates conceptual planning from the exact Python statements so a learner can explain the purpose of every file operation and find the earliest point where the actual output diverges from the requirement.

Stage 1 — Identify the input source

Read the required filename and location. Ask whether the file is given, created by the task or expected from a previous step.

Stage 2 — Identify the expected output artefact

State the destination filename and the exact kind of content to be saved. A printed message is not a substitute for a required file.

Stage 3 — Choose the correct opening mode

Use reading mode for a supplied source and writing mode only for the intended output. Recognise the overwrite consequence of ‘w’.

Stage 4 — Determine the record structure

Ask whether input is one string, one record per line or several formatted fields. The choice determines whether read() or readline() is natural.

Stage 5 — Plan the read cursor

If several reads occur, record where each begins. Do not assume that two reads restart at the front.

Stage 6 — Capture exact returned values

Keep track of embedded newline characters and empty strings. Distinguish a blank line from end of file.

Stage 7 — Convert types deliberately

Use int() or float() only when a suitable numeric representation is expected. Strings do not become integers merely because they contain digits.

Stage 8 — Validate against requirements

Check formats, ranges and required records. The level of recovery should match the assignment; do not invent silent data corrections.

Stage 9 — Compute the stated transformation

Keep the program’s core calculation separate from input and output side effects, making errors easier to trace.

Stage 10 — Write with deliberate separators

Convert numbers back into strings where appropriate and add newline characters when the output needs line separation.

Stage 11 — Close and inspect the destination

Use close() or an appropriate with block. Reopen the output where permitted and compare its actual contents with the expected result.

Stage 12 — Retest from a clean state

Use a fresh fictional source and run again to check that the solution does not depend on an old file or previous notebook execution.

19. Twenty-four original file-handling worked cases

Each case is a fictional, self-contained exercise. Some are designed to expose a common mistake rather than show an elaborate code solution. Read the question, predict the file contents or returned string, and then explain the outcome using mode, cursor, data type and output location.

Worked case 1 — Read all characters from a short source

Given the exact file text CAT, f.read() returns the string ‘CAT’ when the file is opened at its beginning. It does not return a list of the letters or produce console output unless the program prints it.

Worked case 2 — Read one character from ABCDE

After opening a text file containing ABCDE, f.read(1) returns ‘A’. The next read begins before B. The file object remembers its position.

Worked case 3 — Make two consecutive reads

For ABCDE, f.read(2) yields ‘AB’ and a second f.read(2) yields ‘CD’. The second call does not repeat ‘AB’. A final read() yields ‘E’.

Worked case 4 — Read after consuming all text

For the three-character file YES, f.read() first returns ‘YES’. A second f.read() on the same handle returns an empty string because the cursor is at the end.

Worked case 5 — Read two lines without a trailing newline

If the exact content is ‘red\nblue’, the first readline() gives ‘red\n’ and the second ‘blue’. The final line does not need a newline character to be returned.

Worked case 6 — Distinguish blank line and EOF

If a file has a blank line, a readline() call may return ‘\n’, which is not the empty string. After all characters are consumed, another readline() returns ”. The loop should not treat these as equivalent.

Worked case 7 — Why does print create visual spacing?

A value returned by readline() may already end in ‘\n’. Printing that value using the default print() ending adds another newline. The apparent extra blank line can arise from output formatting rather than missing file data.

Worked case 8 — Write two strings without separators

A file opened with ‘w’ receives write(‘Hello’) followed by write(‘World’). Its resulting content is ‘HelloWorld’, because write() does not insert a space or newline automatically.

Worked case 9 — Write two separate lines

write(‘Hello\n’) followed by write(‘World\n’) creates two lines, with a newline after each. The program explicitly controls the separators.

Worked case 10 — Write an integer incorrectly

Calling f.write(12) on a text file does not write the digits 1 and 2, because write() expects a string. Use f.write(str(12)) to store those characters.

Worked case 11 — Accidental overwrite

An existing file contains important notes. Opening it using mode ‘w’ truncates the old content. Students should use an intended separate output filename and never practise on irreplaceable work.

Worked case 12 — Wrong path in a school notebook

The output is created in the notebook’s working directory, but the submission folder is elsewhere. The calculation can be correct while the required artefact is absent. Verify the intended destination.

Worked case 13 — Two numeric lines add mathematically

A file contains ’12\n3\n’. Converting each line using int() then adding produces 15. Concatenating the unconverted strings instead produces a different, unsuitable text result.

Worked case 14 — A non-numeric line causes a conversion failure

If int(‘three’) is attempted, Python raises a ValueError. The design should identify what counts as valid data and what response is required. The file being stored on disk does not make it trusted.

Worked case 15 — A zero-length source is still a file

An empty text file opened in reading mode produces ” from read(). The program needs to know whether an empty input is permitted instead of assuming there must be at least one record.

Worked case 16 — Opening a missing file for reading

Attempting open(‘missing.txt’,’r’) when that file is absent normally raises FileNotFoundError. Opening in reading mode does not automatically create the missing source.

Worked case 17 — Opening a new destination for writing

With a permitted writable directory and a file that does not yet exist, open(‘report.txt’,’w’) creates a new file for output. The destination must still be closed and checked.

Worked case 18 — Reading one character from a newline

If the next unconsumed character is ‘\n’, read(1) returns that newline character. Character-by-character reads include line-ending characters, not only visible letters.

Worked case 19 — Using a with block

When execution leaves the with-open block, Python closes the file. A later operation on that closed handle is not a valid way to continue reading. Open a suitable new handle when further access is needed.

Worked case 20 — Writing a summary without original records

A program reads two invented class counts, calculates their total and writes only that total to a new file. It should not automatically copy private individual details to the output; the required information is the summary.

Worked case 21 — Mixed file operations consume one cursor

read(1) followed by readline() uses the same file position. For ‘AB\nCD’, read(1) yields ‘A’, and readline() yields ‘B\n’. The method names do not define independent cursors.

Worked case 22 — A trailing newline is not a new number

For the line ‘8\n’, int() can interpret the numeric characters despite the surrounding newline. But a blank line ‘\n’ is not a valid integer. Data checking still matters.

Worked case 23 — The program prints the answer but saves nothing

print(total) writes to the console, not automatically to a required output file. Use a writing handle and an appropriate write() call when a file deliverable is required.

Worked case 24 — The output is overwritten during the second run

A program writes a fresh summary with mode ‘w’. On the next run, the file’s previous contents are replaced. This can be desirable for a clean current result, but only when the assignment intends replacement.

20. Practice assignment: fictional club attendance

Design a simple program for a fictional club whose source file contains exactly three valid integer attendance counts, one per line. Its required output file should contain ‘Total attendance: ‘ followed by their sum and a newline. Before writing code, specify the expected input format, exact output filename, behaviour if the source is absent and what the task assumes about invalid data.

A valid toy input of 7, 9 and 8 produces ‘Total attendance: 24’. A test with 0, 3 and 5 produces 8. A source with only two lines violates the stated three-record expectation and should not be quietly treated as having a third zero unless the specification explicitly permits that interpretation. A tutor should ask students to compare the saved text with the expected contents rather than trusting a success message.

21. Short retrieval questions

Question one: what is the difference between read() and readline()? Question two: after calling read() to the end, what does another read() return? Question three: why can opening an existing file in ‘w’ mode be dangerous? Question four: if the input ’15’ is read as text, what conversion is needed before integer addition?

Question five: why might print() show a blank line after a readline() result? Question six: what is a safe way to finalise a file operation? Question seven: why should a teacher check the actual output file rather than only the notebook display? Each answer should explain a mechanism, not recite a function name alone.

22. Frequently asked questions

Python file handling becomes far easier once you separate the storage resource from the values read and written. The following concise answers address the confusions that survive even after students can memorise the syntax.

Is open() the same as read()?

No. open() establishes access to a file and returns a file object. read() obtains characters from that file’s current position. Opening does not by itself load the whole file into the variable.

Does read() return an integer when a text file contains digits?

No. A text-mode read returns a string. Use a suitable conversion such as int() or float() when the contents meet the expected numeric format.

Does readline() remove the newline?

Not normally. When a line ends in a newline, it is included in the returned string. The end-of-file signal is the empty string, which is different from a blank line containing ‘\n’.

Can read(2) return the same first two characters twice?

Not on the same handle without repositioning or reopening. Each read consumes the next characters from the current position.

Does write() automatically insert a line break?

No. Include a newline character where the required file format needs it.

Why is ‘w’ mode risky?

Opening an existing file with ‘w’ replaces its contents. Use it only for an output you intend to create or overwrite, after checking the path.

Is f.close() optional because the script ends?

A reliable solution should close files explicitly or use a with block. Depending on automatic program termination is a poor substitute for managing resources and verifying saved output.

Does print() save output to a text file?

Ordinary print() writes to the console or configured output stream, not to the named file created for an assignment. Use the required file operation for the deliverable.

Is a relative filename always found beside the code?

Not necessarily. Relative paths depend on the current working directory of the process or notebook environment. Verify the school’s specified paths.

Can I use personal student records for practice?

It is safer to use fictional records. File exercises teach the same algorithms without unnecessary disclosure of names, marks or other personal information.

Official syllabus and related eduKateSG learning

The authoritative reference is the 2027 SEC G3 Computing K349 syllabus, especially Module 2.3.4 and the Python quick-reference guide. See also Reference 342 — Manual Algorithms, Reference 361 — Software Engineering, the MOE V3.0 library and the immutable Clementi instructional standard.

Editorial review: 29 October 2026, Singapore. All records and snippets are original classroom examples. The durable lesson is to check what file you opened, where the cursor is, what type was read, what text was written and whether the saved file is the required deliverable.

MOE V3.0 reference navigation

Previous: Reference 362 — Packet Error Detection · MOE V3.0 library.