SHELLAPANDIANGANHUNGING commited on
Commit
9277ad9
·
verified ·
1 Parent(s): e68beae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -105
app.py CHANGED
@@ -1678,34 +1678,11 @@ with col_insights:
1678
 
1679
  st.markdown(f"**Critical Hour Risk (3-6 AM)**")
1680
  bg_color = "#ffcccc" if critical_pct > 50 else "#ffebcc" if critical_pct > 25 else "#ffffcc" if critical_pct > 10 else "#e6ffe6"
1681
-
1682
- # Tampilkan jumlah dan persentase dalam satu div
1683
- st.markdown(
1684
- f"""
1685
- <div style="background-color: {bg_color}; padding: 10px; border-radius: 8px; margin-bottom: 10px;">
1686
- <div style="font-size: 24px; font-weight: bold; color: #000000;">
1687
- {len(critical_alerts)}
1688
- </div>
1689
- <div style="color: #d32f2f; font-size: 16px; font-weight: bold; margin-top: -10px;">
1690
- ↑ {critical_pct:.1f}% of total alerts
1691
- </div>
1692
- </div>
1693
- """,
1694
- unsafe_allow_html=True
1695
- )
1696
-
1697
- # Gunakan st.markdown untuk warning/info dengan persentase berwarna merah tebal
1698
  if critical_pct > 10:
1699
- st.markdown(
1700
- f"<span style='color:#d32f2f; font-weight:bold;'>⚠️ High risk: {critical_pct:.1f}% of fatigue alerts occur during critical hours (3-6 AM). This is a known circadian dip period.</span>",
1701
- unsafe_allow_html=True
1702
- )
1703
  else:
1704
- st.markdown(
1705
- f"<span style='color:#d32f2f; font-weight:bold;'>✅ {critical_pct:.1f}% of alerts occur during critical hours. This is within acceptable range.</span>",
1706
- unsafe_allow_html=True
1707
- )
1708
-
1709
 
1710
  # 2. High-Speed Fatigue Analysis (Environmental Risk)
1711
  if col_speed and col_speed in df.columns:
@@ -1714,107 +1691,69 @@ with col_insights:
1714
  high_speed_pct = (len(high_speed_fatigue) / len(df)) * 100 if len(df) > 0 else 0
1715
 
1716
  st.markdown(f"**High-Speed Fatigue Risk (Speed > {high_speed_threshold:.0f} km/h)**")
1717
-
1718
- # Tampilkan jumlah dan persentase dalam satu div
1719
- st.markdown(
1720
- f"""
1721
- <div style="background-color: #f0f8ff; padding: 10px; border-radius: 8px; margin-bottom: 10px; border-left: 5px solid #007BFF;">
1722
- <div style="font-size: 24px; font-weight: bold; color: #000000;">
1723
- {len(high_speed_fatigue)}
1724
- </div>
1725
- <div style="color: #d32f2f; font-size: 16px; font-weight: bold; margin-top: -10px;">
1726
- ↑ {high_speed_pct:.1f}% of total alerts
1727
- </div>
1728
- </div>
1729
- """,
1730
- unsafe_allow_html=True
1731
- )
1732
-
1733
- # Gunakan st.markdown untuk warning/info dengan persentase berwarna merah tebal
1734
  if high_speed_pct > 20:
1735
- st.markdown(
1736
- f"<span style='color:#d32f2f; font-weight:bold;'>⚠️ High risk: {high_speed_pct:.1f}% of fatigue alerts occur at high speeds. This increases accident severity potential.</span>",
1737
- unsafe_allow_html=True
1738
- )
1739
  else:
1740
- st.markdown(
1741
- f"<span style='color:#d32f2f; font-weight:bold;'>✅ {high_speed_pct:.1f}% of alerts occur at high speeds. This is within acceptable range.</span>",
1742
- unsafe_allow_html=True
1743
- )
1744
  else:
1745
  st.info("Speed data not available for High-Speed Fatigue Analysis.")
1746
-
1747
- # 3. Shift Pattern Analysis
1748
- if col_shift and col_shift in df.columns:
1749
  shift_counts = df[col_shift].value_counts()
1750
- st.markdown(f"**Shift Pattern Risk**")
1751
 
 
1752
  for shift_val in shift_counts.index:
1753
  shift_pct = (shift_counts[shift_val] / len(df)) * 100
 
 
1754
 
1755
- # Tampilkan jumlah dan persentase dalam satu div dengan warna latar belakang seragam
1756
- st.markdown(
1757
- f"""
1758
- <div style="background-color: #f0f8ff; padding: 10px; border-radius: 8px; margin-bottom: 10px; border-left: 5px solid #007BFF;">
1759
- <div style="font-size: 24px; font-weight: bold; color: #000000;">Shift {shift_val}</div>
1760
- <div style="font-size: 28px; font-weight: bold; color: #000000; margin: 10px 0;">
1761
- {shift_counts[shift_val]}
1762
- </div>
1763
- <div style="color: #d32f2f; font-size: 16px; font-weight: bold; margin-top: -10px;">
1764
- ↑ {shift_pct:.1f}% of total alerts
1765
- </div>
1766
- </div>
1767
- """,
1768
- unsafe_allow_html=True
1769
- )
1770
-
1771
- # Gunakan st.markdown untuk warning/info dengan persentase berwarna merah tebal
1772
  if shift_pct > 50:
1773
- st.markdown(
1774
- f"<span style='color:#d32f2f; font-weight:bold;'>⚠️ Shift {shift_val} has disproportionately high alerts ({shift_pct:.1f}%). Review shift scheduling and workload.</span>",
1775
- unsafe_allow_html=True
1776
- )
1777
  else:
1778
- st.markdown(
1779
- f"<span style='color:#d32f2f; font-weight:bold;'>✅ Shift {shift_val} alert distribution is acceptable ({shift_pct:.1f}%).</span>",
1780
- unsafe_allow_html=True
1781
- )
1782
  else:
1783
  st.info("Shift data not available for Shift Pattern Analysis.")
1784
 
1785
 
1786
  # 4. Operator Risk Profiling
1787
- if col_operator and col_operator in df.columns:
1788
- operator_alerts = df[col_operator].value_counts()
1789
- top_risk_operators = operator_alerts.head(5) # Top 5 operators by alerts
 
1790
 
1791
- st.markdown("**High-Risk Operator Identification**")
1792
 
1793
- # Warna berdasarkan ranking 1–5
1794
- colors = ["#d32f2f", "#e57373", "#ef9a9a", "#ffcdd2", "#ffe1e4"]
1795
 
1796
- for idx, (op_name, count) in enumerate(top_risk_operators.items()):
1797
- op_pct = (count / len(df)) * 100
1798
- color = colors[idx] if idx < len(colors) else colors[-1]
1799
 
1800
- # Teks normal untuk nama dan jumlah alert
1801
- st.markdown(f"**Operator:** {op_name} \n**Alerts:** {count}")
1802
 
1803
- # Hanya 'Share' yang berwarna sesuai ranking
1804
- st.markdown(
1805
- f"<span style='font-weight:600'>Share:</span> "
1806
- f"<span style='color:{color}; font-weight:700'>{op_pct:.1f}% of total alerts</span>",
1807
- unsafe_allow_html=True
1808
- )
1809
 
1810
- # Risk message (tetap gunakan component Streamlit agar konsisten)
1811
- if op_pct > 5:
1812
- st.warning(f"Operator {op_name} has high fatigue risk ({op_pct:.1f}%). Consider coaching or rest plan.")
1813
- else:
1814
- st.info(f"Operator {op_name} fatigue risk is within acceptable range ({op_pct:.1f}%).")
 
 
 
1815
 
1816
- else:
1817
- st.info("Operator data not available for Operator Risk Profiling.")
1818
 
1819
 
1820
  # Kolom kanan: AI Recommendations
@@ -1891,6 +1830,7 @@ with col_recs:
1891
  # Ambil data_point dan ganti teks persentase di dalamnya menjadi warna merah
1892
  data_point_text = rec['data_point']
1893
  # Ganti pola persentase (X.X%) dengan span warna merah
 
1894
  # Cari pola seperti "1.6%", "21.2%", dll.
1895
  data_point_colored = re.sub(r'(\d+\.?\d*%)', r'<span style="color: red;">\1</span>', data_point_text)
1896
 
@@ -1939,4 +1879,4 @@ with col_recs:
1939
 
1940
  # ================= FOOTER ===========================
1941
  st.markdown("---")
1942
- st.markdown('<div class="footer">FatigueAnalyzer - Transforming Mining Safety with Intelligent Analytics | Contact: info@bukittechnology.com</div>', unsafe_allow_html=True)
 
1678
 
1679
  st.markdown(f"**Critical Hour Risk (3-6 AM)**")
1680
  bg_color = "#ffcccc" if critical_pct > 50 else "#ffebcc" if critical_pct > 25 else "#ffffcc" if critical_pct > 10 else "#e6ffe6"
1681
+ st.markdown(f'<div style="background-color: {bg_color}; padding: 10px; border-radius: 5px;">Critical Hour Alerts: {len(critical_alerts)} ({critical_pct:.1f}% of total alerts)</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1682
  if critical_pct > 10:
1683
+ st.warning(f"High risk: {critical_pct:.1f}% of fatigue alerts occur during critical hours (3-6 AM). This is a known circadian dip period.")
 
 
 
1684
  else:
1685
+ st.info(f"{critical_pct:.1f}% of alerts occur during critical hours. This is within acceptable range.")
 
 
 
 
1686
 
1687
  # 2. High-Speed Fatigue Analysis (Environmental Risk)
1688
  if col_speed and col_speed in df.columns:
 
1691
  high_speed_pct = (len(high_speed_fatigue) / len(df)) * 100 if len(df) > 0 else 0
1692
 
1693
  st.markdown(f"**High-Speed Fatigue Risk (Speed > {high_speed_threshold:.0f} km/h)**")
1694
+ # Ganti st.metric dengan HTML custom
1695
+ st.markdown(f"""
1696
+ <div style="font-size: 24px; font-weight: bold;">{len(high_speed_fatigue)}</div>
1697
+ <div style="color: red; font-size: 14px; margin-top: -5px;">↑ {high_speed_pct:.1f}% of total alerts</div>
1698
+ """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
1699
  if high_speed_pct > 20:
1700
+ st.warning(f"High risk: {high_speed_pct:.1f}% of fatigue alerts occur at high speeds. This increases accident severity potential.")
 
 
 
1701
  else:
1702
+ st.info(f"{high_speed_pct:.1f}% of alerts occur at high speeds. This is within acceptable range.")
 
 
 
1703
  else:
1704
  st.info("Speed data not available for High-Speed Fatigue Analysis.")
1705
+ # 3.Objective
1706
+ if col_shift and col_shift in df.columns:
 
1707
  shift_counts = df[col_shift].value_counts()
 
1708
 
1709
+ st.markdown(f"**Shift Pattern Risk**")
1710
  for shift_val in shift_counts.index:
1711
  shift_pct = (shift_counts[shift_val] / len(df)) * 100
1712
+ # Ganti st.metric dengan HTML custom
1713
+ st.markdown(f"""<div style="font-size: 24px; font-weight: bold;">{shift_counts[shift_val]}</div><div style="color: red; font-size: 14px; margin-top: -5px;">↑ {shift_pct:.1f}% of total alerts</div>""", unsafe_allow_html=True)
1714
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1715
  if shift_pct > 50:
1716
+ st.warning(f"Shift {shift_val} has disproportionately high alerts ({shift_pct:.1f}%). Review shift scheduling and workload.")
 
 
 
1717
  else:
1718
+ st.info(f"Shift {shift_val} alert distribution is acceptable ({shift_pct:.1f}%).")
 
 
 
1719
  else:
1720
  st.info("Shift data not available for Shift Pattern Analysis.")
1721
 
1722
 
1723
  # 4. Operator Risk Profiling
1724
+ # 4. Operator Risk Profiling
1725
+ if col_operator and col_operator in df.columns:
1726
+ operator_alerts = df[col_operator].value_counts()
1727
+ top_risk_operators = operator_alerts.head(5) # Top 5 operators by alerts
1728
 
1729
+ st.markdown("**High-Risk Operator Identification**")
1730
 
1731
+ # Warna berdasarkan ranking 1–5
1732
+ colors = ["#d32f2f", "#e57373", "#ef9a9a", "#ffcdd2", "#ffe1e4"]
1733
 
1734
+ for idx, (op_name, count) in enumerate(top_risk_operators.items()):
1735
+ op_pct = (count / len(df)) * 100
1736
+ color = colors[idx] if idx < len(colors) else colors[-1]
1737
 
1738
+ # Teks normal untuk nama dan jumlah alert
1739
+ st.markdown(f"**Operator:** {op_name} \n**Alerts:** {count}")
1740
 
1741
+ # Hanya 'Share' yang berwarna sesuai ranking
1742
+ st.markdown(
1743
+ f"<span style='font-weight:600'>Share:</span> "
1744
+ f"<span style='color:{color}; font-weight:700'>{op_pct:.1f}% of total alerts</span>",
1745
+ unsafe_allow_html=True
1746
+ )
1747
 
1748
+ # Risk message (tetap gunakan component Streamlit agar konsisten)
1749
+ if op_pct > 5:
1750
+ st.warning(f"Operator {op_name} has high fatigue risk ({op_pct:.1f}%). Consider coaching or rest plan.")
1751
+ else:
1752
+ st.info(f"Operator {op_name} fatigue risk is within acceptable range ({op_pct:.1f}%).")
1753
+
1754
+ else:
1755
+ st.info("Operator data not available for Operator Risk Profiling.")
1756
 
 
 
1757
 
1758
 
1759
  # Kolom kanan: AI Recommendations
 
1830
  # Ambil data_point dan ganti teks persentase di dalamnya menjadi warna merah
1831
  data_point_text = rec['data_point']
1832
  # Ganti pola persentase (X.X%) dengan span warna merah
1833
+ import re
1834
  # Cari pola seperti "1.6%", "21.2%", dll.
1835
  data_point_colored = re.sub(r'(\d+\.?\d*%)', r'<span style="color: red;">\1</span>', data_point_text)
1836
 
 
1879
 
1880
  # ================= FOOTER ===========================
1881
  st.markdown("---")
1882
+ st.markdown('<div class="footer">FatigueAnalyzer - Transforming Mining Safety with Intelligent Analytics | Contact: info@bukittechnology.com</div>', unsafe_allow_html=True)