Artikel ini bagian dari seri Belajar Python Level Basic di hanifmu.com. Di artikel sebelumnya kita sudah menyelesaikan Proyek 1: Kalkulator Sederhana. Sekarang kita buat program yang datanya berubah selama dipakai.
Kalkulator hanya menghitung lalu melupakan hasilnya. Program To-Do List menyimpan daftar yang bertambah, berubah, dan berkurang sesuai perintah pengguna. Di sinilah list dan dictionary bekerja sama.
Apa yang Akan Dibuat
Program daftar tugas dengan fitur:
- Menambah tugas baru.
- Menampilkan seluruh tugas beserta statusnya.
- Menandai tugas sebagai selesai.
- Menghapus tugas.
- Menu interaktif yang berjalan sampai pengguna keluar.
Merancang Struktur Data
Setiap tugas punya judul dan status selesai. Dictionary cocok untuk satu tugas:
{"judul": "Belajar Python", "selesai": False}
Kumpulan tugas disimpan dalam list:
tugas = [
{"judul": "Belajar Python", "selesai": False},
{"judul": "Olahraga", "selesai": True},
]
Dengan struktur ini, menambah tugas cukup dengan append(), dan menandai selesai cukup mengubah nilai selesai pada dictionary yang bersangkutan.
Function Menambah Tugas
tugas = []
def tambah_tugas(judul):
tugas.append({"judul": judul, "selesai": False})
Function ini menerima judul dan menambahkannya dengan status belum selesai.
Menampilkan Daftar Tugas
Menampilkan daftar sekaligus nomor urutnya memudahkan pengguna memilih:
def tampilkan_tugas():
if not tugas:
print("Belum ada tugas.")
return
print("\nDaftar Tugas:")
for nomor, item in enumerate(tugas, start=1):
tanda = "[x]" if item["selesai"] else "[ ]"
print(f"{nomor}. {tanda} {item['judul']}")
enumerate(tugas, start=1) memberi nomor mulai dari 1. Tanda [x] menandai tugas yang sudah selesai, [ ] untuk yang belum.
Menandai Selesai dan Menghapus
Kedua operasi ini bekerja berdasarkan nomor tugas. Karena nomor yang dilihat pengguna dimulai dari 1 sementara indeks list dimulai dari 0, nomornya dikurangi satu:
def tandai_selesai(nomor):
if 1 <= nomor <= len(tugas):
tugas[nomor - 1]["selesai"] = True
return True
return False
def hapus_tugas(nomor):
if 1 <= nomor <= len(tugas):
tugas.pop(nomor - 1)
return True
return False
Keduanya mengembalikan True bila berhasil dan False bila nomornya di luar jangkauan. Nilai kembalian ini dipakai untuk memberi pesan yang sesuai.
Membaca Nomor dengan Aman
Nomor dari pengguna bisa berupa huruf, jadi konversinya perlu diamankan:
def minta_nomor(prompt):
try:
return int(input(prompt))
except ValueError:
return None
Kalau inputnya bukan angka, function mengembalikan None sebagai tanda gagal.
Menu Interaktif
Bagian utama menggabungkan semuanya dalam loop:
def main():
while True:
print("\n=== To-Do List ===")
print("1. Tambah tugas")
print("2. Lihat tugas")
print("3. Tandai selesai")
print("4. Hapus tugas")
print("5. Keluar")
pilihan = input("Pilih menu (1-5): ")
if pilihan == "1":
judul = input("Judul tugas: ").strip()
if judul:
tambah_tugas(judul)
print("Tugas ditambahkan.")
else:
print("Judul tidak boleh kosong.")
elif pilihan == "2":
tampilkan_tugas()
elif pilihan == "3":
tampilkan_tugas()
nomor = minta_nomor("Nomor tugas: ")
if nomor is not None and tandai_selesai(nomor):
print("Tugas ditandai selesai.")
else:
print("Nomor tidak valid.")
elif pilihan == "4":
tampilkan_tugas()
nomor = minta_nomor("Nomor tugas: ")
if nomor is not None and hapus_tugas(nomor):
print("Tugas dihapus.")
else:
print("Nomor tidak valid.")
elif pilihan == "5":
print("Sampai jumpa!")
break
else:
print("Pilihan tidak tersedia.")
Perhatikan .strip() pada judul untuk membuang spasi di ujung, dan pemeriksaan if judul agar tugas kosong tidak ikut tersimpan.
Kode Lengkap
Simpan sebagai todo.py:
# todo.py
tugas = []
def tambah_tugas(judul):
tugas.append({"judul": judul, "selesai": False})
def tampilkan_tugas():
if not tugas:
print("Belum ada tugas.")
return
print("\nDaftar Tugas:")
for nomor, item in enumerate(tugas, start=1):
tanda = "[x]" if item["selesai"] else "[ ]"
print(f"{nomor}. {tanda} {item['judul']}")
def tandai_selesai(nomor):
if 1 <= nomor <= len(tugas):
tugas[nomor - 1]["selesai"] = True
return True
return False
def hapus_tugas(nomor):
if 1 <= nomor <= len(tugas):
tugas.pop(nomor - 1)
return True
return False
def minta_nomor(prompt):
try:
return int(input(prompt))
except ValueError:
return None
def main():
while True:
print("\n=== To-Do List ===")
print("1. Tambah tugas")
print("2. Lihat tugas")
print("3. Tandai selesai")
print("4. Hapus tugas")
print("5. Keluar")
pilihan = input("Pilih menu (1-5): ")
if pilihan == "1":
judul = input("Judul tugas: ").strip()
if judul:
tambah_tugas(judul)
print("Tugas ditambahkan.")
else:
print("Judul tidak boleh kosong.")
elif pilihan == "2":
tampilkan_tugas()
elif pilihan == "3":
tampilkan_tugas()
nomor = minta_nomor("Nomor tugas: ")
if nomor is not None and tandai_selesai(nomor):
print("Tugas ditandai selesai.")
else:
print("Nomor tidak valid.")
elif pilihan == "4":
tampilkan_tugas()
nomor = minta_nomor("Nomor tugas: ")
if nomor is not None and hapus_tugas(nomor):
print("Tugas dihapus.")
else:
print("Nomor tidak valid.")
elif pilihan == "5":
print("Sampai jumpa!")
break
else:
print("Pilihan tidak tersedia.")
if __name__ == "__main__":
main()
Contoh Jalannya Program
=== To-Do List ===
1. Tambah tugas
2. Lihat tugas
3. Tandai selesai
4. Hapus tugas
5. Keluar
Pilih menu (1-5): 1
Judul tugas: Belajar Python
Tugas ditambahkan.
Pilih menu (1-5): 1
Judul tugas: Olahraga
Tugas ditambahkan.
Pilih menu (1-5): 2
Daftar Tugas:
1. [ ] Belajar Python
2. [ ] Olahraga
Pilih menu (1-5): 3
Daftar Tugas:
1. [ ] Belajar Python
2. [ ] Olahraga
Nomor tugas: 1
Tugas ditandai selesai.
Pilih menu (1-5): 2
Daftar Tugas:
1. [x] Belajar Python
2. [ ] Olahraga
Pilih menu (1-5): 5
Sampai jumpa!
Pengembangan Lanjutan
Setelah versi dasar jalan, coba tambahkan:
- Tenggat waktu untuk setiap tugas memakai
datetime. - Menyimpan daftar ke file JSON agar tetap ada saat program ditutup.
- Menandai tugas kembali menjadi belum selesai.
- Menampilkan tugas yang belum selesai saja.
Kesalahan Umum Pemula
- Lupa mengurangi satu dari nomor — pengguna mengetik 1, tapi kode mengambil indeks 1 yang berarti item kedua.
- Membandingkan nomor tanpa memeriksa batas — memicu
IndexError. - Menyimpan judul kosong — periksa dengan
if judulsetelah.strip(). - Mengubah list saat sedang diiterasi — tampilkan dulu, baru ubah setelah loop selesai.
- Memakai variabel
tugaslokal di dalam function — tanpaglobal, list tetap bisa diubah, tapi hindari menugaskan ulang nama yang sama.
Ringkasan
- To-Do List menyimpan tiap tugas sebagai dictionary di dalam list
append()menambah tugas,pop()menghapusnyaenumerate(..., start=1)memberi nomor yang mudah dibaca pengguna- Nomor dari pengguna dikurangi satu sebelum dipakai sebagai indeks
trydanexceptmelindungi konversi nomor dari input yang salah- Loop utama berjalan sampai pengguna memilih keluar
Langkah Selanjutnya
Program ini masih melupakan datanya begitu ditutup. Setiap kali dijalankan, daftarnya kembali kosong.
Artikel selanjutnya adalah Proyek 3: Program Manajemen Data, tempat kamu menyimpan data ke file agar tidak hilang.
