Bab 10 — Fungsi: Menulis Sekali, Memakai Berkali-kali

Seri B2 — Fondasi Bahasa Python

CatatanDi bab ini, Anda akan:
  • Membuat fungsi sendiri dengan def
  • Memberi bahan masuk (argumen) dan menerima hasil (return)
  • Memahami scope: variabel di dalam dan di luar fungsi
  • Mengenal docstring dan lambda
  • Menyelesaikan pencatat data lapangan: proyek Seri B2

Semua skrip bab ini ada di folder kode/bab10/. Di versi web, Anda juga bisa mengunduh semuanya sekaligus (zip).

Di Bab 6, Anda menghitung biomassa kolam. Bayangkan Anda punya 12 kolam. Menyalin rumusnya 12 kali itu rawan salah, dan bila rumusnya perlu diperbaiki, Anda harus memperbaiki 12 tempat. Solusinya: bungkus rumus itu menjadi fungsi, tulis sekali, panggil berkali-kali. Anda sebenarnya sudah memakai fungsi sejak Bab 4: print(), input(), len(), dan sum() semuanya fungsi. Sekarang Anda membuatnya sendiri.

Fungsi seperti mesin kecil: bahan masuk (argumen), hasil keluar (return).

def: membuat fungsi

01_def_dasar.py
# Bab 10 - def: membuat fungsi sendiri
def sapa_petani():
    print("Selamat pagi, petani!")
    print("Semoga panen hari ini melimpah")


sapa_petani()      # memanggil fungsi
sapa_petani()      # bisa dipanggil berkali-kali
Selamat pagi, petani!
Semoga panen hari ini melimpah
Selamat pagi, petani!
Semoga panen hari ini melimpah
  • def menandai pembuatan fungsi, diikuti nama dan tanda kurung, lalu titik dua.
  • Isinya menjorok (indentasi dari Bab 7).
  • Fungsi baru dikerjakan saat dipanggil: sapa_petani(). Membuatnya saja belum menjalankan apa-apa.
TipTIPS

Beri nama fungsi dengan kata kerja yang menjelaskan tugasnya: hitung_biomassa, cetak_rekap. Orang yang membaca kode Anda langsung paham apa yang dikerjakan tanpa membaca isinya.

Argumen dan return

Fungsi menjadi berguna bila menerima bahan dan memberi hasil:

02_argumen_return.py
# Bab 10 - Argumen (bahan masuk) dan return (hasil keluar)
def biomassa_kg(jumlah_ikan, bobot_rata_g):
    return jumlah_ikan * bobot_rata_g / 1000


total = biomassa_kg(800, 540.5)
print(f"Biomassa kolam A: {total:.1f} kg")

# Argumen boleh diberi nama supaya lebih jelas
print(biomassa_kg(jumlah_ikan=1250, bobot_rata_g=300))
Biomassa kolam A: 432.4 kg
375.0
  • Nama di dalam kurung (jumlah_ikan, bobot_rata_g) disebut parameter: tempat bahan diterima. Nilai yang Anda berikan saat memanggil (800, 540.5) disebut argumen.
  • return mengirim hasil kembali ke pemanggil. Hasilnya bisa disimpan di variabel (total) atau langsung dipakai.
  • Argumen boleh diberi nama (jumlah_ikan=1250) supaya jelas, dan urutannya bebas.

Nilai bawaan

Parameter boleh diberi nilai bawaan (default), dipakai bila pemanggil tidak menyebutkannya:

03_nilai_bawaan.py
# Bab 10 - Nilai bawaan (default) untuk argumen
# (persen pakan 3% adalah angka contoh untuk latihan, bukan anjuran)
def pakan_harian_kg(biomassa, persen=3):
    return biomassa * persen / 100


print(f"Pakai persen bawaan: {pakan_harian_kg(432.4):.2f} kg")
print(f"Persen diganti 2.5:  {pakan_harian_kg(432.4, persen=2.5):.2f} kg")
Pakai persen bawaan: 12.97 kg
Persen diganti 2.5:  10.81 kg

Pemanggilan pertama memakai persen=3 bawaan. Pemanggilan kedua menggantinya menjadi 2,5. Parameter dengan nilai bawaan harus ditulis setelah parameter tanpa nilai bawaan.

Scope: siapa bisa melihat variabel apa

Variabel yang dibuat di dalam fungsi bersifat lokal: hanya hidup selama fungsi berjalan.

04_ruang_lingkup.py
# Bab 10 - Scope: variabel di dalam fungsi tidak mengubah yang di luar
suhu_air = 28

def cek_suhu():
    suhu_air = 31                    # variabel BARU, hanya hidup di dalam fungsi
    print("Di dalam fungsi:", suhu_air)


cek_suhu()
print("Di luar fungsi:", suhu_air)
Di dalam fungsi: 31
Di luar fungsi: 28

Di dalam fungsi, suhu_air = 31 membuat variabel baru yang kebetulan bernama sama. Variabel suhu_air di luar tetap 28. Ini melindungi program: fungsi tidak bisa tanpa sengaja mengubah data di luarnya.

PeringatanAWAS

Karena variabel lokal “mati” setelah fungsi selesai, Anda tidak bisa memakainya dari luar:

08_variabel_lokal_salah.py
# Bab 10 - Salah: memakai variabel lokal dari luar fungsi
def hitung():
    hasil_lokal = 10


hitung()
print(hasil_lokal)
Traceback (most recent call last):
  File "08_variabel_lokal_salah.py", line 7, in <module>
    print(hasil_lokal)
          ^^^^^^^^^^^
NameError: name 'hasil_lokal' is not defined

Kalau butuh hasil dari dalam fungsi, kembalikan dengan return, lalu tangkap di luar.

Mengembalikan beberapa nilai

Satu fungsi bisa mengembalikan lebih dari satu nilai sekaligus (sebenarnya sebuah tuple dari Bab 9), yang bisa langsung dibongkar:

05_return_banyak.py
# Bab 10 - Satu fungsi bisa mengembalikan beberapa nilai
def ringkas(daftar):
    return min(daftar), max(daftar), sum(daftar) / len(daftar)


bobot_g = [520, 480, 560, 540]
terkecil, terbesar, rata_rata = ringkas(bobot_g)
print(f"Terkecil: {terkecil} g")
print(f"Terbesar: {terbesar} g")
print(f"Rata-rata: {rata_rata:.1f} g")
Terkecil: 480 g
Terbesar: 560 g
Rata-rata: 525.0 g

Docstring dan lambda

Docstring adalah kalimat di dalam tiga tanda kutip pada baris pertama fungsi. Ia menjelaskan tugas fungsi, dan bisa dibaca lewat __doc__. Lambda adalah fungsi mini satu baris tanpa nama, sering dipakai sesaat, misalnya sebagai aturan pengurutan.

06_docstring_lambda.py
# Bab 10 - Docstring (catatan fungsi) dan lambda (fungsi mini)
def luas_petak_m2(panjang_m, lebar_m):
    """Menghitung luas petak persegi panjang dalam meter persegi."""
    return panjang_m * lebar_m


print(luas_petak_m2.__doc__)
print(luas_petak_m2(25, 12))

ikan = [("lele", 520), ("nila", 480), ("gurami", 610)]
urut_bobot = sorted(ikan, key=lambda item: item[1])   # urut menurut bobot
print(urut_bobot)
Menghitung luas petak persegi panjang dalam meter persegi.
300
[('nila', 480), ('lele', 520), ('gurami', 610)]

Pada sorted(ikan, key=lambda item: item[1]), lambda itu berarti “ambil isi nomor 1 dari tiap pasangan (bobotnya) dan urutkan berdasarkan itu”. Hasilnya dari bobot terkecil ke terbesar.

Jebakan klasik: lupa return

07_lupa_return.py
# Bab 10 - Jebakan: fungsi tanpa return menghasilkan None
def total_pakan(pagi_kg, sore_kg):
    pagi_kg + sore_kg          # dihitung, tapi tidak dikembalikan


hasil = total_pakan(2, 3)
print(hasil)
None

Tidak ada error, tetapi hasilnya None (“tidak ada”). Fungsi menghitung pagi_kg + sore_kg, lalu membuangnya karena tidak ada return. Ini bug yang licin karena Python tidak memprotes.

CatatanINGAT

Fungsi tanpa return selalu menghasilkan None. Kalau hasil fungsi Anda tiba-tiba None, periksa dulu apakah Anda lupa return.

Proyek Bersambung B2: pencatat data lapangan

Inilah puncak Seri B2: semua bahan yang Anda pelajari bekerja bersama. Ada dict berisi list (Bab 9), dua fungsi (bab ini), sebuah perulangan (Bab 8), dan f-string dengan format kolom (Bab 5 dan 9).

09_proyek_pencatat.py
# Bab 10 - Proyek bersambung B2: pencatat data lapangan (rekap per sektor)
def jumlah(angka):
    """Menjumlahkan semua angka dalam daftar."""
    total = 0
    for a in angka:
        total = total + a
    return total


def rata_rata(angka):
    """Rata-rata daftar angka (daftar tidak boleh kosong)."""
    return jumlah(angka) / len(angka)


data_lapangan = {
    "Pohon (diameter cm)": [32.5, 45.2, 28.0, 51.5],
    "Panen kebun (kg)": [245.5, 310.0, 198.5, 276.0],
    "Ikan (gram)": [520, 480, 560, 540],
    "Ternak (kg)": [350, 412.5, 389.0],
}

for sektor, nilai in data_lapangan.items():
    print(f"{sektor:20} total {jumlah(nilai):8.1f}   rata-rata {rata_rata(nilai):7.2f}")
Pohon (diameter cm)  total    157.2   rata-rata   39.30
Panen kebun (kg)     total   1030.0   rata-rata  257.50
Ikan (gram)          total   2100.0   rata-rata  525.00
Ternak (kg)          total   1151.5   rata-rata  383.83

Perhatikan bahwa rata_rata() memanggil jumlah(): fungsi boleh memakai fungsi lain. Menambah sektor baru (misalnya “Telur (butir)”) cukup menambah satu baris di data_lapangan, tanpa mengubah fungsi atau perulangan. Itulah kekuatan fungsi.

Latihan

  1. Tulis fungsi luas_lingkaran_m2(jari_jari_m) yang mengembalikan luas (pakai 3.14 untuk π). Panggil untuk jari-jari 3 dan 5.
  2. Tulis fungsi status_panen(bobot_g) yang mengembalikan "siap" bila bobot ≥ 500 dan "belum" bila tidak. Pakai di dalam perulangan atas list [480, 520, 505, 495].
  3. Ubah 09_proyek_pencatat.py: tambah sektor “Telur (butir)” dengan tiga angka, dan tambah fungsi terbesar(angka) yang dipakai untuk mencetak nilai terbesar tiap sektor. (Jangan pakai max(); tulis perulangannya sendiri.)
  4. Tantangan: tulis fungsi rata_rata_aman(angka) yang mengembalikan None bila daftarnya kosong, sehingga tidak kena ZeroDivisionError. Gunakan if dari Bab 7.

Ringkasan Bab

  • def nama(parameter): membuat fungsi; isi menjorok. Fungsi baru berjalan saat dipanggil.
  • Argumen = bahan masuk; return = hasil keluar. Tanpa return, hasilnya None.
  • Parameter boleh punya nilai bawaan.
  • Variabel di dalam fungsi bersifat lokal dan tidak terlihat dari luar.
  • Fungsi bisa mengembalikan beberapa nilai, memanggil fungsi lain, dan diberi docstring.
  • Lambda = fungsi mini satu baris.

Penutup Seri B2

Selamat! Anda sudah menguasai seluruh bahan dasar bahasa Python: variabel dan tipe data, operator, keputusan, perulangan, struktur data, dan fungsi. Dengan itu Anda sudah bisa menulis pencatat data lapangan kecil.

Tetapi ada satu kekurangan besar: data hilang setiap program ditutup. Semua angka di data_lapangan harus diketik ulang di kode setiap kali. Di Seri B3, program Anda belajar membaca dan menyimpan file: modul dan pustaka (Bab 11), penanganan error (Bab 12), dan file serta format data (Bab 13 dan 14).

Selanjutnya, di Bab 11: modul dan package, cara meminjam alat siap pakai dari gudang Python.