# /// script
# requires-python = ">=3.10"
# dependencies = ["numpy"]
# ///
# Copyright (c) 2026 Aayush Sharma · SPDX-License-Identifier: MIT
# https://thedataengineering.com/lab-code/LICENSE.txt
"""Average of ratios against ratio of sums.

A year of daily revenue and margin. The margin rate computed as the average
of the daily rates and as total margin over total revenue, at day, month and
year level, and as the average of the monthly averages.
"""
import argparse, json
import numpy as np

p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
p.add_argument("--days", type=int, default=365, help="Days of data.")
p.add_argument("--seed", type=int, default=0, help="Random seed.")
p.add_argument("--json", help="Also write the results to this JSON file.")
args = p.parse_args()
rng = np.random.default_rng(args.seed)

revenue = rng.uniform(100, 10_000, args.days)
rate = np.clip(0.35 - 0.15 * (revenue - 100) / 9_900 + rng.normal(0, 0.05, args.days), 0.02, 0.6)   # big days run on thinner margin
margin = revenue * rate
month = np.minimum(np.arange(args.days) * 12 // args.days, 11)

avg_of_ratios = float(np.mean(margin / revenue))
ratio_of_sums = float(margin.sum() / revenue.sum())
monthly_avg = [float(np.mean(margin[month == m] / revenue[month == m])) for m in range(12)]
monthly_ratio = [float(margin[month == m].sum() / revenue[month == m].sum()) for m in range(12)]
avg_of_monthly = float(np.mean(monthly_avg))
avg_of_monthly_ratios = float(np.mean(monthly_ratio))
rows = [{"method": "AVG(margin / revenue) over days", "margin_rate_pct": avg_of_ratios * 100},
        {"method": "SUM(margin) / SUM(revenue)", "margin_rate_pct": ratio_of_sums * 100},
        {"method": "average of the monthly averages", "margin_rate_pct": avg_of_monthly * 100},
        {"method": "average of the monthly ratios of sums", "margin_rate_pct": avg_of_monthly_ratios * 100}]
for r in rows: print(f"{r['method']:<40} {r['margin_rate_pct']:6.2f}%")

if args.json:
    with open(args.json, "w") as f:
        json.dump({"tables": {"methods": rows, "months": [{"month": m + 1, "avg_of_ratios_pct": a * 100, "ratio_of_sums_pct": b * 100}
                   for m, (a, b) in enumerate(zip(monthly_avg, monthly_ratio))],
                   "summary": [{"gap_pts": (avg_of_ratios - ratio_of_sums) * 100}]}}, f)
