Kode MATLAB yang benar hasilnya belum tentu mudah dipelihara, karena yang dipelihara sehari-hari adalah teksnya, bukan keluarannya. Topik ini membahas empat kebiasaan yang menjaga teks kode tetap terbaca: penamaan variabel yang terukur, praalokasi array sebelum perulangan, penggantian angka ajaib dengan konstanta bernama, serta pemecahan skrip panjang menjadi fungsi. Keempatnya dapat diterapkan pada kode yang sudah berjalan tanpa mengubah hasil komputasinya, sehingga penyempurnaan tidak perlu menunggu kode baru.
Penamaan yang menjelaskan isi#
Nama variabel adalah dokumentasi yang paling sering dibaca, sehingga namanya perlu menyatakan isi dan perannya di dalam alur data. Syarat penamaannya sederhana. Nama harus dimulai dengan huruf, hanya boleh memuat huruf, angka, dan garis bawah, serta peka kapital. Gaya camelCase seperti suhuMentah lazim dipakai di ekosistem MATLAB dan dipakai pada hampir seluruh contoh dokumentasinya, sedangkan sebagian tim memilih suhu_mentah bergaya snake_case. Kedua gaya sama sah, dan yang menentukan keterbacaan adalah konsistensi di dalam satu proyek, bukan gaya itu sendiri.
Prefiks dan sufiks yang bermakna membedakan tahap data. Data mentah dari sensor diberi nama suhuMentah, hasil koreksi diberi suhuTerkoreksi, dan ringkasan diberi suhuRata, sehingga urutan pemrosesan terbaca dari nama variabelnya tanpa menelusuri baris demi baris. Nama satu huruf disimpan untuk pencacah perulangan seperti k karena perannya memang lokal dan singkat. Komentar melengkapi nama dengan menjelaskan alasan, bukan mengulang apa yang sudah terbaca dari kodenya.
suhuMentah = [21 23 22 25 24 26 28 27 29 31 30 32];
suhuTerkoreksi = suhuMentah + 0.4; % sensor terbaca rendah 0.4 derajat, dikoreksi di hulu
ambangSuhu = 30;
suhuPanas = suhuTerkoreksi(suhuTerkoreksi > ambangSuhu);
fprintf('suhu mentah : %d data\n', numel(suhuMentah));
fprintf('suhu terkoreksi : %d data\n', numel(suhuTerkoreksi));
fprintf('di atas ambang : %d data\n', numel(suhuPanas));suhu mentah : 12 data
suhu terkoreksi : 12 data
di atas ambang : 3 dataPraalokasi sebelum perulangan#
Array yang tumbuh di dalam perulangan bekerja dengan menyalin. Ketika pernyataan seperti y(end+1) = nilai menambah elemen di luar ukuran saat ini, MATLAB menyiapkan blok memori baru yang lebih besar, menyalin seluruh isi lama ke sana, lalu menulis satu elemen baru. Pekerjaan penyalinan itu tumbuh seiring banyaknya elemen, sehingga biayanya berlipat meskipun kode terlihat hanya menambah satu nilai pada tiap langkah.
Praalokasi memutus masalah itu dengan menyiapkan seluruh ruang hasil lebih dahulu melalui zeros. Ukuran hasil hampir selalu dapat dihitung sebelum perulangan berjalan, misalnya banyak jendela pada rerata bergerak adalah banyak data dikurangi lebar jendela ditambah satu. Skrip berikut mempraktikkan pola lengkapnya.
% praalokasiJendela.m: rerata bergerak suhu dengan praalokasi hasil
suhuMentah = [21 23 22 25 24 26 28 27 29 31 30 32];
lebarJendela = 4; % konstanta bernama, bukan angka ajaib
banyakJendela = numel(suhuMentah) - lebarJendela + 1;
suhuRata = zeros(1, banyakJendela); % praalokasi: ukuran hasil diketahui lebih dahulu
for k = 1:banyakJendela
suhuRata(k) = mean(suhuMentah(k:k+lebarJendela-1));
end
fprintf('suhu mentah : %d data\n', numel(suhuMentah));
fprintf('suhu rata : %d data\n', numel(suhuRata));
fprintf('dua pertama : %.2f %.2f\n', suhuRata(1), suhuRata(2));suhu mentah : 12 data
suhu rata : 9 data
dua pertama : 22.75 23.50Dua belas data suhu menghasilkan sembilan jendela, dan seluruh isi suhuRata sudah dialokasikan sebelum perulangan pertama dijalankan. Analyzer kode di editor MATLAB menandai pola array yang membesar dengan label penumbuhan array di dalam perulangan, dan penanda itu dapat diredam sementara dengan anotasi %#ok<SAGROW> apabila pembesaran memang disengaja. Biaya penyalinan diukur dengan pencacah sederhana pada bagian Kesalahan umum, tanpa memakai pengukuran waktu yang berubah antar komputer.
Konstanta bernama menggantikan angka ajaib#
Angka ajaib (magic number) adalah nilai harfiah yang maknanya tidak terbaca dari angkanya, misalnya 0.01 atau 2 yang tersebar di tengah perhitungan. Masalahnya ada dua. Pembaca harus menebak arti tiap kemunculannya, dan ketika nilai itu harus diubah, perubahan harus dikejar ke seluruh tempat kemunculannya dengan risiko ada satu yang terlewat. Konstanta bernama menyelesaikan keduanya karena makna tertulis pada namanya dan nilainya cukup diubah di satu tempat.
skalaSensor = 0.01; % satu satuan data mentah mewakili 0.01 derajat
indeksWaktu = 1; % kolom pertama catatan: waktu pencatatan
indeksSuhu = 2; % kolom kedua catatan: suhu tercatat
catatanSensor = [100 2104; 200 2210; 300 2186];
waktuCatat = catatanSensor(:, indeksWaktu) * skalaSensor;
suhuCatat = catatanSensor(:, indeksSuhu) * skalaSensor;
fprintf('waktu pencatatan : %.2f %.2f %.2f\n', waktuCatat);
fprintf('suhu tercatat : %.2f %.2f %.2f\n', suhuCatat);waktu pencatatan : 1.00 2.00 3.00
suhu tercatat : 21.04 22.10 21.86Nomor kolom juga layak menjadi konstanta bernama karena indeks 1 dan 2 tidak menyatakan kolom mana yang diambil. Ketika format catatan berubah, misalnya kolom suhu pindah ke urutan ketiga, cukup indeksSuhu yang disunting dan seluruh pembacaan ikut benar. Konstanta sebaiknya ditempatkan berdekatan di bagian atas berkas agar pembaca menemukan seluruh pengaturan sekali pandang. Kebiasaan yang sama berlaku untuk ukuran jendela, ambang batas, dan faktor koreksi seperti lebarJendela pada skrip praalokasiJendela.m di bagian sebelumnya.
Skrip panjang dipecah menjadi fungsi#
Skrip yang panjang mencampur tiga pekerjaan sekaligus, yaitu menyiapkan data, menghitung, dan menampilkan hasil, sehingga perubahan pada satu bagian berisiko mengganggu bagian lain. Pemecahan menjadi fungsi memberi tiap langkah nama, masukan, dan keluaran yang tegas. Fungsi dapat diuji terpisah dengan data kecil, dipanggil ulang dari skrip lain, dan diberi perilaku bawaan melalui pemeriksaan nargin ketika argumen tidak disertakan.
function statistikSuhu(suhu)
% STATISTIKSUHU mencetak ringkasan satu baris untuk data suhu.
% STATISTIKSUHU(suhu) menampilkan banyak data, rerata, dan nilai terbesar.
% Tanpa argumen, contoh [21 23 22 25 24 26] dipakai.
if nargin < 1
suhu = [21 23 22 25 24 26];
end
fprintf('banyak data : %d\n', numel(suhu));
fprintf('rerata : %.2f\n', mean(suhu));
fprintf('terbesar : %d\n', max(suhu));
endsuhuMentah = [21 23 22 25 24 26 28 27 29 31 30 32];
statistikSuhu(suhuMentah);banyak data : 12
rerata : 26.50
terbesar : 32Satu fungsi disimpan pada satu berkas dengan nama berkas yang sama dengan nama fungsinya, karena itulah cara MATLAB menemukan fungsi saat dipanggil. Ringkasan tiga baris di atas menjadi satu nama yang dapat dipanggil pada skrip mana pun, dan skrip pemanggilnya hanya perlu menyiapkan data. Uji terpisah juga menjadi mudah: cukup panggil statistikSuhu dengan beberapa data kecil yang hasilnya sudah diketahui, dan kesalahan perhitungan ditemukan tanpa menjalankan seluruh skrip. Sebagai patokan, skrip yang panjangnya melewati beberapa layar layak dipecah, dan fungsi yang tugasnya dapat dinyatakan satu kalimat biasanya berukuran tepat.
Kesalahan umum#
- Membiarkan array membesar di dalam perulangan. Pola buruk ini tetap dieksekusi di bawah agar biayanya terlihat sebagai kuantitas yang dapat dihitung, yakni banyak elemen yang tersalin ulang selama pembesaran berlangsung. Sepuluh langkah menyalin 45 elemen karena langkah ke-
kmenyalink-1isi yang sudah ada, sedangkan praalokasizerosmenyalin nol elemen, dan selisihnya melebar kuadratik ketika banyak langkah dinaikkan.
banyakLangkah = 10;
hasilTumbuh = [];
banyakSalin = 0;
for k = 1:banyakLangkah
% tiap pembesaran menyalin ulang isi yang sudah terkumpul lebih dahulu
banyakSalin = banyakSalin + numel(hasilTumbuh);
hasilTumbuh(end+1) = k^2;
end
fprintf('elemen hasil : %d\n', numel(hasilTumbuh));
fprintf('elemen tersalin : %d\n', banyakSalin);elemen hasil : 10
elemen tersalin : 45- Menyimpan konstanta di tengah perhitungan. Nilai
0.01yang ditulis ulang pada dua tempat akan berubah menjadi dua sumber kebenaran ketika salah satunya disunting. Naikkan angka menjadi konstanta bernama di bagian atas berkas sebelum dipakai. - Nama yang menyembunyikan tahap data. Nama
data,data2, danhasilAkhir2memaksa pembaca menebak hubungan ketiganya. Beri prefiks tahap yang konsisten sepertiMentah,Terkoreksi, danRataagar alur pemrosesan terbaca dari daftar variabel.
Ringkasan#
- Nama variabel menyatakan isi dan tahapnya, dengan satu gaya penamaan yang dipertahankan di seluruh proyek, dan komentar menjelaskan alasan di balik kode.
- Praalokasi
zerossebelum perulangan menghapus biaya penyalinan berulang akibat array yang membesar. - Angka ajaib dinaikkan menjadi konstanta bernama agar maknanya terbaca dan nilainya hanya diubah di satu tempat.
- Skrip panjang dipecah menjadi fungsi bernama dengan masukan dan keluaran yang tegas, satu fungsi satu berkas bernama sama.
Referensi#
- Preallocating Arrays — MathWorks — Panduan resmi praalokasi beserta penjelasan biaya array yang membesar.
- Variable Names — MathWorks — Aturan resmi penamaan variabel beserta batasan dan kata kunci yang dihindari.
- Create Functions in Files — MathWorks — Panduan resmi pendefinisian fungsi pada berkas tersendiri.