"""Generate the synthetic sample dataset shipped with this Space. Everything here is fabricated with a fixed seed — no real, customer, or proprietary data is used anywhere in this project. Re-run to regenerate: python make_sample_data.py """ import csv import random from datetime import date, timedelta from pathlib import Path SEED = 20260811 ROWS = 2000 OUT = Path(__file__).parent / "data" / "sample_sales.csv" REGIONS = { "North America": ["United States", "United States", "Canada"], "LATAM": ["Mexico", "Mexico", "Colombia", "Argentina", "Chile"], "EMEA": ["Spain", "Germany", "United Kingdom"], } REGION_WEIGHTS = [0.45, 0.35, 0.20] CATALOG = { "Electronics": [ ("Wireless Headphones", 89.99), ("4K Monitor", 329.00), ("Mechanical Keyboard", 119.50), ("Smart Speaker", 59.00), ], "Home & Kitchen": [ ("Espresso Machine", 249.00), ("Air Fryer", 129.99), ("Cookware Set", 179.00), ("Blender", 74.50), ], "Apparel": [ ("Running Jacket", 94.00), ("Denim Jeans", 68.00), ("Merino Socks", 22.00), ("Rain Shell", 139.00), ], "Sports": [ ("Yoga Mat", 45.00), ("Dumbbell Set", 159.00), ("Trail Backpack", 112.00), ("Water Bottle", 28.00), ], "Beauty": [ ("Skincare Set", 82.00), ("Hair Dryer", 96.00), ("Perfume", 115.00), ("Electric Razor", 68.50), ], } CATEGORY_WEIGHTS = [0.28, 0.22, 0.20, 0.16, 0.14] CHANNELS = ["Online", "Retail Store", "Partner"] CHANNEL_WEIGHTS = [0.58, 0.28, 0.14] SEGMENTS = ["Consumer", "Small Business", "Enterprise"] SEGMENT_WEIGHTS = [0.62, 0.26, 0.12] # Retail seasonality: quiet start, holiday spike in Nov/Dec. MONTH_WEIGHTS = [0.60, 0.58, 0.70, 0.75, 0.80, 0.80, 0.85, 0.80, 0.90, 1.00, 1.60, 1.80] START = date(2025, 1, 1) DAYS = 365 def main() -> None: rng = random.Random(SEED) day_weights = [MONTH_WEIGHTS[(START + timedelta(days=d)).month - 1] for d in range(DAYS)] rows = [] for i in range(ROWS): order_date = START + timedelta( days=rng.choices(range(DAYS), weights=day_weights)[0] ) region = rng.choices(list(REGIONS), weights=REGION_WEIGHTS)[0] country = rng.choice(REGIONS[region]) category = rng.choices(list(CATALOG), weights=CATEGORY_WEIGHTS)[0] product, base_price = rng.choice(CATALOG[category]) channel = rng.choices(CHANNELS, weights=CHANNEL_WEIGHTS)[0] segment = rng.choices(SEGMENTS, weights=SEGMENT_WEIGHTS)[0] quantity = rng.choices([1, 2, 3, 4, 6, 10], weights=[46, 24, 12, 8, 6, 4])[0] if segment == "Enterprise": quantity *= rng.choice([2, 3, 5]) # Prices drift a little by market; discounts cluster around promos. unit_price = round(base_price * rng.uniform(0.94, 1.08), 2) discount_pct = rng.choices( [0.00, 0.05, 0.10, 0.15, 0.25], weights=[52, 18, 15, 9, 6], )[0] if order_date.month in (11, 12) and rng.random() < 0.45: discount_pct = max(discount_pct, 0.15) revenue = round(quantity * unit_price * (1 - discount_pct), 2) rows.append({ "order_id": f"ORD-{100000 + i}", "order_date": order_date.isoformat(), "region": region, "country": country, "channel": channel, "customer_segment": segment, "category": category, "product": product, "quantity": quantity, "unit_price": unit_price, "discount_pct": discount_pct, "revenue": revenue, }) rows.sort(key=lambda r: r["order_date"]) OUT.parent.mkdir(parents=True, exist_ok=True) with OUT.open("w", newline="", encoding="utf-8") as fh: writer = csv.DictWriter(fh, fieldnames=list(rows[0])) writer.writeheader() writer.writerows(rows) total = sum(r["revenue"] for r in rows) print(f"wrote {len(rows)} rows to {OUT} (total revenue {total:,.2f})") if __name__ == "__main__": main()