From 80ef59af5e28b69f7f1b7d8ae4e2e098b6a457f0 Mon Sep 17 00:00:00 2001 From: John Gatward Date: Fri, 20 Mar 2026 12:36:59 +0000 Subject: [PATCH] use env for data.csv --- src/app.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/app.py b/src/app.py index 26ae5fc..7af6772 100644 --- a/src/app.py +++ b/src/app.py @@ -1,3 +1,4 @@ +import os from flask import Flask, render_template import pandas as pd import plotly.express as px @@ -17,6 +18,7 @@ app = Flask(__name__) # Data loading # --------------------------------------------------------------------------- + def get_data_frame(filename): df = pd.read_csv(filename) df["Date"] = pd.to_datetime(df["Date"], dayfirst=True) @@ -27,7 +29,8 @@ def get_data_frame(filename): def build_hovertext(df, attendance_columns): present = [c for c in attendance_columns if c in df.columns] return df[present].apply( - lambda row: ", ".join(p for p in present if row[p] == 1) or "No attendance", + lambda row: ", ".join( + p for p in present if row[p] == 1) or "No attendance", axis=1, ) @@ -45,7 +48,8 @@ def generate_position_trend(df): df = df.copy() df["Date_ordinal"] = df["Date"].map(pd.Timestamp.toordinal) df["Relative Percentile"] = df["Relative Position"] * 100 - df["Rolling Avg (5)"] = df["Relative Percentile"].rolling(5, min_periods=1).mean() + df["Rolling Avg (5)"] = df["Relative Percentile"].rolling( + 5, min_periods=1).mean() df["Attendees"] = build_hovertext(df, constants.PLAYER_NAME_COLUMNS) X = sm.add_constant(df["Date_ordinal"]) @@ -61,7 +65,8 @@ def generate_position_trend(df): if slope < 0: predicted_ordinal = (target_percentile - intercept) / slope - end_ord = max(max_ord, predicted_ordinal) if predicted_ordinal and predicted_ordinal > max_ord else max_ord + end_ord = max( + max_ord, predicted_ordinal) if predicted_ordinal and predicted_ordinal > max_ord else max_ord extended_ords = np.linspace(min_ord, end_ord, 200) extended_percentile = intercept + slope * extended_ords @@ -120,9 +125,11 @@ def generate_position_trend(df): fig.update_layout( title="Relative Position Over Time", xaxis_title="Date", - yaxis=dict(title="Relative Position Percentile (lower is better)", range=[0, 100], ticksuffix="th"), + yaxis=dict(title="Relative Position Percentile (lower is better)", range=[ + 0, 100], ticksuffix="th"), template="plotly_white", - legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1), + legend=dict(orientation="h", yanchor="bottom", + y=1.02, xanchor="right", x=1), hovermode="x unified", margin=dict(t=60, b=40), ) @@ -146,12 +153,14 @@ def generate_player_impact(df): n = len(attended) if n >= MIN_APPEARANCES: percentile = attended["Relative Position"].mean() * 100 - rows.append({"Player": name, "Relative Percentile": round(percentile, 1), "Games": n}) + rows.append( + {"Player": name, "Relative Percentile": round(percentile, 1), "Games": n}) if not rows: return go.Figure() - impact_df = pd.DataFrame(rows).sort_values("Relative Percentile", ascending=True) + impact_df = pd.DataFrame(rows).sort_values( + "Relative Percentile", ascending=True) colors = [ "#16a34a" if p <= overall_percentile else "#dc2626" for p in impact_df["Relative Percentile"] @@ -176,7 +185,8 @@ def generate_player_impact(df): x=overall_percentile, line_dash="dot", line_color="#6b7280", - annotation_text=f"Overall avg ({constants.ordinal(round(overall_percentile))})", + annotation_text=f"Overall avg ({constants.ordinal( + round(overall_percentile))})", annotation_position="top right", ) @@ -330,7 +340,8 @@ def generate_weekly_attendance_calendar(df): y_labels.append(f"{year} · W{start}-{end}") calendar["RowLabel"] = calendar.apply( - lambda r: f"{int(r['Year'])} · W{(int(r['Block']) - 1) * 13 + 1}-{min(int(r['Block']) * 13, 53)}", + lambda r: f"{int(r['Year'])} · W{(int(r['Block']) - 1) + * 13 + 1}-{min(int(r['Block']) * 13, 53)}", axis=1, ) @@ -389,7 +400,7 @@ def generate_visualisations(df): @app.route("/") def index(): - df = get_data_frame("data.csv") + df = get_data_frame(os.environ.get("DATA_CSV_PATH", "data.csv")) stats, highlights = generate_stats(df) player_table = generate_player_table(df) plots = generate_visualisations(df)