|
2 | 2 | import matplotlib.pyplot as plt |
3 | 3 |
|
4 | 4 | ROOT = pathlib.Path(__file__).resolve().parents[1] |
| 5 | + |
| 6 | +# ✅ Ensure folders exist on fresh CI runners |
| 7 | +(ROOT / 'outputs').mkdir(parents=True, exist_ok=True) |
| 8 | +(ROOT / 'images').mkdir(parents=True, exist_ok=True) |
| 9 | + |
5 | 10 | con = duckdb.connect(database=str(ROOT / 'analytics.duckdb')) |
6 | 11 |
|
7 | | -for rel in ['models/staging/stg_events.sql','models/marts/mart_sessions.sql','models/marts/mart_funnel.sql','models/marts/mart_retention.sql']: |
| 12 | +# Build models |
| 13 | +for rel in [ |
| 14 | + 'models/staging/stg_events.sql', |
| 15 | + 'models/marts/mart_sessions.sql', |
| 16 | + 'models/marts/mart_funnel.sql', |
| 17 | + 'models/marts/mart_retention.sql' |
| 18 | +]: |
8 | 19 | con.execute((ROOT / rel).read_text()) |
9 | 20 |
|
10 | 21 | # Export marts to CSVs |
|
19 | 30 | stages = ['visits','signups','activations','purchases'] |
20 | 31 | vals = [row[s] for s in stages] |
21 | 32 | plt.figure(figsize=(6,4)) |
22 | | - plt.bar(stages, vals); plt.title('Funnel (Last Day)') |
23 | | - plt.tight_layout(); plt.savefig(ROOT / 'images' / 'funnel_last_day.png', dpi=150); plt.close() |
| 33 | + plt.bar(stages, vals) |
| 34 | + plt.title('Funnel (Last Day)') |
| 35 | + plt.tight_layout() |
| 36 | + plt.savefig(ROOT / 'images' / 'funnel_last_day.png', dpi=150) |
| 37 | + plt.close() |
24 | 38 |
|
25 | 39 | # Average 7-day retention curve |
26 | 40 | ret = con.execute(""" |
|
34 | 48 | if not ret.empty: |
35 | 49 | plt.figure(figsize=(6,4)) |
36 | 50 | plt.plot(ret['day_num'], ret['avg_retention']) |
37 | | - plt.title('7-Day Retention (Average)'); plt.xlabel('Day'); plt.ylabel('Retention') |
38 | | - plt.tight_layout(); plt.savefig(ROOT / 'images' / 'retention_curve.png', dpi=150); plt.close() |
| 51 | + plt.title('7-Day Retention (Average)') |
| 52 | + plt.xlabel('Day'); plt.ylabel('Retention') |
| 53 | + plt.tight_layout() |
| 54 | + plt.savefig(ROOT / 'images' / 'retention_curve.png', dpi=150) |
| 55 | + plt.close() |
39 | 56 |
|
40 | 57 | print('Built models → outputs/*.csv and images/*.png') |
0 commit comments