Hari ini 15 pertemuan dirangkai jadi satu aplikasi utuh — dan minggu depan kamu berdiri di panggung mempresentasikannya.
list[dict] + file + modular* baseline = standar minimum lulus (nilai B) · stretch = level bonus di atasnya (menuju A) · CLI = Command Line Interface, aplikasi berbasis teks di terminal.
Sebelumnya: latihan per konsep.
Sekarang: proyek utuh milikmu.
Prompt KBT-mu untuk satu fitur — sekarang waktunya dipakai. AI boleh jadi asisten, tapi verifikasi tetap wajib: kamu bosnya.
Dalam proyek hari ini AI boleh dipakai sebagai asisten — bukan gendongan. Setiap baris yang masuk file-mu wajib bisa kamu jelaskan saat demo minggu depan.
Posisimu: 16 dari 17 — 94% perjalanan. Satu langkah lagi sebelum Demo Day!
Semua domain pakai mesin yang sama: menu, list[dict], file. Yang beda cuma field dict-nya — ganti mesinnya nggak perlu.
Analogi hari ini: aplikasimu = restoran. Menu = pelayan yang standby · data = dapur · fungsi = juragan masak per pesanan.
1 · Menu loop while True — 5 opsi: Lihat, Tambah, Cari, Hapus + Statistik, dan Keluar (break)
2 · Data di list[dict] — satu sumber kebenaran, contoh: [{"nama": "Budi", "nilai": 85}]
3 · Modular — 1 menu = 1 fungsi: tampilkan_data, tambah_data, cari_data, hapus_data, statistik, simpan_file, load_file
4 · File I/O — with open, write / read / readlines: data selamat setelah program ditutup
5 · try-except — input angka (ValueError) & file not found (FileNotFoundError) tidak boleh menjatuhkan program
sort() / sorted() nilai tertinggi duluRubrik menilai fungsi yang jalan, bukan daftar mimpi. Baseline yang solid mengalahkan lima fitur error.
kerangka menu → tambah → lihat → cari → hapus → statistik → file I/O. Tambah dulu karena fitur lain butuh data buat diuji.
def load_file(): # baca data.txt -> list[dict]
def simpan_file(): # tulis list[dict] -> data.txt
def tampilkan_data(): # cetak semua data rapi
def tambah_data(): # input, validasi, append, save
def cari_data(kata): # hasil pencarian (case-insensitive)
def hapus_data(): # cari index, del, save
def statistik(): # jumlah, max, min, rata-rata
Kontrak satu baris = pengganti flowchart detail. Yang penting: gambar besar ada sebelum mengetik.
Finalisasi ide 15' + rencana fitur 20' — baru masuk kerja coding 60 menit. Rencana itu bukan formalitas — itu penghemat jam.
while True — 5 opsi + Keluar. Fitur yang belum dibuat boleh placeholder: print("(fitur menyusul)") Menu yang jalan (walau kosong) = kerangka aman. Sisa pekerjaan tinggal mengisi kotak-kotaknya — satu kotak selesai, aplikasi tetap utuh.
data = [] # list[dict] — dapur aplikasimu
while True:
print("\n=== APLIKASI NILAI SISWA ===")
print("1. Lihat 2. Tambah 3. Cari")
print("4. Hapus 5. Statistik 6. Keluar")
pilihan = input("Pilih menu (1-6): ")
if pilihan == "6":
print("Sampai jumpa!")
break
else:
print("Menu belum tersedia.")
Waktu: 20 menit. Output yang benar: menu berulang tanpa crash, pilih 6 → berhenti rapi.
Menu jalan — kerangka dari Tugas 1, semua pilihan tidak crash
tambah_data() — input + validasi + append + save
tampilkan_data() — cetak semua data rapi bernomor
cari_data() + hapus_data() — temukan, lalu del dengan pesan jujur
statistik() — jumlah, max, min, rata-rata
File I/O — load_file() + simpan_file() + try-except
Jebakan terbesar hari ini bukan kode sulit — tapi nafsu fitur: tiba-tiba mau login, gambar, database. Rubrik menilai yang jalan.
data = [# list berisi dict — 1 dict = 1 catatan
{"nama": "Budi", "nilai": 85},
{"nama": "Sari", "nilai": 72},
]
# menambah: fungsi tambah panggil append
data.append({"nama": "Rina", "nilai": 90})
# membaca field dict: pakai kunci (bukan index!)
print(data[0]["nama"]) # Budi
print(data[0]["nilai"]) # 85
for item in data: (Lihat, Statistik)kata.lower() in item["nama"].lower() → "budi" ketemu "Budi"enumerate(data) dapat index → del data[i]Kunci dict harus persis — item["Nama"] saat kuncinya "nama" = KeyError, jebakan paling sering hari ini.
FILE = "data.txt"
def simpan_file():
with open(FILE, "w", encoding="utf-8") as f:
for item in data:
f.write(f"{item['nama']},{item['nilai']}\n")
def load_file():
try:
with open(FILE, "r", encoding="utf-8") as f:
for baris in f.readlines():
baris = baris.strip()
if baris == "":
continue
nama, nilai = baris.split(",")
data.append({"nama": nama, "nilai": int(nilai)})
except FileNotFoundError:
print("File belum ada — mulai dengan data kosong.")
load_file() — dipanggil sekali, sebelum loop menusimpan_file() — dipanggil setiap kali data berubah (dalam tambah_data, hapus_data, edit)Lupa salah satu = data palsu di sesi berikutnya. Sama seperti draft chat-mu: tersimpan karena ada save di tiap perubahan.
Tambah 1 data → tutup program → jalan lagi → data masih ada. Itu bukti file-mu bekerja.
def tambah_data():
nama = input("Nama: ")
while True: # tanya berulang sampai angka sah
try:
nilai = int(input("Nilai (0-100): "))
break
except ValueError:
print("Harus angka! Contoh: 85")
data.append({"nama": nama, "nilai": nilai})
simpan_file()
print(f"Data {nama} ditambahkan.")
"lima" di kolom nilai — tanya ulang, jangan crashdata.txt belum ada — mulai dengan data kosongOutput jalan beneran: user ketik lima → Harus angka! Contoh: 85 → tanya lagi → ketik 85 → Data Budi ditambahkan. Satu huruf nakal tidak menjatuhkan aplikasi.
Setiap except yang kamu tulis = bukti kamu pernah jatuh di situ. Itu nilai plus saat Q&A demo minggu depan.
1. Budi - nilai 85 (Lulus) Fitur selesai = jalan + diuji normal + diuji kasus aneh. Fitur setengah jadi = jalan untuk input yang sopan saja.
Waktu: 40 menit — sisa jam coding 60' setelah kerangka 20'. Guru berkeliling; mentok satu fitur > 10 menit? Tanya, jangan diam di situ.
Pilih sekarang: 1 fungsi yang kamu banggakan — yang bisa kamu jelaskan paling meyakinkan. Modal terbesar Demo Day minggu depan.
sorted() dengan key=lambda laporan.txt berisi statistik lengkap, dibuat otomatis Self-test lolos semua. Fitur wajib yang belum sempurna itu utama — stretch yang belum jadi tidak mengurangi nilai, tapi wajib yang belum jalan mengurangi.
# urutkan dari nilai tertinggi
urut = sorted(data,
key=lambda item: item["nilai"],
reverse=True)
for item in urut:
print(item["nama"], item["nilai"])
# Rina 90, Budi 85, Sari 72
Sisa waktu sesi atau PR di rumah. Semua stretch opsional — demo tetap jalan kalau tidak ada satu pun.
urut = sorted(data,
key=lambda item: item["nilai"],
reverse=True)
for item in urut:
print(item["nama"], item["nilai"])
# Rina 90, Budi 85, Sari 72
sorted(..., reverse=True) — urut menurun tanpa mengubah data aslinya.
def edit_data():
kata = input("Nama yang diedit: ")
for item in data:
if item["nama"].lower() == kata.lower():
while True:
try:
item["nilai"] = int(input("Nilai baru: "))
break
except ValueError:
print("Harus angka! Contoh: 85")
simpan_file() # edit = data berubah = WAJIB save
print("Data diperbarui.")
return # berhenti — pesan "tidak ketemu" tidak ikut
print(f"Data '{kata}' tidak ditemukan.")
Yang sampai sini dengan baseline utuh — aplikasimu bukan tugas lagi, itu produk.
nilai = int(input("Nilai: "))
# user ketik: lima
# ValueError: invalid literal...
Obat: while True + try-except ValueError — tanya ulang sampai sah (slide 11). Jangan biarkan satu huruf menjatuhkan aplikasi.
with open("data.txt", "r") as f:
# run pertama, file belum ada!
# FileNotFoundError
Obat: bungkus load dengan try-except FileNotFoundError → "mulai dengan data kosong". File tercipta otomatis saat save pertama.
data.append(...) # masuk list...
# ...tapi tidak simpan_file()!
# program ditutup -> data hilang
Obat: kontrak save di dalam tiap fungsi yang mengubah data — bukan cuma saat keluar (keluar pakai Ctrl+C artinya tak pernah sampai).
item["Nama"] # KeyError! kuncinya "nama"
item["niali"] # KeyError! typo
Obat: kunci dict persis sama dengan yang ditulis saat append. Pilih nama field sekali di awal, tulis konsisten — snake_case semua.
Plus satu kebiasaan: def semua fungsi di atas, loop menu paling bawah — Python baca atas-ke-bawah; fungsi yang dipanggil sebelum didefinisikan = NameError.
while True — pelayan yang standby: Lihat, Tambah, Cari, Hapus, Statistik, Keluar (break)list[dict] — satu sumber kebenaran; akses pakai kunci yang persis, bukan nebakload_file() sekali di awal, simpan_file() tiap data berubahValueError (input nakal) & FileNotFoundError (run pertama) tidak boleh crashRumah kerja yang sama, panggung yang berbeda — Demo Day!
Tiap kelompok 5–7 menit: Masalah → Fitur → Demo Live → 1 potongan kode dibanggakan → Q&A. Rubrik sama persis dengan hari ini: Fungsi jalan 30% · Struktur 25% · Logika 20% · Demo & Penjelasan 15% · Kreativitas 10%.