Kita telah menyiapkan Python, lingkungan terisolasi, library inti, notebook, dan daftar dependensi — semua peralatan kini lengkap. Satu hal terakhir menentukan apakah proyek kita bertahan lebih lama dari satu pekan: tata letak foldernya. Proyek analisis yang semua berkasnya menggunung di satu folder akan membuat kita tersesat di pekan ketiga, ketika data mentah, data hasil olah, notebook, dan grafik saling bertukar nama. Pada chapter penutup Section ini kita menyusun struktur proyek baku yang sederhana tetapi kuat: memisahkan data mentah dari data olahan, menomori notebook, dan memindahkan kode inti keluar dari notebook.

Struktur Folder Baku #

Mari kita lihat dulu gambar utuhnya, lalu bedah satu per satu:

text
proyek-analisis-kopi/
├── data/
│   ├── raw/
│   │   └── penjualan_2025.csv
│   └── processed/
│       └── penjualan_bersih.csv
├── notebooks/
│   ├── 01-eksplorasi.ipynb
│   ├── 02-pembersihan-data.ipynb
│   └── 03-pemodelan.ipynb
├── src/
│   ├── __init__.py
│   ├── muat_data.py
│   └── fitur.py
├── output/
│   └── grafik-penjualan.png
├── README.md
└── requirements.txt

Peran setiap direktori dan berkas dirangkum di tabel berikut:

LokasiPeran
data/raw/Data asli apa adanya — hasil unduhan, ekspor kasir, jawaban survei. Sifatnya hanya-baca
data/processed/Data hasil pembersihan dan transformasi; selalu dapat dibangkitkan ulang dari raw/
notebooks/Analisis bernarasi: eksplorasi, visualisasi, eksperimen model
src/Kode yang dipakai ulang: fungsi pemuat data, pembersihan, pembentukan fitur
output/Hasil jadi yang dibagikan: grafik, tabel ringkasan, laporan
README.mdRingkasan proyek: pertanyaan analisis, cara menyiapkan lingkungan, urutan menjalankan notebook
requirements.txtDaftar dependensi terkunci dari chapter sebelumnya

Struktur ini bukan aturan resmi yang diwajibkan siapa pun, melainkan bentuk paling umum dari prinsip yang berlaku di mana saja: setiap jenis barang punya tempatnya, dan siapa pun dapat menebak isinya tanpa membuka satu per satu. Rekan tim yang membuka proyek kita untuk pertama kali — termasuk diri kita sendiri tiga bulan kemudian — langsung tahu ke mana harus mencari.

Memisahkan Data Mentah dari Data Olahan #

Pembagian raw/ dan processed/ adalah keputusan paling berpengaruh pada struktur ini. Data mentah di raw/ adalah sumber kebenaran: kita tidak pernah menyunting isinya, apa pun yang terjadi. Semua pembersihan — membuang duplikat, menyeragamkan format tanggal, mengisi nilai kosong — terjadi di kode, dan hasilnya ditulis ke processed/. Dua keuntungan mengalir dari disiplin ini.

Pertama, kesalahan menjadi murah. Bila proses pembersihan ternyata keliru, kita cukup memperbaiki kodenya lalu menjalankan ulang; data asli tidak pernah terkontaminasi. Kedua, alur kerja menjadi jujur: karena processed/ selalu dapat dibangkitkan ulang dari raw/ plus kode, folder tersebut tidak perlu kita cadangkan atau bagikan — cukup data mentah dan kodenya. Notebook pertama proyek kita bahkan bisa memuat ulang dari nol sebagai verifikasi bahwa seluruh rantai masih berjalan.

Menamai Notebook dengan Nomor Urut #

Folder notebooks/ menyimpan cerita analisis, dan setiap cerita punya urutan bab. Itulah guna angka dua digit di depan nama berkas: 01-eksplorasi.ipynb, 02-pembersihan-data.ipynb, 03-pemodelan.ipynb. Manfaatnya sederhana tetapi nyata: peramban berkas dan Git menampilkan daftar dalam urutan alfabetis, sehingga nomor membuat urutan baca tetap terjaga tanpa perlu dijelaskan ulang. Nomor dua digit memberi ruang hingga notebook ke-99 sebelum polanya bergeser.

Bagaimana bentuk aturan penamaan tersebut bila dinyatakan presisi? Kode berikut memeriksa beberapa nama berkas terhadap pola dua digit, tanda hubung, nama kebab-case, akhiran .ipynb:

python
import re

pola_nama_notebook = re.compile(r"^\d{2}-[a-z0-9-]+\.ipynb$")
kandidat = [
    "01-eksplorasi.ipynb",
    "02-pembersihan-data.ipynb",
    "analisis-akhir.ipynb",
    "3-model.ipynb",
]

for nama in kandidat:
    if pola_nama_notebook.match(nama):
        print(f"{nama:26} -> sesuai pola")
    else:
        print(f"{nama:26} -> perlu diperbaiki")

Output yang Dihasilkan:

text
01-eksplorasi.ipynb        -> sesuai pola
02-pembersihan-data.ipynb  -> sesuai pola
analisis-akhir.ipynb       -> perlu diperbaiki
3-model.ipynb              -> perlu diperbaiki

Mari kita bedah skrip di atas:

  1. Baris 3 (re.compile(...)): pola ^\d{2}-[a-z0-9-]+\.ipynb$ dibaca: awali dengan tepat dua digit (\d{2}), tanda hubung, lalu satu atau lebih huruf kecil/angka/tanda hubung, dan akhiri dengan .ipynb. Tanda sirkumfleks dan dolar mengunci pola pada awal dan akhir nama berkas.
  2. Baris 4-9 (kandidat): dua nama pertama lolos; analisis-akhir.ipynb gagal karena tanpa nomor urut, dan 3-model.ipynb gagal karena nomornya hanya satu digit — dalam urutan alfabetis, 3- akan muncul sesudah 29-.
  3. Baris 11-15 (for ... match): match() mengembalikan None bila nama tidak sesuai pola, sehingga cabang if/else memberi vonis untuk tiap nama. Skrip seperti ini bisa kita simpan sebagai pemeriksa kecil di awal sesi kerja.

Memisahkan Kode dari Notebook #

Folder src/ menjawab kelemahan yang pasti kita temui saat notebook membesar: blok kode yang sama disalin-tempel antar notebook, lalu satu perbaikan harus diulang di banyak tempat. Solusinya adalah memindahkan fungsi yang stabil — memuat data, membersihkan kolom, menghitung fitur — ke berkas .py di src/, lalu notebook cukup mengimpornya. Contoh berikut menyimulasikan struktur src/ dalam direktori sementara supaya pola impornya bisa kita lihat berjalan nyata:

python
import sys
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    src = Path(tmp) / "src"
    src.mkdir()
    (src / "__init__.py").write_text("")
    (src / "muat_data.py").write_text(
        "def muat_penjualan():\n"
        "    return [42, 18, 65, 30]\n"
    )
    sys.path.insert(0, tmp)

    from src.muat_data import muat_penjualan

    print(muat_penjualan())

Output yang Dihasilkan:

text
[42, 18, 65, 30]

Pemisahan ini memberi tiga keuntungan nyata. Pertama, satu sumber kebenaran untuk logika: fungsi pembersihan ditulis sekali, dan setiap notebook otomatis memakai versi terbarunya. Kedua, fungsi di src/ dapat diuji terpisah — topik yang kita dalami jauh di kemudian Course. Ketiga, notebook tetap ramping dan fokus pada narasi: pertanyaan, langkah, dan tafsiran — bukan dua layar penuh kode pendukung. Berkas __init__.py yang kosong menjadikan src/ sebagai package yang dapat diimpor.

Aturan praktisnya jangan dibuat rumit: biarkan kode lahir di notebook saat masih dieksplorasi, lalu pindahkan ke src/ begitu kode tersebut dipakai di tempat kedua. Struktur folder adalah alat, bukan upacara.

Referensi Resmi #

Rangkuman #

  • Struktur baku: data/raw/ dan data/processed/, notebooks/, src/, output/, plus README.md dan requirements.txt di akar proyek.
  • Data mentah bersifat hanya-baca sebagai sumber kebenaran; data olahan selalu dapat dibangkitkan ulang dari mentah plus kode.
  • Nama notebook bernomor dua digit (01-eksplorasi.ipynb) menjaga urutan baca pada urutan alfabetis; polanya dapat diperiksa dengan regex.
  • Kode yang stabil dipindah ke src/ dan diimpor notebook — satu sumber kebenaran, dapat diuji, notebook tetap ramping.
  • Struktur boleh bertambah (docs/, tests/, models/) mengikuti kebutuhan proyek.

Dengan ini persiapan lingkungan kita tuntas: Python terpasang, venv mengisolasi dependensi, library inti terverifikasi, notebook dikuasai, daftar dependensi terkunci, dan proyek tertata dalam struktur yang dapat dibaca orang lain. Peralatan sudah bukan penghalang — saatnya mengasah bahasa penggeraknya. Kita melangkah ke Section Python untuk Data Science , dimulai dari dasar Python yang benar-benar kita perlukan sebagai analis data.