Strings and files
Much real-world data is text stored in files. Python makes it straightforward to clean text and read and write files safely.
String basics
Strings are immutable sequences of characters. They can be indexed and sliced like lists: "python"[0] is "p". + joins strings, * repeats them, and in tests for substrings: "cat" in "concatenate" is True. Because strings are immutable, methods return new strings rather than changing the original.
Useful string methods
lower() and upper() change case; strip() removes surrounding whitespace; replace("a", "b") substitutes text; split() breaks a string into a list of words, or on a given separator such as split(","); and ", ".join(items) joins a list into one string. startswith() and find() help locate text.
Formatting
f-strings insert values into text: f"{name} scored {score}". Format specifiers control appearance: {price:.2f} shows two decimal places, {n:,} adds thousands separators, and {name:>10} right-aligns in 10 characters. Clear formatting makes program output much easier to read.
Opening files
open("notes.txt") opens a file for reading; open("out.txt", "w") opens for writing, replacing existing contents; "a" appends. The recommended pattern is with open("notes.txt") as f:, which automatically closes the file afterwards, even if an error occurs. Specifying encoding="utf-8" avoids problems with non-English characters.
Reading and writing
f.read() returns the whole file as one string; for line in f: reads line by line, which is memory-efficient for large files; each line keeps its newline, so strip() is often used. f.write(text) writes a string; it does not add newlines automatically, so include "\n" where needed.
Paths and CSV files
The pathlib module handles file paths in a way that works on Windows, macOS, and Linux: Path("data") / "scores.csv". CSV (comma-separated values) files store tables as text. The csv module reads them correctly, including tricky cases such as commas inside quoted fields; csv.DictReader turns each row into a dictionary keyed by column name.
Handling errors
File operations can fail: the file may not exist or may be locked. try and except catch exceptions: try: f = open(path) except FileNotFoundError: print("No such file"). Catch specific exceptions rather than everything, so unexpected bugs are not silently hidden. finally runs clean-up code whether or not an error occurred.
Worked example
Averaging a CSV column: import csv; with open("scores.csv", encoding="utf-8") as f: rows = list(csv.DictReader(f)); avg = sum(float(r["score"]) for r in rows) / len(rows); print(f"Average: {avg:.1f}"). For scores 70, 85, and 90, it prints Average: 81.7. A robust version would handle an empty file and non-numeric scores.
Key takeaways
Strings are immutable sequences supporting indexing, slicing, +, *, and in. Methods such as lower, strip, replace, split, and join transform text and return new strings. f-strings with format specifiers produce clear output. Use with open(...) to handle files safely, choosing modes r, w, or a, and specifying utf-8. Read whole files or line by line; write adds no automatic newlines. pathlib handles paths; csv parses tables. try-except handles specific errors.
Flashcard
Methods return new strings
Check your understanding
Why is with open("data.txt") as f: the recommended way to open files?
