Pendamping Bab 17: Mengatur Code dengan Modul dan Paket. Gunakan nomor contoh dan latihan yang sama dengan buku.

Tujuan Belajar

  • Memisahkan tanggung jawab ke beberapa file.
  • Mengimpor fungsi dari modul sendiri.
  • Mengenali struktur paket dan blok __main__.

Persiapan

Gunakan Python pada komputer dan simpan file sesuai struktur folder yang ditunjukkan. Jalankan dari folder proyek. Unduhan pendamping menyertakan semua file yang diperlukan.

Program dengan tombol Coba di IDE dapat dijalankan di browser. Untuk program lokal, unduh sumber, ekstrak ZIP, lalu ikuti README.txt.

Pembahasan

17-01 – Membuat Modul Sendiri

Membuat modul sangat mudah. Cukup buat file Python baru (misalnya, kalkulasi_dasar.py) dan tulis code di dalamnya.

Coba di IDE Unduh Sumber
# File: kalkulasi_dasar.py

PI = 3.14159  # Sebuah variabel (konstanta)


def tambah(a, b):
    """Fungsi ini menjumlahkan dua angka."""
    return a + b


def kurang(a, b):
    """Fungsi ini mengurangkan dua angka."""
    return a - b


def kali(a, b):
    """Fungsi ini mengalikan dua angka."""
    return a * b


def bagi(a, b):
    """Fungsi ini membagi dua angka.
    Hati-hati dengan pembagian oleh nol!"""
    if b == 0:
        return "Error: Tidak bisa dibagi dengan nol!"
    return a / b


# Code di bawah ini akan berjalan jika file ini dieksekusi langsung
# dan TIDAK akan berjalan jika file ini diimpor sebagai modul.
if __name__ == "__main__":
    print("Modul kalkulasi_dasar.py sedang diuji.")
    print(f"Hasil 5 + 3 = {tambah(5, 3)}")
    print(f"Hasil 10 - 4 = {kurang(10, 4)}")
    print(f"PI = {PI}")
    print(f"Hasil 7 / 0 = {bagi(7,0)}")
    print(f"Hasil 10 / 2 = {bagi(10,2)}")

Hasil yang diharapkan:

Modul kalkulasi_dasar.py sedang diuji.
Hasil 5 + 3 = 8
Hasil 10 - 4 = 6
PI = 3.14159
Hasil 7 / 0 = Error: Tidak bisa dibagi dengan nol!
Hasil 10 / 2 = 5.0

Coba ubah: Ubah PI dari 3.14159 menjadi 4.14159, lalu prediksi hasilnya.

Studi Kasus

17-02 – Memakai modul kalkulator

main.py memakai fungsi yang didefinisikan dalam operasi.py. File sumber lengkap tersedia bersama agar impor dapat dijalankan.

Unduh Sumber

File pendamping: operasi.py.

from operasi import tambah, kali

print(f"Jumlah: {tambah(7, 3)}")
print(f"Hasil kali: {kali(7, 3)}")

Hasil yang diharapkan:

Jumlah: 10
Hasil kali: 21

Coba ubah: Tambahkan fungsi kurang dalam operasi.py lalu panggil dari main.py.

Rangkuman

Modul membantu memisahkan tanggung jawab program; paket mengelompokkan modul. Jalur impor dan direktori kerja perlu sesuai. Blok __main__ membedakan file yang dijalankan langsung dari file yang diimpor.

Cek Pemahaman

Lima pertanyaan ini sama dengan pertanyaan di buku. Periksa jawaban di kuis untuk melihat skor dan pembahasan.

  1. Modul Python sederhana biasanya berupa …
  2. Apa arti from alat import tambah?
  3. Kapan if __name__ == "__main__": bernilai True?
  4. Pada paket biasa dalam contoh buku, __init__.py berfungsi …
  5. Prinsip pemisahan modul yang membantu adalah …
Kerjakan Kuis

Latihan Mandiri

Latihan 17-L01 – Modul geometri

Dasar. Buat geometri.py berisi luas_persegi(sisi). Dari main.py, cetak luas untuk sisi 5.

Unduh Latihan

Hasil yang diharapkan:

25
Lihat Petunjuk

Simpan kedua file dalam folder yang sama.

Lihat Solusi
from geometri import luas_persegi

print(luas_persegi(5))

geometri.py

def luas_persegi(sisi):
    return sisi * sisi

Fungsi dipanggil melalui impor dari file lain.

Unduh Solusi

Latihan 17-L02 – Dua operasi

Penerapan. Buat operasi.py berisi tambah dan kali. Impor keduanya, lalu cetak tambah(2, 3) dan kali(2, 3).

Unduh Latihan

Hasil yang diharapkan:

5
6
Lihat Petunjuk

Pisahkan definisi fungsi dari program pemanggil.

Lihat Solusi
from operasi import tambah, kali

print(tambah(2, 3))
print(kali(2, 3))

operasi.py

def tambah(a, b):
    return a + b


def kali(a, b):
    return a * b

Satu modul dapat menyediakan beberapa fungsi yang berkaitan.

Unduh Solusi

Latihan 17-L03 – Paket pesan

Pengembangan. Buat paket pesan dengan __init__.py dan sapaan.py. Impor sapa dari pesan.sapaan, lalu cetak sapa("Ayu").

Unduh Latihan

Hasil yang diharapkan:

Halo, Ayu!
Lihat Petunjuk

Folder pesan berada di samping main.py.

Lihat Solusi
from pesan.sapaan import sapa

print(sapa("Ayu"))

pesan/__init__.py

pesan/sapaan.py

def sapa(nama):
    return f"Halo, {nama}!"

Nama bertitik menunjukkan modul dalam paket.

Unduh Solusi

Pengembangan

Kegiatan Tambahan

Saatnya menguji pemahamanmu tentang arsitektur code!

  1. Modul Geometri Sederhana
    • Buat modul bernama geometri.py.
    • Di dalamnya, definisikan fungsi untuk menghitung:
      • luas_persegi(sisi)
      • keliling_persegi(sisi)
      • luas_lingkaran(radius) (gunakan math.pi)
      • keliling_lingkaran(radius)
    • Tambahkan blok if __name__ == "__main__": di geometri.py untuk mencetak contoh penggunaan semua fungsi tersebut.
    • Buat file tes_geometri.py yang mengimpor modul geometri dan menggunakan fungsinya untuk menghitung dan mencetak luas dan keliling persegi dengan sisi 5, serta luas dan keliling lingkaran dengan radius 7. Coba impor dengan cara import geometri dan from geometri import ....
  2. Paket Manajemen String
    • Buat paket bernama olah_teks.
    • Di dalam olah_teks, buat dua modul:
      • pembersih.py: berisi fungsi hapus_spasi_berlebih(teks) yang menghapus spasi ekstra di awal, akhir, dan antar kata.
      • analisis.py: berisi fungsi hitung_kata(teks) yang mengembalikan jumlah kata dalam teks.
    • Buat file __init__.py di dalam olah_teks yang membuat fungsi-fungsi dari kedua modul tersebut bisa diimpor langsung dari olah_teks (misalnya, from olah_teks import hapus_spasi_berlebih).
    • Buat file main_program_teks.py di luar paket olah_teks yang mengimpor dan menggunakan fungsi-fungsi dari paket olah_teks pada sebuah contoh string.
  3. Refaktor Code ke Modul
    • Bayangkan kamu punya skrip panjang yang melakukan beberapa hal: membaca data dari pengguna, memvalidasinya, lalu memprosesnya.
    • Pikirkan bagaimana kamu akan memecah skrip tersebut menjadi setidaknya dua modul (misalnya, input_pengguna.py dan proses_data.py).
    • Tuliskan nama fungsi-fungsi utama yang akan ada di setiap modul tersebut dan bagaimana file utama akan mengimpor dan menggunakannya. (Tidak perlu implementasi penuh, cukup struktur dan alur impor).
Petunjuk dan Solusi Pengembangan

Solusi Latihan

Solusi 1: Modul Geometri Sederhana

File: geometri.py

#### File: geometri.py
import math

def luas_persegi(sisi):
    """Menghitung luas persegi."""
    return sisi * sisi

def keliling_persegi(sisi):
    """Menghitung keliling persegi."""
    return 4 * sisi

def luas_lingkaran(radius):
    """Menghitung luas lingkaran."""
    return math.pi * radius * radius

def keliling_lingkaran(radius):
    """Menghitung keliling lingkaran."""
    return 2 * math.pi * radius

if __name__ == "__main__":
    print("--- Menguji Modul Geometri ---")
    s_test = 4
    r_test = 3

    print(f"Persegi dengan sisi {s_test}:")
    print(f"  Luas: {luas_persegi(s_test)}")
    print(f"  Keliling: {keliling_persegi(s_test)}")

    print(f"Lingkaran dengan radius {r_test}:")
    print(f"  Luas: {luas_lingkaran(r_test):.2f}")
    print(f"  Keliling: {keliling_lingkaran(r_test):.2f}")

File: tes_geometri.py

#### File: tes_geometri.py

#### Cara 1: import seluruh modul
print("--- Menggunakan 'import geometri' ---")
import geometri

sisi_persegi = 5
radius_lingkaran = 7

luas_p = geometri.luas_persegi(sisi_persegi)
print(f"Luas persegi (sisi {sisi_persegi}): {luas_p}")

keliling_p = geometri.keliling_persegi(sisi_persegi)
print(f"Keliling persegi (sisi {sisi_persegi}): {keliling_p}")

luas_l = geometri.luas_lingkaran(radius_lingkaran)
print(f"Luas lingkaran (radius {radius_lingkaran}): {luas_l:.2f}")

keliling_l = geometri.keliling_lingkaran(radius_lingkaran)
keliling_info = f"Keliling lingkaran (radius {radius_lingkaran}): "
keliling_info += f"{keliling_l:.2f}"
print(keliling_info)

print("\n--- Menggunakan 'from geometri import ...' ---")
#### Cara 2: import item spesifik
#### Bisa juga import semua yang dibutuhkan
from geometri import luas_persegi, keliling_lingkaran

#### Kita sudah punya sisi_persegi dan radius_lingkaran dari atas
luas_p_lagi = luas_persegi(sisi_persegi)
print(f"Luas persegi (sisi {sisi_persegi}) lagi: {luas_p_lagi}")

keliling_l_lagi = keliling_lingkaran(radius_lingkaran)
keliling_lagi = "Keliling lingkaran "
keliling_lagi += f"(radius {radius_lingkaran}) lagi: "
keliling_lagi += f"{keliling_l_lagi:.2f}"
print(keliling_lagi)

#### Cara 3: Impor modul dengan alias
import geometri as geo

print(f"Luas persegi (sisi 10): {geo.luas_persegi(10)}")
print(f"Luas lingkaran (radius 5): {geo.luas_lingkaran(5):.2f}")

Solusi 2: Paket Manajemen String

Struktur Direktori:

proyek_olah_teks/
|-- main_program_teks.py
`-- olah_teks/
    |-- __init__.py
    |-- pembersih.py
    `-- analisis.py

File: olah_teks/__init__.py

#### File: olah_teks/__init__.py
from .pembersih import hapus_spasi_berlebih
from .analisis import hitung_kata

print("Paket 'olah_teks' berhasil diinisialisasi.")

__all__ = [
    'hapus_spasi_berlebih',
    'hitung_kata'
]

File: olah_teks/pembersih.py

#### File: olah_teks/pembersih.py
import re

def hapus_spasi_berlebih(teks):
    """Menghapus spasi ekstra di awal, akhir, dan
    mengganti spasi ganda menjadi tunggal."""
    teks = teks.strip() # Hapus spasi awal/akhir
    # Ganti spasi ganda/lebih menjadi tunggal
    teks = re.sub(r'\s+', ' ', teks)
    return teks

if __name__ == "__main__":
    txt = "  Ini  contoh  teks  dengan  spasi  berlebih.  "
    print(f"Asli: '{txt}'")
    print(f"Bersih: '{hapus_spasi_berlebih(txt)}'")

File: olah_teks/analisis.py

#### File: olah_teks/analisis.py
def hitung_kata(teks):
    """Menghitung jumlah kata dalam teks
    (dipisahkan spasi)."""
    # Jika teks kosong atau hanya spasi
    if not teks.strip():
        return 0
    kata_kata = teks.split()
    return len(kata_kata)

if __name__ == "__main__":
    c1 = "Ini adalah contoh kalimat."
    c2 = "   SatuDua   Tiga  "
    c3 = ""
    print(f"'{c1}' -> Jumlah kata: {hitung_kata(c1)}")
    # Perlu dibersihkan dulu idealnya
    print(f"'{c2}' -> Jumlah kata: {hitung_kata(c2)}")
    print(f"'{c3}' -> Jumlah kata: {hitung_kata(c3)}")

File: main_program_teks.py

#### File: main_program_teks.py
from olah_teks import hapus_spasi_berlebih, hitung_kata

kalimat_kotor = "  Halo  dunia!  Selamat  pagi  semua.  "
print(f"Asli: '{kalimat_kotor}'")

kalimat_bersih = hapus_spasi_berlebih(kalimat_kotor)
print(f"Bersih: '{kalimat_bersih}'")

jml_kata = hitung_kata(kalimat_bersih)
print(f"Jumlah kata: {jml_kata}")

#### Menguji __all__ dengan import *
#### from olah_teks import *
#### print(hapus_spasi_berlebih(" test  test "))

Solusi 3: Refaktor Code ke Modul (Konseptual)

Misalkan skrip awal program_panjang.py:

#### program_panjang.py (sebelum refaktor)
def dapatkan_input_pengguna():
    # ... logika meminta nama, usia, email ...
    nama = input("Nama: ")
    # ... (validasi sederhana mungkin di sini)
    return {"nama": nama, "email": None, "usia": None}

def validasi_data_lengkap(data):
    # ... logika validasi kompleks untuk nama, usia, email ...
    if not data["nama"]: return False, "Nama tidak boleh kosong"
    # ...
    return True, "Data valid"

def proses_dan_simpan(data_valid):
    # ... logika memproses data, mungkin menyimpannya ke file/db ...
    print(f"Memproses data untuk {data_valid['nama']}...")
    return "Proses berhasil"

if __name__ == "__main__":
    data_input = dapatkan_input_pengguna()
    status_valid, pesan = validasi_data_lengkap(data_input)
    if status_valid:
        hasil_proses = proses_dan_simpan(data_input)
        print(hasil_proses)
    else:
        print(f"Error validasi: {pesan}")

Setelah Refaktor:

Modul 1: manajemen_input.py

#### manajemen_input.py
def minta_info_pengguna():
    """Meminta informasi dasar dari pengguna."""
    nama = input("Masukkan nama kamu: ")
    email = input("Masukkan email kamu: ")
    # ... (mungkin input lain)
    return {"nama": nama, "email": email}

def validasi_input_awal(data_input):
    """Melakukan validasi dasar pada input."""
    nama = data_input.get("nama")
    email = data_input.get("email")

    if not nama or not email:
        return False, "Nama dan email wajib diisi."
    if "@" not in email:
        return False, "Format email tidak valid."
    return True, "Input awal valid."

if __name__ == "__main__":
    print("Menguji manajemen_input.py...")
    info = minta_info_pengguna()
    print(f"Info diterima: {info}")
    status, pesan = validasi_input_awal(info)
    print(f"Status validasi: {status}, Pesan: {pesan}")

Modul 2: pemrosesan_data.py

#### pemrosesan_data.py
def transformasi_data_pengguna(data_pengguna):
    """Melakukan transformasi atau pemrosesan lebih lanjut."""
    # Contoh: membuat username, mengubah format, dll.
    nama_lower = data_pengguna["nama"].lower()
    username = nama_lower.replace(" ", "") + "123"
    data_pengguna["username"] = username
    print(f"Data ditransformasi untuk {data_pengguna['nama']}.")
    return data_pengguna

def simpan_data_ke_sistem(data_final):
    """Menyimpan data ke sistem."""
    print(f"Menyimpan data: {data_final}")
    # with open("data_pengguna.txt", "a") as f:
    #     f.write(str(data_final) + "\n")
    username = data_final['username']
    return f"Data {username} berhasil disimpan."

if __name__ == "__main__":
    print("Menguji pemrosesan_data.py...")
    data = {
        "nama": "Budi Santoso",
        "email": "[email protected]"
    }
    data_trans = transformasi_data_pengguna(data)
    hasil = simpan_data_ke_sistem(data_trans)
    print(hasil)

File Utama: aplikasi_utama.py

#### aplikasi_utama.py
from manajemen_input import (
    minta_info_pengguna,
    validasi_input_awal
)
from pemrosesan_data import (
    transformasi_data_pengguna,
    simpan_data_ke_sistem
)

def jalankan_aplikasi():
    print("--- Aplikasi Pengguna ---")

    info = minta_info_pengguna()
    valid, pesan = validasi_input_awal(info)

    if not valid:
        print(f"Validasi Gagal: {pesan}")
        return

    print("Valid. Melanjutkan pemrosesan...")
    data_trans = transformasi_data_pengguna(info)
    hasil = simpan_data_ke_sistem(data_trans)

    print(f"Status: {hasil}")

if __name__ == "__main__":
    jalankan_aplikasi()

Ini menunjukkan bagaimana tanggung jawab dipisahkan ke modul yang berbeda, dan file utama menjadi lebih ringkas dan fokus pada alur kerja.


Dengan memahami dan menerapkan konsep modul dan paket, kamu telah mengambil langkah besar untuk menjadi programmer Python yang lebih terorganisir dan efisien. Code yang kamu tulis akan lebih mudah dipelihara, diperluas, dan dibagikan.

Di bab berikutnya, kita akan membahas bagaimana mengelola pustaka atau library eksternal (code yang dibuat oleh orang lain) menggunakan alat bernama pip, dan pentingnya lingkungan virtual (virtual environment) untuk menjaga proyek-proyekmu tetap terisolasi dan rapi. Sampai jumpa di sana!

Referensi dan Materi Pendamping

Langkah Selanjutnya

Bab 18 membahas Library, pip, dan Virtual Environment. Sebelum melanjutkan, pastikan kamu dapat menjelaskan tujuan belajar dan menyelesaikan tiga latihan inti bab ini.

Edisi September 2026. Nomor contoh, pertanyaan, dan latihan digunakan bersama pada buku dan halaman ini.

Bab 16 | Bab 18