Handbook AI Engineering
Bagian I - Bab 1

Python untuk AI Engineer

Subset Python yang paling sering digunakan dalam pekerjaan AI Engineering: manipulasi data, pemanggilan API eksternal, dan diagnosis error secara sistematis.

Apa yang Akan Kamu Pahami Setelah Bab Ini

Bab ini bukan tutorial Python dari nol. Jika kamu belum pernah menulis Python sama sekali, ada baiknya menyelesaikan satu tutorial Python dasar terlebih dahulu sebelum melanjutkan, referensinya ada di Appendix D.

Yang dibahas di sini adalah subset Python yang paling sering kamu gunakan dalam pekerjaan AI Engineering: bagaimana data mengalir dari sumber eksternal ke dalam program kamu, bagaimana memanipulasinya, dan bagaimana membaca pesan error ketika sesuatu tidak berjalan sesuai rencana.

1.1 Struktur Data yang Perlu Dikuasai

Dua struktur data yang akan paling sering kamu temui dalam AI Engineering adalah list dan dictionary. Bukan karena keduanya paling canggih, tapi karena hampir semua data yang berpindah antar sistem, dari API, database, hingga response LLM, menggunakan salah satu dari keduanya.

  • List adalah kumpulan item berurutan. Urutannya penting dan setiap item bisa diakses berdasarkan posisinya.
  • Dictionary adalah kumpulan pasangan kunci-nilai (key-value pairs). Tidak ada urutan yang dijamin, kamu mengakses data berdasarkan nama kuncinya, bukan posisinya.

Mengapa ini relevan untuk AI Engineering? Karena hampir semua response dari LLM API dikembalikan dalam format JSON, dan JSON di Python direpresentasikan sebagai dictionary. Memahami cara menavigasi dictionary yang bersarang (nested) adalah skill yang akan kamu gunakan setiap hari.

Struktur Data

List

Urutan penting, diakses via indeks

langkah = [
    "Ekstrak data",   # indeks 0
    "Bersihkan data", # indeks 1
    "Muat ke model"   # indeks 2
]

langkah[0]  # -> "Ekstrak data"
langkah[2]  # -> "Muat ke model"
Struktur Data

Dictionary

Urutan tidak dijamin, diakses via kunci

config = {
    "model": "gemini-pro",
    "temperature": 0.1,
    "max_tokens": 1024
}

config["model"]        # -> "gemini-pro"
config["temperature"]  # -> 0.1

1.2 Manipulasi Data dengan Pandas dan NumPy

Sebelum data apapun bisa digunakan oleh sistem AI yang kamu bangun, data itu hampir selalu perlu dibersihkan dan dimanipulasi terlebih dahulu. Dua library yang paling sering digunakan untuk ini adalah Pandas dan NumPy.

NumPy bekerja di level array numerik. Ia menyediakan struktur data ndarray yang jauh lebih efisien dari list Python untuk operasi matematis. Dalam konteks AI Engineering, NumPy paling sering muncul saat bekerja dengan embedding, representasi numerik dari teks yang akan dibahas lebih dalam di Bab 9.

Pandas bekerja di level tabel. Struktur data utamanya, DataFrame, adalah representasi tabel dengan baris dan kolom, mirip spreadsheet, tapi bisa dimanipulasi dengan kode. Pandas adalah alat utama untuk membersihkan, memfilter, dan mentransformasi data sebelum data tersebut masuk ke pipeline AI.

Memuat Data

Cara paling umum memuat data ke dalam DataFrame dari file CSV atau langsung dari URL.

import pandas as pd

# Memuat dari file CSV lokal
df = pd.read_csv("data/produk.csv")

# Memuat langsung dari URL
url = "https://example.com/dataset.csv"
df = pd.read_csv(url)

# Memuat dari file JSON
df = pd.read_json("data/hasil_api.json")

# Membuat DataFrame dari dictionary Python
# (berguna saat data datang dari response API)
data = {
    "nama": ["Produk A", "Produk B", "Produk C"],
    "harga": [50000, 75000, 120000],
    "stok": [10, 0, 5]
}
df = pd.DataFrame(data)

Inspeksi Awal

Langkah pertama setelah memuat data: memahami bentuk, tipe, dan kondisi datanya.

# Melihat 5 baris pertama
df.head()

# Melihat dimensi data: (jumlah baris, jumlah kolom)
df.shape          # contoh output: (1500, 8)

# Ringkasan tipe data per kolom
df.dtypes

# Statistik deskriptif kolom numerik
df.describe()

# Menghitung nilai yang hilang per kolom
df.isnull().sum()

# Melihat nama semua kolom
df.columns.tolist()

Membersihkan Data

Operasi pembersihan yang paling sering dibutuhkan sebelum data siap digunakan.

# Menghapus baris yang memiliki nilai kosong
df = df.dropna()

# Mengisi nilai kosong dengan nilai tertentu
df["stok"] = df["stok"].fillna(0)

# Menghapus baris duplikat
df = df.drop_duplicates()

# Mengubah tipe data kolom
df["harga"] = df["harga"].astype(float)

# Menghapus spasi berlebih di kolom teks
df["nama"] = df["nama"].str.strip()

# Mengganti nama kolom agar konsisten
df = df.rename(columns={
    "Nama Produk": "nama",
    "Harga (Rp)": "harga"
})

Filter dan Seleksi

Cara memilih subset data berdasarkan kondisi tertentu.

# Memilih satu kolom
nama_produk = df["nama"]

# Memilih beberapa kolom sekaligus
subset = df[["nama", "harga"]]

# Filter baris berdasarkan kondisi
produk_mahal = df[df["harga"] > 100000]

# Filter dengan beberapa kondisi
tersedia = df[
    (df["stok"] > 0) & (df["harga"] < 100000)
]

# Mengurutkan berdasarkan kolom
df_sorted = df.sort_values("harga", ascending=False)

1.3 Mengambil Data Eksternal via API

Sebagian besar data yang kamu gunakan dalam sistem AI tidak tersimpan di file lokal, ia datang dari API eksternal: database perusahaan, layanan cuaca, katalog produk, atau sistem lain yang sudah berjalan. Library requests adalah cara standar Python untuk berkomunikasi dengan API tersebut.

Sebuah request ke API bekerja seperti pengiriman surat: kamu mengirim request ke alamat tertentu (endpoint), menyertakan informasi yang diperlukan (headers, parameters, body), dan menerima balasan (response) yang berisi data atau konfirmasi.

Berikut adalah alur lengkap dari pengambilan data hingga siap digunakan:

Langkah 1

Request

requests.get() kirim ke endpoint

Langkah 2

Response

response.json() terima JSON

Langkah 3

Parse

data["key"] navigasi dictionary

Langkah 4

DataFrame

pd.DataFrame(data) siap dimanipulasi

Berikut implementasi konkretnya, dari request hingga data siap digunakan:

import requests
import pandas as pd

# 1. Kirim request ke endpoint API
# Header digunakan untuk autentikasi atau menentukan format respons
headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}
response = requests.get(
    "https://api.example.com/produk",
    headers=headers,
    params={"kategori": "elektronik", "limit": 100}
)

# 2. Periksa apakah request berhasil sebelum memproses data
# Status 200 berarti sukses, selain itu ada masalah
if response.status_code != 200:
    print(f"Request gagal: {response.status_code} - {response.text}")
else:
    # 3. Parse JSON: response otomatis jadi dictionary Python
    data = response.json()

    # Navigasi struktur JSON, sesuaikan dengan format API yang digunakan
    # Contoh: {"status": "ok", "data": {"produk": [...]}}
    daftar_produk = data["data"]["produk"]

    # 4. Ubah ke DataFrame untuk manipulasi lebih lanjut
    df = pd.DataFrame(daftar_produk)

    # Data sekarang siap dibersihkan, difilter, atau dimasukkan ke pipeline
    print(f"Berhasil memuat {len(df)} produk")
    print(df.head())

1.4 Membaca Pesan Error Python

Salah satu skill yang paling membedakan engineer berpengalaman dari pemula bukan kemampuan menulis kode tanpa error, tapi kemampuan membaca dan mendiagnosis error dengan cepat. Error di Python selalu memberikan informasi yang kamu butuhkan. Masalahnya, banyak pemula membaca error dari atas, padahal yang paling informatif justru ada di bawah.

Cara Membaca Traceback Python

Baris paling bawah berisi jenis error dan pesannya, ini yang harus dibaca pertama. Baris di atasnya menunjukkan lokasi spesifik di kode kamu di mana error terjadi. Baris-baris di atasnya lagi adalah jejak pemanggilan fungsi (call stack), berguna jika error terjadi di dalam library.

Berikut adalah error yang paling sering kamu temui beserta cara mendiagnosisnya.

ModuleNotFoundError, Library Tidak Ditemukan

ModuleNotFoundError: No module named 'pandas'

Penyebab paling umum: library belum diinstal di environment yang sedang aktif, atau virtual environment yang salah sedang aktif.

Langkah diagnosis: periksa apakah (venv) muncul di terminal. Jika ya, jalankan pip install pandas. Jika tidak, aktifkan dulu virtual environment-nya (lihat Bab 2).

KeyError, Kunci Tidak Ditemukan di Dictionary

KeyError: 'produk'

Penyebab paling umum: kamu mengakses kunci yang tidak ada di dictionary, biasanya karena struktur JSON dari API berbeda dari yang diasumsikan, atau ada typo pada nama kunci.

Langkah diagnosis: print seluruh dictionary terlebih dahulu dengan print(data.keys()) untuk melihat kunci apa yang sebenarnya tersedia.

TypeError, Operasi pada Tipe Data yang Salah

TypeError: can only concatenate str (not "int") to str

Penyebab paling umum: mencoba menggabungkan string dengan angka tanpa konversi, atau memanggil method yang tidak dimiliki tipe data tersebut.

Langkah diagnosis: gunakan print(type(variabel)) untuk memastikan tipe data variabel sebelum operasi. Gunakan str(angka) untuk mengonversi angka ke string.

AttributeError, Method atau Atribut Tidak Ditemukan

AttributeError: 'NoneType' object has no attribute 'json'

Penyebab paling umum: variabel bernilai None karena fungsi tidak mengembalikan nilai, atau request API gagal dan response-nya None.

Langkah diagnosis: print nilai variabel sebelum baris error. Jika hasilnya None, lacak ke mana variabel itu pertama kali diberi nilai.

IndentationError, Masalah Indentasi Kode

IndentationError: unexpected indent

Penyebab paling umum: campuran spasi dan tab di file yang sama, atau baris kode berada di level indentasi yang salah.

Langkah diagnosis: di VS Code, aktifkan "Render Whitespace" untuk melihat karakter spasi dan tab secara visual. Pastikan semua indentasi menggunakan spasi (4 spasi per level), bukan tab.

Kesalahan Umum

Jangan mengakses struktur JSON tanpa memeriksa bentuknya terlebih dahulu.

Struktur respons API bisa berbeda antara satu endpoint dengan endpoint lainnya, bahkan dari API yang sama. Selalu print dulu keseluruhan respons sebelum mengakses kuncinya, ini mencegah KeyError yang sulit dilacak.

Pandas tidak mengubah DataFrame asli secara default.

Banyak operasi Pandas seperti dropna() atau rename() mengembalikan DataFrame baru, bukan mengubah yang sudah ada. Jika hasilnya tidak tersimpan ke variabel, perubahan akan hilang. Selalu gunakan df = df.dropna(), bukan hanya df.dropna().

Baca error dari bawah ke atas, bukan dari atas ke bawah.

Baris pertama sebuah traceback hanya menunjukkan bahwa ada error. Informasi yang paling berguna jenis error dan lokasinya di kode kamu, ada di baris-baris paling bawah.

Selalu periksa status code sebelum memproses respons API.

Status 200 berarti request berhasil. Status 401 berarti masalah autentikasi. Status 429 berarti terlalu banyak request. Status 500 berarti ada masalah di sisi server API. Memproses respons tanpa memeriksa status code bisa menyebabkan error yang sulit dilacak di tahap berikutnya.

Ringkasan Bab 1

Checklist Pemahaman
  • Saya memahami perbedaan antara list dan dictionary, dan tahu kapan menggunakan masing-masing.
  • Saya bisa memuat data dari file CSV dan dari URL menggunakan Pandas.
  • Saya bisa melakukan inspeksi awal DataFrame: melihat dimensi, tipe data, dan nilai yang hilang.
  • Saya bisa membersihkan DataFrame: menghapus duplikat, mengisi nilai kosong, dan mengubah tipe data.
  • Saya bisa mengirim request GET ke API menggunakan requests dan memeriksa status code-nya.
  • Saya bisa mengubah respons JSON dari API menjadi DataFrame menggunakan Pandas.
  • Saya tahu cara membaca traceback Python: dari bawah ke atas, dan di mana menemukan informasi yang relevan.
  • Saya bisa mendiagnosis ModuleNotFoundError, KeyError, dan TypeError secara mandiri.