Download src/streamlit_app.py from LOLMAN65/Stephen: direct link, hf CLI and curl.
- Browser
- Download file 9.86 kB
-
https://huggingface.co/spaces/LOLMAN65/Stephen/resolve/main/src/streamlit_app.py
- Command line
-
hf download hf://spaces/LOLMAN65/Stephen/src/streamlit_app.py
-
curl -L -o streamlit_app.py https://huggingface.co/spaces/LOLMAN65/Stephen/resolve/main/src/streamlit_app.py
9.86 kB
| # Collaborative Decision Hub (Python Demo) — Streamlit | |
| # DISCLAIMER: This is a toy simulation for demonstration only. Numbers and models are illustrative. | |
| import streamlit as st | |
| import numpy as np | |
| import pandas as pd | |
| import altair as alt | |
| # ----------------------------- | |
| # App config | |
| # ----------------------------- | |
| st.set_page_config(page_title="Collaborative Decision Hub (Python Demo)", layout="wide") | |
| # ----------------------------- | |
| # Scenario constants (toy values) | |
| # ----------------------------- | |
| SCENARIO = { | |
| "airport": "ZNY", | |
| "window_startZ": "14:00Z", | |
| "window_endZ": "18:00Z", | |
| "hours": 4.0, | |
| "arrivals_impacted": 126, | |
| "departures_impacted": 40, | |
| "runway_config_note": "Runway 22R closed", | |
| "airspace_note": "Convective weather causing sector restrictions", | |
| "sector_capacity_per_hour": [32, 32, 36, 36], | |
| "airport_arr_capacity_per_hour": [38, 38, 38, 38], | |
| } | |
| # Economic/operational constants (toy) | |
| EMISSION_FACTOR_CO2_PER_KG_FUEL = 3.16 # kg CO2 per kg fuel | |
| FUEL_COST_PER_KG_USD = 0.8 | |
| DELAY_COST_PER_MIN_USD = 75 | |
| MISCONNECT_DELAY_THRESHOLD_MIN = 20 | |
| MISCONNECT_PER_FLIGHT_PER_MIN_FACTOR = 0.002 | |
| # ----------------------------- | |
| # Utility helpers | |
| # ----------------------------- | |
| def clamp(x, low=0.0, high=1.0): | |
| return max(low, min(high, x)) | |
| def normalize(val, ref_max): | |
| if ref_max <= 0: | |
| return 0.0 | |
| return clamp(val / ref_max, 0.0, 1.0) | |
| # ----------------------------- | |
| # Compute KPIs given controls | |
| # ----------------------------- | |
| def compute_metrics( | |
| flights_total, | |
| arrivals, | |
| hours, | |
| sector_capacity_per_hour, | |
| airport_arr_capacity_per_hour, | |
| reroute_pct, | |
| fuel_saved_per_rerouted_flight_kg, | |
| reroute_delay_delta_min_per_flight, | |
| gdp_avg_delay_min, | |
| meter_reduction_pct, | |
| slot_swap_pct, | |
| ): | |
| flights_rerouted = int(round(flights_total * reroute_pct / 100.0)) | |
| flights_not_rerouted = flights_total - flights_rerouted | |
| avg_delay_min = gdp_avg_delay_min + (reroute_delay_delta_min_per_flight if flights_rerouted > 0 else 0) | |
| avg_delay_min = max(0.0, avg_delay_min) | |
| total_delay_min = flights_total * avg_delay_min | |
| fuel_saved_kg = flights_rerouted * fuel_saved_per_rerouted_flight_kg | |
| co2_saved_t = (fuel_saved_kg * EMISSION_FACTOR_CO2_PER_KG_FUEL) / 1000.0 | |
| cost_usd = total_delay_min * DELAY_COST_PER_MIN_USD - fuel_saved_kg * FUEL_COST_PER_KG_USD | |
| avg_sector_capacity = np.mean(sector_capacity_per_hour) | |
| base_arrival_rate = arrivals / hours | |
| effective_arrival_rate = base_arrival_rate * (1.0 - meter_reduction_pct / 100.0) | |
| sector_relief = 0.2 * (reroute_pct / 100.0) * base_arrival_rate | |
| effective_sector_demand = max(0.0, effective_arrival_rate - sector_relief) | |
| overload = max(0.0, effective_sector_demand - avg_sector_capacity) | |
| safety_score = clamp(100.0 - 120.0 * (overload / max(1.0, avg_sector_capacity)), 0.0, 100.0) | |
| avg_airport_capacity = np.mean(airport_arr_capacity_per_hour) | |
| slot_utilization_pct = clamp((effective_arrival_rate / avg_airport_capacity) * 100.0, 0.0, 150.0) | |
| delay_over_threshold = max(0.0, avg_delay_min - MISCONNECT_DELAY_THRESHOLD_MIN) | |
| misconnects_est = flights_total * delay_over_threshold * MISCONNECT_PER_FLIGHT_PER_MIN_FACTOR * (1.0 - slot_swap_pct / 100.0) | |
| otp_rate = clamp(1.0 / (1.0 + np.exp((avg_delay_min - 15.0) / 3.0)), 0.0, 1.0) | |
| return { | |
| "flights_rerouted": flights_rerouted, | |
| "avg_delay_min": avg_delay_min, | |
| "total_delay_min": total_delay_min, | |
| "fuel_saved_kg": fuel_saved_kg, | |
| "co2_saved_t": co2_saved_t, | |
| "cost_usd": cost_usd, | |
| "safety_score": safety_score, | |
| "slot_utilization_pct": slot_utilization_pct, | |
| "misconnects_est": misconnects_est, | |
| "otp_rate": otp_rate, | |
| "effective_sector_demand_per_hr": effective_sector_demand, | |
| "avg_sector_capacity": avg_sector_capacity, | |
| "avg_airport_capacity": avg_airport_capacity, | |
| } | |
| # ----------------------------- | |
| # Scoring (weighted multi-objective) | |
| # ----------------------------- | |
| def score_solution(metrics, weights): | |
| norm_ontime = clamp(1.0 - normalize(metrics["avg_delay_min"], 30.0)) | |
| norm_sust = normalize(metrics["fuel_saved_kg"], 6000.0) | |
| norm_safety = clamp(metrics["safety_score"] / 100.0) | |
| norm_cost = clamp(normalize(-metrics["cost_usd"], 120000.0)) | |
| return ( | |
| weights["On-time"] * norm_ontime + | |
| weights["Sustainability"] * norm_sust + | |
| weights["Safety"] * norm_safety + | |
| weights["Cost"] * norm_cost | |
| ), { | |
| "On-time": norm_ontime, | |
| "Sustainability": norm_sust, | |
| "Safety": norm_safety, | |
| "Cost": norm_cost | |
| } | |
| # ----------------------------- | |
| # Grid search recommender | |
| # ----------------------------- | |
| def recommend_best(flights_total, arrivals, hours, sector_cap, airport_cap, weights): | |
| candidates = [] | |
| for reroute_pct in range(0, 35, 5): | |
| for gdp_delay in range(0, 25, 5): | |
| for meter_pct in range(0, 35, 10): | |
| for slot_swap in range(0, 35, 10): | |
| m = compute_metrics( | |
| flights_total=flights_total, | |
| arrivals=arrivals, | |
| hours=hours, | |
| sector_capacity_per_hour=sector_cap, | |
| airport_arr_capacity_per_hour=airport_cap, | |
| reroute_pct=reroute_pct, | |
| fuel_saved_per_rerouted_flight_kg=150.0, | |
| reroute_delay_delta_min_per_flight=-2.0, | |
| gdp_avg_delay_min=gdp_delay, | |
| meter_reduction_pct=meter_pct, | |
| slot_swap_pct=slot_swap, | |
| ) | |
| s, norms = score_solution(m, weights) | |
| candidates.append({ | |
| "reroute_pct": reroute_pct, | |
| "gdp_avg_delay_min": gdp_delay, | |
| "meter_reduction_pct": meter_pct, | |
| "slot_swap_pct": slot_swap, | |
| "score": s, | |
| "cost_usd": m["cost_usd"], | |
| "co2_saved_t": m["co2_saved_t"], | |
| "metrics": m, | |
| "norms": norms | |
| }) | |
| best = max(candidates, key=lambda x: x["score"]) if candidates else None | |
| return best, candidates | |
| # ----------------------------- | |
| # Sidebar: Objective Weights | |
| # ----------------------------- | |
| st.sidebar.title("Objective Weights") | |
| w_ontime = st.sidebar.slider("On-time performance", 0.0, 1.0, 0.30, 0.05) | |
| w_cost = st.sidebar.slider("Cost (savings)", 0.0, 1.0, 0.25, 0.05) | |
| w_sust = st.sidebar.slider("Sustainability (CO₂/fuel)", 0.0, 1.0, 0.25, 0.05) | |
| w_safety = st.sidebar.slider("ANSP Safety", 0.0, 1.0, 0.20, 0.05) | |
| w_sum = w_ontime + w_cost + w_sust + w_safety | |
| weights = { | |
| "On-time": w_ontime / w_sum if w_sum else 0.25, | |
| "Cost": w_cost / w_sum if w_sum else 0.25, | |
| "Sustainability": w_sust / w_sum if w_sum else 0.25, | |
| "Safety": w_safety / w_sum if w_sum else 0.25, | |
| } | |
| st.sidebar.caption(f"Weights normalized: On-time {weights['On-time']:.2f}, Cost {weights['Cost']:.2f}, Sustain {weights['Sustainability']:.2f}, Safety {weights['Safety']:.2f}") | |
| # ----------------------------- | |
| # Header | |
| # ----------------------------- | |
| st.title("Collaborative Decision Hub (Python Demo)") | |
| st.write(f"{SCENARIO['airport']} | Window {SCENARIO['window_startZ']}–{SCENARIO['window_endZ']} | {SCENARIO['runway_config_note']} | {SCENARIO['airspace_note']}") | |
| # ----------------------------- | |
| # Layout columns | |
| # ----------------------------- | |
| left, center, right = st.columns([1.1, 1.2, 1.0]) | |
| # LEFT: Scenario + What-if Controls | |
| with left: | |
| st.subheader("Scenario") | |
| st.markdown( | |
| f"- Arrivals impacted: {SCENARIO['arrivals_impacted']}\n" | |
| f"- Departures impacted: {SCENARIO['departures_impacted']}\n" | |
| f"- Sector capacity (hr): {SCENARIO['sector_capacity_per_hour']}\n" | |
| f"- Airport arrivals capacity (hr): {SCENARIO['airport_arr_capacity_per_hour']}" | |
| ) | |
| st.subheader("What-if Controls") | |
| reroute_pct = st.slider("Targeted reroutes (% of flights)", 0, 40, 10, 1) | |
| fuel_saved_per_rerouted_flight_kg = st.slider("Fuel saved per rerouted flight (kg)", 0, 400, 150, 10) | |
| reroute_delay_delta = st.slider("Reroute delay change per rerouted flight (min; negative is good)", -5.0, 5.0, -2.0, 0.5) | |
| gdp_avg_delay_min = st.slider("GDP average delay (min)", 0, 30, 15, 1) | |
| meter_reduction_pct = st.slider("Departure metering reduction (%)", 0, 40, 10, 1) | |
| slot_swap_pct = st.slider("Slot swaps applied (%)", 0, 40, 10, 1) | |
| # CENTER: Collaboration (agent chat) + Recommendations | |
| with center: | |
| st.subheader("Agent Collaboration") | |
| flights_total = SCENARIO["arrivals_impacted"] + SCENARIO["departures_impacted"] | |
| m = compute_metrics( | |
| flights_total=flights_total, | |
| arrivals=SCENARIO["arrivals_impacted"], | |
| hours=SCENARIO["hours"], | |
| sector_capacity_per_hour=SCENARIO["sector_capacity_per_hour"], | |
| airport_arr_capacity_per_hour=SCENARIO["airport_arr_capacity_per_hour"], | |
| reroute_pct=reroute_pct, | |
| fuel_saved_per_rerouted_flight_kg=fuel_saved_per_rerouted_flight_kg, | |
| reroute_delay_delta_min_per_flight=reroute_delay_delta, | |
| gdp_avg_delay_min=gdp_avg_delay_min, | |
| meter_reduction_pct=meter_reduction_pct, | |
| slot_swap_pct=slot_swap_pct, | |
| ) | |
| score, norms = score_solution(m, weights) | |
| consensus_pct = int(round(score * 100)) | |
| with st.container(border=True): | |
| st.markdown("**Airline AI**") | |
| st.write( | |
| f"With {reroute_pct}% reroutes (~{m['flights_rerouted']} flights), " | |
| f"forecast avg delay {m['avg_delay_min']:.1f} min, fuel saved {m['fuel_saved_kg']:.0f} kg " | |
| f"({m['co2_saved_t']:.2f} t CO₂), cost | |