Analisis yang tidak sampai ke pembuat keputusan adalah analisis yang setengah jadi. Pipeline proyek ini menutup pekerjaannya dengan menulis laporan/laporan-akhir.txt — teks polos berisi ringkasan data, statistik, temuan, rekomendasi, dan keterbatasan. Bagian terakhir ini membaca laporan tersebut dari baris pertama sampai baris terakhir: membedah strukturnya, memeriksa satu klaim angkanya terhadap data, menimbang rekomendasi bagi Bu Warni, dan merefleksikan apa yang sudah — dan belum — bisa kita simpulkan. Kita tutup dengan refleksi proyek dan jembatan menuju proyek berikutnya.
Laporan yang Ditulis Pipeline, Bukan Diketik #
Fungsi susun_laporan() pada src/analisis_harga.py merangkai seluruh laporan dari nilai yang sudah dihitung: statistik dari statistik_harga(), lonjakan dari ringkasan_cabai(), tren dari tren_akhir(). Tidak ada satu angka pun yang diketik tangan ke dalam laporan, sehingga tidak ada ruang untuk salah salin. Bila musim depan Bu Warni mengganti berkas data dengan catatan delapan pekan yang baru, menjalankan ulang pipeline akan menghasilkan laporan baru dengan bentuk yang konsisten. Struktur enam bagiannya tampak sebagai berikut:
====================================================================
LAPORAN AKHIR - ANALISIS HARGA KOMODITAS (ringkas)
====================================================================
1. RINGKASAN DATA asal data, satuan, 41 baris mentah -> 40 bersih
2. STATISTIK HARGA tabel mean, std, min, max, cv untuk 5 komoditas
3. TEMUAN UTAMA empat temuan T1-T4 lengkap dengan angka kuncinya
4. PERUBAHAN TERBESAR lima perubahan pekan-ke-pekan terbesar
5. REKOMENDASI empat rekomendasi R1-R4 untuk Bu Warni
6. KETERBATASAN ANALISIS batas tafsir: 8 pekan, satu pasar, satu imputasiBlok berikut membuka berkas laporan dari folder proyek dan mencetak judul tiap bagiannya — bukti bahwa strukturnya bisa dipetakan secara mekanis, bukan hanya dikenali oleh penulisnya:
import re
from pathlib import Path
laporan = Path("../laporan/laporan-akhir.txt").read_text(encoding="utf-8")
baris_laporan = laporan.splitlines()
print("Berkas : laporan/laporan-akhir.txt")
print(f"Panjang : {len(baris_laporan)} baris")
print()
print("Enam bagian laporan:")
for baris in baris_laporan:
if re.match(r"^[0-9]+\. [A-Z]", baris):
print(" " + baris)Output yang Dihasilkan:
Berkas : laporan/laporan-akhir.txt
Panjang : 80 baris
Enam bagian laporan:
1. RINGKASAN DATA
2. STATISTIK HARGA PER KOMODITAS (ribu rupiah per kg)
3. TEMUAN UTAMA
4. PERUBAHAN PEKAN-KE-PEKAN TERBESAR
5. REKOMENDASI UNTUK BU WARNI
6. KETERBATASAN ANALISISDua baris pertama blok tersebut membaca seluruh isi berkas dan memecahnya menjadi daftar baris; pola ^[0-9]+\. [A-Z] kemudian menangkap judul bagian yang diawali nomor dan huruf kapital. Laporan 80 baris itu memang ringkas — cukup panjang untuk memuat seluruh temuan, cukup pendek untuk dibaca Bu Warni sambil menunggu nasi matang. Prinsip menyusun laporan untuk pembaca non-teknis dibahas pada chapter Membuat Laporan untuk Non-Teknis
.
Temuan Utama dan Angka Kuncinya #
Bagian 3 laporan merangkum empat temuan yang sudah kita bangun sepanjang Bagian 5–8:
| Temuan | Isi singkat | Angka kunci |
|---|---|---|
| T1 | Cabai merah melonjak pada M4–M5 lalu pulih | 42.0 → 65.0 → 78.0 (naik 85.7% dari M3 ke M5), puncak 2.05 kali harga M1, kembali ke 40.0 pada M8 |
| T2 | Beras dan gula pasir paling stabil | Kisaran beras 13.0–13.5 (cv 1.21%), gula pasir 17.5–17.8 (cv 0.68%) |
| T3 | Ayam broiler menanjak tipis tetapi konsisten | 33.0 (M1) → 35.2 (M8), +6.7%, 6 dari 7 pekan naik |
| T4 | Bawang merah bergejolak sedang | Kisaran 30.0–36.0 (cv 6.10%), dua lompatan terbesar +16.1% dan +13.3% |
Bagian 4 laporan melengkapi daftar tersebut dengan lima perubahan pekan-ke-pekan terbesar — empat di antaranya milik cabai merah, dipimpin lonjakan +54.8% pada M3 → M4. Angka sekeras apa pun pada laporan selayaknya diperiksa ulang sebelum dipercaya, kebiasaan yang kita latih pada chapter Pemeriksaan Kualitas Hasil . Sebagai contoh, kita hitung ulang klaim yang paling sering dikutip dari temuan T1:
import pandas as pd
# Resep pembersihan Bagian 4: 41 baris mentah menjadi 40 baris bersih.
df = pd.read_csv("../data/harga_komoditas.csv")
df = df.drop_duplicates(subset=["minggu", "komoditas"], keep="first").copy()
df["komoditas"] = df["komoditas"].str.strip().str.lower()
df["harga_rata_ribu"] = pd.to_numeric(df["harga_rata_ribu"], errors="coerce")
df = df.sort_values(["komoditas", "minggu"])
df["harga_rata_ribu"] = df.groupby("komoditas")["harga_rata_ribu"].transform(
lambda s: s.interpolate()
)
pivot = df.pivot(index="minggu", columns="komoditas", values="harga_rata_ribu")
cabai = pivot["cabai merah"]
rasio = cabai["M5"] / cabai["M1"]
print(f"Hitung ulang : M5 {cabai['M5']:.1f} / M1 {cabai['M1']:.1f} = {rasio:.2f}")
print("Klaim laporan: puncak M5 mencapai 2.1x harga awal M1")
print(f"Cocok : {round(rasio, 1) == 2.1}")Output yang Dihasilkan:
Hitung ulang : M5 78.0 / M1 38.0 = 2.05
Klaim laporan: puncak M5 mencapai 2.1x harga awal M1
Cocok : TruePerhitungan ulang dari data memberi rasio 2.05, dan laporan mencantumkan versi yang dibulatkan menjadi 2.1x; round(rasio, 1) menghasilkan tepat 2.1 sehingga pemeriksaan menyimpulkan klaim tersebut didukung data. Inilah cara membaca laporan yang sehat: percaya, tetapi verifikasi angka yang paling menentukan keputusan.
Rekomendasi untuk Bu Warni #
Bagian 5 laporan menerjemahkan temuan menjadi empat rekomendasi. Tabel berikut memetakan masing-masing ke keputusan warung yang sudah kita definisikan pada Bagian 1 beserta dasar datanya:
| Rekomendasi | Isi | Keputusan yang didukung | Dasar dalam data |
|---|---|---|---|
| R1 | Awasi cabai merah tiap pekan; tunda pembelian besar bila naik lebih dari 20% | Menentukan waktu belanja | Lonjakan +54.8% dalam satu pekan (M3 → M4) |
| R2 | Saat cabai 38–44 beli lebih banyak untuk stok sambal; saat di atas 60 geser menu ke olahan tanpa cabai segar | Menentukan stok dan menu | Kisaran murah M1–M3 dan M7–M8; kisaran mahal 65.0–78.0 pada M4–M5 |
| R3 | Beras dan gula pasir cukup dibeli mingguan sesuai kebutuhan | Menentukan jumlah belanja | cv di bawah 1.5% sepanjang periode |
| R4 | Hitung ulang harga jual paket nasi ayam dengan asumsi naik sekitar 3% per 4 pekan | Menetapkan harga jual | Ayam broiler +6.7% dalam 8 pekan, 6 dari 7 pekan naik |
Keempat rekomendasi dirumuskan untuk horizon pendek — pekan hingga bulan — karena seluruh dasarnya adalah data delapan pekan yang belum bisa memisahkan tren dari musiman, sebagaimana kita sepakati pada Bagian 7. Tidak ada satu pun rekomendasi yang menuntut Bu Warni berkomitmen setahun. Teknik merumuskan rekomendasi agar bisa ditindaklanjuti pembacanya dibahas pada chapter Menyajikan Rekomendasi .
Refleksi Proyek #
Sepuluh bagian yang kita jalani membentuk satu lingkaran penuh. Keluhan “cabai kok mahal sekali akhir-akhir ini” dirapikan menjadi empat pertanyaan analisis pada Bagian 1; asal-usul data dicatat pada Bagian 2; validasi menemukan tiga masalah pada Bagian 3; pembersihan memperbaikinya dengan cara yang dipertanggungjawabkan pada Bagian 4; eksplorasi, statistik, dan tren menjawab Q1–Q3 pada Bagian 5–7; perbandingan antar komoditas dan visualisasi merangkai jawaban Q4 pada Bagian 8–9; laporan akhir menutup lingkaran itu menjadi keputusan.
Dari perjalanan tersebut, tiga pelajaran paling melekat. Pertama, data mentah tidak layak langsung dipercaya: tanpa validasi, satu baris duplikat dan satu nama kapital akan mendistorsi statistik cabai merah tanpa memberi peringatan apa pun. Kedua, ukuran harus adil: simpangan baku mentah memihak komoditas mahal, dan koefisien variasi memulihkan keadilan perbandingan. Ketiga, satu angka bisa menipu — bawang merah tampak paling cepat mahal (+16.67%) padahal hanya menanjak pada dua titik ujung, sementara cabai merah tampak jinak (+5.26%) justru karena pernah menembus 78.0.
Keterbatasan analisis tetap kita pegang terbuka: delapan pekan, satu pasar, dan satu nilai hasil imputasi (bawang merah M6 = 32.5). Langkah lanjut yang wajar adalah data minimal 12 bulan untuk memisahkan tren dari musiman tahunan, harga dari beberapa pasar untuk mengukur sebaran, serta data cuaca untuk menguji dugaan musim hujan. Pipeline yang sama tinggal dijalankan ulang pada data baru — itulah buah memilih skrip deterministik alih-alih analisis sekali pakai. Bila kelak proyek Anda tumbuh lebih besar dan menuntut selarasnya kode dengan narasi, bentuk notebook yang memadukan keduanya dalam satu berkas adalah kelanjutan yang umum; dokumentasi Jupyter memandu mulainya. Untuk warung Bu Warni, skrip biasa plus laporan teks polos sudah lebih dari cukup.
Ringkasan Bagian 10 #
- Pipeline menulis laporan sepenuhnya dari nilai terhitung: struktur enam bagian, 80 baris, tanpa satu angka pun yang diketik manual.
- Empat temuan T1–T4 dan empat rekomendasi R1–R4 saling bertaut; setiap rekomendasi berdiri di atas angka yang bisa dihitung ulang dari data — seperti rasio puncak 2.05 yang terverifikasi menjadi klaim 2.1x.
- Keterbatasan dilaporkan terbuka — delapan pekan, satu pasar, satu nilai imputasi — sebagai batas tafsir seluruh kesimpulan.
- Proyek menutup lingkaran dari keluhan pembuka menjadi keputusan terukur: kapan membeli, berapa yang dibeli, menu yang digeser, dan harga jual yang ditinjau.
Jawaban atas keluhan pembuka Bu Warni kini lengkap. Cabai merah memang pernah membengkak hingga 78.0 pada M5 — 2.05 kali harga awal — tetapi pada M8 harga sudah kembali ke 40.0, sehingga keluhan “akhir-akhir ini” lebih tepat dibaca sebagai kenangan akan puncak M5, bukan kondisi hari ini. Pertanyaan Q1 sampai Q4 terjawab dengan angka yang bisa diulang siapa pun dari berkas data yang sama.
Proyek ini adalah proyek kedua kita: analisis deskriptif atas satu deret harga dengan jawaban yang terukur. Tantangan berikutnya bekerja tanpa label jawaban — mengelompokkan pelanggan menjadi segmen yang belum diketahui sebelumnya. Kita hadapi pada proyek Segmentasi Pelanggan .