Cohort 4Register

PART 1 · PYTHON FROM ZERO · LESSON 18

Files: read and write

FreeLesson 20 of 78

Data engineering starts with files. Reading, writing and appending text files needs only open() and a with block.

READING A FILEPYTHON 3.12
with open("orders.csv") as f:          # open for reading
    header = f.readline()               # first line
    first_row = f.readline()
print(repr(header))
print(first_row.strip().split(","))

with open("orders.csv") as f:
    lines = f.read().splitlines()       # the whole file
print(len(lines), "lines; last:", lines[-1])

Output

'order_id,customer_id,order_date,status,amount\n'
['101', '1', '2025-01-10', 'delivered', '1198.00']
16 lines; last: 115,5,2025-04-28,delivered,1598.00
LOOP OVER A FILE LINE BY LINEPYTHON 3.12
with open("orders.csv") as f:
    next(f)                              # skip the header
    delivered = 0
    for line in f:                       # one line at a time
        cols = line.strip().split(",")
        status, amount = cols[3], cols[4]
        if status == "delivered":
            delivered += float(amount)
print(f"delivered revenue: {delivered:,.2f}")

Output

delivered revenue: 18,972.00

Looping over f reads one line at a time, so this works on a file of any size. split(",") is fine for simple files; real CSVs with quoted commas need the csv module (page 33).

WRITING AND APPENDINGPYTHON 3.12
with open("report.txt", "w") as f:   # write (replace)
    f.write("date,revenue\n")
    f.write("2025-04-20,2397\n")

with open("report.txt", "a") as f:   # append
    f.write("2025-04-28,1598\n")

print(open("report.txt").read())

Output

date,revenue
2025-04-20,2397
2025-04-28,1598
ModeDoesIf the file existsIf it does not
"r"Read (the default)Reads itFileNotFoundError
"w"WriteEmpties it firstCreates it
"a"AppendAdds to the endCreates it
"x"CreateFileExistsErrorCreates it
PATHS AND FOLDERS WITH PATHLIBPYTHON 3.12
from pathlib import Path

out_dir = Path("reports") / "2025-04"          # / joins path parts
out_dir.mkdir(parents=True, exist_ok=True)      # make folders
(out_dir / "summary.txt").write_text("orders,15\n")

print(Path("orders.csv").exists(), Path("missing.csv").exists())
print(sorted(p.name for p in Path(".").glob("*.json*")))
print([str(p) for p in Path("reports").rglob("*.txt")])

Output

True False
['customers.json', 'events.jsonl']
['reports/2025-04/summary.txt']

pathlib builds paths that work on Windows, Mac and Linux, so you never glue folder names with "/" or "\\" by hand. glob finds files by pattern; rglob searches sub-folders too.

Try it yourself before moving on

  1. Count the lines in orders.csv without the header.
  2. Write every cancelled order into cancelled.txt.
  3. Append a line with today's total to report.txt without deleting what is there.