Module 1 · Section 7 of 10
Lesson 1.6 - Working with Files
Target: ~10 min read - 20 min hands-on
Overview
Every real analysis starts with getting data into Python. This lesson reads a CSV using
the built-in open() and the csv module - before Pandas (Module 2) makes this
dramatically easier. We load an energy-meter log, parse it row by row, compute a
summary, then write results back out.
Real logs are rarely clean - missing samples, blank cells, inconsistent timestamps. We start simple here; Module 2 goes deep on cleaning messy real-world data.
Why This Matters (PH Context)
This is the exact shape of data you'll pull from a building's energy meter, a plant utility log, or a SCADA historian export - a timestamp column and one or more value columns, thousands of rows long.
Code-Along
# Lesson 1.6 - Reading and writing files
# In the course platform, CSVs are pre-bundled and loaded via fetch();
# here we work with an in-memory example first, then show the
# open()/csv pattern you'd use with a real file.
import csv
import io
# A CSV is just text: a header row, then one comma-separated record per line.
csv_text = """timestamp,power_kW
2026-03-01T00:00,180
2026-03-01T01:00,165
2026-03-01T02:00,150
2026-03-01T03:00,300
2026-03-01T04:00,520
2026-03-01T05:00,545
"""
# io.StringIO wraps the text so it behaves like an open file object.
f = io.StringIO(csv_text) # in real use: f = open("meter_log.csv")
# DictReader yields each row as a dict keyed by the header names.
reader = csv.DictReader(f)
rows = []
for r in reader:
# every CSV value arrives as a STRING - convert the number with float()
rows.append({"timestamp": r["timestamp"], "power_kW": float(r["power_kW"])})
print(f"Loaded {len(rows)} hourly readings")
# generator expressions (a list comp without the brackets) feed sum() / max()
total_kWh = sum(r["power_kW"] for r in rows) # 1 hour per reading
peak_kW = max(r["power_kW"] for r in rows)
load_factor = (total_kWh / len(rows)) / peak_kW # average load / peak load
print(f"Energy: {total_kWh:.1f} kWh, peak: {peak_kW:.0f} kW, load factor: {load_factor:.2f}")
# --- Writing: csv.writer + writerow() emits one comma-separated line at a time ---
out = io.StringIO() # in real use: out = open("summary.csv", "w", newline="")
writer = csv.writer(out)
writer.writerow(["metric", "value"]) # header row
writer.writerow(["energy_kWh", total_kWh])
writer.writerow(["peak_kW", peak_kW])
writer.writerow(["load_factor", round(load_factor, 3)])
print("\nWritten CSV content:")
print(out.getvalue()) # .getvalue() reads back everything written to the buffer
Expected output:
Loaded 6 hourly readings
Energy: 1860.0 kWh, peak: 545 kW, load factor: 0.57
Written CSV content:
metric,value
energy_kWh,1860.0
peak_kW,545.0
load_factor,0.569
Practice Exercises
- Count how many readings are above 400 kW.
- Add the average power to the summary CSV.
- Create a second day's 6-row CSV text block, load both days, and print each day's peak.
# Try the practice exercises here
Knowledge Check
- Which Python module makes it easy to parse rows of a CSV file into dictionaries?
- Why must values read from a CSV often be explicitly converted with
float()? - What real-world challenge does this lesson flag as common in log data?
Answer key
csv(viaDictReader)- All CSV values are read as strings by default
- Missing samples, blank cells, and inconsistent timestamps
7 / 63 sections · Course home · Join the coaching cohort