irhamni commited on
Commit
5016ed8
·
verified ·
1 Parent(s): ba3da9f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -45
app.py CHANGED
@@ -605,8 +605,8 @@ def load_default_files(force=False):
605
 
606
  # ============================================================
607
  # 6) FAKTOR WILAYAH (TOTAL) — hanya untuk faktor/target/pop/coverage
608
- # UPDATE: total wilayah (pop_total & target_total_68) ditambah kontribusi POP_KHUSUS
609
- # TANPA bikin kolom khusus baru (langsung dijumlahkan)
610
  # ============================================================
611
 
612
  def build_faktor_wilayah(
@@ -631,15 +631,16 @@ def build_faktor_wilayah(
631
  pop_field = "Pop_Total"
632
  name_field = "Kab_Kota_Label"
633
 
634
- # khs (kab) -> pakai kab_key
635
- khs = pop_khusus.copy() if (pop_khusus is not None and not pop_khusus.empty) else pd.DataFrame()
636
- if not khs.empty and "kab_key" in khs.columns:
637
- khs_kab = khs.groupby("kab_key", as_index=False).agg({
638
  "Target68_Total_Jenis": "sum",
639
  "Pop_Total_Jenis": "sum"
640
  }).set_index("kab_key")
641
  else:
642
- khs_kab = pd.DataFrame().set_index(pd.Index([]))
 
 
643
 
644
  elif "PROV" in kew_norm:
645
  key_col = "prov_key"
@@ -650,17 +651,19 @@ def build_faktor_wilayah(
650
  pop_field = "Pop_Total_Prov"
651
  name_field = "Provinsi_Label"
652
 
653
- # khs (prov) -> agregasi dari pop_khusus ke prov_key
654
- khs = pop_khusus.copy() if (pop_khusus is not None and not pop_khusus.empty) else pd.DataFrame()
655
- if not khs.empty and "prov_key" in khs.columns:
656
- khs_prov = khs.groupby("prov_key", as_index=False).agg({
657
  "Target68_Total_Jenis": "sum",
658
  "Pop_Total_Jenis": "sum"
659
  }).set_index("prov_key")
660
  else:
661
- khs_prov = pd.DataFrame().set_index(pd.Index([]))
 
 
662
 
663
  else:
 
664
  key_col = "kab_key"
665
  label_col = "KAB_DISP"
666
  label_name = "Kab/Kota"
@@ -669,14 +672,15 @@ def build_faktor_wilayah(
669
  pop_field = "Pop_Total"
670
  name_field = "Kab_Kota_Label"
671
 
672
- khs = pop_khusus.copy() if (pop_khusus is not None and not pop_khusus.empty) else pd.DataFrame()
673
- if not khs.empty and "kab_key" in khs.columns:
674
- khs_kab = khs.groupby("kab_key", as_index=False).agg({
675
  "Target68_Total_Jenis": "sum",
676
  "Pop_Total_Jenis": "sum"
677
  }).set_index("kab_key")
678
  else:
679
- khs_kab = pd.DataFrame().set_index(pd.Index([]))
 
 
680
 
681
  base = df.groupby([key_col, label_col], dropna=False).agg(
682
  n_total=("Indeks_Dasar_0_100", "size"),
@@ -686,7 +690,7 @@ def build_faktor_wilayah(
686
  for _, r in base.iterrows():
687
  gk = r["group_key"]
688
 
689
- # ===== ambil target/pop dari POP utama (kab/prov) =====
690
  if gk in pop.index:
691
  target_total = pop.loc[gk, target_field] if target_field in pop.columns else np.nan
692
  pop_total = pop.loc[gk, pop_field] if pop_field in pop.columns else np.nan
@@ -694,35 +698,25 @@ def build_faktor_wilayah(
694
  else:
695
  target_total, pop_total, nm = np.nan, np.nan, r[label_name]
696
 
697
- # ===== UPDATE: tambah target/pop dari POP_KHUSUS (langsung dijumlah) =====
698
  add_target, add_pop = 0.0, 0.0
699
  if "PROV" in kew_norm:
700
- if "khs_prov" in locals() and (gk in khs_prov.index):
701
- add_target = khs_prov.loc[gk, "Target68_Total_Jenis"] if "Target68_Total_Jenis" in khs_prov.columns else 0.0
702
- add_pop = khs_prov.loc[gk, "Pop_Total_Jenis"] if "Pop_Total_Jenis" in khs_prov.columns else 0.0
703
  else:
704
- if "khs_kab" in locals() and (gk in khs_kab.index):
705
- add_target = khs_kab.loc[gk, "Target68_Total_Jenis"] if "Target68_Total_Jenis" in khs_kab.columns else 0.0
706
- add_pop = khs_kab.loc[gk, "Pop_Total_Jenis"] if "Pop_Total_Jenis" in khs_kab.columns else 0.0
707
-
708
- try:
709
- add_target = float(pd.to_numeric(add_target, errors="coerce") or 0.0)
710
- except Exception:
711
- add_target = 0.0
712
- try:
713
- add_pop = float(pd.to_numeric(add_pop, errors="coerce") or 0.0)
714
- except Exception:
715
- add_pop = 0.0
716
-
717
- # jumlahkan (kalau NaN -> treat 0 dulu)
718
  t0 = float(pd.to_numeric(target_total, errors="coerce")) if pd.notna(target_total) else 0.0
719
  p0 = float(pd.to_numeric(pop_total, errors="coerce")) if pd.notna(pop_total) else 0.0
 
 
720
 
721
- target_total = t0 + add_target
722
- pop_total = p0 + add_pop
723
-
724
- target_vals.append(target_total)
725
- pop_vals.append(pop_total)
726
  label_fix.append(nm)
727
 
728
  base[label_name] = label_fix
@@ -733,7 +727,7 @@ def build_faktor_wilayah(
733
  m = base["pop_total"].isna() & base["target_total_68"].notna() & (base["target_total_68"] > 0)
734
  base.loc[m, "pop_total"] = base.loc[m, "target_total_68"] / float(FALLBACK_TARGET_RATIO)
735
 
736
- # faktor pakai target_total_68 yang SUDAH ditambah khusus
737
  base["faktor_penyesuaian"] = [
738
  faktor_penyesuaian_total(n, t)
739
  for n, t in zip(
@@ -750,7 +744,7 @@ def build_faktor_wilayah(
750
  )
751
  ]
752
 
753
- # ====== UPDATE SESUAI PERMINTAAN (DISPLAY) ======
754
  base["target_total_68"] = pd.to_numeric(base["target_total_68"], errors="coerce").fillna(0).round(0).astype(int)
755
  base["pop_total"] = pd.to_numeric(base["pop_total"], errors="coerce").fillna(0).round(0).astype(int)
756
  base["coverage_total_%"] = pd.to_numeric(base["coverage_total_%"], errors="coerce").fillna(0.0).round(2)
@@ -758,7 +752,6 @@ def build_faktor_wilayah(
758
 
759
  return base
760
 
761
-
762
  # ============================================================
763
  # 7) AGREGAT WILAYAH × JENIS (Final pakai faktor wilayah)
764
  # ============================================================
@@ -1495,6 +1488,17 @@ def generate_word_report(wilayah, summary_jenis, agg_total, agg_jenis, analysis_
1495
  # 15) CORE RUN
1496
  # ============================================================
1497
 
 
 
 
 
 
 
 
 
 
 
 
1498
  def run_calc(prov_value, kab_value, kew_value, df_all, df_raw, pop_kab, pop_prov, pop_khusus, meta):
1499
  try:
1500
  if df_all is None or df_all.empty or df_raw is None or df_raw.empty:
@@ -1513,7 +1517,6 @@ def run_calc(prov_value, kab_value, kew_value, df_all, df_raw, pop_kab, pop_prov
1513
  return _empty_outputs("Tidak ada data untuk filter ini.")
1514
 
1515
  # ==== PIPELINE BARU (KUNCI KONSISTENSI) ====
1516
- # UPDATE: faktor_wilayah sekarang menambahkan POP_KHUSUS ke target_total_68 & pop_total (total wilayah)
1517
  faktor_wilayah = build_faktor_wilayah(df, pop_kab, pop_prov, pop_khusus, kew_value or "(Semua)")
1518
  agg_jenis_full = build_agg_wilayah_jenis(df, faktor_wilayah, pop_khusus, kew_value or "(Semua)")
1519
  agg_total = build_agg_wilayah_total_from_jenis(agg_jenis_full, faktor_wilayah, kew_value or "(Semua)")
@@ -1540,7 +1543,6 @@ def run_calc(prov_value, kab_value, kew_value, df_all, df_raw, pop_kab, pop_prov
1540
  cols_upto = [c for c in cols_upto if c in agg_jenis_full.columns]
1541
  agg_jenis_view = agg_jenis_full[cols_upto].copy()
1542
 
1543
-
1544
  # FILTER RAW DOWNLOAD (df_raw)
1545
  raw = df_raw.copy()
1546
  if prov_value and prov_value != "(Semua)":
 
605
 
606
  # ============================================================
607
  # 6) FAKTOR WILAYAH (TOTAL) — hanya untuk faktor/target/pop/coverage
608
+ # UPDATE: pop_total & target_total_68 wilayah ditambah data KHUSUS (POP_KHUSUS)
609
+ # TANPA ubah logika faktor (tetap min(n_total/target,1))
610
  # ============================================================
611
 
612
  def build_faktor_wilayah(
 
631
  pop_field = "Pop_Total"
632
  name_field = "Kab_Kota_Label"
633
 
634
+ # agregat KHUSUS per kab_key (sum)
635
+ if pop_khusus is not None and not pop_khusus.empty and "kab_key" in pop_khusus.columns:
636
+ pk_kab = pop_khusus.groupby("kab_key", as_index=False).agg({
 
637
  "Target68_Total_Jenis": "sum",
638
  "Pop_Total_Jenis": "sum"
639
  }).set_index("kab_key")
640
  else:
641
+ pk_kab = pd.DataFrame().set_index(pd.Index([]))
642
+
643
+ pk_prov = None # tidak dipakai
644
 
645
  elif "PROV" in kew_norm:
646
  key_col = "prov_key"
 
651
  pop_field = "Pop_Total_Prov"
652
  name_field = "Provinsi_Label"
653
 
654
+ # agregat KHUSUS per prov_key (sum)
655
+ if pop_khusus is not None and not pop_khusus.empty and "prov_key" in pop_khusus.columns:
656
+ pk_prov = pop_khusus.groupby("prov_key", as_index=False).agg({
 
657
  "Target68_Total_Jenis": "sum",
658
  "Pop_Total_Jenis": "sum"
659
  }).set_index("prov_key")
660
  else:
661
+ pk_prov = pd.DataFrame().set_index(pd.Index([]))
662
+
663
+ pk_kab = None # tidak dipakai
664
 
665
  else:
666
+ # fallback: perlakukan seperti kab/kota
667
  key_col = "kab_key"
668
  label_col = "KAB_DISP"
669
  label_name = "Kab/Kota"
 
672
  pop_field = "Pop_Total"
673
  name_field = "Kab_Kota_Label"
674
 
675
+ if pop_khusus is not None and not pop_khusus.empty and "kab_key" in pop_khusus.columns:
676
+ pk_kab = pop_khusus.groupby("kab_key", as_index=False).agg({
 
677
  "Target68_Total_Jenis": "sum",
678
  "Pop_Total_Jenis": "sum"
679
  }).set_index("kab_key")
680
  else:
681
+ pk_kab = pd.DataFrame().set_index(pd.Index([]))
682
+
683
+ pk_prov = None
684
 
685
  base = df.groupby([key_col, label_col], dropna=False).agg(
686
  n_total=("Indeks_Dasar_0_100", "size"),
 
690
  for _, r in base.iterrows():
691
  gk = r["group_key"]
692
 
693
+ # --- ambil dari POP_KAB/POP_PROV (existing) ---
694
  if gk in pop.index:
695
  target_total = pop.loc[gk, target_field] if target_field in pop.columns else np.nan
696
  pop_total = pop.loc[gk, pop_field] if pop_field in pop.columns else np.nan
 
698
  else:
699
  target_total, pop_total, nm = np.nan, np.nan, r[label_name]
700
 
701
+ # --- TAMBAH KHUSUS (ini inti request kamu) ---
702
  add_target, add_pop = 0.0, 0.0
703
  if "PROV" in kew_norm:
704
+ if pk_prov is not None and (gk in pk_prov.index):
705
+ add_target = pk_prov.loc[gk, "Target68_Total_Jenis"] if "Target68_Total_Jenis" in pk_prov.columns else 0.0
706
+ add_pop = pk_prov.loc[gk, "Pop_Total_Jenis"] if "Pop_Total_Jenis" in pk_prov.columns else 0.0
707
  else:
708
+ if pk_kab is not None and (gk in pk_kab.index):
709
+ add_target = pk_kab.loc[gk, "Target68_Total_Jenis"] if "Target68_Total_Jenis" in pk_kab.columns else 0.0
710
+ add_pop = pk_kab.loc[gk, "Pop_Total_Jenis"] if "Pop_Total_Jenis" in pk_kab.columns else 0.0
711
+
712
+ # amanin numeric
 
 
 
 
 
 
 
 
 
713
  t0 = float(pd.to_numeric(target_total, errors="coerce")) if pd.notna(target_total) else 0.0
714
  p0 = float(pd.to_numeric(pop_total, errors="coerce")) if pd.notna(pop_total) else 0.0
715
+ at = float(pd.to_numeric(add_target, errors="coerce")) if pd.notna(add_target) else 0.0
716
+ ap = float(pd.to_numeric(add_pop, errors="coerce")) if pd.notna(add_pop) else 0.0
717
 
718
+ target_vals.append(t0 + at)
719
+ pop_vals.append(p0 + ap)
 
 
 
720
  label_fix.append(nm)
721
 
722
  base[label_name] = label_fix
 
727
  m = base["pop_total"].isna() & base["target_total_68"].notna() & (base["target_total_68"] > 0)
728
  base.loc[m, "pop_total"] = base.loc[m, "target_total_68"] / float(FALLBACK_TARGET_RATIO)
729
 
730
+ # logika faktor TIDAK DIUBAH
731
  base["faktor_penyesuaian"] = [
732
  faktor_penyesuaian_total(n, t)
733
  for n, t in zip(
 
744
  )
745
  ]
746
 
747
+ # ====== DISPLAY (sesuai permintaan awal kamu) ======
748
  base["target_total_68"] = pd.to_numeric(base["target_total_68"], errors="coerce").fillna(0).round(0).astype(int)
749
  base["pop_total"] = pd.to_numeric(base["pop_total"], errors="coerce").fillna(0).round(0).astype(int)
750
  base["coverage_total_%"] = pd.to_numeric(base["coverage_total_%"], errors="coerce").fillna(0.0).round(2)
 
752
 
753
  return base
754
 
 
755
  # ============================================================
756
  # 7) AGREGAT WILAYAH × JENIS (Final pakai faktor wilayah)
757
  # ============================================================
 
1488
  # 15) CORE RUN
1489
  # ============================================================
1490
 
1491
+ def _empty_outputs(msg="⚠️ Data belum siap."):
1492
+ empty = pd.DataFrame()
1493
+ empty_fig = go.Figure()
1494
+ return (
1495
+ "", # kpi_md
1496
+ empty, empty, empty, empty, empty,
1497
+ None, None, None, None, None,
1498
+ empty_fig, empty_fig, empty_fig,
1499
+ msg, "Analisis belum tersedia."
1500
+ )
1501
+
1502
  def run_calc(prov_value, kab_value, kew_value, df_all, df_raw, pop_kab, pop_prov, pop_khusus, meta):
1503
  try:
1504
  if df_all is None or df_all.empty or df_raw is None or df_raw.empty:
 
1517
  return _empty_outputs("Tidak ada data untuk filter ini.")
1518
 
1519
  # ==== PIPELINE BARU (KUNCI KONSISTENSI) ====
 
1520
  faktor_wilayah = build_faktor_wilayah(df, pop_kab, pop_prov, pop_khusus, kew_value or "(Semua)")
1521
  agg_jenis_full = build_agg_wilayah_jenis(df, faktor_wilayah, pop_khusus, kew_value or "(Semua)")
1522
  agg_total = build_agg_wilayah_total_from_jenis(agg_jenis_full, faktor_wilayah, kew_value or "(Semua)")
 
1543
  cols_upto = [c for c in cols_upto if c in agg_jenis_full.columns]
1544
  agg_jenis_view = agg_jenis_full[cols_upto].copy()
1545
 
 
1546
  # FILTER RAW DOWNLOAD (df_raw)
1547
  raw = df_raw.copy()
1548
  if prov_value and prov_value != "(Semua)":