PART 1 · PYTHON FROM ZERO · LESSON 19
Mini project: a monthly sales report
FreeLesson 21 of 78
Everything from Lessons 1 to 18 in one small program: read a file, clean, decide, group, calculate and print a report.
# daily_sales_report.py: only the basics from Lessons 1 to 18
def read_orders(path):
"""Read orders.csv into a list of dicts."""
rows = []
with open(path) as f:
header = f.readline().strip().split(",")
for line in f:
values = line.strip().split(",")
rows.append(dict(zip(header, values)))
return rows
def month_of(day):
return day[:7] # "2025-04-20" -> "2025-04"
def build_report(rows):
report = {}
for r in rows:
if r["status"] != "delivered":
continue
month = month_of(r["order_date"])
if month not in report:
report[month] = {"orders": 0, "revenue": 0.0, "best": 0.0}
stats = report[month]
amount = float(r["amount"])
stats["orders"] += 1
stats["revenue"] += amount
if amount > stats["best"]:
stats["best"] = amount
return report
def print_report(report):
print(f"{'month':<9}{'orders':>7}{'revenue':>11}{'average':>10}{'best':>9}")
print("-" * 46)
grand = 0.0
for month in sorted(report):
s = report[month]
avg = s["revenue"] / s["orders"]
grand += s["revenue"]
print(f"{month:<9}{s['orders']:>7}{s['revenue']:>11,.2f}{avg:>10,.2f}{s['best']:>9,.0f}")
print("-" * 46)
print(f"{'total':<9}{'':>7}{grand:>11,.2f}")
rows = read_orders("orders.csv")
print(len(rows), "orders read")
print_report(build_report(rows))Output
15 orders read month orders revenue average best ---------------------------------------------- 2025-01 2 1,994.00 997.00 1,198 2025-02 2 2,847.00 1,423.50 1,499 2025-03 4 7,291.00 1,822.75 3,498 2025-04 4 6,840.00 1,710.00 2,397 ---------------------------------------------- total 18,972.00
| Line of thinking | Where it is in the code | Lesson |
|---|---|---|
| Read the file into rows, with column names | read_orders: open, readline, split, zip, dict | 12, 13, 18 |
| Skip what does not count | if r["status"] != "delivered": continue | 7, 9 |
| Group by month | a dict keyed by "2025-04", created the first time a month appears | 12 |
| Count, total, track the best | the three loop patterns | 8 |
| Print it, keep it readable | f-strings with widths; four small, well-named functions | 4, 14 |
Your turn: report per city instead of per month (load customers.json into a lookup dict), then add a cancellation rate. Do both without looking back and you are ready for Part 2.
Practice before you move on
- Extend the report with the number of cancelled and returned orders in each month.
- Add a closing line that names the month with the highest delivered revenue.