Python & AI Tutorials Logo
Pemrograman Python

39. Modul Pustaka Standar Esensial

Pustaka standar (standard library) Python adalah kumpulan modul yang sudah tersedia bawaan bersama Python—kamu tidak perlu menginstal apa pun tambahan untuk memakainya. Modul-modul ini menyediakan alat yang kuat untuk tugas pemrograman yang umum: menghasilkan angka acak, bekerja dengan tanggal dan waktu, bertukar data dengan program lain, dan menggunakan struktur data khusus yang melampaui list dan dictionary dasar.

Di bab ini, kita akan mengeksplorasi lima modul pustaka standar esensial yang akan sering kamu pakai dalam pemrograman Python di dunia nyata.

39.1) Menghasilkan Keacakan dengan random

Modul random menyediakan fungsi untuk menghasilkan angka acak dan membuat pilihan secara acak. Ini berguna untuk simulasi, game, pengujian, sampling data, dan situasi apa pun ketika kamu membutuhkan perilaku yang tidak bisa diprediksi.

39.1.1) Menghasilkan Integer Acak dengan randint()

Fungsi randint() menghasilkan integer acak di antara dua nilai, inklusif di kedua ujungnya:

python
import random
 
# Menyimulasikan pelemparan dadu enam sisi
die_roll = random.randint(1, 6)
print(f"You rolled: {die_roll}")  # Output: You rolled: 4 (varies each run)
 
# Menghasilkan usia acak antara 18 dan 65
age = random.randint(18, 65)
print(f"Random age: {age}")  # Output: Random age: 42 (varies)

Perhatikan bahwa nilai awal dan akhir sama-sama termasuk dalam hasil yang mungkin. randint(1, 6) bisa mengembalikan 1, 2, 3, 4, 5, atau 6—semua enam nilai mungkin.

Berikut contoh praktis yang menyimulasikan beberapa kali lempar dadu:

python
import random
 
# Menyimulasikan lempar dua dadu dan menghitung jumlahnya
die1 = random.randint(1, 6)
die2 = random.randint(1, 6)
total = die1 + die2
 
print(f"Die 1: {die1}")  # Output: Die 1: 3 (varies)
print(f"Die 2: {die2}")  # Output: Die 2: 5 (varies)
print(f"Total: {total}")  # Output: Total: 8 (varies)
 
if total == 7:
    print("Lucky seven!")
elif total == 2 or total == 12:
    print("Snake eyes or boxcars!")

Kenapa kedua ujung inklusif: Ini membuat randint() terasa intuitif untuk kasus penggunaan yang umum. Saat kamu ingin angka dari 1 sampai 6 (seperti dadu), kamu menulis randint(1, 6) dan 1 maupun 6 sama-sama mungkin muncul.

39.1.2) Menghasilkan Angka Floating-Point Acak

Untuk angka desimal acak, gunakan random() (mengembalikan float antara 0.0 dan 1.0) atau uniform() (mengembalikan float antara dua nilai yang ditentukan):

python
import random
 
# Menghasilkan float acak antara 0.0 dan 1.0 (0.0 termasuk, 1.0 tidak termasuk)
probability = random.random()
print(f"Random probability: {probability:.4f}")  # Output: Random probability: 0.7284 (varies)
 
# Menghasilkan temperatur acak antara 15.0 dan 30.0 derajat
temperature = random.uniform(15.0, 30.0)
print(f"Temperature: {temperature:.2f}°C")  # Output: Temperature: 23.47°C (varies)
 
# Menghasilkan harga acak antara $10.00 dan $99.99
price = random.uniform(10.0, 99.99)
print(f"Price: ${price:.2f}")  # Output: Price: $45.67 (varies)

Fungsi random() berguna saat kamu membutuhkan nilai probabilitas atau persentase. Fungsi uniform() lebih cocok saat kamu membutuhkan desimal acak pada rentang tertentu.

39.1.3) Membuat Pilihan Acak dengan choice()

Fungsi choice() memilih satu elemen secara acak dari sebuah sequence (list, tuple, atau string):

python
import random
 
# Memilih sebuah warna secara acak
colors = ["red", "blue", "green", "yellow", "purple"]
selected_color = random.choice(colors)
print(f"Selected color: {selected_color}")  # Output: Selected color: green (varies)
 
# Memilih pemenang secara acak dari para peserta
participants = ["Alice", "Bob", "Charlie", "Diana"]
winner = random.choice(participants)
print(f"The winner is: {winner}")  # Output: The winner is: Bob (varies)
 
# Memilih sebuah karakter secara acak dari sebuah string
vowels = "aeiou"
random_vowel = random.choice(vowels)
print(f"Random vowel: {random_vowel}")  # Output: Random vowel: i (varies)

Ini sangat berguna untuk game, sampling acak, atau memilih data uji secara acak. Setiap elemen dalam sequence punya peluang yang sama untuk dipilih.

Berikut contoh yang lebih kompleks yang menyimulasikan game kuis sederhana:

python
import random
 
# Pertanyaan kuis beserta jawabannya
questions = [
    ("What is 2 + 2?", "4"),
    ("What is the capital of France?", "Paris"),
    ("What color is the sky?", "blue")
]
 
# Memilih sebuah pertanyaan secara acak
question, correct_answer = random.choice(questions)
print(f"Question: {question}")
 
user_answer = input("Your answer: ")
if user_answer.lower() == correct_answer.lower():
    print("Correct!")
else:
    print(f"Wrong! The answer was: {correct_answer}")

39.1.4) Memilih Beberapa Item Acak dengan sample()

Saat kamu perlu memilih beberapa item unik dari sebuah sequence, gunakan sample(). Ini seperti mengambil kartu dari setumpuk kartu tanpa pengembalian—begitu sebuah item terpilih, item itu tidak akan terpilih lagi:

python
import random
 
# Memilih 3 siswa acak untuk proyek kelompok
students = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"]
group = random.sample(students, 3)
print(f"Group members: {group}")  # Output: Group members: ['Diana', 'Alice', 'Frank'] (varies)
 
# Mengambil 5 nomor lotre dari 1 sampai 50 (tanpa duplikat)
lottery_numbers = random.sample(range(1, 51), 5)
lottery_numbers.sort()  # Urutkan untuk tampilan
print(f"Lottery numbers: {lottery_numbers}")  # Output: Lottery numbers: [7, 15, 23, 38, 49] (varies)

Argumen kedua untuk sample() menentukan berapa banyak item yang dipilih. Angkanya harus kurang dari atau sama dengan panjang sequence—kamu tidak bisa memilih lebih banyak item daripada yang tersedia.

39.1.5) Mengacak Sequence dengan shuffle()

Fungsi shuffle() mengacak ulang elemen-elemen sebuah list secara in place (memodifikasi list asli):

python
import random
 
# Mengacak setumpuk kartu
cards = ["A♠", "K♠", "Q♠", "J♠", "10♠", "9♠", "8♠", "7♠"]
print(f"Original: {cards}")
random.shuffle(cards)
print(f"Shuffled: {cards}")  # Output: Shuffled: ['Q♠', '7♠', 'A♠', '10♠', '9♠', 'J♠', 'K♠', '8♠'] (varies)
 
# Mengacak pertanyaan kuis untuk urutan acak
questions = ["Question 1", "Question 2", "Question 3", "Question 4"]
random.shuffle(questions)
print(f"Randomized order: {questions}")  # Output: Randomized order: ['Question 3', 'Question 1', 'Question 4', 'Question 2'] (varies)

Fungsi Modul Random

randint: Integer acak

random/uniform: Float acak

choice: Ambil satu item

sample: Ambil beberapa item unik

shuffle: Ubah urutan list secara in place

Inklusif di kedua ujung

random: 0.0 sampai 1.0

uniform: Rentang kustom

Peluang sama untuk tiap elemen

Tanpa duplikat

Memodifikasi list asli

39.2) Bekerja dengan Tanggal dan Waktu

Modul datetime menyediakan class untuk bekerja dengan tanggal, waktu, dan interval waktu. Ini penting untuk penjadwalan, logging, menghitung durasi, dan aplikasi apa pun yang perlu melacak kapan sesuatu terjadi.

39.2.1) Mendapatkan Tanggal dan Waktu Saat Ini

Class datetime merepresentasikan sebuah titik waktu tertentu dengan komponen tanggal dan waktu:

python
from datetime import datetime
 
# Mendapatkan tanggal dan waktu saat ini
now = datetime.now()
print(f"Current datetime: {now}")
# Output: Current datetime: 2026-01-02 14:30:45.123456
 
# Mengakses komponen satu per satu
print(f"Year: {now.year}")      # Output: Year: 2026
print(f"Month: {now.month}")    # Output: Month: 1
print(f"Day: {now.day}")        # Output: Day: 2
print(f"Hour: {now.hour}")      # Output: Hour: 14
print(f"Minute: {now.minute}")  # Output: Minute: 30
print(f"Second: {now.second}")  # Output: Second: 45

Untuk hanya tanggal saja (tanpa waktu), gunakan class date:

python
from datetime import date
 
# Mendapatkan tanggal hari ini
today = date.today()
print(f"Today: {today}")  # Output: Today: 2026-01-02
 
print(f"Year: {today.year}")    # Output: Year: 2026
print(f"Month: {today.month}")  # Output: Month: 1
print(f"Day: {today.day}")      # Output: Day: 2

39.2.2) Membuat Tanggal dan Waktu Tertentu

Kamu bisa membuat objek datetime dan date untuk titik waktu tertentu:

python
from datetime import datetime, date
 
# Membuat tanggal tertentu
birthday = date(1995, 7, 15)
print(f"Birthday: {birthday}")  # Output: Birthday: 1995-07-15
 
# Membuat datetime tertentu
meeting = datetime(2026, 3, 15, 14, 30)  # March 15, 2026 at 2:30 PM
print(f"Meeting: {meeting}")  # Output: Meeting: 2026-03-15 14:30:00

Ini berguna untuk merepresentasikan deadline, janji temu, tanggal historis, atau titik waktu tetap lainnya:

python
from datetime import date
 
# Tanggal penting dalam sebuah proyek
project_start = date(2026, 1, 15)
project_end = date(2026, 6, 30)
 
print(f"Project duration: {project_start} to {project_end}")
# Output: Project duration: 2026-01-15 to 2026-06-30

39.2.3) Menghitung Selisih Waktu dengan timedelta

Class timedelta merepresentasikan durasi—selisih antara dua tanggal atau waktu. Kamu bisa memakainya untuk menghitung berapa lama waktu berlalu atau untuk menambah/mengurangi waktu dari tanggal:

python
from datetime import date, timedelta
 
# Menghitung usia
birth_date = date(1995, 7, 15)
today = date(2026, 1, 2)
age_delta = today - birth_date
 
print(f"Days since birth: {age_delta.days}")  # Output: Days since birth: 11128
print(f"Years (approximate): {age_delta.days // 365}")  # Output: Years (approximate): 30

Saat kamu mengurangkan satu tanggal dari tanggal lain, kamu akan mendapatkan objek timedelta. Atribut days memberi tahu jumlah hari dalam durasi tersebut.

Kamu juga bisa membuat objek timedelta secara langsung untuk merepresentasikan durasi tertentu:

python
from datetime import date, timedelta
 
# Menambahkan hari ke sebuah tanggal
today = date(2026, 1, 2)
one_week = timedelta(days=7)
next_week = today + one_week
 
print(f"Today: {today}")        # Output: Today: 2026-01-02
print(f"Next week: {next_week}")  # Output: Next week: 2026-01-09
 
# Mengurangi hari dari sebuah tanggal
thirty_days_ago = today - timedelta(days=30)
print(f"30 days ago: {thirty_days_ago}")  # Output: 30 days ago: 2025-12-03

timedelta bisa merepresentasikan hari, detik, mikrodetik, milidetik, menit, jam, dan minggu:

python
from datetime import datetime, timedelta
 
# Menghitung sebuah deadline
now = datetime(2026, 1, 2, 14, 30)
deadline = now + timedelta(hours=48, minutes=30)
 
print(f"Current time: {now}")    # Output: Current time: 2026-01-02 14:30:00
print(f"Deadline: {deadline}")   # Output: Deadline: 2026-01-04 15:00:00
 
# Menghitung sisa waktu
time_left = deadline - now
print(f"Hours remaining: {time_left.total_seconds() / 3600}")  # Output: Hours remaining: 48.5

Metode total_seconds() mengonversi seluruh durasi menjadi detik, yang kemudian bisa kamu ubah ke jam, menit, atau satuan lainnya.

Berikut contoh praktis menghitung milestone proyek:

python
from datetime import date, timedelta
 
# Perencanaan proyek
project_start = date(2026, 1, 15)
sprint_duration = timedelta(weeks=2)
 
sprint_1_end = project_start + sprint_duration
sprint_2_end = sprint_1_end + sprint_duration
sprint_3_end = sprint_2_end + sprint_duration
 
print(f"Sprint 1: {project_start} to {sprint_1_end}")
# Output: Sprint 1: 2026-01-15 to 2026-01-29
print(f"Sprint 2: {sprint_1_end} to {sprint_2_end}")
# Output: Sprint 2: 2026-01-29 to 2026-02-12
print(f"Sprint 3: {sprint_2_end} to {sprint_3_end}")
# Output: Sprint 3: 2026-02-12 to 2026-02-26

39.2.4) Membandingkan Tanggal dan Waktu

Objek date dan datetime bisa dibandingkan menggunakan operator perbandingan standar:

python
from datetime import date
 
# Membandingkan tanggal
date1 = date(2026, 1, 15)
date2 = date(2026, 2, 20)
date3 = date(2026, 1, 15)
 
print(date1 < date2)   # Output: True
print(date1 == date3)  # Output: True
print(date2 > date1)   # Output: True

Ini berguna untuk mengecek deadline, memvalidasi rentang tanggal, dan mengurutkan tanggal:

python
from datetime import date
 
# Mengecek apakah sebuah tanggal sudah lewat
event_date = date(2025, 12, 25)
today = date(2026, 1, 2)
 
if event_date < today:
    print("This event has already passed")  # Output: This event has already passed
else:
    print("This event is upcoming")
 
# Mengurutkan list tanggal
important_dates = [
    date(2026, 3, 15),
    date(2026, 1, 10),
    date(2026, 2, 28)
]
 
important_dates.sort()
print("Dates in order:")  # Output: Dates in order:
for d in important_dates:
    print(f"  {d}")
# Output:
#   2026-01-10
#   2026-02-28
#   2026-03-15

39.2.5) Memformat Tanggal dan Waktu dengan strftime()

Metode strftime() (string format time) mengonversi tanggal dan waktu menjadi string terformat. Kamu menentukan formatnya menggunakan kode khusus:

python
from datetime import datetime
 
now = datetime(2026, 1, 2, 14, 30, 45)
 
# Format tanggal umum
print(now.strftime("%Y-%m-%d"))           # Output: 2026-01-02
print(now.strftime("%m/%d/%Y"))           # Output: 01/02/2026
print(now.strftime("%B %d, %Y"))          # Output: January 02, 2026
print(now.strftime("%A, %B %d, %Y"))      # Output: Friday, January 02, 2026
 
# Format waktu umum
print(now.strftime("%H:%M:%S"))           # Output: 14:30:45
print(now.strftime("%I:%M %p"))           # Output: 02:30 PM
 
# Format gabungan
print(now.strftime("%Y-%m-%d %H:%M:%S"))  # Output: 2026-01-02 14:30:45
print(now.strftime("%B %d, %Y at %I:%M %p"))  # Output: January 02, 2026 at 02:30 PM

Kode format yang umum:

CodeDeskripsiContoh
%YTahun dengan abad2026
%mBulan sebagai angka dengan nol di depan (01-12)01
%dHari sebagai angka dengan nol di depan (01-31)02
%BNama bulan lengkapJanuary
%bNama bulan singkatJan
%ANama hari lengkapFriday
%aNama hari singkatFri
%HJam format 24 jam (00-23)14
%IJam format 12 jam (01-12)02
%MMenit (00-59)30
%SDetik (00-59)45
%pAM/PMPM

Berikut contoh praktis membuat entri log:

python
from datetime import datetime
 
def log_event(message):
    """Mencatat sebuah event dengan timestamp"""
    now = datetime.now()
    timestamp = now.strftime("%Y-%m-%d %H:%M:%S")
    print(f"[{timestamp}] {message}")
 
log_event("User logged in")
# Output: [2026-01-02 14:30:45] User logged in
 
log_event("File uploaded successfully")
# Output: [2026-01-02 14:30:45] File uploaded successfully

39.2.6) Mem-parsing Tanggal dari String dengan strptime()

Fungsi strptime() (string parse time) mengonversi string terformat kembali menjadi objek datetime. Kamu menentukan kode format yang sama untuk memberi tahu Python cara menginterpretasikan string tersebut:

python
from datetime import datetime
 
# Mem-parsing format tanggal yang berbeda
date_str1 = "2026-01-15"
date1 = datetime.strptime(date_str1, "%Y-%m-%d")
print(f"Parsed: {date1}")  # Output: Parsed: 2026-01-15 00:00:00
 
date_str2 = "January 15, 2026"
date2 = datetime.strptime(date_str2, "%B %d, %Y")
print(f"Parsed: {date2}")  # Output: Parsed: 2026-01-15 00:00:00
 
# Mem-parsing datetime beserta waktunya
datetime_str = "2026-01-15 14:30:00"
dt = datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
print(f"Parsed: {dt}")  # Output: Parsed: 2026-01-15 14:30:00

Ini penting saat membaca tanggal dari file, input pengguna, atau sumber data eksternal:

python
from datetime import datetime
 
# Mem-parsing input pengguna
user_input = "03/15/2026"
try:
    event_date = datetime.strptime(user_input, "%m/%d/%Y")
    print(f"Event scheduled for: {event_date.strftime('%B %d, %Y')}")
    # Output: Event scheduled for: March 15, 2026
except ValueError:
    print("Invalid date format. Please use MM/DD/YYYY")

Penting: String format harus cocok persis dengan string input, atau kamu akan mendapat ValueError:

python
from datetime import datetime
 
# Ini akan gagal - formatnya tidak cocok
try:
    datetime.strptime("2026-01-15", "%m/%d/%Y")  # Wrong format
except ValueError as e:
    print(f"Error: {e}")
    # Output: Error: time data '2026-01-15' does not match format '%m/%d/%Y'

Modul datetime

datetime.now: Tanggal/waktu saat ini

date.today: Tanggal saat ini

datetime/date: Membuat tanggal tertentu

timedelta: Durasi waktu

strftime: Format ke string

strptime: Parse dari string

Tambah/kurangi dari tanggal

Hitung selisih

%Y, %m, %d, %H, %M, %S

Harus cocok persis dengan format

39.3) Membaca dan Menulis Data JSON

JSON (JavaScript Object Notation) adalah format teks untuk menyimpan dan bertukar data terstruktur. Ini adalah format yang paling umum untuk web API, file konfigurasi, dan pertukaran data antar program. Modul json Python memudahkan konversi antara struktur data Python dan teks JSON.

39.3.1) Memahami Struktur JSON

JSON terlihat mirip dengan dictionary dan list Python, tetapi ada beberapa perbedaan:

JSON mendukung tipe data berikut:

  • Object (seperti dictionary Python): {"name": "Alice", "age": 30}
  • Array (seperti list Python): [1, 2, 3, 4]
  • String: "hello" (harus memakai tanda kutip ganda)
  • Number: 42, 3.14
  • Boolean: true, false (huruf kecil)
  • Null: null (seperti None di Python)

Perbedaan utama dari Python:

  • JSON memakai true/false/null alih-alih True/False/None milik Python
  • String JSON harus memakai tanda kutip ganda ("text"), bukan tanda kutip tunggal
  • JSON tidak mendukung tuple, set, atau objek kustom secara langsung

Berikut tampilan data JSON:

json
{
    "name": "Alice Johnson",
    "age": 30,
    "email": "alice@example.com",
    "is_active": true,
    "scores": [85, 92, 78, 95],
    "address": {
        "street": "123 Main St",
        "city": "Springfield",
        "zip": "12345"
    }
}

Catatan: Ini adalah teks JSON murni, bukan kode Python. Perhatikan true huruf kecil dan penggunaan tanda kutip ganda.

39.3.2) Mengonversi Data Python ke JSON dengan dumps()

Fungsi dumps() (dump string) mengonversi struktur data Python menjadi string berformat JSON:

python
import json
 
student = {
    "name": "Alice Johnson",
    "age": 30,
    "email": "alice@example.com",
    "is_active": True,
    "scores": [85, 92, 78, 95]
}
 
# Mengonversi dictionary ke JSON
json_string = json.dumps(student)
print(json_string)
# Output: {"name": "Alice Johnson", "age": 30, "email": "alice@example.com", "is_active": true, "scores": [85, 92, 78, 95]}
 
print(type(json_string))  # Output: <class 'str'>

Perhatikan bagaimana True di Python berubah menjadi true di JSON pada output. Fungsi dumps() secara otomatis menangani konversi ini.

Untuk output yang lebih mudah dibaca, gunakan parameter indent:

python
import json
 
student = {
    "name": "Alice Johnson",
    "age": 30,
    "scores": [85, 92, 78, 95]
}
 
# Pretty-print dengan indentasi
json_string = json.dumps(student, indent=2)
print(json_string)
# Output:
# {
#   "name": "Alice Johnson",
#   "age": 30,
#   "scores": [
#     85,
#     92,
#     78,
#     95
#   ]
# }

Parameter indent menentukan berapa spasi yang dipakai untuk setiap level indentasi. Ini membuat JSON jauh lebih mudah dibaca, terutama untuk struktur bertingkat yang kompleks.

39.3.3) Mengonversi JSON ke Data Python dengan loads()

Fungsi loads() (load string) mengonversi string berformat JSON kembali menjadi struktur data Python:

python
import json
 
# String JSON (seperti yang mungkin kamu terima dari web API)
json_string = '{"name": "Bob Smith", "age": 25, "scores": [90, 88, 92]}'
 
# Mengonversi ke dictionary Python
student = json.loads(json_string)
print(student)  # Output: {'name': 'Bob Smith', 'age': 25, 'scores': [90, 88, 92]}
print(type(student))  # Output: <class 'dict'>
 
# Mengakses data seperti dictionary Python pada umumnya
print(f"Name: {student['name']}")  # Output: Name: Bob Smith
print(f"Average score: {sum(student['scores']) / len(student['scores'])}")
# Output: Average score: 90.0

true, false, dan null milik JSON secara otomatis dikonversi menjadi True, False, dan None di Python:

python
import json
 
json_string = '{"active": true, "verified": false, "middle_name": null}'
data = json.loads(json_string)
 
print(data)  # Output: {'active': True, 'verified': False, 'middle_name': None}
print(type(data["active"]))  # Output: <class 'bool'>
print(type(data["middle_name"]))  # Output: <class 'NoneType'>

39.3.4) Menulis JSON ke File dengan dump()

Fungsi dump() menulis data Python langsung ke file dalam format JSON:

python
import json
 
# Rekaman data siswa
students = [
    {"name": "Alice", "age": 20, "gpa": 3.8},
    {"name": "Bob", "age": 22, "gpa": 3.5},
    {"name": "Charlie", "age": 21, "gpa": 3.9}
]
 
# Menulis ke file JSON
with open("students.json", "w") as file:
    json.dump(students, file, indent=2)
 
print("Data written to students.json")
# Output: Data written to students.json

Setelah menjalankan kode ini, file students.json berisi:

json
[
  {
    "name": "Alice",
    "age": 20,
    "gpa": 3.8
  },
  {
    "name": "Bob",
    "age": 22,
    "gpa": 3.5
  },
  {
    "name": "Charlie",
    "age": 21,
    "gpa": 3.9
  }
]

Kenapa memakai dump() alih-alih dumps()? Fungsi dump() menulis langsung ke file, yang lebih efisien daripada mengonversi ke string dulu lalu menulis string tersebut. Gunakan dump() untuk file dan dumps() ketika kamu membutuhkan JSON sebagai string (misalnya, untuk dikirim lewat jaringan).

39.3.5) Membaca JSON dari File dengan load()

Fungsi load() membaca data JSON dari sebuah file dan mengonversinya menjadi struktur data Python:

python
import json
 
# Membaca dari file JSON yang kita buat sebelumnya
with open("students.json", "r") as file:
    students = json.load(file)
 
print(f"Loaded {len(students)} students")  # Output: Loaded 3 students
 
# Mengolah datanya
for student in students:
    print(f"{student['name']}: GPA {student['gpa']}")
# Output:
# Alice: GPA 3.8
# Bob: GPA 3.5
# Charlie: GPA 3.9

39.3.6) Menangani Error JSON

Saat bekerja dengan JSON, kamu mungkin menemui data yang tidak valid. Selalu tangani kemungkinan error:

python
import json
 
# JSON tidak valid - kurang tanda kutip penutup
invalid_json = '{"name": "Alice", "age": 30'
 
try:
    data = json.loads(invalid_json)
except json.JSONDecodeError as e:
    print(f"Invalid JSON: {e}")
    # Output: Invalid JSON: Expecting ',' delimiter: line 1 column 28 (char 27)

Ini sangat penting terutama saat membaca JSON dari sumber eksternal (file, web API, input pengguna) di mana kamu tidak bisa menjamin datanya valid:

python
import json
 
def load_config(filename):
    """Memuat konfigurasi dari file JSON dengan penanganan error"""
    try:
        with open(filename, "r") as file:
            config = json.load(file)
            return config
    except FileNotFoundError:
        print(f"Config file '{filename}' not found")
        return None
    except json.JSONDecodeError as e:
        print(f"Invalid JSON in '{filename}': {e}")
        return None
 
# Mencoba memuat konfigurasi
config = load_config("config.json")
if config:
    print(f"Configuration loaded: {config}")
else:
    print("Using default configuration")

39.3.7) Contoh JSON Praktis: Menyimpan dan Memuat State Aplikasi

Berikut contoh lengkap yang menunjukkan cara menyimpan dan memuat data aplikasi:

python
import json
 
def save_game_state(filename, player_data):
    """Menyimpan state game ke file JSON"""
    with open(filename, "w") as file:
        json.dump(player_data, file, indent=2)
    print(f"Game saved to {filename}")
 
def load_game_state(filename):
    """Memuat state game dari file JSON"""
    try:
        with open(filename, "r") as file:
            player_data = json.load(file)
        print(f"Game loaded from {filename}")
        return player_data
    except FileNotFoundError:
        print("No saved game found")
        return None
 
# Data game
player = {
    "name": "Hero",
    "level": 5,
    "health": 85,
    "inventory": ["sword", "shield", "potion"],
    "position": {"x": 10, "y": 20}
}
 
# Menyimpan game
save_game_state("savegame.json", player)
# Output: Game saved to savegame.json
 
# Nanti, memuat game
loaded_player = load_game_state("savegame.json")
# Output: Game loaded from savegame.json
 
if loaded_player:
    print(f"Welcome back, {loaded_player['name']}!")
    print(f"Level: {loaded_player['level']}, Health: {loaded_player['health']}")
    # Output:
    # Welcome back, Hero!
    # Level: 5, Health: 85

Modul json

dumps: Python → string JSON

loads: string JSON → Python

dump: Python → file JSON

load: file JSON → Python

parameter indent untuk keterbacaan

Menangani konversi tipe

Lebih efisien daripada dumps + write

Tangani JSONDecodeError

39.4) Container Praktis di collections

Modul collections menyediakan tipe container khusus yang memperluas container bawaan Python (list, dictionary, set) dengan fungsionalitas tambahan. Container ini menyelesaikan masalah umum dengan lebih elegan dibandingkan memakai struktur data dasar.

39.4.1) Menghitung Item dengan Counter

Class Counter dirancang untuk menghitung objek yang bisa di-hash. Ini adalah subclass dictionary yang menyimpan item sebagai key dan jumlahnya sebagai value.

Apa yang bisa diterima Counter sebagai input:

  • Iterable apa pun (list, string, tuple, dll.)
  • Dictionary lain yang berisi hitungan
  • Keyword arguments dengan hitungan

Apa yang disimpan Counter:

  • Sebuah dictionary di mana key adalah item dan value adalah jumlahnya
  • Contoh: Counter(['a', 'b', 'a']) menyimpan {'a': 2, 'b': 1}

Keunggulan utama dibanding dictionary biasa:

  • Mengembalikan 0 untuk key yang hilang alih-alih melempar KeyError
  • Menyediakan metode khusus penghitungan seperti most_common()
  • Mendukung operasi aritmetika antar counter

Penggunaan Dasar

python
from collections import Counter
 
# Menghitung huruf dalam sebuah kata
word = "mississippi"
letter_counts = Counter(word)
print(letter_counts)
# Output: Counter({'i': 4, 's': 4, 'p': 2, 'm': 1})
 
# Mengakses hitungan seperti dictionary
print(f"Number of 'i's: {letter_counts['i']}")
# Output: Number of 'i's: 4
 
print(f"Number of 'z's: {letter_counts['z']}")
# Output: Number of 'z's: 0 (returns 0 for missing keys, no KeyError!)

Membuat Counter dari Berbagai Sumber

python
from collections import Counter
 
# Dari list
votes = ["Alice", "Bob", "Alice", "Charlie", "Alice", "Bob", "Alice"]
vote_counts = Counter(votes)
print(vote_counts)
# Output: Counter({'Alice': 4, 'Bob': 2, 'Charlie': 1})
 
# Dari string (menghitung tiap karakter)
letter_counts = Counter("hello")
print(letter_counts)
# Output: Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
 
# Dari dictionary
existing_counts = {'apple': 3, 'banana': 2}
fruit_counts = Counter(existing_counts)
print(fruit_counts)
# Output: Counter({'apple': 3, 'banana': 2})
 
# Dari keyword arguments
color_counts = Counter(red=5, blue=3, green=2)
print(color_counts)
# Output: Counter({'red': 5, 'blue': 3, 'green': 2})

Menemukan Item Paling Umum dengan most_common()

Signature metode: most_common(n=None)

Parameter:

  • n (opsional): Jumlah item paling umum yang akan dikembalikan
  • Jika n dihilangkan atau None, mengembalikan semua item

Mengembalikan:

  • List tuple (item, count)
  • Diurutkan berdasarkan count, yang tertinggi dulu
  • Jika count sama, item mengikuti urutan pertama kali muncul
python
from collections import Counter
 
# Menganalisis frekuensi kata dalam teks
text = "the quick brown fox jumps over the lazy dog the fox"
words = text.split()
word_counts = Counter(words)
 
# Mengambil 3 kata yang paling umum
top_3 = word_counts.most_common(3)
print(top_3)
# Output: [('the', 3), ('fox', 2), ('quick', 1)]

Operasi Aritmetika pada Counter

Kamu bisa menambah, mengurangi, dan melakukan operasi lain pada objek Counter:

python
from collections import Counter
 
# Menghitung item dalam dua grup
group1 = Counter(["apple", "banana", "apple", "orange"])
print(group1)
# Output: Counter({'apple': 2, 'banana': 1, 'orange': 1})
 
group2 = Counter(["banana", "banana", "grape", "apple"])
print(group2)
# Output: Counter({'banana': 2, 'grape': 1, 'apple': 1})
 
# Menjumlahkan hitungan
combined = group1 + group2
print(combined)
# Output: Counter({'apple': 3, 'banana': 3, 'orange': 1, 'grape': 1})
 
# Mengurangkan hitungan (hanya menyimpan hasil positif)
difference = group1 - group2
print(difference)
# Output: Counter({'apple': 1, 'orange': 1})
# banana: 1 - 2 = -1 (negative, so excluded)
# grape: not in group1, so excluded

Contoh Praktis: Menganalisis Nilai Siswa

python
from collections import Counter
 
# Distribusi nilai
grades = ["A", "B", "A", "C", "B", "A", "B", "D", "A", "B", "C", "A"]
grade_counts = Counter(grades)
 
print(f"Total students: {len(grades)}")
# Output: Total students: 12
 
print("\nGrade Distribution:")
for grade, count in grade_counts.most_common():
    percentage = (count / len(grades)) * 100
    bar = "█" * count
    print(f"  {grade}: {count} students ({percentage:4.1f}%) {bar}")
# Output:
# Grade Distribution:
#   A: 5 students (41.7%) █████
#   B: 4 students (33.3%) ████
#   C: 2 students (16.7%) ██
#   D: 1 students ( 8.3%) █

39.4.2) Dictionary dengan Nilai Default Menggunakan defaultdict

Class defaultdict adalah subclass dictionary yang secara otomatis membuat entri dengan nilai default ketika kamu mengakses key yang hilang. Ini menghilangkan kebutuhan untuk mengecek apakah key ada sebelum digunakan.

Apa yang bisa diterima defaultdict sebagai input:

  • Fungsi default factory (wajib): Callable yang mengembalikan nilai default untuk key yang hilang
  • Argumen apa pun yang diterima dict biasa (pasangan key-value, dictionary lain, keyword arguments)

Keunggulan utama dibanding dictionary biasa:

  • Tidak perlu mengecek apakah key ada sebelum digunakan
  • Secara otomatis menginisialisasi key yang hilang dengan nilai default
  • Kode yang lebih bersih, lebih mudah dibaca untuk operasi pengelompokan, penghitungan, dan akumulasi

Memahami Default Factory

Saat kamu membuat defaultdict, kamu harus menyediakan default factory—sebuah callable (fungsi) yang tidak menerima argumen dan mengembalikan nilai default. Default factory yang umum:

  • int - mengembalikan 0 (berguna untuk menghitung)
  • list - mengembalikan [] (berguna untuk mengelompokkan item)
  • set - mengembalikan set() (berguna untuk mengumpulkan item unik)
  • str - mengembalikan '' (berguna untuk penggabungan string)
  • lambda: value - mengembalikan nilai default kustom
python
from collections import defaultdict
 
# Berbagai default factory
counts = defaultdict(int)        # Key yang hilang mengembalikan 0
groups = defaultdict(list)       # Key yang hilang mengembalikan []
unique = defaultdict(set)        # Key yang hilang mengembalikan set()
custom = defaultdict(lambda: "N/A")  # Key yang hilang mengembalikan "N/A"
 
# Uji dengan key yang hilang
print(counts['missing'])     # Output: 0
print(groups['missing'])     # Output: []
print(unique['missing'])     # Output: set()
print(custom['missing'])     # Output: N/A

Penggunaan Dasar: Menghitung dengan defaultdict

Bandingkan dictionary biasa vs defaultdict untuk menghitung:

python
from collections import defaultdict
 
word = "mississippi"
 
# Dictionary biasa - perlu cek apakah key ada
regular_dict = {}
for letter in word:
    if letter not in regular_dict:
        regular_dict[letter] = 0
    regular_dict[letter] += 1
 
print(regular_dict)
# Output: {'m': 1, 'i': 4, 's': 4, 'p': 2}
 
# defaultdict - otomatis membuat entri dengan nilai default
letter_counts = defaultdict(int)  # int() mengembalikan 0
for letter in word:
    letter_counts[letter] += 1  # Tidak perlu cek apakah key ada!
 
print(dict(letter_counts))
# Output: {'m': 1, 'i': 4, 's': 4, 'p': 2}

Cara kerjanya:

  1. Saat kamu mengakses letter_counts[letter] untuk huruf baru, defaultdict memanggil int() yang mengembalikan 0
  2. Key dibuat dengan nilai 0, lalu += 1 membuatnya menjadi 1
  3. Untuk key yang sudah ada, perilakunya seperti dictionary biasa

Mengelompokkan Item dengan defaultdict(list)

Salah satu use case yang umum adalah mengelompokkan item ke dalam kategori:

python
from collections import defaultdict
 
students = [
    ("Alice", "A"),
    ("Bob", "B"),
    ("Charlie", "A"),
    ("Diana", "C"),
    ("Eve", "B"),
    ("Frank", "A")
]
 
# Mengelompokkan siswa berdasarkan nilai
# Dengan defaultdict - bersih dan sederhana
students_by_grade = defaultdict(list)
for name, grade in students:
    students_by_grade[grade].append(name)
 
print(dict(students_by_grade))
# Output: {'A': ['Alice', 'Charlie', 'Frank'], 'B': ['Bob', 'Eve'], 'C': ['Diana']}
 
# Mengakses nilai yang belum ada
print(students_by_grade["D"])  # Output: [] (empty list, not KeyError!)

Cara kerjanya:

  1. Saat kamu mengakses students_by_grade[grade] untuk grade baru, defaultdict memanggil list() yang mengembalikan []
  2. Key dibuat dengan list kosong, lalu .append(name) menambahkan siswa pertama
  3. Untuk grade yang sudah ada, tinggal menambahkan ke list yang ada

Membuat defaultdict dari Dictionary yang Sudah Ada

Kamu bisa menginisialisasi defaultdict dengan data yang sudah ada:

python
from collections import defaultdict
 
# Mulai dari hitungan yang sudah ada
existing_data = {'apple': 5, 'banana': 3}
 
# Membuat defaultdict dari dictionary yang sudah ada
fruit_counts = defaultdict(int, existing_data)
 
# Menambah hitungan lagi
fruit_counts['apple'] += 2     # 5 + 2 = 7
fruit_counts['orange'] += 1    # 0 + 1 = 1 (key baru, mulai dari 0)
 
print(dict(fruit_counts))
# Output: {'apple': 7, 'banana': 3, 'orange': 1}

Default Factory Kustom

Kamu bisa memberikan callable apa pun sebagai default factory:

python
from collections import defaultdict
 
# Memakai lambda untuk nilai default kustom
page_views = defaultdict(lambda: {'views': 0, 'unique': 0})
 
page_views['home']['views'] = 100
page_views['home']['unique'] = 75
 
print(page_views['home'])
# Output: {'views': 100, 'unique': 75}
 
print(page_views['about'])  # Key baru mendapat dictionary default
# Output: {'views': 0, 'unique': 0}

Catatan Penting

Mengakses vs. Mengecek Key:

python
from collections import defaultdict
 
counts = defaultdict(int)
 
# Mengakses key yang hilang AKAN MEMBUAT key tersebut
value = counts['missing']  # Membuat 'missing' dengan nilai 0
print('missing' in counts)  # Output: True
 
# Untuk mengecek tanpa membuat, gunakan 'in' atau .get()
counts2 = defaultdict(int)
print('missing' in counts2)      # Output: False (doesn't create key)
print(counts2.get('missing'))    # Output: None (doesn't create key)

39.5) (Opsional) Alat Iterasi yang Berguna

Modul itertools menyediakan fungsi untuk membuat iterator yang efisien. Alat ini membantu kamu bekerja dengan sequence dengan cara yang kuat tanpa membuat list perantara yang besar.

39.5.1) Merangkai Iterable dengan chain()

Fungsi chain() menggabungkan beberapa iterable menjadi satu iterator yang menghasilkan elemen dari tiap iterable secara berurutan.

Apa yang diterima chain():

  • Beberapa iterable (list, tuple, string, dll.) sebagai argumen terpisah

Apa yang dikembalikan chain():

  • Sebuah iterator yang menghasilkan semua elemen dari iterable pertama, lalu semua elemen dari iterable kedua, dan seterusnya

Keunggulan utama:

  • Lebih hemat memori dibanding menggabungkan dengan + (tidak membuat list perantara)
  • Bekerja untuk iterable apa pun, bukan hanya list
python
from itertools import chain
 
# Menggabungkan beberapa list
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]
 
combined = chain(list1, list2, list3)
print(list(combined))  # Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Ini lebih hemat memori dibanding menggabungkan list dengan +, terutama untuk sequence besar:

python
from itertools import chain
 
# Memproses beberapa sumber data tanpa membuat list gabungan yang besar
students_class_a = ["Alice", "Bob", "Charlie"]
students_class_b = ["Diana", "Eve", "Frank"]
students_class_c = ["Grace", "Henry", "Iris"]
 
# Melakukan iterasi semua siswa tanpa membuat list gabungan
for student in chain(students_class_a, students_class_b, students_class_c):
    print(f"Processing: {student}")
# Output:
# Processing: Alice
# Processing: Bob
# Processing: Charlie
# Processing: Diana
# Processing: Eve
# Processing: Frank
# Processing: Grace
# Processing: Henry
# Processing: Iris

Kamu bisa me-chain tipe iterable yang berbeda:

python
from itertools import chain
 
# Chain list, tuple, dan string
numbers = [1, 2, 3]
letters = ("a", "b", "c")
word = "xyz"
 
combined = chain(numbers, letters, word)
print(list(combined))  # Output: [1, 2, 3, 'a', 'b', 'c', 'x', 'y', 'z']

39.5.2) Mengulang Elemen dengan cycle()

Fungsi cycle() membuat iterator tak hingga yang berulang-ulang memutar elemen-elemen dari sebuah iterable.

Apa yang diterima cycle():

  • Satu iterable (list, tuple, string, dll.)

Apa yang dikembalikan cycle():

  • Iterator tak hingga yang menghasilkan elemen dari iterable berulang-ulang
  • Setelah mencapai akhir, ia mulai lagi dari awal

Karakteristik utama:

  • Membuat iterator tak hingga - tidak pernah berhenti dengan sendirinya
  • Harus dipakai dengan kondisi berhenti (counter, break, atau zip())
  • Hemat memori: tidak membuat salinan data
python
from itertools import cycle
 
# Membuat cycle warna tak hingga
colors = cycle(["red", "green", "blue"])
 
# Ambil 10 warna pertama
for i, color in enumerate(colors):
    if i >= 10:
        break
    print(f"Item {i}: {color}")
# Output:
# Item 0: red
# Item 1: green
# Item 2: blue
# Item 3: red
# Item 4: green
# Item 5: blue
# Item 6: red
# Item 7: green
# Item 8: blue
# Item 9: red

Peringatan: cycle() membuat iterator tak hingga. Selalu gunakan dengan kondisi berhenti (seperti counter atau pernyataan break), atau kamu akan membuat loop tak hingga.

Use case praktisnya adalah bergantian antara nilai:

python
from itertools import cycle
 
# Bergantian antara dua warna latar untuk baris tabel
row_colors = cycle(["white", "lightgray"])
 
rows = ["Row 1", "Row 2", "Row 3", "Row 4", "Row 5"]
for row, color in zip(rows, row_colors):
    print(f"{row}: background-color: {color}")
# Output:
# Row 1: background-color: white
# Row 2: background-color: lightgray
# Row 3: background-color: white
# Row 4: background-color: lightgray
# Row 5: background-color: white

Di sini kita memakai zip() (yang kita pelajari di Bab 37) untuk memasangkan setiap baris dengan warna. Iterator cycle() otomatis mengulang warna sesuai kebutuhan.

39.5.3) Menggabungkan chain() dan cycle()

Kamu bisa menggabungkan fungsi itertools untuk pola yang lebih kompleks:

python
from itertools import chain, cycle
 
# Membuat pola yang berputar melalui beberapa sequence
pattern1 = [1, 2, 3]
pattern2 = [10, 20]
 
# Chain pola-pola, lalu cycle hasilnya
combined_pattern = cycle(chain(pattern1, pattern2))
 
# Ambil 12 nilai pertama
for i, value in enumerate(combined_pattern):
    if i >= 12:
        break
    print(value, end=" ")
# Output: 1 2 3 10 20 1 2 3 10 20 1 2
 
print()  # Newline

Ini membuat pola berulang: 1, 2, 3, 10, 20, 1, 2, 3, 10, 20, ...

Berikut contoh praktis membuat jadwal bergilir:

python
from itertools import cycle
 
# Membuat jadwal bergilir untuk anggota tim
team_members = ["Alice", "Bob", "Charlie"]
schedule = cycle(team_members)
 
# Menugaskan tugas ke anggota tim secara bergiliran
tasks = [
    "Review code",
    "Write tests",
    "Update documentation",
    "Fix bug #123",
    "Implement feature X",
    "Deploy to staging"
]
 
print("Task Assignments:")
for task, assignee in zip(tasks, schedule):
    print(f"  {assignee}: {task}")
# Output:
# Task Assignments:
#   Alice: Review code
#   Bob: Write tests
#   Charlie: Update documentation
#   Alice: Fix bug #123
#   Bob: Implement feature X
#   Charlie: Deploy to staging

Modul itertools

chain: Gabungkan iterable

cycle: Ulangi selamanya

Lebih hemat memori daripada +

Bekerja dengan tipe yang berbeda

Membuat iterator tak hingga

Selalu gunakan dengan kondisi berhenti

Berguna untuk pola bergantian


Di bab ini, kita mengeksplorasi lima modul pustaka standar esensial yang memperluas kemampuan Python:

  • random: Menghasilkan angka acak, membuat pilihan acak, dan mengacak sequence—penting untuk simulasi, game, dan pengujian
  • datetime: Bekerja dengan tanggal, waktu, dan durasi—menghitung usia, menjadwalkan event, dan memformat timestamp
  • json: Bertukar data dengan program lain menggunakan format JSON yang universal—menyimpan state aplikasi, bekerja dengan web API, dan menyimpan konfigurasi
  • collections: Menggunakan container khusus seperti Counter untuk menghitung dan defaultdict untuk membuat key otomatis
  • itertools: Membuat iterator yang efisien dengan chain() untuk menggabungkan sequence dan cycle() untuk mengulang pola

Modul-modul ini adalah bagian dari pustaka standar Python—selalu tersedia, teruji dengan baik, dan menyelesaikan masalah pemrograman yang umum secara elegan. Saat kamu membangun program yang lebih kompleks, kamu akan sering mengambil alat-alat ini. Mereka merepresentasikan filosofi Python “batteries included”—menyediakan solusi yang kuat dan siap pakai untuk tugas pemrograman sehari-hari.

© 2025. Primesoft Co., Ltd.
support@primesoft.ai