Berita:

Update RPN OJ forum! Petualangan keenam kelompok Trihörrèan di Kerajaan Líghtran berlanjut. Sanggupkah mereka mengakhiri masalah di Líghtran? Baca rangkuman kisah maraton sesi terakhir di sini dan lanjutkan petualangan mereka.

Main Menu

Buat program yuk!

Dimulai oleh Èxsharaèn, 04 November 2006, 08:41:59

« sebelumnya - berikutnya »

0 Anggota dan 1 Pengunjung sedang melihat topik ini.

Èxsharaèn

Nah, ada kalanya kita harus menghentikan paksa perulangan yang tengah dijalankan. Untuk melakukan ini, gunakan kata break. break akan menghentikan paksa sebuah perulangan for, while, until, loop do.

Jadi, saat menggunakan loop do, berikut cara berhenti dari perulangan tersebut:
loop do
  program yang harus diulang
  break if kondisi
end

Lho, bentuk if-nya kok lain? Ya, ini bentuk khusus blok if: Jika ia tidak punya bagian else dan perintah yang dilakukan hanya satu, bentuk
if kondisi
  perintah
end

bisa diringkas ke dalam bentuk
perintah if kondisi
Tapi ingat, perintah yang dilakukan cuma boleh satu ya...

Kadang-kadang kita juga perlu melanjutkan perulangan begitu saja tanpa melakukan beberapa potongan program yang semestinya dilakukan. Misalnya kita ingin membuat faktorial yang "unik": ia hanya menghitung perkalian bilangan ganjil. Jadi, 3! berarti 3 * 1, 6! berarti 5 * 3 * 1. Untuk kasus ini, kita bisa menggunakan kata next. Contoh:
p "Masukkan angka:"
angka = gets.chomp.to_i
faktorial = 1
i = 0
loop do
  i += 1
  next if i % 2 == 0
  break if i > angka
  faktorial *= i
end
p "Faktorial unik ini hasilnya " + faktorial.to_s


Program yang aneh... :D Program ini berulang kali menambah i dengan 1. Kalau ternyata i genap, langsung lanjutkan perulangan. Baris setelah next tidak akan dikerjakan.

Yah, memang kasus-kasus ini agak jarang terjadi, tapi cukup berguna saat program kita sudah cukup kompleks.

Terakhir! Ada kalanya kita harus melakukan perulangan paling tidak sekali. Blok while dan until bisa melakukan hal ini, hanya dengan bentuk yang sedikit berbeda:
begin
  program yang harus diulang
end while|until kondisi

Dengan bentuk seperti ini, program kita akan menjalankan apapun yang ada di blok begin lebih dahulu baru mengecek kondisinya. Itu sebabnya, perulangan seperti ini pasti dilakukan paling tidak sekali.

Wow, banyak juga yah bentuk perulangan yang kita kenali! Silakan pilih bentuk yang paling bersahabat dan mudah dikuasai. Sekarang, ayo kita terapkan pengetahuan kita sejauh ini!
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Yuk latihan!

1. Buat program yang menghitung panjang nama yang dimasukkan pengguna. Program akan menampilkan seberapa panjang nama tersebut dengan ketentuan:
kurang dari 10 karakter: pendek
10 hingga 20 karakter: sedang
lebih dari 20 karakter: panjang
Tips: Gunakan perintah length untuk mengetahui panjang sebuah string (contoh: variabelku.length)

2. Buat program yang menerima masukan sebuah huruf. Tentukan apakah huruf tersebut vokal atau konsonan.

3. Buat program untuk mengetahui faktor sebuah angka. Contoh: Faktor dari 6 adalah 1, 2, 3, 6. Tampilkan seperti ini:
KutipMasukkan angka: 6
Faktor-faktornya:
1
2
3
6

4. Buat program untuk menghitung KPK (kelipatan persekutuan terkecil). Misal: KPK 5 dan 3 adalah 15.

5. Buat program untuk mengetahui apakah sebuah bilangan yang dimasukkan adalah bilangan prima. Program (3) dapat digunakan untuk membuat program ini.

6. Buat program yang menerima dua masukan: tahun awal dan tahun akhir. Tampilkan seluruh tahun kabisat yang berada di jangka waktu tersebut.

7. Buat program permainan tebak-tebakan. Komputer akan mengacak sebuah angka dan pengguna harus menebak angka tersebut. Beri petunjuk (respon dari komputer), apakah angka yang dimasukkan lebih besar atau lebih kecil dari angka tebakan. Setelah tertebak, tampilkan berapa kali tebakan pemain dan beri pujian berdasarkan jumlah tebakan:
1: Hebat sekali!
2 - 10: Hebat!
11 - 20: Lumayan
20 - 30: Payah!
>30: Ngawur amat sih?
Tips: Gunakan perintah rand(angka_max) untuk mengacak angka. rand(100) akan mengembalikan angka acak antara 0 hingga 99. Batasi angka acak antara 0 hingga 100.

8. Kali ini, biarkan komputer yang menebak angkamu. Masukkan jangkauan angkanya (misal dari 0 hingga 100). Ingat-ingat angka yang harus ditebak. Tiap kali komputer menebak, beri petunjuk apakah angka tebakannya lebih besar atau lebih kecil dari angkamu. Buat sedemikian rupa sehingga komputer menebak dengan jumlah tebakan paling sedikit.

Salah satu pendekatannya adalah sebagai berikut. Komputer akan langsung mengambil nilai tengah jangkauan awal. Beri tahu komputer apakah angka sebenarnya lebih besar atau lebih kecil dari angka acak tersebut. Berikutnya, komputer akan memperkecil jangkauan tebakannya dan mengambil nilai tengah sebagai tebakan berikutnya. Lakukan terus sampai angkanya tertebak.

Contoh: Angka yang harus ditebak = 65. Jangkauan tebakan 0 hingga 100
Tebakan pertama komputer: (0 + 100) / 2 = 50.
Ternyata angka tebakan komputer lebih kecil dari angka sebenarnya. Komputer akan memperkecil jangkauannya menjadi 50 hingga 100. Tebakan berikutnya adalah (100 + 50) / 2, yaitu 75.
Lebih besar. Komputer mempersempit lagi jangkauannya menjadi 50 ke 75. Tebakan berikutnya adalah (50 + 75) / 2 = 62.
Llebih kecil. Jangkauan menjadi 62 ke 75. Tebakan berikutnya adalah (62 + 75) / 2 = 68.
Lebih besar. Jangkauan menjadi 62 ke 68. Tebakan berikutnya adalah (62 + 68) / 2 = 65.
Akhirnya tertebak juga...

Jangan lupa hitung berapa kali komputer menebak, dan beri dia pujian seperti pada program sebelumnya.

Selamat mencoba!
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Oke, gimana? Nggak sulit kan? Kalau ada yang kesulitan, atau ingin mencocokkan jawaban, silakan baca jawaban di bawah ini. Kalau sudah bisa, ayo lanjut!

Ingat, ini hanya salah satu alternatif jawaban! Punya kalian mungkin lebih panjang atau bahkan lebih pendek dari jawaban ini, namun yang penting logikanya benar.

1.
puts "Masukkan nama:"
nama = gets.chomp
case nama.length
when 0 .. 10
  puts "Namamu pendek yah."
when 11 .. 20
  puts "Lumayan panjang..."
else
  puts "Wah, panjangnya namamu..."
end


2. Perbaiki program ini agar karakter apapun yang dimasukkan selain huruf tidak terdeteksi sebagai "huruf konsonan!"
puts "Masukkan huruf:"
huruf = gets.chomp.upcase
case huruf
when "A", "E", "I", "O", "U"
  p "Huruf vokal"
else # waduh, karakter nonhuruf juga masuk bagian ini!
  p "Huruf konsonan"
end


3.
puts "Masukkan angka:"
angka = gets.chomp.to_i
p "Faktor-faktornya:"
i = 1 # hitung mulai dari 1...
while i <= angka
  if angka % i == 0 # kalau sisa pembagian (modulus, %) angka terhadap i adalah 0...
    puts i # ...i adalah faktor dari angka!
  end
  i += 1 # jangan lupa ubah kondisi perulangan
end


4. Ada yang bisa memanfaatkan program nomor 3?
puts "Masukkan angka pertama:"
angka1 = gets.chomp.to_i
puts "Masukkan angka kedua:"
angka2 = gets.chomp.to_i
i = angka1 # ambil salah satu angka
until i % angka2 == 0 # berhenti kalau hasil sisa pembagiannya 0
  i += angka1
end
# keluar dari blok until, i akan bernilai sama dengan KPK kedua angka! Kenapa begitu?
p "KPK-nya: " + i.to_s


5. Ada yang bisa memanfaatkan program nomor 3?
puts "Masukkan angka:"
angka = gets.chomp.to_i
i = 1
faktor = 0
for i in 1 .. angka
  faktor += 1 if angka % i == 0 # hitung jumlah faktor
  break if faktor > 2 # hentikan saja loop for ini kalau jumlah faktor sudah lebih dari dua (berarti bukan prima, ya kan?)
end
if faktor == 2
  p "Angka prima!"
else
  p "Bukan angka prima!"
end


Tunggu sebentar... Kenapa ada banyak tanda # di dalam kode program di atas?
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Walaupun Ruby sudah didesain agar se-Inggris mungkin (maksudnya mirip dengan tata bahasa Inggris) sehingga mudah dibaca, programmer tingkat ahli pun masih sering memanfaatkan fitur berikut:

Komentar

Pada Ruby, komentar ditandai dengan #. Apapun yang kita tulis setelah tanda ini, asalkan tidak ganti baris, akan dianggap sebagai komentar. Komputer akan mengabaikan seluruh komentar yang ada dalam program kita. Walaupun mungkin memperbesar ukuran berkas kode program kita, amat dianjurkan memberi komentar terutama pada baris-baris kode yang sudah cukup rumit. Komentar ini amat bermanfaat saat kita membaca ulang program kita lama setelah pembuatannya, supaya kita ingat untuk apa program ini dibuat dan bagaimana cara kerjanya. Komentar juga bermanfaat agar program kita dapat dimengerti oleh orang lain yang membaca program kita.

Ada satu lagi cara untuk menandai komentar, terutama kalau komentarnya panjang sekali, berbaris-baris. Gunakan blok =begin untuk menulis komentar berbaris-baris dan akhiri dengan blok =end. Awas! Penulisan =begin dan =end harus diletakkan di awal baris tanpa ada awalan apapun, termasuk spasi dan tabulasi. Contoh:

=begin
Ini adalah komentar yang cukup panjang.
Biasanya berisi nama program...
  Pembuatnya... (boleh diawali spasi)
Tanggal dibuat... (juga boleh diawali tabulasi)
Keterangan singkat kegunaan program...
Dan hal-hal lain yang perlu diketahui orang yang membaca kode program ini.
Ini adalah baris terakhir komentar kita.
=end


Coba biasakan untuk memberi komentar kapanpun dirasa perlu.
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Nah, untuk latihan nomor 6, 7, dan 8, aku serahkan dulu pada kalian. Kalau ada kesulitan, silakan ditanyakan di sini langsung (atau buat topik baru kalau memang perlu). Kita lanjut ke bagian berikutnya.

Metode

Pada beberapa bagian di awal kita sebenarnya sudah menyinggung beberapa metode, seperti to_i, chomp, upcase, length, dan sebagainya. Ada penggunaan lain metode, yaitu untuk mengulang potongan program kapanpun kita butuhkan. Lho, bukannya bisa pakai perulangan (loop)? Ada kalanya kita tidak langsung memerlukan potongan program tersebut. Lihat contoh berikut.

Ada proses A di sini...
Ada proses B di sini...
Ada proses C di sini...
Ternyata kita butuh proses B.
Ada proses D...
Butuh lagi proses B.

Bagaimana ini dilakukan dengan perulangan biasa? Nah, metode bisa mengatasi masalah ini. Dengan memanggil metode tersebut, kita bisa mengulangi kembali baris program yang kita perlukan. Dengan cara ini, program kita sudah mulai bisa "lompat-lompat", karena metode harus didefinisikan dulu sebelum bisa digunakan. Contohnya untuk kasus di atas...

Definisikan dulu proses B.
Ada proses A di sini...
Panggil proses B.
Ada proses C...
Ternyata kita buruh proses B. Panggil saja proses B.
Ada proses D...
Butuh lagi proses B. Panggil lagi proses B!

Nah, bagaimana cara membuat sebuah metode? Ingat, sebuah metode harus didefinisikan dahulu sebelum dipakai? Mudah saja, Ruby mendefinisikan metode dengan

def nama_metode
  # apapun yang ingin kita lakukan di sini...
end


Untuk menggunakan metode ini, cukup panggil namanya.

Ini adalah bentuk metode paling sederhana. Kita coba contoh programnya dulu.

def panggil
  p "Halo " + nama + "!"
end
p "Masukkan nama:"
nama = gets.chomp
panggil
p "Masukkan nama sahabat karibmu:"
nama = gets.chomp
panggil


Aduh, kenapa Ruby memberikan error?
KutipUndefined local variable or method 'nama' for main:Object (NameError)
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Apa yang salah dengan program kita sebelumnya? Well, Ruby ternyata tidak mengenali variabel nama yang ada di baris kedua program kita:
p "Halo " + nama + "!"
Kok tidak kenal? Bukannya ada variabel nama di bawahnya? Memang namanya sama, tapi sebenarnya kita belum punya variabel nama di metode kita. Ingat, variabel harus paling tidak pernah digunakan sekali sebelum digunakan kembali. Karena pada metode panggil kita sama sekali belum pernah menggunakan variabel nama, Ruby tidak akan mengenalinya.

Lha terus gimana? Ada dua pemecahan masalah ini, tapi aku berikan satu dulu. Ingatkan untuk pemecahan masalah satunya yah!

Supaya metode kita bisa mengakses variabel dari luar dirinya, kita memerlukan yang dinamakan

Parameter

Parameter adalah variabel bantu yang bisa "dilemparkan" program dari luar suatu metode agar metode itu bisa mengaksesnya. Bentuknya seperti ini:

def nama_metode(parameter)
  # apa saja yang mau dilakukan di sini...
  # boleh juga mengakses parameter lho!
end


Waktu memanggil metode ini, jangan lupa parameternya. Metode di atas akan dipanggil dengan nama_metode(nilai_parameter_ini).

Parameter boleh lebih dari satu! Misalnya...
def metodeku(param1, param2)

end


Parameter boleh juga diberi nilai awal, jadi kalau pengguna kita kelupaan memasukkan nilai untuk suatu parameter, program akan otomatis memberi nilai. Contoh:
def faktor(angka = 1)

end

Parameter seperti ini juga sering disebut dengan optional parameter, artinya boleh dipakai boleh tidak. Program kita harus mampu mengecek apakah parameter tersebut digunakan atau tidak. Kalau parameternya lebih dari satu dan beberapa memang opsional, usahakan seluruh parameter opsional berada di belakang. Misalnya:
def panggil(nama, jenis_kelamin, alamat = "Jl. Antah Berantah", umur = 0)

end


Nah, program kita tadi bisa dibetulkan menjadi seperti berikut:

def panggil(nama)
  p "Halo " + nama + "!"
end
p "Masukkan nama:"
nama = gets.chomp
panggil(nama)
p "Masukkan nama sahabat karibmu:"
nama = gets.chomp
panggil(nama)


Asyik, program kita sekarang berjalan dengan mulus! Rupanya metode ini berguna sekali ya? Tunggu dulu, masih ada satu lagi kegunaan metode...
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Ada kalanya kita ingin metode kita bisa "berkomunikasi" dengan program kita berikutnya. Misalnya, kita ingin hasil proses dalam metode kita bisa tetap diakses di luar metode tersebut. Untuk itulah, ada satu bentu metode yang spesial...

Fungsi

Ruby tetap menyebutnya sebagai metode. Fungsi adalah metode yang "mengembalikan sebuah nilai" (dalam arti sebenarnya). Jadi, hasil proses sebuah metode bisa "dikembalikan" ke program untuk diproses lebih lanjut. Sama seperti metode, fungsi amat berguna kalau kita membutuhkan proses ini berulang-ulang. Misalnya...

Anggap saja kita ingin menghitung nilai sinus suatu sudut (pada Ruby, fungsinya adalah Math.sin(x)). Kita memasukkan nilai sudut itu dalam derajat, namun fungsi trigonometri pada umumnya meminta sudut dalam radian (untuk yang tidak belajar matematika, satu lingkaran penuh (360°) adalah satu radian atau 2
π
). Supaya kita tidak melulu harus mengubah satuan sudut saat menghitung, kita bisa membuat sebuah fungsi berikut:

def deg_to_rad(sudut_deg)
  sudut_rad = sudut_deg.to_f / 180 * Math::PI
  return sudut_rad
end


Perhatikan kata return di akhir fungsi kita? Itu adalah kata kunci untuk menandai Ruby, apa yang ingin kita kembalikan (return). Sebenarnya, tiap metode mengembalikan suatu nilai, yaitu nilai apapun yang berada di akhir metode. Jadi, kata kunci return tidak mutlak dituliskan, seperti ini:

def deg_to_rad(sudut_deg)
  sudut_rad = sudut_deg.to_f / 180 * Math::PI
  sudut_rad
end


Tapi agar tidak bingung dan mudah membedakannya dari metode biasa, biasakan memberi kata return untuk mengembalikan suatu nilai. Metode biasa juga mengembalikan nilai berupa nil (ini akan kita singgung kemudian). Jangan lupa untuk menampung nilai suatu fungsi ke suatu variabel.

Nah, fungsi itu kini bisa dipakai pada program kita:

def deg_to_rad(sudut_deg)
  sudut_rad = sudut_deg.to_f / 180 * Math::PI
  return sudut_rad
end

p "Masukkan sudut (derajat):"
sudut = gets.chomp
p "sin(" + sudut.to_s + ") dalam derajat = " + deg_to_rad(sudut).to_s

Coba masukkan angka 30. Hasilnya mungkin seperti berikut:
Kutip"Masukkan sudut (derajat):"
30
"sin(30) dalam derajat = 0.523598775598299"

Wah, jauh lebih akurat dari yang diajarkan guru matematika kita dulu yah :D

Coba perhatikan baris ini:
p "sin(" + sudut.to_s + ") dalam derajat = " + deg_to_rad(sudut).to_s
Hasil dari suatu fungsi dapat langsung digunakan pada proses berikutnya, seperti contoh di atas. Jadi, kalau sudah mahir, kita bisa menggunakan cara di atas kalau memang hasil fungsi tersebut tidak perlu diolah lagi. Bentuk sederhananya adalah sebagai berikut:
sudut_rad = deg_to_rad(sudut)
p "sin(" + sudut.to_s + ") dalam derajat = " + sudut_rad.to_s

Silakan gunakan kesukaan kalian.
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Kita berhenti sejenak di sini. Wow, banyak juga yah yang sudah kita pelajari bersama! Kita sudah belajar bagaimana menggunakan variabel dan konstanta; mengatur alur program kita dengan perulangan, percabangan, ditambah metode dan fungsi yang kita pelajari barusan, memberi komentar pada program kita, dan mengubah tipe data. Dasar-dasar pemrograman sebenarnya selesai sampai di sini, jadi selamat! Kalian sudah bisa membuat program yang lebih kompleks lagi!

Tapi tunggu, masih ada beberapa konsep dasar yang umum dijumpai di bahasa pemrograman manapun, termasuk Ruby. Tunggu artikel berikutnya untuk mengetahui lebih banyak lagi!

Untuk sekarang, coba kerjakan ulang latihan sebelumnya. Bisakah kalian menulis ulang program nomor 3 untuk digunakan pada program nomor 4 dan 5?

Ini soalnya kalau ada yang ketinggalan:

3. Buat program untuk mengetahui faktor sebuah angka. Contoh: Faktor dari 6 adalah 1, 2, 3, 6. Tampilkan seperti ini:
KutipMasukkan angka: 6
Faktor-faktornya:
1
2
3
6
Modifikasi seperlunya untuk mengerjakan nomor 4 dan 5.

4. Buat program untuk menghitung KPK (kelipatan persekutuan terkecil). Misal: KPK 5 dan 3 adalah 15.

5. Buat program untuk mengetahui apakah sebuah bilangan yang dimasukkan adalah bilangan prima. Program (3) dapat digunakan untuk membuat program ini.

Untuk tambahan latihan:

9. Buat metode untuk menghitung faktorial suatu angka (dimasukkan lewat parameter).

10. Buat metode untuk menggambar bintang sejumlah angka yang dimasukkan lewat parameter. Misalnya: gambar_bintang(5) akan menghasilkan gambar seperti berikut:
*
**
***
****
*****


11. Buat metode untuk mengubah bilangan desimal yang dimasukkan lewat parameter menjadi bilangan biner. Contoh, dec_to_bin(7) akan menghasilkan 111.
Petunjuk: Bilangan biner adalah bilangan yang hanya terdiri dari 0 dan 1.
Tips: Anggap bilangan biner adalah kumpulan string 0 dan 1, bukan angka 0 dan 1.

12. Kebalikan dari nomor 11, buat metode untuk mengubah bilangan biner yang dimasukkan lewat parameter menjadi bilangan desimal.
Petunjuk: Akses satu huruf dari sebuah string dengan cara nama_string[indeks, 1]. Contoh:
stringku = "Halo!"
p stringku[0, 1] # "H"


Selamat bekerja! ;)
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Nah, bagaimana? Sudah bisa bikin program sendiri? Yang suka baca-baca pasti sudah tahu bahwa fungsi untuk latihan nomor 11 dan 12 sebenarnya sudah disediakan oleh Ruby :D

Sebentar lagi kita akan melangkah lebih jauh dengan mengenal konsep pemrograman yang dipakai Ruby, yaitu Pemrograman Berbasis Objek (PBO), tapi kita akan meneruskan artikel ini dengan dua materi lagi sebelum kita pindah ke materi baru.

Jadi, apa yang akan kita pelajari sekarang?

Error handling

Sudah mencoba menunjukkan program pertama pada teman? Bagaimana reaksi mereka?
Nah, andaikan saja ada pengguna yang kelewat iseng. Kita ambil contoh program menghitung luas lingkaran kita (masih ingat?). Bagaimana seandainya ada yang iseng memasukkan angka seperti ini?

KutipMasukkan jari-jari lingkaran: sapi

Di bahasa pemrograman lain, program tersebut mungkin sudah pasti error. Sama juga dengan Ruby, program kita tersebut bisa mengalami kesalahan apabila masukan yang diterima ternyata bukan masukan yang benar. Program tersebut mungkin akan menghasilkan nilai yang tidak diharapkan, atau paling parah terjadi error.

Tidak hanya kesalahan masukan saja yang dapat menyebabkan program kita error. Kesalahan sintaks (syntax error) akibat ketidaktelitian saat mengetik juga menjadi salah satu hal yang berperan, terutama pada programmer pemula (jangan khawatir, bahkan aku dulu juga sering kok mengalami syntax error). Kesalahan yang agak tidak terlihat namun termasuk paling sering terjadi adalah kesalahan logika, misalnya secara tidak sadar mengalikan sebuah angka dengan variabel yang ternyata string (tidak bisa kan?).

Nah, namanya manusia tidak bisa lepas dari kesalahan, tapi komputer tidak bisa menoleransi kesalahan. Kesalahan sedikit saja mungkin dapat berakibat fatal pada komputer, mulai dengan komputer hang, aplikasi tiba-tiba menutup sendiri, bahkan paling parah sistem operasi juga kena imbasnya (ingat kan blue screen of death di Windows 98?). Jadi, kita sebagai programmer harus meminimalkan kesalahan-kesalahan yang mungkin terjadi, bahkan kalau bisa meniadakannya. Itu bukan hal yang cukup sulit kok.

Pertama-tama, kita harus membatasi masukan dari pengguna program kita. Misal, pada contoh program luas lingkaran, tentu kita hanya ingin masukan berupa angka, ya kan? Sebelum memroses luas lingkaran, kita bisa mengecek dulu masukan pengguna. Dua baris pertama program kita bentuknya kan seperti ini...

p "Masukkan jari-jari lingkaran: "
radius = gets.chomp.to_f


Nah, perintah to_f ternyata mengembalikan nilai 0 kalau string yang ia coba ubah ternyata bukan angka yang valid (karakter pertama string yang akan diubah ternyata bukan angka). Kita bisa coba cara ini:

# Cek dulu!!!
if radius > 0
  luas = Math::PI * radius ** 2
  p "Luas lingkaran: " + luas.to_s
else
  p "Maaf, masukkan hanya angka!"
end


Oke! Masukan bukan angka sudah tidak diterima lagi. Tapi... waktu dimasukkan jari-jari 0 satuan, kenapa program kita mengeluarkan Maaf, masukkan hanya angka!? Nah, rupanya ada kesalahan logika di sini ^_^; Tapi, jika dipikirkan lebih jauh, masukan yang kita terima sebenarnya kan memang string? Trus, gimana dong?
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Nah, ada banyak pendekatan untuk menyelesaikan masalah ini. Kita bisa membiarkan program kita menerima masukan string (sehingga luas lingkaran menjadi 0.0, atau melakukan pengecekan yang agak "ekstrim". Tetap lakukan komversi to_f, namun jika hasilnya 0 (awas, 0 di sini adalah 0 bulat, bukan 0 yang diikuti angka desimal), lihat karakter pertama. 0 atau bukan? Kalau ternyata 0, tetap hitung luas lingkaran (tentu saja, hasilnya 0.0); kalau tidak, tampilkan pesan kesalahan.

Tapi, ada kalanya kita tahu persis baris program kita yang mungkin menimbulkan kesalahan, misalnya saat mengerjakan pembagian. Sudah jadi rahasia umum bahwa pembagian dengan 0 tidak diizinkan. Apa yang terjadi seandainya kita tetap membiarkan pembagian dengan 0?

a = 0
b = 20 / a
p b.to_s


Yang terjadi adalah:
Kutipdivided by 0

Andaikan saja memang tidak dapat dicegah bahwa pembaginya kadang-kadang bisa bernilai 0, kita bisa menggunakan bantuan Ruby untuk menangkap kesalahan yang mungkin terjadi. Istilah kerennya exception. Untuk itulah, blok begin ... rescue ... [ensure ...] end digunakan. Gimana cara pakainya?

begin
  # Lakukan apa saja yang dicurigai dapat menyebabkan error/exception di sini...
  # Bisa beberapa baris
rescue [<tipe exception> => <variabel bantu untuk menangkap exception>]
  # Lakukan apa saja yang akan terjadi andaikan terjadi error di sini...
[ensure]
  # Lakukan apa saja yang pasti harus dilakukan di sini, tidak peduli terjadi error atau tidak...
end


Langkah kerjanya begini. Ruby akan melakukan apa saja yang ada pada bagian begin. Andaikan di suatu tempat di bagian itu terjadi error, Ruby akan menghentikan diri (sehingga baris berikutnya dalam blok begin tidak akan pernah dijalankan) dan langsung lompat ke bagian rescue, kemudian menjalankan apapun yang ada di blok rescue. Jika ada blok ensure (blok ini boleh ada boleh tidak), selesai dari blok rescue Ruby akan menjalankan perintah pada blok ensure, tidak peduli apakah pernah terjadi error pada blok begin atau tidak.

Susah dimengerti? Nii contohnya...

begin
  a = 0
  b = 20 / a # (1) Baris ini salah!!! Ruby akan lompat ke...
  p b.to_s # ini tidak akan pernah dijalankan karena baris sebelumnya ada error.
rescue
  p "Salah oi!" # (2) ...sini!
  # Oh, ternyata tidak ada lagi yang dikerjakan di blok ini. Selanjutnya, Ruby akan mengerjakan...
ensure
  # (3) ...blok ini sampai selesai.
  a = 1 if a == 0
  b = 20 / a
  p "Hasil pembagian: " + b.to_s
end


Bagaimana hasilnya?
KutipSalah oi!
Hasil pembagian: 20

Coba kita ganti nilai variabel a ke angka lain selain 0.

begin
  a = 10
  b = 20 / a # Tadi dicurigai salah, kan? Ternyata tidak ada error!
  p b.to_s # Jadi, baris ini tetap dikerjakan.
  # Oh, selesai! Apa blok rescue tetap dikerjakan? Tentu saja tidak, kan tidak ada error!
rescue
  p "Salah oi!"
ensure
  # Tapi, Ruby akan tetap mengerjakan bagian ini.
  a = 1 if a == 0
  b = 20 / a
  p "Hasil pembagian: " + b.to_s
end


Hasilnya:
Kutip2
Hasil pembagian: 2
Ups, hasil pembagiannya tampil dua kali :P

Oke! Jadi kita sudah bisa memperkecil area kesalahan ke potongan kecil program kita yang dicurigai "bersalah". Tapi, apa guna teks-teks tambahan di belakang rescue itu? Kok tidak digunakan?
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

#25
Ada kalanya pula kita tahu persis jenis kesalahan (exception) yang mungkin terjadi, misalnya pembagian nol (ZeroDivisionError), salah tipe (TypeError), dan sebagainya. Kalau kita tahu persis jenis kesalahannya, kita boleh pakai format rescue <tipe error> => <variabel bantu untuk error>. Informasi kesalahan yang terjadi akan disimpan ke variabel bantu kita, sehingga kita bisa mengetahui beberapa informasi tambahan, seperti nama error, pesan kesalahan yang dibuat Ruby, baris berapa yang menyebabkan kesalahan, dan sebagainya. Kita boleh juga menggunakan beberapa blok rescue seperti berikut:

begin
  a = "sapi" # Coba ganti-ganti nilai variabel ini dengan angka biasa, 0, atau apapun.
  b = 20 / a
  p b.to_s
rescue ZeroDivisionError => zde # khusus untuk pembagian 0
  p "Salah oi! " + zde.message
rescue TypeError => tye # khusus untuk tipe data yang tidak sesuai
  p "Jangan pakai string dong!"
rescue Exception => exc # untuk error lainnya yang tidak kita ketahui
  p "Error apa ini ya? " + exc.message
ensure
  p "Program selesai!"
end


Lha jenis-jenis error tahu dari mana? Ada dua cara untuk mengetahui jenis-jenis error. Gunakan Ruby Doc, dan cari Error. Ada banyak kelas Error yang disediakan, tapi mungkin informasinya kurang lengkap. Cara lainnya, gunakan saja rescue Exception => ex dan tampilkan jenis kesalahan dengan kode p ex.inspect.. Hasilnya mungkin seperti ini:

Kutip#<TypeError: String can't be coerced into Fixnum>
Yang dicetak tebal adalah jenis error.

Nah, bisa kan sekarang mengurangi kesalahan yang mungkin terjadi pada program kita?
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

#26
Selagi kita membebaskan diri dari kesalahan program, ada dua tipe data (sebenarnya objek) khusus yang disediakan Ruby untuk berurusan dengan daftar.

Andaikan saja kita membuat program untuk memasukkan nama beberapa barang, anggap saja lima barang. Kita mungkin memulai program kita seperti ini:

p "Berapa barang?"
jum_brg = gets.chomp.to_i
for i in 1 .. jum_brg
  p "Nama barang " + i.to_s + ": "


Lha, nama barangnya disimpan di mana? Apa seperti ini?

p "Berapa barang?"
jum_brg = gets.chomp.to_i
for i in 1 .. jum_brg
  p "Nama barang " + i.to_s + ": "
  nama_brg = gets.chomp
end
# Tampilkan seluruh barang
for i in 1 .. jum_brg
  p "Nama barang " + i.to_s + ": " + nama_brg
end


Coba jalankan. Bagaimana hasilnya?

Kutip"Berapa barang?"
5
"Nama barang 1: "
Pensil
"Nama barang 2: "
Buku
"Nama barang 3: "
Penggaris
"Nama barang 4: "
Pena
"Nama barang 5: "
Kertas
"Nama barang 1: Kertas"
"Nama barang 2: Kertas"
"Nama barang 3: Kertas"
"Nama barang 4: Kertas"
"Nama barang 5: Kertas"

Lha kok Kertas semua? Mana barang yang lain?

Atau pakai cara ini? Kita sediakan banyak-banyak variabel, jadi nanti tinggal pakai satu per satu. Tapi, berapa banyak variabel yang harus kita sediakan? Nggak tahu juga kan kalau kasusnya seperti di atas?

Untuk itulah, kita akan mengenal satu kawan baru (objek sebenarnya, tapi kita bisa mempelajari objek ini tanpa belajar PBO dulu). Perkenalkan:

Array

Bahasa Indonesianya mungkin agak aneh: larik. Kita pakai array saja.

Array adalah objek khusus (di bahasa pemrograman lain mungkin bukan objek) yang bisa digunakan untuk menyimpan sebanyak-banyaknya variabel yang kita perlukan. Anggap saja kita punya banyak variabel seperti ini: nama_brg1, nama_brg2, nama_brg3, nama_brg4, nama_brg5. Kelima variabel tersebut bisa diwakili oleh satu array nama_brg yang berdimensi satu dengan ukuran 5.

Aduh, sudah ada dua istilah baru lagi: dimensi dan ukuran! Apa lagi nih?

Akan sangat mudah jika kita menganggap array adalah sebuah tabel. Anggap saja kita mempunyai tabel dengan penyimpanan data dilakukan menurun (per baris), sehingga nama 5 barang disimpan ke tabel berikut:

Pensil
Buku
Penggaris
Pena
Kertas


Jumlah kolom pada tabel tersebut adalah dimensi sebuah array, dan jumlah barisnya sama persis dengan ukuran array.

Ayo kita buat array pertama kita! Agak berbeda dengan variabel biasa, variabel array harus dideklarasikan terlebih dahulu (karena array adalah objek). Jadi, untuk menggunakan array, kita harus membuatnya terlebih dahulu dengan:

arrayku = Array.new
arrayku = Array.new(<ukuran>)

Baris pertama akan membuat sebuah array baru yang tidak punya ukuran. Baris kedua membuat array dengan ukuran tertentu. Kalau memang tahu ukuran array yang kita perlukan, disarankan pakai bentuk kedua saja.

Setelah dibuat, bagaimana caranya mengisi array kita? Nanti setelah diisi, cara mengaksesnya bagaimana?
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Nah, untuk mengisi dan mengakses sebuah array, kita memerlukan indeks, yaitu sebuah bilangan bulat (integer) yang menunjukkan lokasi array yang ingin kita isi/akses. Gampangannya, pada tabel, indeks adalah nomor baris. Misalnya seperti ini:

arrayku[0] = "Sapi"
p arrayku[0] # hasilnya [color=red]"Sapi"[/color]


Tunggu dulu... kenapa pakai angka 0? Kenapa nggak 1 saja? Nah, inilah salah satu keanehan dunia pemrograman. Nyaris semua bahasa pemrograman yang memiliki array akan setuju bahwa indeks pertama yang dimiliki sebuah array adalah 0, bukan 1 (ini disebut zero-based array index). Ada alasan mengapa mereka menggunakan angka 0 sebagai indeks pertama, tapi untuk konsumsi kita cukup lah kalau indeks pertama array di Ruby adalah 0.

Awas! Karena dimulai dari 0, indeks tertinggi yang dimiliki sebuah array adalah ukurannya dikurangi 1. Lebih lanjut nanti, kita dapat mengetahui ukuran sebuah array dengan perintah <nama array>.size atau <nama array>.length.

Nah, setelah mengetahui kegunaan array, masalah kita pun terpecahkan! Programnya akan menjadi seperti ini:

p "Berapa barang?"
jum_brg = gets.chomp.to_i
nama_brg = Array.new(jum_brg)
for i in 0 ... jum_brg # perhatikan tanda titiknya!
  p "Nama barang " + (i + 1).to_s + ": "
  nama_brg[i] = gets.chomp
end
# Tampilkan seluruh barang
for i in 0 ... jum_brg
  p "Nama barang " + (i + 1).to_s + ": " + nama_brg[i]
end


Ayo dicoba!

Kutip"Berapa barang?"
5
"Nama barang 1: "
Pensil
"Nama barang 2: "
Buku
"Nama barang 3: "
Penggaris
"Nama barang 4: "
Pena
"Nama barang 5: "
Kertas
"Nama barang 1: Pensil"
"Nama barang 2: Buku"
"Nama barang 3: Penggaris"
"Nama barang 4: Pena"
"Nama barang 5: Kertas"

Mudah kan?
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

#28
Ada kalanya kita membutuhkan array yang lebih besar. Misalkan program tadi kita perluas untuk menerima masukan dari beberapa orang untuk memesan barang kesukaannya. Tentu saja, array kita jadi tidak cukup menampung semuanya. Ada dua pendekatan untuk ini:

1. Tetap menggunakan array satu dimensi, dengan ukuran jumlah orang dikalikan jumlah barang. Hanya saja, pendekatan ini akan gagal kalau tiap orang memiliki jumlah barang yang berbeda (ada yang bisa mengatasinya?).

2. Kita gunakan array berdimensi lebih besar, dalam kasus ini cukup berdimensi dua. Aduh, gimana bikinnya?
Agak berbeda dengan bahasa pemrograman lain, pada Ruby kita tidak bisa secara langsung mendefinisikan array multidimensi dari awal. Mau tidak mau, kita harus mendefinisikan array baru di setiap elemennya. Kasarannya seperti ini:

arrayku = Array.new(jumlah_baris)
for i in 0 ... jumlah_baris
  arrayku[i] = Array.new(jumlah_kolom)
end


Hati-hati, perintah Array.size tidak serta merta memberikan ukuran total array kita (yang diduga adalah jumlah baris dikalikan jumlah kolom), namun hanya mengembalikan ukuran array terluar saja (dalam kasus di atas adalah jumlah baris). Tidak percaya? Nii...

arrayku = Array.new(5)
for i in 0 ... 5 # sementara kita pastikan dulu jumlahnya 5
  arrayku[i] = Array.new(2)
end
# Ukuran array kita seharusnya 5 x 2 = 10 kan?
p arrayku.size

Hasilnya?
Kutip5

Ini terjadi karena sebenarnya array kita bukan array multidimensi, namun array yang "bersarang" dalam array lain (istilah kerennya nested array). Jadi, arrayku pada contoh di atas sebenarnya adalah array satu dimensi yang memiliki array satu dimensi di tiap elemennya. Walaupun demikian, kita bisa menganggapnya array multidimensi.

Lalu, cara aksesnya bagaimana? Jangan khawatir, nggak sulit kok. Karena kini array kita memiliki dimensi banyak, indeks yang diperlukan juga jadi banyak, tergantung jumlah dimensinya. Untuk array berdimensi dua, cukup gunakan arrayku[indeks1][indeks2]. Array dimensi tiga? Ya arrayku[indeks1][indeks2][indeks3]. Dan seterusnya.

Perlu dicoba? Ayo!

p "Berapa orang?"
jml_org = gets.chomp.to_i
nama_brg = Array.new(jml_org)
for i in 0 ... jml_org
  p "Orang " + (i + 1).to_s + ": Berapa barang?"
  jml_brg = gets.chomp.to_i
  nama_brg[i] = Array.new(jml_brg)
  for j in 0 ... jml_brg
    p "Barang " + (j + 1).to_s + ":"
    nama_brg[i][j] = gets.chomp
  end
end
# sekarang tampilkan masukan keseluruhan
for i in 0 ... nama_brg.size
  p "Orang " + (i + 1).to_s
  for j in 0 ... nama_brg[i].size
    p "Barang " + (j + 1).to_s + ": #{nama_brg[i][j]}"
  end
end


Hasilnya:
Kutip"Berapa orang?"
2
"Orang 1: Berapa barang?"
3
"Barang 1:"
Kursi
"Barang 2:"
Meja
"Barang 3:"
Papan tulis
"Orang 2: Berapa barang?"
2
"Barang 1:"
Buku
"Barang 2:"
Pena
"Orang 1"
"Barang 1: Kursi"
"Barang 2: Meja"
"Barang 3: Papan tulis"
"Orang 2"
"Barang 1: Buku"
"Barang 2: Pena"

Tidak sesulit yang dibayangkan!

Tapi tunggu, ada yang aneh di program di atas... Apa ini?
    p "Barang " + (j + 1).to_s + ": #{nama_brg[i][j]}"

Ini adalah jalan pintas untuk menuliskan nilai suatu variabel dalam string, jadi kita tidak perlu memanggil perintah to_s. Formatnya adalah #{nama_variabel}. Tapi ingat, ini hanya berlaku kalau string-nya menggunakan tanda kutip ganda, dan tidak semua variabel bisa diakses dengan cara ini. Coba deh ganti kode itu menjadi:
    p "Barang #{(j + 1)}: #{nama_brg[i][j]}"
dan lihat hasilnya!

Oke! Itu saja tentang array! Lebih banyak lagi tentang array akan kita kupas di topik selanjutnya. Tapi tunggu, ada satu bentuk khusus dari array...

EDIT:
Aduh, maaf, aku lupa kalau [ i ] itu BBCode untuk mencetak miring :P koreksinya sudah aku berikan di atas, yaitu:
untuk mengakses array dua dimensi: arrayku[indeks1][indeks2]
untuk mengakses array tiga dimensi: arrayku[indeks1][indeks2][indeks3]
Ada kebiasaan sih bahwa variabel penghitung (counter) itu namanya i, j, dan k :P
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen

Èxsharaèn

Wah, sudah lama juga yah aku nggak nulis di sini, padahal materinya tinggal satu :P

Yuk dilanjutkan! Setelah artikel ini selesai, kita bisa melanjutkan ke artikel berikutnya, yaitu PBO.

Jadi, apa satu bentuk spesial dari array?

Hash

Pengguna PHP pasti familiar dengan istilah ini. Hash pada Ruby sejatinya juga array juga, namun ada perbedaannya. Kalau pada array kita hanya bisa mengindeks menggunakan angka (0, 1, 2, bahkan angka negatif diizinkan di Ruby), hash mengizinkan kita mengindeks menggunakan hampir apapun. Wah, gimana caranya? Niii...

# Inisialisasi awal...
hashku = Hash.new
# atau...
hashku_yang_lain = {}


Lalu, masukkan nilainya? Mirip array kok. Misalkan saja kita ingin punya daftar orang dan binatang peliharaannya, itu bisa dimasukkan ke dalam hash seperti berikut:

pet = {}
pet["Adi"] = "Kucing"
pet["Budi"] = "Anjing"
pet["Charlie"] = "Ikan"
# Istilah kerennya...
hash[key] = value


Hmm... lalu, cara aksesnya? Kalau mau akses satu-satu per elemen, bisa dengan cara ini:

p pet["Adi"] # "Kucing"

Lha kalau mau semuanya? Di sini kelemahan hash, isinya tidak diurutkan, jadi kita harus tahu kuncinya (key). Tapi nggak masalah kan, bukannya kita memang sudah tahu kuncinya?

OK, andaikan saja kita dipaksa menampilkan isi hash tersebut, kita bisa gunakan dua metode milik objek Hash, yaitu Hash.keys untuk mengetahui semua kunci yang dimiliki sebuah hash, dan Hash.values untuk mengetahui semua nilai yang dimiliki sebuah hash. Misal, untuk hash kita di atas...

for key in pet.keys
  p "#{key} memiliki binatang peliharaan {#pet[key]}"
end


Hasilnya:

Kutip"Charlie memiliki binatang peliharaan Ikan"
"Budi memiliki binatang peliharaan Kucing"
"Adi memiliki binatang peliharaan Anjing"

OK! Silakan bermain-main sendiri dengan array dan hash. Artikel ini selesai sampai di sini (yay!). Dengan pengetahuan dasar yang sudah didapat dari artikel ini, kita sudah bisa membuat program sendiri. Namun, ada satu lagi pengetahuan yang sebaiknya didapat supaya kita bisa beradaptasi dengan segala macam bahasa pemrograman, yaitu Pemrograman Berbasis Objek. Lanjutkan di artikel itu yah!

Selamat mencoba-coba!
Jangan lupa ikutan serunya petualangan Our Journey!
~ A, èxshna il utnön qu our journey shallaran a èndh... ~

Profiles
About.me https://about.me/hoshiro.exsharaen