SHELLAPANDIANGANHUNGING commited on
Commit
330a681
·
verified ·
1 Parent(s): 2103d03

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -41
app.py CHANGED
@@ -549,7 +549,7 @@ if 'temuan_kode_distrik' in df_local.columns:
549
  f"(<strong>{top_company_pg['avg_monthly_ratio']:.2f}</strong>), indicating potentially high exposure or active reporting. "
550
  f"Consider reviewing their operational procedures. "
551
  f"Conversely, <strong>{low_company_pg['nama_perusahaan']}</strong> has the lowest ratio "
552
- f"(<strong>{low_company_pg['avg_monthly_ratio']:.2f}</strong>), suggesting effective risk management or lower activity levels."
553
  f"</div>"
554
  )
555
  st.markdown(insight_text, unsafe_allow_html=True)
@@ -570,10 +570,10 @@ if 'temuan_kode_distrik' in df_local.columns:
570
  st.markdown("### Insight")
571
  insight_text = (
572
  f"<div class='ai-insight'>"
573
- f"In UM Area, <strong>{top_company_um['nama_perusahaan']}</strong> exhibits the highest average finding-to-person ratio "
574
- f"(<strong>{top_company_um['avg_monthly_ratio']:.2f}</strong>), warranting a focused safety audit. "
575
- f"<strong>{low_company_um['nama_perusahaan']}</strong> shows the lowest ratio "
576
- f"(<strong>{low_company_um['avg_monthly_ratio']:.2f}</strong>), which could reflect strong safety practices or requires verification of reporting completeness."
577
  f"</div>"
578
  )
579
  st.markdown(insight_text, unsafe_allow_html=True)
@@ -848,11 +848,11 @@ with col_3a:
848
  low = sorted_data.iloc[-1] if sort_option_3a == "Top 10" else sorted_data_all.iloc[0]
849
  insight_text = (
850
  f"<div class='ai-insight'>"
851
- f"The division <strong>{top['nama']}</strong> has the highest average finding-to-person ratio "
852
  f"(<strong>{top['avg_monthly_ratio']:.2f}</strong>). "
853
- f"<strong>{low['nama']}</strong> has the lowest ratio "
854
  f"(<strong>{low['avg_monthly_ratio']:.2f}</strong>). "
855
- f"Monitor high-ratio divisions for potential systemic issues and verify reporting completeness in low-ratio ones."
856
  f"</div>"
857
  )
858
  st.markdown(insight_text, unsafe_allow_html=True)
@@ -911,9 +911,9 @@ with col_3c:
911
  low = sorted_data.iloc[-1] if sort_option_3c == "Top 10" else sorted_data_all.iloc[0]
912
  insight_text = (
913
  f"<div class='ai-insight'>"
914
- f"The reporter <strong>{top['creator_name']}</strong> has the highest average monthly finding rate "
915
  f"(<strong>{top['avg_monthly_rate']:.2f}</strong>). "
916
- f"<strong>{low['creator_name']}</strong> has the lowest rate "
917
  f"(<strong>{low['avg_monthly_rate']:.2f}</strong>). "
918
  f"Recognize high performers and investigate low performers."
919
  f"</div>"
@@ -1124,7 +1124,7 @@ else:
1124
 
1125
 
1126
  # =================== 5. Matrix (Tetap Dipertahankan) ===================
1127
- st.markdown("<h3 class='section-title'>OBJECTIVE 5 - Findings vs Lead Time: Which Companies Move Slow?</h3>", unsafe_allow_html=True)
1128
 
1129
  import math
1130
  import plotly.express as px
@@ -1185,7 +1185,7 @@ try:
1185
  # 6. Merge Risk Matrix
1186
  # ============================
1187
  risk_matrix = operator_avg.merge(operator_lead, on='nama', how='left')
1188
- risk_matrix = risk_matrix.rename(columns={'nama': 'Operator Name'})
1189
  # Handle operator tanpa lead time (e.g., belum closed)
1190
  risk_matrix['Average Lead Time'] = risk_matrix['Average Lead Time'].fillna(0)
1191
  # ============================
@@ -1638,14 +1638,14 @@ df_category = predict_categories(df_filtered)
1638
 
1639
  # 🎯 PANEL 1: Creators (FILTERED: Coverage < 90% & Slope < 0)
1640
  st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1641
- st.markdown("<div class='predictive-header'>1. Which Reporters Are Predicted to Have No Future Inspections? (Top 10 Most Declining)</div>", unsafe_allow_html=True)
1642
  if not df_creator.empty:
1643
- cols = ['Creator', 'Avg Reports/Month', 'Coverage (%)', 'Trend Slope', 'Trend', 'Reason']
1644
 
1645
  # 🔥 Rename hanya untuk DISPLAY, bukan data asli
1646
- df_display = df_creator[cols].rename(columns={
1647
- "Reason": "Reason Forecast"
1648
- })
1649
 
1650
  html = df_display.to_html(escape=False, index=False, table_id="tbl-creators")
1651
  st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
@@ -1674,14 +1674,14 @@ st.markdown("</div>", unsafe_allow_html=True)
1674
 
1675
  # 🎯 PANEL 2: Locations (FILTERED: Coverage < 90% & Slope < 0)
1676
  st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1677
- st.markdown("<div class='predictive-header'>2. Which Locations Are Predicted to Have No Future Inspections? (Top 10 Most Declining)</div>", unsafe_allow_html=True)
1678
  if not df_location.empty:
1679
- cols = ['Location', 'Avg Reports/Month', 'Coverage (%)', 'Trend Slope', 'Trend', 'Reason']
1680
 
1681
- # 🔥 Rename hanya untuk DISPLAY, bukan data asli
1682
- df_display = df_location[cols].rename(columns={
1683
- "Reason": "Reason Forecast"
1684
- })
1685
 
1686
  html = df_display.to_html(escape=False, index=False, table_id="tbl-locations")
1687
  st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
@@ -1710,14 +1710,14 @@ st.markdown("</div>", unsafe_allow_html=True)
1710
 
1711
  # 🎯 PANEL 3: Divisions (FILTERED: Coverage < 90% & Slope < 0)
1712
  st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1713
- st.markdown("<div class='predictive-header'>3. Which Divisions Are Predicted to Have No Future Inspections? (Top 10 Most Declining)</div>", unsafe_allow_html=True)
1714
  if not df_division.empty:
1715
- cols = ['Division', 'Avg Reports/Month', 'Coverage (%)', 'Trend Slope', 'Trend', 'Reason']
1716
 
1717
- # 🔥 Rename hanya untuk DISPLAY, bukan data asli
1718
- df_display = df_division[cols].rename(columns={
1719
- "Reason": "Reason Forecast"
1720
- })
1721
 
1722
  html = df_display.to_html(escape=False, index=False, table_id="tbl-divisions")
1723
  st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
@@ -1748,7 +1748,7 @@ st.markdown("</div>", unsafe_allow_html=True)
1748
  # st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1749
  st.markdown(
1750
  "<div class='predictive-header'>"
1751
- "4. Which Issue Categories Are Likely to Appear in the Next 3 Months (Non-Positive Only)"
1752
  "<span style='font-size:0.75em; font-weight:400; color:#003DA5;'>"
1753
  " &nbsp;&nbsp;(* Categorization uses NLP — Natural Language Processing from random text)"
1754
  "</span>"
@@ -1808,9 +1808,9 @@ if not df_category.empty:
1808
  fig.add_trace(go.Scatter(
1809
  x=df_plot['Category'],
1810
  y=df_plot['Y'],
1811
- mode='markers+text',
1812
  marker=dict(
1813
- size=df_plot['Size'] * 0.5, # Skala ukuran agar tidak terlalu besar
1814
  color='#003DA5',
1815
  line=dict(width=2, color='white'),
1816
  opacity=0.8
@@ -1885,15 +1885,15 @@ if not df_category.empty:
1885
  st.plotly_chart(fig, use_container_width=True)
1886
 
1887
  # Insight
1888
- st.markdown("### 💡 Insight")
1889
- insight_text = (
1890
- f"<div class='ai-insight'>"
1891
- f"The scatter plot visualizes issue categories with 100% coverage and positive trend. "
1892
- f"Categories higher on the Y-axis indicate stronger upward trends, while larger circles indicate higher average monthly frequency. "
1893
- f"This helps identify which non-positive issues are both increasing in trend and frequently reported — these should be prioritized for intervention."
1894
- f"</div>"
1895
- )
1896
- st.markdown(insight_text, unsafe_allow_html=True)
1897
  else:
1898
  st.info("No data available for non-positive issue categories with 100% coverage and positive trend.")
1899
 
 
549
  f"(<strong>{top_company_pg['avg_monthly_ratio']:.2f}</strong>), indicating potentially high exposure or active reporting. "
550
  f"Consider reviewing their operational procedures. "
551
  f"Conversely, <strong>{low_company_pg['nama_perusahaan']}</strong> has the lowest ratio "
552
+ f"(<strong>{low_company_pg['avg_monthly_ratio']:.2f}</strong>), suggesting the need to actively improve reporting frequency."
553
  f"</div>"
554
  )
555
  st.markdown(insight_text, unsafe_allow_html=True)
 
570
  st.markdown("### Insight")
571
  insight_text = (
572
  f"<div class='ai-insight'>"
573
+ f"In UM Area, all companies show almost the same average finding per person ration"
574
+ # f"(<strong>{top_company_um['avg_monthly_ratio']:.2f}</strong>), warranting a focused safety audit. "
575
+ # f"<strong>{low_company_um['nama_perusahaan']}</strong> shows the lowest ratio "
576
+ # f"(<strong>{low_company_um['avg_monthly_ratio']:.2f}</strong>), which could reflect strong safety practices or requires verification of reporting completeness."
577
  f"</div>"
578
  )
579
  st.markdown(insight_text, unsafe_allow_html=True)
 
848
  low = sorted_data.iloc[-1] if sort_option_3a == "Top 10" else sorted_data_all.iloc[0]
849
  insight_text = (
850
  f"<div class='ai-insight'>"
851
+ f"The division <strong>{top['nama']}</strong> has the lowest average finding-to-person ratio "
852
  f"(<strong>{top['avg_monthly_ratio']:.2f}</strong>). "
853
+ f"<strong>{low['nama']}</strong> has the highest ratio "
854
  f"(<strong>{low['avg_monthly_ratio']:.2f}</strong>). "
855
+ f"Monitor low-ratio divisions for potential systemic issues and verify reporting completeness."
856
  f"</div>"
857
  )
858
  st.markdown(insight_text, unsafe_allow_html=True)
 
911
  low = sorted_data.iloc[-1] if sort_option_3c == "Top 10" else sorted_data_all.iloc[0]
912
  insight_text = (
913
  f"<div class='ai-insight'>"
914
+ f"The reporter <strong>{top['creator_name']}</strong> has the lowest average monthly finding rate "
915
  f"(<strong>{top['avg_monthly_rate']:.2f}</strong>). "
916
+ f"<strong>{low['creator_name']}</strong> has the highest rate "
917
  f"(<strong>{low['avg_monthly_rate']:.2f}</strong>). "
918
  f"Recognize high performers and investigate low performers."
919
  f"</div>"
 
1124
 
1125
 
1126
  # =================== 5. Matrix (Tetap Dipertahankan) ===================
1127
+ st.markdown("<h3 class='section-title'>OBJECTIVE 5 - Findings vs Lead Time: Which Divisions Move Slow?</h3>", unsafe_allow_html=True)
1128
 
1129
  import math
1130
  import plotly.express as px
 
1185
  # 6. Merge Risk Matrix
1186
  # ============================
1187
  risk_matrix = operator_avg.merge(operator_lead, on='nama', how='left')
1188
+ risk_matrix = risk_matrix.rename(columns={'nama': 'Division'})
1189
  # Handle operator tanpa lead time (e.g., belum closed)
1190
  risk_matrix['Average Lead Time'] = risk_matrix['Average Lead Time'].fillna(0)
1191
  # ============================
 
1638
 
1639
  # 🎯 PANEL 1: Creators (FILTERED: Coverage < 90% & Slope < 0)
1640
  st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1641
+ st.markdown("<div class='predictive-header'>1. Which Reporters Are Predicted to Have Less Future Inspections? (Top 10 Most Declining)</div>", unsafe_allow_html=True)
1642
  if not df_creator.empty:
1643
+ cols = ['Creator', 'Avg Reports/Month', 'Coverage (%)', 'Trend Slope', 'Trend']
1644
 
1645
  # 🔥 Rename hanya untuk DISPLAY, bukan data asli
1646
+ # df_display = df_creator[cols].rename(columns={
1647
+ # "Reason": "Reason Forecast"
1648
+ # })
1649
 
1650
  html = df_display.to_html(escape=False, index=False, table_id="tbl-creators")
1651
  st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
 
1674
 
1675
  # 🎯 PANEL 2: Locations (FILTERED: Coverage < 90% & Slope < 0)
1676
  st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1677
+ st.markdown("<div class='predictive-header'>2. Which Locations Are Predicted to Have Less Future Inspections? (Top 10 Most Declining)</div>", unsafe_allow_html=True)
1678
  if not df_location.empty:
1679
+ cols = ['Location', 'Avg Reports/Month', 'Coverage (%)', 'Trend Slope', 'Trend']
1680
 
1681
+ # # 🔥 Rename hanya untuk DISPLAY, bukan data asli
1682
+ # df_display = df_location[cols].rename(columns={
1683
+ # "Reason": "Reason Forecast"
1684
+ # })
1685
 
1686
  html = df_display.to_html(escape=False, index=False, table_id="tbl-locations")
1687
  st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
 
1710
 
1711
  # 🎯 PANEL 3: Divisions (FILTERED: Coverage < 90% & Slope < 0)
1712
  st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1713
+ st.markdown("<div class='predictive-header'>3. Which Divisions Are Predicted to Have Less Future Inspections? (Top 10 Most Declining)</div>", unsafe_allow_html=True)
1714
  if not df_division.empty:
1715
+ cols = ['Division', 'Avg Reports/Month', 'Coverage (%)', 'Trend Slope', 'Trend']
1716
 
1717
+ # # 🔥 Rename hanya untuk DISPLAY, bukan data asli
1718
+ # df_display = df_division[cols].rename(columns={
1719
+ # "Reason": "Reason Forecast"
1720
+ # })
1721
 
1722
  html = df_display.to_html(escape=False, index=False, table_id="tbl-divisions")
1723
  st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
 
1748
  # st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
1749
  st.markdown(
1750
  "<div class='predictive-header'>"
1751
+ "4. Which Issue Categories Are Likely to Appear in the Next 3 Months (Increasing Trend Only)"
1752
  "<span style='font-size:0.75em; font-weight:400; color:#003DA5;'>"
1753
  " &nbsp;&nbsp;(* Categorization uses NLP — Natural Language Processing from random text)"
1754
  "</span>"
 
1808
  fig.add_trace(go.Scatter(
1809
  x=df_plot['Category'],
1810
  y=df_plot['Y'],
1811
+ mode='markers',
1812
  marker=dict(
1813
+ size=df_plot['Size'] * 1.5, # Skala ukuran agar tidak terlalu besar
1814
  color='#003DA5',
1815
  line=dict(width=2, color='white'),
1816
  opacity=0.8
 
1885
  st.plotly_chart(fig, use_container_width=True)
1886
 
1887
  # Insight
1888
+ # st.markdown("### 💡 Insight")
1889
+ # insight_text = (
1890
+ # f"<div class='ai-insight'>"
1891
+ # f"The scatter plot visualizes issue categories with 100% coverage and positive trend. "
1892
+ # f"Categories higher on the Y-axis indicate stronger upward trends, while larger circles indicate higher average monthly frequency. "
1893
+ # f"This helps identify which non-positive issues are both increasing in trend and frequently reported — these should be prioritized for intervention."
1894
+ # f"</div>"
1895
+ # )
1896
+ # st.markdown(insight_text, unsafe_allow_html=True)
1897
  else:
1898
  st.info("No data available for non-positive issue categories with 100% coverage and positive trend.")
1899