Open files with with open(...) as f: — the with block closes the file automatically, even if an error happens. Use mode "w" to write, "a" to append and the default "r" to read, and always pass encoding="utf-8".
Any .py file is a module. Put related functions in one file and import them elsewhere. The check if __name__ == "__main__": runs code only when the file is executed directly, not when it is imported.
Python's standard library covers a lot (csv, json, datetime, pathlib, random...). For everything else, install packages from PyPI with pip install inside your virtual environment, and record them in requirements.txt.
PASS_MARK = 30
def average(values: list[float]) -> float:
return sum(values) / len(values) if values else 0.0
def passed(values: list[float]) -> int:
return sum(1 for v in values if v >= PASS_MARK)import csv
from grading import average, passed
def main() -> None:
with open("scores.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["name", "score"])
writer.writerows([["Amina", 88], ["Juma", 25], ["Neema", 71]])
with open("scores.csv", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
scores = [float(r["score"]) for r in rows]
print(f"Average: {average(scores):.1f}")
print(f"Passed: {passed(scores)} of {len(scores)}")
if __name__ == "__main__":
main()python main.py
pip install requests # install a package from PyPI
pip freeze > requirements.txt # record exact versions
pip install -r requirements.txt # recreate on another machineKey points
- Always use
with open(...)andencoding="utf-8". - Use
if __name__ == "__main__":for a module's entry point. - Install packages inside a virtual environment and pin them in requirements.txt.
Exercise
Create text_tools.py with word_count(text) and longest_word(text). In main.py, read a .txt file, print both results, and append a summary line to report.txt.
Show solution
Try the exercise yourself first — then compare your approach with this one.
text_tools.py holds the reusable functions. main.py imports them, reads the essay with with open(...), prints the results, and opens report.txt in append mode ("a") so each run adds a new line instead of overwriting.
def word_count(text: str) -> int:
return len(text.split())
def longest_word(text: str) -> str:
return max(text.split(), key=len, default="")from text_tools import longest_word, word_count
def main() -> None:
with open("essay.txt", "w", encoding="utf-8") as f:
f.write("Photosynthesis happens in the chloroplasts of green plants.")
with open("essay.txt", encoding="utf-8") as f:
text = f.read()
count = word_count(text)
longest = longest_word(text)
print(f"Words: {count}, longest: {longest}")
with open("report.txt", "a", encoding="utf-8") as report:
report.write(f"essay.txt: {count} words, longest '{longest}'\n")
if __name__ == "__main__":
main()