irhamni commited on
Commit
14cdebf
·
verified ·
1 Parent(s): e7b287d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -11
app.py CHANGED
@@ -607,7 +607,7 @@ def load_default_files(force=False):
607
  # 6) FAKTOR WILAYAH (TOTAL) — hanya untuk faktor/target/pop/coverage
608
  # ============================================================
609
 
610
- def build_faktor_wilayah(df_filtered: pd.DataFrame, pop_kab: pd.DataFrame, pop_prov: pd.DataFrame, kew_value: str):
611
  if df_filtered is None or df_filtered.empty:
612
  return pd.DataFrame()
613
 
@@ -622,6 +622,7 @@ def build_faktor_wilayah(df_filtered: pd.DataFrame, pop_kab: pd.DataFrame, pop_p
622
  target_field = "Target68_Total"
623
  pop_field = "Pop_Total"
624
  name_field = "Kab_Kota_Label"
 
625
  elif "PROV" in kew_norm:
626
  key_col = "prov_key"
627
  label_col = "PROV_DISP"
@@ -630,6 +631,7 @@ def build_faktor_wilayah(df_filtered: pd.DataFrame, pop_kab: pd.DataFrame, pop_p
630
  target_field = "Target68_Total_Prov"
631
  pop_field = "Pop_Total_Prov"
632
  name_field = "Provinsi_Label"
 
633
  else:
634
  key_col = "kab_key"
635
  label_col = "KAB_DISP"
@@ -638,11 +640,13 @@ def build_faktor_wilayah(df_filtered: pd.DataFrame, pop_kab: pd.DataFrame, pop_p
638
  target_field = "Target68_Total"
639
  pop_field = "Pop_Total"
640
  name_field = "Kab_Kota_Label"
 
641
 
642
  base = df.groupby([key_col, label_col], dropna=False).agg(
643
  n_total=("Indeks_Dasar_0_100", "size"),
644
  ).reset_index().rename(columns={key_col: "group_key", label_col: label_name})
645
 
 
646
  target_vals, pop_vals, label_fix = [], [], []
647
  for _, r in base.iterrows():
648
  gk = r["group_key"]
@@ -660,33 +664,59 @@ def build_faktor_wilayah(df_filtered: pd.DataFrame, pop_kab: pd.DataFrame, pop_p
660
  base["target_total_68"] = pd.to_numeric(pd.Series(target_vals), errors="coerce")
661
  base["pop_total"] = pd.to_numeric(pd.Series(pop_vals), errors="coerce")
662
 
 
663
  m = base["pop_total"].isna() & base["target_total_68"].notna() & (base["target_total_68"] > 0)
664
  base.loc[m, "pop_total"] = base.loc[m, "target_total_68"] / float(FALLBACK_TARGET_RATIO)
665
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
  base["faktor_penyesuaian"] = [
667
  faktor_penyesuaian_total(n, t)
668
  for n, t in zip(
669
  pd.to_numeric(base["n_total"], errors="coerce").fillna(0).astype(float).tolist(),
670
- pd.to_numeric(base["target_total_68"], errors="coerce").tolist()
671
  )
672
  ]
673
 
 
674
  base["coverage_total_%"] = [
675
  (safe_div(n, p) * 100) if (p is not None and not pd.isna(p) and float(p) > 0) else np.nan
676
  for n, p in zip(
677
  pd.to_numeric(base["n_total"], errors="coerce").fillna(0).astype(float).tolist(),
678
- base["pop_total"].tolist()
679
  )
680
  ]
681
 
682
- # ====== UPDATE SESUAI PERMINTAAN (DISPLAY) ======
683
- # 1) target_total_68 bulat
684
- # 2) pop_total bulat
685
- # 3) coverage_total_% 2 desimal
686
  base["target_total_68"] = pd.to_numeric(base["target_total_68"], errors="coerce").fillna(0).round(0).astype(int)
687
- base["pop_total"] = pd.to_numeric(base["pop_total"], errors="coerce").fillna(0).round(0).astype(int)
688
- base["coverage_total_%"] = pd.to_numeric(base["coverage_total_%"], errors="coerce").fillna(0.0).round(2)
689
- # tetap seperti sebelumnya:
690
  base["faktor_penyesuaian"] = pd.to_numeric(base["faktor_penyesuaian"], errors="coerce").fillna(1.0).round(3)
691
 
692
  return base
@@ -1495,7 +1525,7 @@ def run_calc(prov_value, kab_value, kew_value, df_all, df_raw, pop_kab, pop_prov
1495
  return _empty_outputs("Tidak ada data untuk filter ini.")
1496
 
1497
  # ==== PIPELINE BARU (KUNCI KONSISTENSI) ====
1498
- faktor_wilayah = build_faktor_wilayah(df, pop_kab, pop_prov, kew_value or "(Semua)")
1499
  agg_jenis_full = build_agg_wilayah_jenis(df, faktor_wilayah, pop_khusus, kew_value or "(Semua)")
1500
  agg_total = build_agg_wilayah_total_from_jenis(agg_jenis_full, faktor_wilayah, pop_khusus, kew_value or "(Semua)")
1501
  summary_jenis = build_summary_per_jenis(agg_jenis_full, agg_total)
 
607
  # 6) FAKTOR WILAYAH (TOTAL) — hanya untuk faktor/target/pop/coverage
608
  # ============================================================
609
 
610
+ def build_faktor_wilayah(df_filtered: pd.DataFrame, pop_kab: pd.DataFrame, pop_prov: pd.DataFrame, pop_khusus: pd.DataFrame, kew_value: str):
611
  if df_filtered is None or df_filtered.empty:
612
  return pd.DataFrame()
613
 
 
622
  target_field = "Target68_Total"
623
  pop_field = "Pop_Total"
624
  name_field = "Kab_Kota_Label"
625
+ khusus_group_key = "kab_key"
626
  elif "PROV" in kew_norm:
627
  key_col = "prov_key"
628
  label_col = "PROV_DISP"
 
631
  target_field = "Target68_Total_Prov"
632
  pop_field = "Pop_Total_Prov"
633
  name_field = "Provinsi_Label"
634
+ khusus_group_key = "prov_key"
635
  else:
636
  key_col = "kab_key"
637
  label_col = "KAB_DISP"
 
640
  target_field = "Target68_Total"
641
  pop_field = "Pop_Total"
642
  name_field = "Kab_Kota_Label"
643
+ khusus_group_key = "kab_key"
644
 
645
  base = df.groupby([key_col, label_col], dropna=False).agg(
646
  n_total=("Indeks_Dasar_0_100", "size"),
647
  ).reset_index().rename(columns={key_col: "group_key", label_col: label_name})
648
 
649
+ # --- ambil target & pop dari POP_KAB / POP_PROV (existing) ---
650
  target_vals, pop_vals, label_fix = [], [], []
651
  for _, r in base.iterrows():
652
  gk = r["group_key"]
 
664
  base["target_total_68"] = pd.to_numeric(pd.Series(target_vals), errors="coerce")
665
  base["pop_total"] = pd.to_numeric(pd.Series(pop_vals), errors="coerce")
666
 
667
+ # fallback pop dari target kalau pop kosong
668
  m = base["pop_total"].isna() & base["target_total_68"].notna() & (base["target_total_68"] > 0)
669
  base.loc[m, "pop_total"] = base.loc[m, "target_total_68"] / float(FALLBACK_TARGET_RATIO)
670
 
671
+ # =========================================================
672
+ # ✅ UPDATE LO: Tambahkan komponen KHUSUS dari POP_KHUSUS
673
+ # target_total_68 += target_khusus
674
+ # pop_total += pop_khusus
675
+ # =========================================================
676
+ if (pop_khusus is not None) and (not pop_khusus.empty):
677
+ pk = pop_khusus.copy()
678
+
679
+ # pastikan numeric
680
+ pk["Target68_Total_Jenis"] = pd.to_numeric(pk.get("Target68_Total_Jenis", 0), errors="coerce").fillna(0.0)
681
+ pk["Pop_Total_Jenis"] = pd.to_numeric(pk.get("Pop_Total_Jenis", 0), errors="coerce").fillna(0.0)
682
+
683
+ if khusus_group_key in pk.columns:
684
+ add_df = pk.groupby(khusus_group_key, as_index=False).agg(
685
+ add_target=("Target68_Total_Jenis", "sum"),
686
+ add_pop=("Pop_Total_Jenis", "sum"),
687
+ ).rename(columns={khusus_group_key: "group_key"})
688
+
689
+ base = base.merge(add_df, on="group_key", how="left")
690
+ base["add_target"] = pd.to_numeric(base.get("add_target", 0), errors="coerce").fillna(0.0)
691
+ base["add_pop"] = pd.to_numeric(base.get("add_pop", 0), errors="coerce").fillna(0.0)
692
+
693
+ base["target_total_68"] = pd.to_numeric(base.get("target_total_68", 0), errors="coerce").fillna(0.0) + base["add_target"]
694
+ base["pop_total"] = pd.to_numeric(base.get("pop_total", 0), errors="coerce").fillna(0.0) + base["add_pop"]
695
+
696
+ base = base.drop(columns=[c for c in ["add_target", "add_pop"] if c in base.columns])
697
+
698
+ # faktor penyesuaian pakai TOTAL baru
699
  base["faktor_penyesuaian"] = [
700
  faktor_penyesuaian_total(n, t)
701
  for n, t in zip(
702
  pd.to_numeric(base["n_total"], errors="coerce").fillna(0).astype(float).tolist(),
703
+ pd.to_numeric(base["target_total_68"], errors="coerce").fillna(0).astype(float).tolist()
704
  )
705
  ]
706
 
707
+ # coverage pakai TOTAL baru
708
  base["coverage_total_%"] = [
709
  (safe_div(n, p) * 100) if (p is not None and not pd.isna(p) and float(p) > 0) else np.nan
710
  for n, p in zip(
711
  pd.to_numeric(base["n_total"], errors="coerce").fillna(0).astype(float).tolist(),
712
+ pd.to_numeric(base["pop_total"], errors="coerce").fillna(0).astype(float).tolist()
713
  )
714
  ]
715
 
716
+ # ===== display fix (sesuai permintaan lo sebelumnya) =====
 
 
 
717
  base["target_total_68"] = pd.to_numeric(base["target_total_68"], errors="coerce").fillna(0).round(0).astype(int)
718
+ base["pop_total"] = pd.to_numeric(base["pop_total"], errors="coerce").fillna(0).round(0).astype(int)
719
+ base["coverage_total_%"]= pd.to_numeric(base["coverage_total_%"], errors="coerce").fillna(0.0).round(2)
 
720
  base["faktor_penyesuaian"] = pd.to_numeric(base["faktor_penyesuaian"], errors="coerce").fillna(1.0).round(3)
721
 
722
  return base
 
1525
  return _empty_outputs("Tidak ada data untuk filter ini.")
1526
 
1527
  # ==== PIPELINE BARU (KUNCI KONSISTENSI) ====
1528
+ faktor_wilayah = build_faktor_wilayah(df, pop_kab, pop_prov, pop_khusus, kew_value or "(Semua)")
1529
  agg_jenis_full = build_agg_wilayah_jenis(df, faktor_wilayah, pop_khusus, kew_value or "(Semua)")
1530
  agg_total = build_agg_wilayah_total_from_jenis(agg_jenis_full, faktor_wilayah, pop_khusus, kew_value or "(Semua)")
1531
  summary_jenis = build_summary_per_jenis(agg_jenis_full, agg_total)