Langsung ke konten
KamusNgoding
Menengah Python 4 menit baca

Menguasai Fungsi di Python untuk Kode yang Rapi dan Reusable

#python #intermediate #fungsi
📚

Baca dulu sebelum ini:

Pendahuluan

Pada artikel sebelumnya, kita telah mempelajari bagaimana mengelola variabel dan tipe data untuk menyimpan informasi pengeluaran seperti nama barang, nominal, dan tanggal. Namun, jika kita terus menulis kode secara berurutan (prosedural) dalam satu file yang sangat panjang, kode kita akan menjadi “spaghetti code”—sulit dibaca, sulit didebug, dan sangat sulit untuk dikembangkan.

Bayangkan Anda sedang membangun aplikasi keuangan untuk perusahaan besar. Anda tidak mungkin menulis ulang logika perhitungan pajak atau validasi saldo setiap kali ada transaksi baru. Di sinilah peran Fungsi (Function) menjadi sangat krusial. Fungsi memungkinkan kita untuk membungkus sekumpulan instruksi ke dalam satu blok kode yang dapat dipanggil berulang kali.

Dalam tutorial ini, kita akan melangkah ke level intermediate. Kita tidak hanya akan belajar cara membuat fungsi sederhana, tetapi juga cara menggunakan parameter, return value, hingga memahami cakupan variabel (scope). Semua konsep ini akan kita terapkan langsung untuk merefaktor (memperbaiki struktur) aplikasi CLI Expense Tracker kita agar menjadi lebih modular, bersih, dan profesional seperti standar industri.

Mengenal Dasar Fungsi di Python

Fungsi adalah blok kode terorganisir yang dapat digunakan kembali untuk melakukan satu tindakan terkait. Di Python, kita mendefinisikan fungsi menggunakan kata kunci def.

Mari kita mulai dengan contoh paling sederhana. Bayangkan Budi ingin membuat fungsi untuk menyapa pengguna saat aplikasi Expense Tracker dimulai.

# Mendefinisikan fungsi sederhana
def sapa_pengguna():
    print("Selamat datang di Aplikasi Pencatat Penglan!)")
    print("Siap untuk mencatat pengeluaran hari ini?")

# Memanggil fungsi
sapa_pengguna()

Pada contoh di atas, sapa_pengguna adalah nama fungsinya. Saat kita memanggil sapa_pengguna(), Python akan mengeksekusi semua baris kode yang berada di dalam blok indentasi fungsi tersebut. Tanpa pemanggilan, kode di dalam def tidak akan pernah berjalan.

Parameter dan Argumen: Membuat Fungsi yang Dinamis

Fungsi akan jauh lebih berguna jika kita bisa memberikan input ke dalamnya. Input ini disebut sebagai parameter, sedangkan nilai yang kita masukkan saat memanggil fungsi disebut sebagai argumen.

Dalam konteks aplikasi pengeluaran, kita ingin fungsi yang bisa menerima nama pengeluaran dan nominalnya secara dinamis.

# Fungsi dengan dua parameter: nama_item dan nominal
def cetak_ringkasan_transaksi(nama_item, nominal):
    print(f"Transaksi: {nama_item} | Total: Rp{nominal:,}")

# Menggunakan argumen positional
cetak_ringkasan_transaksi("Beli Kopi di Tokopedia", 25000)

# Menggunakan argumen keyword (lebih jelas dan aman)
cetual_ringkasan_transaksi(nominal=50000, nama_item="Bayar Gojek")

Perhatikan penggunaan :, pada f-string. Ini adalah teknik Python untuk memberikan pemisah ribuan agar nominal Rupiah lebih mudah dibaca (misal: 25000 menjadi 25,000).

Default Parameter

Terkadang, kita ingin sebuah parameter memiliki nilai bawaan jika pengguna tidak memberikan input. Ini sangat berguna untuk kategori pengeluaran yang seringkali bersifat umum.

def tambah_pengeluaran(nama, nominal, kategori="Lain-lain"):
    print(f"Berhasil mencatat: {nama} sebesar Rp{nominal:,} ke kategori [{kategori}]")

# Menggunakan kategori default
tambah_pengeluaran("Pulsa Mandiri", 50000)

# Mengganti kategori default
tambah_pengeluaran("Beli Nasi Padang", 25000, "Makanan")

Return Value: Mengambil Hasil dari Fungsi

Fungsi tidak hanya bertugas untuk mencetak sesuatu ke layar (print), tetapi seringkali bertugas untuk melakukan perhitungan dan mengembalikan hasilnya ke program utama. Untuk melakukan ini, kita menggunakan kata kunci return.

Tanpa return, hasil dari sebuah fungsi akan “terjebak” di dalam fungsi tersebut dan tidak bisa digunakan oleh bagian kode lainnya.

def hitung_total_dengan_pajak(nominal, persen_pajak=0.11):
    """
    Menghitung total pengeluaran termasuk PPN 11%
    """
    total = nominal + (nominal * persen_pajak)
    return total

# Menyimpan hasil return ke dalam variabel
total_bayar = hitung_total_dengan_pajak(100000)

print(f"Nominal awal: Rp100,000")
print(f"Total setelah pajak: Rp{total_arg:,.0f}")

Dalam contoh ini, return total mengirimkan nilai hasil perhitungan keluar dari fungsi, sehingga kita bisa menyimpannya ke variabel total_bayar dan menggunakannya untuk perhitungan lain di luar fungsi.

Memahami Scope: Variabel Lokal vs Global

Sebagai developer, Anda harus waspada terhadap Scope atau cakupan variabel. Variabel yang dibuat di dalam sebuah fungsi disebut Local Variable, dan ia hanya hidup di dalam fungsi tersebut.

total_pengeluaran_global = 0 # Variabel Global

def tambah_transaksi(nominal):
    # Variabel lokal
    pajak = 0.11 
    
    # Kita perlu menggunakan keyword 'global' jika ingin mengubah variabel global
    global total_pengeluaran_global
    
    total_setelah_pajak = nominal + (nominal * pajak)
    total_pengeluaran_global += total_setelah_pajak
    print(f"Menambahkan Rp{nominal:,} ke total.")

tambah_transaksi(50000)
print(f"Total pengeluaran saat ini: Rp{total_pengeluaran_global:,}")

# Mencoba mengakses 'pajak' di luar fungsi akan menyebabkan error
# print(pajarg) # Ini akan menyebabkan NameError

Implementasi dalam Proyek: Refactoring CLI Expense Tracker

Sekarang, mari kita terapkan semua ilmu ini ke dalam proyek CLI Expense Tracker kita. Sebelumnya, kode kita mungkin hanya berupa urutan input() yang panjang. Sekarang, kita akan memecahnya menjadi fungsi-fungsi yang terpisah dan modular.

Berikut adalah struktur kode yang lebih profesional:

# List untuk menyimpan data pengeluaran (Database sederhana)
data_pengeluaran = []

def tambah_pengeluaran(nama, nominal, kategori):
    """Menambahkan transaksi baru ke dalam list."""
    transaksi = {
        "nama": nama,
        "nominal": nominal,
        "kategori": kategori
    }
    data_pengeluaran.append(transaksi)
    print(f"✅ Berhasil menambahkan: {nama}")

def tampilkan_semua_pengeluaran():
    """Menampilkan seluruh daftar pengeluaran."""
    if not data_pengeluaran:
        print("📭 Belum ada pengeluaran yang dicatat.")
        return

    print("\n=== DAFTAR PENGELUARAN ANDA ===")
    total = 0
    for index, item in enumerate(data_pengeluaran, start=1):
        print(f"{index}. {item['nama']} | {item['kategori']} | Rp{item['nominal']:,}")
        total += item['nominal']
    
    print("-" * 30)
    print(f"TOTAL PENGELUARAN: Rp{total:,}")
    print("-" * 30)

def main():
    """Fungsi utama untuk menjalankan program."""
    while True:
        print("\n--- MENU TRACKER KEUANGAN ---")
        print("1. Tambah Pengeluaran")
        print("2. Lihat Semua Pengeluaran")

        print("3. Keluar")
        
        pilihan = input("Pilih menu (1/2/3): ")

        if pilihan == '1':
            nama = input("Nama pengeluaran: ")
            try:
                jumlah = float(input("Jumlah nominal: "))
                kategori = input("Kategori (misal: Makan/Transport): ")
                tambah_pengeluaran(nama, jumlah, kategori)
            except ValueError:
                print("❌ Error: Masukkan angka yang valid untuk nominal!")
        
        elif pilihan == '2':
            tampilkan_semua_pengeluaran()
        
        elif pilihan == '3':
            print("Terima kasih telah menggunakan Tracker Keuangan!")
            break
        else:
            print("❌ Pilihan tidak valid!")

if __name__ == "__main__":
    main()

Mengapa Struktur Ini Lebih Baik?

  1. Modularitas: Jika Anda ingin mengubah cara perhitungan pajak, Anda cukup mengubah fungsi tambah_pengeluaran tanpa merusak fungsi main.
  2. Reusability: Fungsi tampilkan_semua_pengeluaran bisa dipanggil dari mana saja (misalnya jika nanti kita menambah fitur laporan bulanan).
  3. Readability: Orang lain (atau Anda di masa depan) dapat memahami alur program hanya dengan membaca nama-nama fungsinya.

Kesimpulan

Menguasai fungsi adalah langkah krusial untuk naik kelas dari sekadar “bisa coding” menjadi “software engineer”. Dengan fungsi, kode Anda menjadi lebih terorganisir, mudah diuji, dan profesional. Jangan lupa untuk selalu mencoba menulis fungsi dengan tanggung jawab tunggal (Single Responsibility Principle): satu fungsi, satu tugas.

Artikel Terkait