Brake_Lab_Test / src /streamlit_app.py
MaxBDKT's picture
Update src/streamlit_app.py
8982db1 verified
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
# ==============================================================================
@st.cache_data
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.")