Learn
← Previous

Hari 30: Mini Project — Sistem Analisis Data Penjualan

90 min Last updated 26 Mar 2026

Mini Project: Sistem Analisis Data Penjualan

Hari terakhir! Kita bangun aplikasi nyata yang menggabungkan semua konsep 30 hari: dataclass, OOP, exception handling, collections, lambda, comprehension, file I/O, dan type hints.

Arsitektur

from dataclasses import dataclass
from collections import defaultdict
from typing import List, Dict, Tuple
import json, os

@dataclass
class Transaksi:
    id        : str
    tanggal   : str
    pelanggan : str
    produk    : str
    kategori  : str
    qty       : int
    harga     : float

    @property
    def total(self) -> float:
        return self.qty * self.harga

    @property
    def bulan(self) -> str:
        return self.tanggal[:7]   # "2026-01"

class AnalisaPenjualan:
    def __init__(self, data: List[Dict]):
        self.transaksi = [Transaksi(**d) for d in data]

    def ringkasan(self) -> Dict:
        totals = [t.total for t in self.transaksi]
        return {
            "total_transaksi": len(self.transaksi),
            "total_revenue"  : sum(totals),
            "rata_rata"      : sum(totals) / len(totals),
            "terbesar"       : max(totals),
            "terkecil"       : min(totals),
        }

    def per_produk(self) -> Dict[str, float]:
        d = defaultdict(float)
        for t in self.transaksi: d[t.produk] += t.total
        return dict(sorted(d.items(), key=lambda x: x[1], reverse=True))

    def per_bulan(self) -> Dict[str, float]:
        d = defaultdict(float)
        for t in self.transaksi: d[t.bulan] += t.total
        return dict(sorted(d.items()))

    def per_kategori(self) -> Dict[str, float]:
        d = defaultdict(float)
        for t in self.transaksi: d[t.kategori] += t.total
        return dict(sorted(d.items(), key=lambda x: x[1], reverse=True))

    def top_pelanggan(self, n=5) -> List[Tuple]:
        d = defaultdict(float)
        for t in self.transaksi: d[t.pelanggan] += t.total
        return sorted(d.items(), key=lambda x: x[1], reverse=True)[:n]

    def bulan_terbaik(self) -> Tuple:
        return max(self.per_bulan().items(), key=lambda x: x[1])

    def produk_tidak_laku(self) -> Tuple:
        d = defaultdict(int)
        for t in self.transaksi: d[t.produk] += t.qty
        return min(d.items(), key=lambda x: x[1])

    def cetak_laporan(self):
        r   = self.ringkasan()
        SEP = "=" * 52
        print(f"\n{SEP}")
        print(f"     LAPORAN ANALISA PENJUALAN")
        print(f"{SEP}")
        print(f"Total Transaksi : {r['total_transaksi']}")
        print(f"Total Revenue   : Rp {r['total_revenue']:>12,.0f}")
        print(f"Rata-rata/Trx   : Rp {r['rata_rata']:>12,.0f}")
        print(f"\n{'\1':<18} {'\1':>15}")
        print(f"{SEP}")
        for p, rev in self.per_produk().items():
            bar = '█' * max(1, int(rev / 2_000_000))
            print(f"  {p:<16}: Rp {rev:>10,.0f}  {bar}")
        print(f"\nPer Bulan:")
        for bln, rev in self.per_bulan().items():
            print(f"  {bln}: Rp {rev:>12,.0f}")
        print(f"\nTop 3 Pelanggan:")
        for i, (nama, total) in enumerate(self.top_pelanggan(3), 1):
            print(f"  {i}. {nama:<15}: Rp {total:>10,.0f}")
        print(f"\nPer Kategori:")
        total_rev = r['total_revenue']
        for kat, rev in self.per_kategori().items():
            pct = rev / total_rev * 100
            print(f"  {kat:<14}: Rp {rev:>10,.0f}  ({pct:.1f}%)")
        print(f"\nBulan terbaik : {self.bulan_terbaik()[0]} (Rp {self.bulan_terbaik()[1]:,.0f})")
        print(f"Paling sedikit: {self.produk_tidak_laku()[0]} ({self.produk_tidak_laku()[1]} unit)")
        print(f"{SEP}\n")

Eksekusi

DATA = [
    {"id":"T001","tanggal":"2026-01-05","pelanggan":"Budi",  "produk":"Laptop Pro",  "kategori":"Elektronik","qty":1,"harga":12_000_000},
    {"id":"T002","tanggal":"2026-01-12","pelanggan":"Ani",   "produk":"Mouse",       "kategori":"Aksesori",  "qty":3,"harga":  150_000},
    {"id":"T003","tanggal":"2026-01-20","pelanggan":"Citra", "produk":"Monitor",     "kategori":"Elektronik","qty":2,"harga": 2_500_000},
    {"id":"T004","tanggal":"2026-02-03","pelanggan":"Doni",  "produk":"Keyboard",    "kategori":"Aksesori",  "qty":1,"harga":  450_000},
    {"id":"T005","tanggal":"2026-02-14","pelanggan":"Budi",  "produk":"Laptop Pro",  "kategori":"Elektronik","qty":1,"harga":12_000_000},
    {"id":"T006","tanggal":"2026-02-18","pelanggan":"Eva",   "produk":"Webcam HD",   "kategori":"Aksesori",  "qty":2,"harga":  350_000},
    {"id":"T007","tanggal":"2026-03-01","pelanggan":"Fani",  "produk":"SSD 1TB",     "kategori":"Storage",   "qty":2,"harga": 1_200_000},
    {"id":"T008","tanggal":"2026-03-10","pelanggan":"Ani",   "produk":"Monitor",     "kategori":"Elektronik","qty":1,"harga": 2_500_000},
    {"id":"T009","tanggal":"2026-03-22","pelanggan":"Citra", "produk":"Mouse",       "kategori":"Aksesori",  "qty":5,"harga":  150_000},
    {"id":"T010","tanggal":"2026-03-25","pelanggan":"Doni",  "produk":"SSD 1TB",     "kategori":"Storage",   "qty":1,"harga": 1_200_000},
]

analisa = AnalisaPenjualan(DATA)
analisa.cetak_laporan()

Rekap Perjalanan 30 Hari

MingguTopikKonsep Kunci
1FondasiVariabel, String, Operator, I/O, if/elif, for, while
2Struktur Data & FungsiList, Tuple, Dict, Set, def, *args, **kwargs, lambda
3Advanced & OOPComprehension, Closure, Decorator, Class, Inheritance, Exception, File I/O
4Library & ModuleModule, datetime, os, regex, collections, NumPy, Pandas, requests
BonusProject & Best PracticesTesting, Type Hints, PEP 8, Mini Project
Selamat menyelesaikan Python Mastery 30 Hari! Langkah selanjutnya: pilih jalur — Data Science (Pandas, Scikit-learn, Matplotlib), Web (FastAPI, Django), atau Automation (Selenium, Airflow).

Assignment

Tambahkan method ekspor_json(filename) ke AnalisaPenjualan yang menyimpan ringkasan, per_produk, per_bulan, top_pelanggan, bulan_terbaik, dan produk_tidak_laku ke dalam satu file JSON yang terstruktur.

Expected output:

Data diekspor ke laporan.json
Bulan terbaik : 2026-01 (Rp 12,600,000)
Paling sedikit : Keyboard (1 unit)
PY main.py
Solution
Output