Spaces:
Running
Running
| import streamlit as st | |
| import pandas as pd | |
| import os | |
| import numpy as np | |
| # ============================================================================== | |
| # 1. STYLE CSS V2.4 (FORÇAGE BLANC TOTAL SUR COMPOSANTS NOIRS) | |
| # ============================================================================== | |
| st.set_page_config(page_title="Brake Lab V2.4", layout="centered") | |
| st.markdown(""" | |
| <style> | |
| /* 1.1 FOND GLOBAL */ | |
| .stApp { background-color: #FFFFFF !important; } | |
| /* 1.2 FORÇAGE DES TEXTES DANS LES BLOCS NOIRS */ | |
| /* On cible tout ce qui est dans un input ou une liste déroulante */ | |
| div[data-baseweb="select"] *, | |
| input, | |
| .stNumberInput div *, | |
| div[role="listbox"] *, | |
| .streamlit-expanderHeader * { | |
| color: #FFFFFF !important; | |
| fill: #FFFFFF !important; | |
| } | |
| /* 1.3 RÉGLAGE DES BOITES (NOIR) */ | |
| div[data-baseweb="select"], | |
| input, | |
| .stNumberInput div[data-baseweb="input"], | |
| .streamlit-expanderHeader { | |
| background-color: #1E1E1E !important; | |
| border: 2px solid #000000 !important; | |
| border-radius: 8px !important; | |
| } | |
| /* 1.4 TITRES HORS BLOCS (DOIVENT RESTER NOIRS SUR BLANC) */ | |
| h1, h2, h3, h4, p, label, .stMarkdown div p { | |
| color: #000000 !important; | |
| } | |
| /* 1.5 LISTE DÉROULANTE (OPTIONS) */ | |
| div[role="listbox"], ul[role="listbox"] { | |
| background-color: #1E1E1E !important; | |
| } | |
| li[role="option"]:hover { | |
| background-color: #0082C3 !important; | |
| } | |
| /* 1.6 BOUTONS + ET - (BOINS VISIBLES) */ | |
| button[aria-label="Step up"], button[aria-label="Step down"] { | |
| background-color: #333333 !important; | |
| } | |
| /* 1.7 CARTES DE RÉSULTATS */ | |
| .perf-box { | |
| padding: 40px; | |
| border: 4px solid #000000; | |
| border-radius: 15px; | |
| background-color: #FFFFFF; | |
| text-align: center; | |
| margin-top: 20px; | |
| box-shadow: 8px 8px 0px #000; | |
| } | |
| .perf-value { font-size: 55px; font-weight: 900; margin: 0px; } | |
| /* COULEURS COMPARAISON */ | |
| .comp-pos { color: #1B5E20 !important; font-weight: bold; font-size: 18px; margin-top: 10px; } | |
| .comp-neg { color: #B71C1C !important; font-weight: bold; font-size: 18px; margin-top: 10px; } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # ============================================================================== | |
| # 2. CHARGEMENT DES DONNÉES | |
| # ============================================================================== | |
| def load_data(): | |
| current_dir = os.path.dirname(__file__) | |
| file_path = os.path.join(current_dir, "Brake_Lab_Test_Data.xlsx") | |
| if not os.path.exists(file_path): return pd.DataFrame() | |
| df = pd.read_excel(file_path, sheet_name='Data') | |
| df.columns = df.columns.str.strip() | |
| return df | |
| df = load_data() | |
| # ============================================================================== | |
| # 3. INTERFACE V2.4 | |
| # ============================================================================== | |
| if not df.empty: | |
| # --- BLOC 1 : DONNÉES D'USAGE --- | |
| with st.expander("📊 Données d'usage", expanded=False): | |
| c1, c2 = st.columns(2) | |
| with c1: | |
| effort_val = st.number_input("Effort Levier [N]", value=100, step=1) | |
| mass_total = st.number_input("Masse Totale (kg)", value=100, step=1) | |
| wheel_size = st.number_input("Roue [inch]", value=28, step=1) | |
| with c2: | |
| speed_kmh = st.number_input("Vitesse [km/h]", value=25, step=1) | |
| mass_ratio = st.number_input("Rapport masse AR [%]", value=70, step=1) | |
| # --- BLOC 2 : DONNÉES COMPOSANTS --- | |
| with st.expander("⚙️ Données composant", expanded=True): | |
| model_list = df['model name'].unique().tolist() | |
| col_comp1, col_comp2 = st.columns(2) | |
| with col_comp1: | |
| main_model = st.selectbox("Système étudié", options=model_list) | |
| with col_comp2: | |
| comp_options = ["Aucun"] + model_list | |
| compare_model = st.selectbox("Système de comparaison", options=comp_options) | |
| # --- CALCULS --- | |
| row = df[df['model name'] == main_model].iloc[0] | |
| res_dry = row['dry a'] * effort_val + row['dry b'] | |
| res_wet = row['wet a'] * effort_val + row['wet b'] | |
| res_dry_c, res_wet_c = None, None | |
| if compare_model != "Aucun": | |
| row_c = df[df['model name'] == compare_model].iloc[0] | |
| res_dry_c = row_c['dry a'] * effort_val + row_c['dry b'] | |
| res_wet_c = row_c['wet a'] * effort_val + row_c['wet b'] | |
| # --- AFFICHAGE --- | |
| st.write("") | |
| res_c1, res_c2 = st.columns(2) | |
| def get_comp_html(val_main, val_comp): | |
| if val_comp is None: return "" | |
| diff_pct = ((val_main - val_comp) / val_comp) * 100 | |
| color_class = "comp-pos" if diff_pct >= 0 else "comp-neg" | |
| sign = "+" if diff_pct >= 0 else "" | |
| return f'<p class="{color_class}">{sign}{round(diff_pct, 1)}% vs comp</p>' | |
| with res_c1: | |
| st.markdown(f"""<div class="perf-box"> | |
| <p style="font-size: 20px; font-weight: bold; margin-bottom:10px;">CONDITION : SEC</p> | |
| <p class="perf-value" style="color: #0082C3 !important;">{round(res_dry, 1)} N</p> | |
| {get_comp_html(res_dry, res_dry_c)} | |
| </div>""", unsafe_allow_html=True) | |
| with res_c2: | |
| st.markdown(f"""<div class="perf-box"> | |
| <p style="font-size: 20px; font-weight: bold; margin-bottom:10px;">CONDITION : HUMIDE</p> | |
| <p class="perf-value" style="color: #E63312 !important;">{round(res_wet, 1)} N</p> | |
| {get_comp_html(res_wet, res_wet_c)} | |
| </div>""", unsafe_allow_html=True) | |
| else: | |
| st.error("Erreur : Fichier Excel manquant.") |