Setiap pemrogram NumPy pasti pernah berhadapan dengan layar penuh traceback. Kabar baiknya: pesan error NumPy tergolong yang paling informatif — ValueError biasanya menyebut shape kedua operand, IndexError menyebut ukuran axis, dan LinAlgError menyebut sifat matriks yang bermasalah. Masalahnya sering bukan pada pesan, melainkan pada cara kita membacanya: banyak pemula membaca traceback dari atas dan berhenti di baris pertama.

Bab ini melatih kebiasaan membaca traceback dari bawah ke atas, memperkenalkan jenis error yang paling sering muncul saat menghitung dengan array, serta menjelaskan perbedaan penting antara exception yang menghentikan program dan RuntimeWarning yang hanya memberi peringatan.

Membaca Traceback dari Bawah ke Atas #

Misalkan kita punya file laporan.py yang mengalikan array harga dengan array jumlah item:

python
# notest
# isi laporan.py
import numpy as np

harga = np.array([15000, 22000, 8000])
jumlah = np.array([2, 3, 1, 4])
total = harga * jumlah
print(total)

Menjalankan python laporan.py memunculkan traceback berikut:

text
$ python laporan.py
Traceback (most recent call last):
  File "laporan.py", line 5, in <module>
    total = harga * jumlah
            ~~~~~~^~~~~~~~
ValueError: operands could not be broadcast together with shapes (3,) (4,) 

Urutan membaca yang efektif adalah dari bawah ke atas:

  1. Baris terakhir (ValueError: ...): bagian terpenting — jenis error dan pesannya; untuk error broadcasting, pesan langsung menyebut kedua shape yang bertabrakan.
  2. Baris File "laporan.py", line 5: lokasi error — file laporan.py, baris 5.
  3. Baris total = harga * jumlah dan tanda ^: interpreter mencetak ulang baris yang gagal dan menandai operator * beserta kedua operandnya.
  4. Baris Traceback (most recent call last): pembuka traceback; daftar frame dicetak dari pemanggil paling luar menuju titik error, sehingga frame paling relevan memang berada di bawah.

Pada program dengan banyak fungsi, daftar frame di tengah bisa panjang — naik saja sampai frame pertama yang berada di kode milik kita sendiri.

ValueError dan TypeError #

Dua error yang paling sering muncul saat operasi array adalah ValueError (bentuk atau isi nilai tidak cocok) dan TypeError (tipe data tidak didukung operasi). Keduanya bisa direproduksi dan ditangkap agar pesannya menjadi output yang dapat kita bedah:

python
import numpy as np

penjualan_senin = np.array([120, 135, 98])
penjualan_selasa = np.array([140, 110, 105, 122])
try:
    print(penjualan_senin + penjualan_selasa)
except ValueError as e:
    print("ValueError:", e)

try:
    print(penjualan_senin + np.array(["sepuluh"]))
except TypeError as e:
    print("TypeError:", e)

Output yang Dihasilkan:

text
ValueError: operands could not be broadcast together with shapes (3,) (4,) 
TypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('int64'), dtype('<U7')) -> None

Mari kita bedah:

  1. Baris 3-4: dua array penjualan dibuat; keduanya 1-D tetapi panjangnya berbeda.
  2. Baris 5-8: penjumlahan array (3,) dan (4,) tidak dapat di-broadcast, sehingga interpreter memunculkan ValueError. Blok try/except menangkap dan mencetak pesannya tanpa menghentikan script.
  3. Baris 10-13: menjumlahkan array bilangan dengan array string tidak punya aturan penjumlahan, sehingga interpreter memunculkan TypeError. Pesannya menyebut ufunc 'add' — fungsi universal di balik operator + — beserta kedua dtype yang bermasalah.

Tabel berikut merangkum jenis error yang sering kita temui:

Jenis errorPemicu umumPetunjuk kunci di pesan
ValueErrorshape tidak dapat di-broadcast, isi tidak validdua shape yang bertabrakan
TypeErroroperasi pada dtype yang tak didukungnama ufunc dan dtype yang bermasalah
IndexErrorindeks di luar jangkauannomor axis dan ukuran array
AxisErrornomor axis tidak adanomor axis dan dimensi array
np.linalg.LinAlgErrormatriks singular atau gagal faktorisasikondisi matriks, mis. “Singular matrix”

IndexError dan AxisError #

IndexError muncul saat kita mengambil elemen dengan indeks di luar jangkauan, sedangkan AxisError muncul saat kita meminta agregasi pada nomor axis yang tidak ada pada array tersebut:

python
import numpy as np

nilai = np.array([82.5, 90.0, 77.0])
try:
    print(nilai[5])
except IndexError as e:
    print("IndexError:", e)

matriks = np.array([[1.0, 2.0], [3.0, 4.0]])
try:
    print(matriks.sum(axis=2))
except Exception as e:
    print(type(e).__name__, "->", e)

Output yang Dihasilkan:

text
IndexError: index 5 is out of bounds for axis 0 with size 3
AxisError -> axis 2 is out of bounds for array of dimension 2

Penjelasan tiap bagian:

  1. Baris 3-6: array nilai hanya punya tiga elemen; mengakses indeks 5 memunculkan IndexError yang pesannya menyebut size 3.
  2. Baris 8-12: matriks berdimensi 2 sehingga axis yang sah hanyalah 0 dan 1; meminta axis=2 memunculkan AxisError, yang namanya tercetak lewat type(e).__name__ tanpa perlu menebak dari pesan.

LinAlgError dari numpy.linalg #

Operasi linear algebra punya jenis error sendiri: np.linalg.LinAlgError, yang muncul ketika matriks tidak memenuhi syarat operasi — misalnya matriks singular yang diminta di-inverse:

python
import numpy as np

A = np.array([[1.0, 2.0], [2.0, 4.0]])
try:
    np.linalg.inv(A)
except np.linalg.LinAlgError as e:
    print("LinAlgError:", e)

Output yang Dihasilkan:

text
LinAlgError: Singular matrix

Mari kita telaah:

  1. Baris 3 (A = np.array(...)): baris kedua matriks adalah dua kali baris pertama, sehingga kedua barisnya sejajar dan matriksnya singular — tak ada inverse yang mungkin.
  2. Baris 4-7: np.linalg.inv menolak matriks tersebut dengan LinAlgError berpesan Singular matrix. Jenis error ini juga muncul pada solve, cholesky, dan eig ketika syarat matematisnya tidak terpenuhi.

Pesan Singular matrix jauh lebih ramah daripada hasil inf atau nan yang merembet ke bagian lain program. Bila perlu, deteksi dini lewat np.linalg.matrix_rank dapat dilakukan sebelum memanggil inv — dibahas pada Chapter Matrix Rank.

RuntimeWarning: Peringatan, Bukan Error #

Tidak semua kejanggalan numerik memunculkan exception. Operasi seperti menghitung akar dari bilangan negatif menghasilkan nan dan hanya mencetak RuntimeWarning ke stderr — program tetap berjalan. Kita bisa merekamnya dengan modul warnings:

python
import numpy as np
import warnings

suhu = np.array([12.0, -3.0, 25.0])
with warnings.catch_warnings(record=True) as terekam:
    warnings.simplefilter("always")
    akar = np.sqrt(suhu)
for w in terekam:
    print(w.category.__name__, "->", w.message)
print("Program tetap berjalan, hasil:", akar)

Output yang Dihasilkan:

text
RuntimeWarning -> invalid value encountered in sqrt
Program tetap berjalan, hasil: [3.46410162        nan 5.        ]

Bedah baris demi baris:

  1. Baris 4 (suhu = ...): array suhu memuat satu nilai negatif, dan akar kuadrat bilangan negatif tidak terdefinisi pada bilangan real.
  2. Baris 5-8: warnings.catch_warnings(record=True) mencegat peringatan ke dalam list tererekam sehingga pesannya dapat dicetak secara deterministik.
  3. Baris 9-11: hanya ada satu peringatan, dan hasilnya tetap terisi: elemen negatif menjadi nan, sisanya dihitung normal.

Ringkasan kebiasaan saat berhadapan dengan error NumPy: baca baris terakhir traceback terlebih dahulu, catat jenis errornya, ekstrak petunjuk teknis dari pesan, lalu naikkan pandangan ke frame kode kita sendiri. Dua bab berikutnya mempraktikkan pola ini untuk kasus shape dan dtype.