Your time-tracker exports a CSV every month. You open it in Excel, copy the columns, paste them into your invoice template. What if Python read the CSV directly?
I would need to open the file, read each row, and split it into fields. That sounds like a lot of steps.
In the sandbox, the CSV arrives as a string argument — the same string that would come from file.read() on disk. splitlines() gives you rows; .split(",") gives you fields. The summarize_client function from yesterday expected dicts with name, rate, and hours — that is exactly what you parse out:
# CSV data arrives as a multi-line string
lines = csv_text.strip().splitlines()
header = lines[0].split(',')
rows = []
for line in lines[1:]:
values = line.split(',')
rows.append(dict(zip(header, values)))Why splitlines() instead of split("\n")? I have been using split for everything.
splitlines() handles both \n (Unix) and \r\n (Windows) line endings automatically. A CSV exported on Windows and parsed on Mac will have \r\n terminators. split("\n") leaves \r on every field. splitlines() is the safe default for any file-origin string.
And I can call clean_client_name from Week 1 on the name field to normalise it while I parse. The pipeline connects all the way back.
There it is. Clean, parse, summarise, format. The data flows from the export to the invoice without your hands touching it:
def parse_client_csv(csv_text: str) -> list:
lines = csv_text.strip().splitlines()
if not lines:
return []
header = lines[0].split(",")
clients = []
for row in lines[1:]:
if not row.strip():
continue
fields = row.split(",")
client = dict(zip(header, fields))
client["rate"] = float(client.get("rate", 0))
client["hours"] = float(client.get("hours", 0))
clients.append(client)
print(f"Parsed {len(clients)} clients")
return clientsMy end-of-month spreadsheet ritual just became a one-liner.
One caution: split(",") breaks on commas inside quoted fields. A client name like "Smith, Jones" splits into two fields. Day 20 fixes this with csv.DictReader — the right tool for production CSV parsing.
csv.DictReaderWhen you receive CSV as a string (not a file), split it into lines and parse manually:
lines = csv_text.strip().splitlines()
header = lines[0].split(',')
for line in lines[1:]:
values = line.split(',')
row = dict(zip(header, values))splitlines() handles \r\n (Windows) and \n (Unix) line endings — more robust than split('\n') for real CSV exports.
zip(header, values) pairs each header name with its value — cleaner than indexing by position. Day 20 replaces this approach with csv.DictReader which handles quoted fields and escaped characters automatically.
Your time-tracker exports a CSV every month. You open it in Excel, copy the columns, paste them into your invoice template. What if Python read the CSV directly?
I would need to open the file, read each row, and split it into fields. That sounds like a lot of steps.
In the sandbox, the CSV arrives as a string argument — the same string that would come from file.read() on disk. splitlines() gives you rows; .split(",") gives you fields. The summarize_client function from yesterday expected dicts with name, rate, and hours — that is exactly what you parse out:
# CSV data arrives as a multi-line string
lines = csv_text.strip().splitlines()
header = lines[0].split(',')
rows = []
for line in lines[1:]:
values = line.split(',')
rows.append(dict(zip(header, values)))Why splitlines() instead of split("\n")? I have been using split for everything.
splitlines() handles both \n (Unix) and \r\n (Windows) line endings automatically. A CSV exported on Windows and parsed on Mac will have \r\n terminators. split("\n") leaves \r on every field. splitlines() is the safe default for any file-origin string.
And I can call clean_client_name from Week 1 on the name field to normalise it while I parse. The pipeline connects all the way back.
There it is. Clean, parse, summarise, format. The data flows from the export to the invoice without your hands touching it:
def parse_client_csv(csv_text: str) -> list:
lines = csv_text.strip().splitlines()
if not lines:
return []
header = lines[0].split(",")
clients = []
for row in lines[1:]:
if not row.strip():
continue
fields = row.split(",")
client = dict(zip(header, fields))
client["rate"] = float(client.get("rate", 0))
client["hours"] = float(client.get("hours", 0))
clients.append(client)
print(f"Parsed {len(clients)} clients")
return clientsMy end-of-month spreadsheet ritual just became a one-liner.
One caution: split(",") breaks on commas inside quoted fields. A client name like "Smith, Jones" splits into two fields. Day 20 fixes this with csv.DictReader — the right tool for production CSV parsing.
csv.DictReaderWhen you receive CSV as a string (not a file), split it into lines and parse manually:
lines = csv_text.strip().splitlines()
header = lines[0].split(',')
for line in lines[1:]:
values = line.split(',')
row = dict(zip(header, values))splitlines() handles \r\n (Windows) and \n (Unix) line endings — more robust than split('\n') for real CSV exports.
zip(header, values) pairs each header name with its value — cleaner than indexing by position. Day 20 replaces this approach with csv.DictReader which handles quoted fields and escaped characters automatically.
Your clients send monthly CSV exports from their project tools. Write `parse_client_csv(csv_text)` that takes a CSV-formatted string (header row + data rows), splits on newlines, and parses each row into a dict with `rate` and `hours` as floats. Use `clean_client_name` on the name column.
Tap each step for scaffolded hints.
No blank-editor panic.