Cohort 4Register

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.PYPYTHON 3.12
# 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 thinkingWhere it is in the codeLesson
Read the file into rows, with column namesread_orders: open, readline, split, zip, dict12, 13, 18
Skip what does not countif r["status"] != "delivered": continue7, 9
Group by montha dict keyed by "2025-04", created the first time a month appears12
Count, total, track the bestthe three loop patterns8
Print it, keep it readablef-strings with widths; four small, well-named functions4, 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

  1. Extend the report with the number of cancelled and returned orders in each month.
  2. Add a closing line that names the month with the highest delivered revenue.