NeuralGearheads commited on
Commit
8555c27
·
verified ·
1 Parent(s): e0b1f9c

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +64 -22
src/streamlit_app.py CHANGED
@@ -14,7 +14,42 @@ st.set_page_config(
14
  )
15
 
16
  # ---------------------------
17
- # Global CSS (mac-neon + rev gauge)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  # ---------------------------
19
  st.markdown(
20
  """
@@ -28,17 +63,19 @@ st.markdown(
28
  [data-testid="stHeader"] { background: transparent; }
29
  [data-testid="stToolbar"] { display: none; }
30
 
 
31
  .hero {
32
  border-radius: 24px;
33
- padding: 18px 22px;
34
  background: radial-gradient(circle at top left, rgba(96,165,250,0.35), transparent 55%),
35
  radial-gradient(circle at bottom right, rgba(236,72,153,0.35), transparent 55%),
36
  rgba(15,23,42,0.94);
37
- box-shadow: 0 25px 60px rgba(15,23,42,0.9);
38
  border: 1px solid rgba(148,163,184,0.35);
39
  position: relative;
40
- overflow: hidden;
41
  }
 
42
  .hero-title {
43
  font-size: 1.9rem;
44
  font-weight: 700;
@@ -70,13 +107,15 @@ st.markdown(
70
  100% { background-position: 0% 50%; }
71
  }
72
 
 
73
  .glass {
74
  background: radial-gradient(circle at top left, rgba(148,163,184,0.24), transparent 55%),
75
  rgba(15,23,42,0.96);
76
- border-radius: 18px;
77
- padding: 18px 18px 14px 18px;
78
  border: 1px solid rgba(148,163,184,0.4);
79
- box-shadow: 0 20px 40px rgba(15,23,42,0.6);
 
80
  }
81
 
82
  .chip {
@@ -100,7 +139,7 @@ st.markdown(
100
  color: #6b7280;
101
  }
102
 
103
- /* Tabs */
104
  button[data-baseweb="tab"] {
105
  background: transparent !important;
106
  border-radius: 999px !important;
@@ -114,7 +153,7 @@ st.markdown(
114
  box-shadow: 0 0 0 1px rgba(59,130,246,0.7);
115
  }
116
 
117
- /* Rev limiter gauge */
118
  .rev-wrap {
119
  display:flex;
120
  justify-content:center;
@@ -130,7 +169,7 @@ st.markdown(
130
  background: radial-gradient(circle at 50% 120%, #991b1b, transparent 60%),
131
  radial-gradient(circle at 0% 0%, rgba(59,130,246,0.4), transparent 60%),
132
  #020617;
133
- overflow:hidden;
134
  border:1px solid rgba(148,163,184,0.5);
135
  box-shadow: 0 12px 30px rgba(0,0,0,0.8);
136
  }
@@ -236,7 +275,7 @@ model = KNeighborsRegressor(n_neighbors=5, weights="distance")
236
  model.fit(X_scaled, y)
237
 
238
  # ---------------------------
239
- # PRESET CALLBACKS (use session_state)
240
  # ---------------------------
241
  def preset_daily():
242
  s = st.session_state
@@ -331,7 +370,7 @@ def preset_max():
331
  s.traction_mode = "Track / Drag"
332
 
333
  # ---------------------------
334
- # HERO
335
  # ---------------------------
336
  st.markdown(
337
  """
@@ -394,44 +433,47 @@ with left:
394
 
395
  tabs = st.tabs(["Core Specs", "Bolt-Ons", "Boost & Cooling", "ECU & Fuel"])
396
 
 
 
 
397
  # --- Core specs ---
398
  with tabs[0]:
399
  col1, col2 = st.columns(2)
400
  engine_disp_options = [0.8,1.0,1.2,1.4,1.6,1.8,2.0,2.2,2.4,2.5,
401
  2.8,3.0,3.2,3.5,4.0,4.4,5.0,6.0,7.0,8.0]
 
 
 
 
402
  engine_disp = col1.selectbox(
403
  "Engine Displacement (L)",
404
  engine_disp_options,
405
- index=engine_disp_options.index(2.0),
406
  key="engine_disp"
407
  )
408
  engine_layout = col2.selectbox(
409
  "Engine Layout",
410
  ["I3","I4","I6","V6","V8","V10","V12"],
411
- index=2,
412
  key="engine_layout"
413
  )
414
 
415
  layout_to_cyl = {"I3":3,"I4":4,"I6":6,"V6":6,"V8":8,"V10":10,"V12":12}
416
  cyl = layout_to_cyl[engine_layout]
417
 
418
- # FIX: Increased max_value to 3000 to prevent crash on high displacement/cylinder combinations
419
  base_hp = st.number_input(
420
  "Base Horsepower (stock dyno)",
421
  min_value=60, max_value=3000,
422
- value=int(max(90, round(engine_disp * cyl * 20))),
423
  key="base_hp"
424
  )
425
 
426
  col3, col4 = st.columns(2)
427
  weight_kg = col3.number_input(
428
  "Vehicle Weight (kg)",
429
- min_value=700, max_value=4000, value=1500,
430
  key="weight_kg"
431
  )
432
  weight_reduction = col4.slider(
433
  "Weight Reduction (%)",
434
- 0, 40, 0,
435
  key="weight_reduction"
436
  )
437
 
@@ -441,7 +483,7 @@ with left:
441
  intake = col1.selectbox("Intake", ["Stock", "Cold Air", "Performance"], key="intake")
442
  headers = col2.selectbox("Headers", ["Stock", "Shorty", "Long Tube"], key="headers")
443
  exhaust = col3.selectbox("Exhaust", ["Stock", "Cat-back", "Straight Pipe"], key="exhaust")
444
- exhaust_dia = st.slider("Exhaust Diameter (mm)", 40, 120, 60, key="exhaust_dia")
445
 
446
  cam = st.selectbox(
447
  "Cam Profile",
@@ -461,7 +503,7 @@ with left:
461
  ["None", "Turbo", "Twin-Turbo", "Supercharger", "Twincharged"],
462
  key="induction"
463
  )
464
- boost_psi = st.slider("Target Boost (psi)", 0, 40, 10, key="boost_psi")
465
  turbo_size = st.selectbox(
466
  "Turbo Size",
467
  ["N/A", "Small 45-55mm", "Medium 56-65mm", "Big 66-75mm", "XL 76mm+"],
@@ -472,7 +514,7 @@ with left:
472
  ["None", "Air-to-Air", "Air-to-Water", "Front-mount High-Flow"],
473
  key="intercooler"
474
  )
475
- meth = st.checkbox("Methanol Injection Kit", value=False, key="meth")
476
 
477
  # --- ECU & fuel ---
478
  with tabs[3]:
@@ -486,7 +528,7 @@ with left:
486
  ["87", "91", "93", "E85 / Race Blend"],
487
  key="fuel"
488
  )
489
- altitude = st.slider("Altitude (meters)", 0, 3500, 200, key="altitude")
490
  traction_mode = st.radio(
491
  "Traction Mode Vibe",
492
  ["Daily", "Spirited", "Track / Drag"],
 
14
  )
15
 
16
  # ---------------------------
17
+ # SESSION STATE INITIALIZATION (Fixes Yellow Warning)
18
+ # ---------------------------
19
+ def init_session_state():
20
+ # Only set these defaults if they don't exist yet
21
+ defaults = {
22
+ "engine_disp": 2.0,
23
+ "engine_layout": "I6",
24
+ "base_hp": 240,
25
+ "weight_kg": 1500,
26
+ "weight_reduction": 0,
27
+ "intake": "Stock",
28
+ "headers": "Stock",
29
+ "exhaust": "Stock",
30
+ "exhaust_dia": 60,
31
+ "cam": "Stock",
32
+ "intake_manifold": "Stock",
33
+ "induction": "None",
34
+ "boost_psi": 0,
35
+ "turbo_size": "N/A",
36
+ "intercooler": "None",
37
+ "meth": False,
38
+ "tune": "None",
39
+ "fuel": "93",
40
+ "altitude": 200,
41
+ "traction_mode": "Spirited"
42
+ }
43
+
44
+ for key, value in defaults.items():
45
+ if key not in st.session_state:
46
+ st.session_state[key] = value
47
+
48
+ # Run init immediately
49
+ init_session_state()
50
+
51
+ # ---------------------------
52
+ # Global CSS (Fixes "Cutting Out" / Rounds)
53
  # ---------------------------
54
  st.markdown(
55
  """
 
63
  [data-testid="stHeader"] { background: transparent; }
64
  [data-testid="stToolbar"] { display: none; }
65
 
66
+ /* Fix: Removed overflow:hidden to stop cutting off shadows */
67
  .hero {
68
  border-radius: 24px;
69
+ padding: 24px 28px;
70
  background: radial-gradient(circle at top left, rgba(96,165,250,0.35), transparent 55%),
71
  radial-gradient(circle at bottom right, rgba(236,72,153,0.35), transparent 55%),
72
  rgba(15,23,42,0.94);
73
+ box-shadow: 0 20px 50px rgba(0,0,0,0.5);
74
  border: 1px solid rgba(148,163,184,0.35);
75
  position: relative;
76
+ margin-bottom: 20px;
77
  }
78
+
79
  .hero-title {
80
  font-size: 1.9rem;
81
  font-weight: 700;
 
107
  100% { background-position: 0% 50%; }
108
  }
109
 
110
+ /* Fix: Removed overflow:hidden and added margin for shadow breathing room */
111
  .glass {
112
  background: radial-gradient(circle at top left, rgba(148,163,184,0.24), transparent 55%),
113
  rgba(15,23,42,0.96);
114
+ border-radius: 20px;
115
+ padding: 20px;
116
  border: 1px solid rgba(148,163,184,0.4);
117
+ box-shadow: 0 15px 35px rgba(0,0,0,0.6);
118
+ margin: 5px;
119
  }
120
 
121
  .chip {
 
139
  color: #6b7280;
140
  }
141
 
142
+ /* Tabs styling */
143
  button[data-baseweb="tab"] {
144
  background: transparent !important;
145
  border-radius: 999px !important;
 
153
  box-shadow: 0 0 0 1px rgba(59,130,246,0.7);
154
  }
155
 
156
+ /* Rev limiter gauge - Only this keeps overflow hidden for the semi-circle */
157
  .rev-wrap {
158
  display:flex;
159
  justify-content:center;
 
169
  background: radial-gradient(circle at 50% 120%, #991b1b, transparent 60%),
170
  radial-gradient(circle at 0% 0%, rgba(59,130,246,0.4), transparent 60%),
171
  #020617;
172
+ overflow:hidden;
173
  border:1px solid rgba(148,163,184,0.5);
174
  box-shadow: 0 12px 30px rgba(0,0,0,0.8);
175
  }
 
275
  model.fit(X_scaled, y)
276
 
277
  # ---------------------------
278
+ # PRESET CALLBACKS
279
  # ---------------------------
280
  def preset_daily():
281
  s = st.session_state
 
370
  s.traction_mode = "Track / Drag"
371
 
372
  # ---------------------------
373
+ # HERO SECTION
374
  # ---------------------------
375
  st.markdown(
376
  """
 
433
 
434
  tabs = st.tabs(["Core Specs", "Bolt-Ons", "Boost & Cooling", "ECU & Fuel"])
435
 
436
+ # NOTE: I removed 'index=...' from these selectboxes.
437
+ # They now just rely on the key being present in st.session_state (handled by init_session_state)
438
+
439
  # --- Core specs ---
440
  with tabs[0]:
441
  col1, col2 = st.columns(2)
442
  engine_disp_options = [0.8,1.0,1.2,1.4,1.6,1.8,2.0,2.2,2.4,2.5,
443
  2.8,3.0,3.2,3.5,4.0,4.4,5.0,6.0,7.0,8.0]
444
+
445
+ # We manually update value if it's missing (failsafe), though init handles it.
446
+ if "engine_disp" not in st.session_state: st.session_state.engine_disp = 2.0
447
+
448
  engine_disp = col1.selectbox(
449
  "Engine Displacement (L)",
450
  engine_disp_options,
 
451
  key="engine_disp"
452
  )
453
  engine_layout = col2.selectbox(
454
  "Engine Layout",
455
  ["I3","I4","I6","V6","V8","V10","V12"],
 
456
  key="engine_layout"
457
  )
458
 
459
  layout_to_cyl = {"I3":3,"I4":4,"I6":6,"V6":6,"V8":8,"V10":10,"V12":12}
460
  cyl = layout_to_cyl[engine_layout]
461
 
 
462
  base_hp = st.number_input(
463
  "Base Horsepower (stock dyno)",
464
  min_value=60, max_value=3000,
 
465
  key="base_hp"
466
  )
467
 
468
  col3, col4 = st.columns(2)
469
  weight_kg = col3.number_input(
470
  "Vehicle Weight (kg)",
471
+ min_value=700, max_value=4000,
472
  key="weight_kg"
473
  )
474
  weight_reduction = col4.slider(
475
  "Weight Reduction (%)",
476
+ 0, 40,
477
  key="weight_reduction"
478
  )
479
 
 
483
  intake = col1.selectbox("Intake", ["Stock", "Cold Air", "Performance"], key="intake")
484
  headers = col2.selectbox("Headers", ["Stock", "Shorty", "Long Tube"], key="headers")
485
  exhaust = col3.selectbox("Exhaust", ["Stock", "Cat-back", "Straight Pipe"], key="exhaust")
486
+ exhaust_dia = st.slider("Exhaust Diameter (mm)", 40, 120, key="exhaust_dia")
487
 
488
  cam = st.selectbox(
489
  "Cam Profile",
 
503
  ["None", "Turbo", "Twin-Turbo", "Supercharger", "Twincharged"],
504
  key="induction"
505
  )
506
+ boost_psi = st.slider("Target Boost (psi)", 0, 40, key="boost_psi")
507
  turbo_size = st.selectbox(
508
  "Turbo Size",
509
  ["N/A", "Small 45-55mm", "Medium 56-65mm", "Big 66-75mm", "XL 76mm+"],
 
514
  ["None", "Air-to-Air", "Air-to-Water", "Front-mount High-Flow"],
515
  key="intercooler"
516
  )
517
+ meth = st.checkbox("Methanol Injection Kit", key="meth")
518
 
519
  # --- ECU & fuel ---
520
  with tabs[3]:
 
528
  ["87", "91", "93", "E85 / Race Blend"],
529
  key="fuel"
530
  )
531
+ altitude = st.slider("Altitude (meters)", 0, 3500, key="altitude")
532
  traction_mode = st.radio(
533
  "Traction Mode Vibe",
534
  ["Daily", "Spirited", "Track / Drag"],