Anda di sini

Pemrograman

Python 3 RLE BAB 7: Perulangan

Aditya Suranata - 06 Juni 2016 18:55:38 0

Komputer sering digunakan untuk mengotomatiskan tugas-tugas yang berulang. Mengulang tugas-tugas yang sama atau mirip tanpa membuat kesalahan adalah hal yang dilakukan dengan sangat baik oleh komputer dan sangat buruk oleh manusia.

Eksekusi berulang dari sekumpulan pernyataan dinamakan perulangan (iteration). Karena perulangan sangatlah umum, Python menyediakan beberapa fitur bahasa untuk mempermudahnya. Kita sudah melihat pernyataan for pada bab 3. Ini adalah bentuk dari perulangan yang akan sering kamu gunakan. Tapi pada bab ini kita akan mempelajari tentang pernyataan while -- cara lain untuk membuat program melakukan perulangan, yang akan berguna untuk situasi yang berbeda.

Sebelum kita melakukannya, mari kita review beberapa pemahaman...

7.1. Pemberian Nilai (Assigment)

Seperti yang kita bahas sebelumnya, pemberian nilai pada suatu variabel lebih dari satu kali itu dibolehkan. Pemberian nilai baru membuat variabel sebelumnya merujuk pada nilai yang baru (dan berhenti merujuk ke nilai yang sebelumnya).

waktu_tersisa = 15
print(waktu_tersisa)
waktu_tersisa = 7
print(waktu_tersisa)

Output dari program ini adalah:

15
7

Itu karena waktu_tersisa pertama kali memegang nilai 15, dan kedua kali nilainya diganti menjadi 7. Tercetaklah 15 dan kemudian 7.

Sangatlah penting untuk bisa membedakan antara sebuah pemberian nilai dan ekspresi Boolean untuk menguji kesetaraan. Karena Python menggunakan token sama dengan ( = ) untuk pemberian nilai, sangat mungkin seseorang akan menganggap pernyataan seperti a = b sebagai sebuah pengujian Boolean. Tidak seperti matematika! Ingat bahwa token untuk operator persetaraan pada Python adalah menggunakan ==.

Ingat juga bahwa sebuah pengujian kesetaraan sifatnya simetris, tapi pemberian nilai tidak. Sebagai contoh, jika a == 7 maka 7 == a juga artinya sama. Tapi di Python, pernyataan a = 7 adalah legal dan 7 = a adalah tidak.

Di Python, sebuah pernyataan pemberian nilai bisa membuat dua variabel bernilai sama, tapi karena, pemberian nilai selanjutnya bisa merubah masing-masing, hal itu tidak mesti dikatakan demikian:

a = 5
b = a    # Setelah menjalankan baris ini, a dan b bernilai sama
a = 3    # Setelah menjalankan baris ini, a dan b tidak lagi sama

Baris ketiga merubah nilai dari a tapi tidak merubah nilai dari b, jadi mereka tidak lagi sama. (dalam beberapa bahasa pemrograman lainnya, digunakan simbol yang berbeda untuk pemberian nilai, misalnya seperti <- atau :=, untuk menghindari kebingungan. Beberapa orang juga menganggap bahwa variabel adalah kata yang tidak tepat untuk digunakan, tapi lebih tepat kalau kita memanggilnya sebagai assignable. Python memilih untuk mengikuti peristilahan umum dan penggunaan tokennya, juga ditemukan dalam bahasa seperti C, C++, Java, dan C#, jadi kita menggunakan token = untuk pemberian nilai, == untuk persetaraan, dan kita menyebutnya sebagai variabel.

7.2. Memperbaharui Variabel

Ketika sebuah pernyataan pemberian nilai dieksekusi, ekspresi di sisi kanan (contoh: ekspresi yang ditulis setelah token pemberian nilai) akan dinilai terlebih dahulu. Ini akan menghasilkan sebuah nilai. Lalu pemberian nilai dilakukan, jadi itu berarti variabel pada sisi kiri sekarang merujuk ke nilai yang baru.

Satu dari banyak bentuk yang paling umum dari pemberian nilai adalah sebuah pembaharuan, dimana nilai baru dari variabel bergantung pada nilai lamanya. Ambil tarik 50 ribu dari ATM, atau tambah satu putaran ke papan nilai.

n = 5
n = 3 * n + 1

Baris 2 berarti dapatkan nilai sekarang dari n, kalikan dengan tiga dan tambahkan satu, dan berikan jawabannya ke n, sehingga n merujuk ke nilai itu. Jadi setelah mengeksekusi dua baris diatas, n akan berisi atau merujuk ke integer 16.

Jika kamu mencoba untuk mendapatkan nilai sebuah variabel yang sama sekali belum diberikan nilai, kamu akan mendapatkan sebuah error.

>>> w = x + 1
Traceback (most recent call last):
File "<interactive input>", line 1, in
NameError: name 'x' is not defined

Sebelum kamu bisa memperbaharui sebuah variabel, kamu mesti menginisialisasi nilai awalnya, biasanya dengan sebuah pemberian nilai sederhana:

skor_tim = 0
...
skor_tim = skor_tim + 1

Baris 3 -- memperbaharui sebuah variabel dengan menambahkannya 1 -- sangatlah umum. Ini dimanakan sebagai increment dari variabel; pengurangan dengan 1 dinamakan decrement. Terkadang programer juga menyebutnya bumping variabel, yang artinya juga sama menjumlahkan dengan 1.

7.3. Meninjau Lagi Perulangan for

Ingat bahwa perulangan for memproses setiap item dalam sebuah list. Setiap item pada gilirannya dimuat ulang ke variabel perulangan, dan body dari perulangan pun dieksekusi. Kita melihat contoh ini pada bab sebelumnya:

for f in ["Joe", "Zoe", "Brad", "Angelina", "Zuki", "Thandi", "Paris"]:
    invitation = "Hi " + f + ".  Please come to my party on Saturday!"
    print(invitation)

Memproses semua item dalam sebuah list dinamakan dengan traversing list, atau traversal.

Mari buat sebuah fungsi untuk menjumlahkan semua elemen dari sebuah list bilangan. Lakukan ini secara manual dulu, dan coba pisahkan langkah-langkap apa saja yang kamu ambil. Kamu akan menyadari kamu perlu mempersiapkan "total berjalan" dari penjumlahan yang telah lewat, baik dalam selembar kertas, atau di kepala mu, atau kalkulator. Mengingat hal-hal dari satu langkah ke langkah selanjutnya adalah alasan mengapa kita punya variabel-variabel dalam sebuah program: jadi kita akan perlu beberapa variabel untuk mengingat "total berjalan". Yang mestinya dimulai dengan nilai nol, dan kemudian kita perlu melintasi item-item yang ada dalam daftar. Untuk setiap item, kita akan perlu memperbaharui nilai dari total berjalan dengan menjumlahkannya dengan bilangan selanjutnya.

def mysum(xs):
    """ Sum all the numbers in the list xs, and return the total. """
    running_total = 0
    for x in xs:
        running_total = running_total + x
    return running_total

# Add tests like these to your test suite ...
test(mysum([1, 2, 3, 4]) == 10)
test(mysum([1.25, 2.5, 1.75]) == 5.5)
test(mysum([1, -2, 3]) == 2)
test(mysum([ ]) == 0)
test(mysum(range(11)) == 55)  # 11 is not included in the list.

7.4. Pernyataan while

Berikut merupakan potongan kode yang mendemonstrasikan penggunaan dari pernyataan while:

def sum_to(n):
    """ Return the sum of 1+2+3 ... n """
    ss  = 0
    v = 1
    while v <= n:
        ss = ss + v
        v = v + 1
    return ss

# For your test suite
test(sum_to(4) == 10)
test(sum_to(1000) == 500500)

Kamu hampir bisa membaca pernyataan while sebagaimana dalam bahasa Inggris. Itu berarti, sementara v nilainya kurang dari atau sama dengan n, lanjutkan eksekusi dari body perulangan. Di dalam body, setiap kali putaran, increment nilai v. Ketika v nilainya melewati n, kembalikan (return) hasil penjumlahan yang sudah terakumulasi.

Lebih formalnya, berikut adalah alur tepat dari pernyataan while:

  • Nilai kondisi pada baris ke 5, menghasilkan sebuah nilai baik False atau True.
  • Jika nilainya adalah False, keluar dari pernyataan while dan lanjutkan eksekusi ke pernyataan berikutnya (dalam kasus ini line 8).
  • Jika nilainya adalah True, eksekusi setiap pernyataan di dalam body (baris 6 dan 7) lalu kembali ke pernyataan while pada baris ke 5.

Bagian body terdiri dari semua pernyataan yang bertakuk dibawah keyword while.

Perhatikan bahwa jika kondisi perulangan mengubah nilai dari satu atau lebih variabel-variabel sehingga akhirnya kondisinya menjadi false dan perulangan dihentikan. Selain itu perulangan akan melakukan pengulangan selama-lamanya, yang dinamakan dengan infinite loop. Salah satu sumber hiburan untuk ilmuan komputer adalah hasil pengamatan bahwa cara pakai yang ditulis pada kemasan sampo, "lather, rinse, repeat", adalah sebuah infinite loop.

Pada kasus ini, kita bisa membuktikan bahwa perulangan berakhir karena kita tahu bahwa nilai dari n adalah terbatas, dan kita bisa melihat nilai dari v ber-increment setiap kali perulangan berputar. Jadi pada akhirnya tibalah waktunya ia akan melewati n. Dalam kasus lainnya, itu tidaklah mudah, bahkan menjadi tidak mungkin dalam beberapa kasus, untuk mengetahui apakah perulangan akan berhenti.

Apa yang akan kamu sadari disini adalah bahwa perulangan while adalah pekerjaan lebih untuk mu -- sang programer -- ketimbang saudaranya perulangan for. Ketika menggunakan sebuah perulangan while kita mesti mengatur variabel perulangan kita sendiri: berikan nilai awal, cara uji kondisi untuk menentukan penyelesaian, lalu memastikan kamu merubah sesuatu pada body sehingga perulangan akan berhenti. Sebagai perbandingan, berikut adalah sebuah fungsi yang sama tetapi menggunakan for:

def sum_to(n):
    """ Return the sum of 1+2+3 ... n """
    ss  = 0
    for v in range(n+1):
        ss = ss + v
    return ss

Perhatikan pemanggilan fungsi range yang cukup sulit -- kita mesti menambah satu ke n, karena range menghasilkan listnya hingga tapi tidak termasuk nilai yang kamu berikan padanya. Kesalahan pemrograman sangat mungkin terjadi dan mengabaikan hal ini, tapi karena kita telah membuat investasi dari penulisan beberapa unit tes, tes suite kita akan menangkap erorr kita.

Jadi mengapa harus ada dua perulangan jika for terlihat lebih mudah? Contoh selanjutnya memperlihatkan kasus dimana kita perlu kemampuan ekstra yang akhirnya kita dapatkan dari perulangan while.

7.5. Urutan Collatz 3n + 1

Mari lihat pada urutan sederhana yang telah membuat para ahli matematika berdecak kagum dan mabuk selama bertahun-tahun. Mereka masih belum bisa jawab bahkan pertanyaan yang paling sederhana mengenai hal ini.

"Aturan perhitungan" untuk membuat urutannya adalah mulai dari menentukan bilangan n, dan membuat urutan berikutnya dari n, baik dengan membelah dua n, (ketika n adalah genap), atau lainnya dengan mengalikannya dengan tiga dan menambahkan satu. Urutan ini akan brakhir ketika n mencapai 1.

Fungsi Python berikut menggambarkan algoritma tersebut:

def seq3np1(n):
    """ Print the 3n+1 sequence from n,
        terminating when it reaches 1.
    """
    while n != 1:
        print(n, end=", ")
        if n % 2 == 0:        # n is even
            n = n // 2
        else:                 # n is odd
            n = n * 3 + 1
    print(n, end=".\n")

Pertama perhatikan bahwa fungsi print pada baris 6 memiliki argumen tambahan end=", ". Ini memberitahu fungsi print untuk menyertakan string yang tercetak apapun yang dipilih oleh programmer (dalam kasus ini, sebuah koma diikuti dengan sebuah spasi), daripada mengakhiri baris. Jadi setiap kali sesuatu tercetak dalam perulangan, hasilnya akan tercetak pada baris yang sama, menjadi bilangan-bilangan yang dipisahkan dengan koma. Pemanggilan print(n, end=".\n" pada baris ke 11 setelah perulangan selesai akan mencetak nilai akhir dari n diikuti dengan sebuah titik dan sebuah karakter baris baru. (Kamu akan mengetahui apa itu \n (karakter baris baru atau newline) dalam bab berikutnya).

Kondisi untuk meneruskan perulangan ini adalah n != 1, jadi perulangan akan terus berlanjut hingga ia mencapai kondisi pengakhirannya, (misal n == 1).

Setiap kali dalam perulangan, program akan mencetak nilai dari n dan kemudian menguji apakah nilainya genap atau ganjil. Jika genap, nilai dari n dibagi dua menggunakan pembagian integer. Jika ganjil, nilainya digantikan menjadi n * 3 + 1. Berikut beberapa contohnya:

>>> seq3np1(3)
3, 10, 5, 16, 8, 4, 2, 1.
>>> seq3np1(19)
19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13,
40, 20, 10, 5, 16, 8, 4, 2, 1.
>>> seq3np1(21)
21, 64, 32, 16, 8, 4, 2, 1.
>>> seq3np1(16)
16, 8, 4, 2, 1.
>>>

Karena n terkadang bertambah dan terkadang berkurang, tidak ada bukti yang bisa terlihat bahwa n akan bisa mencapai 1, atau programnya akan berhenti. Untuk beberapa nilai tertentu dari n, kita bisa membuktikan pengakhiran. Sebagai contoh, jika nilai awal adalah pangkat dua, maka nilai dari n akan menjadi genap setiap kali dalam perulangan hingga ia mencapai 1. Contoh sebelumnya berhenti dengan sebuah urutan, yang dimulai dengan 16.

Lihat jika kamu bisa menemukan sebuah nilai awal kecil yang memerlukan ratusan langkah sebelum akhirnya selesai.

Disamping nilai tertentu, pertanyaan menarik pertama kali diungkapkan oleh seorang ahli matematika Jerman bernama Lothar Collatz: Collatz conjecture (juga dikenal sebagai 3n + 1 conjecture), adalah bahwa urutan ini berakhir untuk semua nilai positif dari n. Sejauh ini, tak seorang pun mampu membuktikan menyangkalnya! (Sebuah conjecture atau tebakan adalah sebuah pernyataan yang mungkin benar, tapi tak ada seorang pun yang tahu dengan pasti.)

Pikirkan dengan matang mengenai apa yang dibutuhkan untuk sebuah pembuktian dan sebuah penyangkalan dari tebakan "Semua integer positif pada akhirnya akan bertemu dengan 1 menggunakan aturan Collatz". Dengan komputer yang cepat kita telah mampu menguji setiap integer hingga nilai yang sangat besar, dan sejauh ini, mereka semua pada akhirnya berakhir dengan satu. Tapi siapa yang tahu? Mungkin terdapat bilangan yang berkurang menjadi 1.

Kamu akan menyadari bahwa jika kamu berhenti ketika kamu mencapai 1, urutannya masuk kedalam lingkaran putarnya sendiri: 1, 4, 2, 1, 4, 2, 1, 4 ... Jadi satu kemungkinannya adalah bahwa mungkin terdapat putaran lainnya yang belum kita ketahui hingga sekarang.

Wikipedia memiliki artikel informatif mengenai dugaan Collatz. Urutannya juga memiliki nama lain (Urutan Hailstone, bilangan-bilangan Wonderous, dll.) kamu akan menemukan seberapa banyak integer yang telah diuji oleh komputer, dan diketahui bisa bertemu!

Memilih antara for dan while
Gunakan perulangan for jika kamu tahu, sebelum kamu memulai perulangan, jumlah maksimal putaran yang kamu perlukan untuk mengeksekusi body. Sebagai contoh, jika kamu melintasi sebuah list yang berisi elemen-elemen, kamu tahu bahwa jumlah maksimal dari iterasi perulangan yang mungkin kamu butuhkan adalah "semuah elemen yang berada dalam daftar". Atau jika kamu perlu mencetak 12 kali putaran, kita tahu dengan pasti seberapa banyak perulangan yang perlu dilakukan.

Jadi masalah apapun seperti "putari model cuaca ini untuk 1000 kali putaran", atau "cari daftar kata-kata ini". "temukan semua bilangan primer hingga 10000" untuk itu paling bagus adalah menggunakan perulangan for.

Kebalikannya, jika kamu harus mengulang beberapa komputasi hingga beberapa kondisi terpenuhi, dan kamu tidak bisa menghitung lebih detil ketika (dari if) hal tersebut akan terjadi, seperti yang kita lakukan pada masalah 3n + 1 ini, kamu akan memerlukan sebuah perulangan while.

Kita menamai kasus pertama sebagai definite iteration -- kita tahu seberapa banyak perulangan diperlukan. Kasus selanjutnya adalah indefinite iteration -- kita tidak tahu pasti seberapa banyak perlulangan yang kita perlukan -- kita bahkan tidak bisa menentukan batas atasnya!

7.6. Menelusuri Sebuah Program (Tracing)

Untuk menulis program komputer yang efektif, dan untuk membangun model konseptual sebuah eksekusi program, seorang programer perlu mengembangkan kemampuannya dalam melacak eksekusi dari program komputer. Penelusuran melibatkan sudut pandang menjadi itu sendiri dan mengikuti flow of execution melalui sebuah sampel program berjalan, merekam kondisi dari semua variabel dan output apapun yang dihasilkan program setelah setiap intruksi selesai dieksekusi.

Untuk memahami proses ini, mari lacak pemanggilan ke fungsi seq3np1(3) dari sesi sebelumnya. Pada permulaan dari pelacakan, kita punya sebuah variabel, n (sebuah parameter), dengan sebuah nilai awal 3. Karena 3 tidak sama dengan 1, body dari perulangan while dieksekusi. 3 tercetak dan 3 % 2 == 0 dinilai. Karena itu akan menghasilkan False, maka cabang else dieksekusi dan 3 * 3 + 1 dinilai dan hasilnya diberikan ke n.

Untuk mencatat semuanya ketika kita menelusuri program, buat sebuah kolom dalam selembar kertas untuk setiap variabel yang dibuat sebagaimana program berjalan dan satu lagi untuk outputnya. Penelurusan kita sejauh ini akan terlihat seperti berikut:

n output printed so far
-- ---------------------
3 3,
10

Karena 10 != 1 menghasilkan True, body perulangan dieksekusi lagi, dan tercetak 10. 10 % 2 == 0 adalah true, jadi cabang if yang dieksekusi dan n menjadi 5. Pada akhirnya kita mendapatkan:

n output printed so far
-- ---------------------
3 3,
10 3, 10,
5 3, 10, 5,
16 3, 10, 5, 16,
8 3, 10, 5, 16, 8,
4 3, 10, 5, 16, 8, 4,
2 3, 10, 5, 16, 8, 4, 2,
1 3, 10, 5, 16, 8, 4, 2, 1.

Tracing program bisa menjadi sedikit membosankan dan mudah error (itulah kenapa kita menyuruh komputer untuk melakukan hal ini duluan!), tapi ini adalah sebuah skill penting yang harus dimiliki oleh seorang programer. Melalui penelusuran ini kita bisa belajar banyak hal mengenai bagaimana kode-kode yang kita tulis bekerja. Kita bisa mengamati bahwa segera setelah n menjadi pangkat 2, sebagai contoh, program akan memerlukan pengeksekusian log2(n) dari body perulangan untuk bisa selesai. Kita juga bisa melihat bahwa final 1 tidak akan tercetak sebagai output dalam body perulangan, itulah mengapa kita menempatkan fungsi print khusus pada bagian akhir.

Menelusuri program adalah, tentu saja, berhubungan dengan single-stepping pada kode mu dan bisa memeriksa variabel-variabelnya. Menggunakan single-step pada komputer untuk diri mu cenderung mengurangi eror dan tentunya lebih nyaman. Jiga, sebagaimana program mu berkembang menjadi lebih rumit, mereka mungkin mengeksekusi berjuta-juta langkah sebelum mereka bisa sampai ke kode yang benar-benar kamu inginkan, jadi tracing manual tentunya tidak mungkin untuk dilakukan. Bisa menentukan sebuah breakpoint dimana kamu memerlukannya adalah jauh lebih berguna. Jadi kami sangat menganjurkan mu untuk meluangkan waktu mempelajari bagaimana menggunakan lingkungan pemrograman mu (PyScripter, dalam catatan tersebut) dengan sepenuhnya.

Juga tersedia beberapa tools visualisasi yang bagus untuk membantu mu melacak dan memahami bagian kecil dari kode Python. Salah satu yang direkomendasikan adalah http://netserv.ict.ru.ac.za/python3_viz

Kita telah diberitahu mengenai fungsi-fungsi chatterbox, tapi kita sekarang menggunakannya disini. Seiring kita mempelajari Python lebih jauh lagi, kita akan melihat bagaimana cara membuat sebuah list yang berisi nilai-nilai untuk menyimpan urutannya, ketimbang membuat fungsi yang mencetak mereka. Dengan melakukan ini maka kita bisa menghilangkan fungsi-fungsi print yang mengganggu tersebut di pertengahan logika kita, dan tentunya membuat fungsi menjadi lebih berguna.

7.7. Menghitung Digit

Fungsi berikut menghitung jumlah dari digit desimal dalam integer positif.

def num_digits(n):
    count = 0
    while n != 0:
        count = count + 1
        n = n // 10
    return count

Pemanggilan ke fungsi print(num_digits(710)) akan mencetak 3. Pelacakan eksekusi dari pemanggilan fungsi ini (mungkin menggunakan fungsi single-step pada PyScripter, atau Python visualizer, atau menggunakan selembar kertas) untuk meyakinkan diri mu sendiri bahwa ia bekerja.

Fungsi ini menunjukan sebuah pola penting dari komputasi yang dimanakan dengan counter. Variabel count diinisialisasi dengan 0 dan kemudian ditambahkan setiap kali body perulangan dieksekusi. Ketika perulangan keluar, count berisi hasilnya -- yaitu berapa kali body perulangan dieksekusi, yang tentunya sama dengan jumlah digit yang dihitung.

Jika kita hanya ingin menghitung digit 0 atau 5 saja, kita bisa melakukannya dengan menambahkan pengkondisian sebelum menambahkan counter:

def num_zero_and_five_digits(n):
    count = 0
    while n > 0:
        digit = n % 10
        if digit == 0 or digit == 5:
            count = count + 1
        n = n // 10
    return count

Pastikan bahwa test(num_zero_and_five_digits(1055030250) == 7) bisa dilewati.

Perhatikan kalau test(num_digits(0) == 1) hasilnya gagal. Jelaskanlah kenapa bisa demikian. Apakah kamu berpikir ini adalah bug di dalam kode, atau bug di spesifikasi, atau ekspektasi kita, atau pengujiannya yang bermasalah?

7.8. Pemberian Nilai yang Disingkat (Abbreviated assignment)

Menambahkan sebuah variabel (incrementing) adalah tugas umum dan maka dari itu Python memiliki syntax yang disingkat untuk itu:

>>> count = 0
>>> count += 1
>>> count
1
>>> count += 1
>>> count
2

count += 1 adalah sebuah singkatan untuk count = count + 1. Kita mengucapkan operator tersebut sebagai "plus-sama dengan". Nilai increment tidak harus 1:

>>> n = 2
>>> n += 5
>>> n
7

Ada juga singkatan-singkatan lainnya untuk -=. *=, /=, //= dan %=:

>>> n = 2
>>> n *= 5
>>> n
10
>>> n -= 4
>>> n
6
>>> n //= 2
>>> n
3
>>> n %= 2
>>> n
1

7.9. Bantuan dan meta-notation

Python datang dengan dokumentasi luas untuk semua fungsi-fungsi built-in, dan library-library atau pustakanya. Sistem lain memiliki cara lain untuk mengakses bantuan ini. Di PyScripter, caranya dengan mengklik item menu Help, dan memilih Python Manual. Kemudian cari bantuan pada fungsi built-in range. Kamu akan menemukan bantuan seperti gambar berikut:

Perhatikan kurung siku pada deskripsi argumen. Itu adalah contoh dari meta-notation -- notasi yang menjelaskan syntax Python, tapi bukan merupakan bagian dari argumen. Kurung siku pada dokumentasi ini berarti bahwa argumen tersebut sifatnya opsional -- programer bisa mengisi atau menghiraukannya. Jadi apa yang baris help ini maksud adalah bahwa range harus selalu memiliki argumen stop, tapi untuk argumen start nya bisa opsional (yang mana harus diikuti dengan koma jika ada), dan ia juga bisa memiliki argumen tambahan berupa step, diawali dengan koma jika ada.

Contoh dari help tersebut memperlihatkan bahwa range bisa memiliki 1, 2 atau 3 argumen. Hasilnya yang berupa list bisa dimulai dari nilai awal berapapun, dan bertambah atau berkurang terus dalam increment 1 (step = 1). Dokumentasi ini juga mengatakan bahwa, argumennya harus bertipe integer.

Meta-notation lainnya yang juga akan sering kamu lihat adalah penggunaan huruf tebal dan huruf miring. Huruf tebal artinya ia adalah sejenis token -- keyword atau simbol -- yang artinya ia harus ditulis pada kode Python mu seperti apa adanya, timana istilah yang ditulis dengan huruf miring berarti "sesuatu dengan tipe ini". Jadi deskripsi syntax:

for variabel in list:

artinya adalah kamu bisa menggantinya dengan variabel legal dan list legal apapun ketika kamu menulisnya pada kode Python mu.

Deskripsi ini (yang disederhanakan) adalah miliki fungsi print, juga memperlihatkan contoh lain dari meta-notation yang mana tanda elipsis (...) berarti bahwa kamu bisa memiliki objek sebanyak yang kamu inginkan (bahkan nol), dipisahkan dengan koma:

print( [object, ...] )

Meta-notation memberikan kita cara ringkas dan powerful untuk menjelaskan pola-pola dari beberapa syntax atau fitur.

7.10. Tabel

Satu dari sekian hal yang paling bagus jika diselesaikan menggunakan perulangan adalah pembuatan tabel. Sebelum adanya komputer, orang-orang mesti menghitung logaritma, sin dan cos, dan fungsi matematika rumit lainnya secara manual dengan tangan. Untuk membuatnya menjadi lebih mudah, buku-buku matematika berisi tabel-tabel panjang yang berisi daftar nilai-nilai dari fungsi-fungsi tersebut. Membuat tabel tentu merupakan pekerjaan yang lamban dan membosankan, dan mereka tentunya cenderung menghasilkan banyak error.

Ketika komputer datang sebagai solusi, satu dari reaksi-reaksi awal yang muncul adalah, "Wah ini bagus sekali! Sekarang kita bisa menggunakan komputer untuk membuat tabel, jadi pasti tidak akan ada lagi error." Hal tersebut memang menjadi kenyataan (kebanyakan) tapi masih merupakan opini jangka pendek. Karena segera setelahnya, komputer-komputer dan kalkulator telah menyebar dengan sangat cepat, dan begitu banyak orang yang menggunakan, sehingga secara otomatis penggunaan tabel berangsur-angsur ditinggalkan. Komputer tidak lagi diharapkan ada untuk membuat tabel, tetapi komputer dan kalkulator sendiri sudah bisa menggantikan fungsi tabel!

Ya, hampir. Tapi untuk beberapa operasi, komputer-komputer juga ternyata masih menggunakan tabel dari nilai-nilai untuk mendapatkan jawaban terdekat dan kemudian melakukan perhitungan untuk meningkatkan keakuratan hasilnya. Dalam beberapa kasus, terdapat error-error dalam tabel-tabel pokok tersebut, kejadian yang paling terkenal adalah tabel pada chip prosesor Intel Pentium yang digunakan untuk melakukan pembagian floating-point.

Meskipun tabel log tidak terlalu berguna seperti sedia kala, ia masih bisa dijadikan contoh dari perulangan. Program berikut menghasilkan urutan dari nilai-nilai pada kolom sisi kiri dan nilai di kiri tadi dipangkatkan dengan dua dan hasilnya ditampilkan pada kolom di sisi kanan:

for x in range(13):   # Generate numbers 0 to 12
    print(x, "\t", 2**x)

String "\t" fungsinya untuk mewakili karakter tab. Karakter garis miring belakang (backslash) pada "\t" menandakan awal dari sebuah escape sequence. Escape sequence digunakan untuk mewakili karakter-karakter yang tidak terlihat seperti tab dan baris baru. Urutan dari \n mewakili baris baru.

Escape squence bisa muncul dimana saja di dalam string; pada contoh ini, escape sequence tab adalah satu-satunya yang digunakan pada string untuk membuat tab. Bagaimana menurut mu cara untuk mewakili backslash dalam sebuah string?

Seperti halnya karakter-karakter dan string-string ditampilkan di layar, tanda tak terlihat yang dinamakan cursor mencatat posisi dimana karakter selanjutnya akan ditempatkan. Setelah fungsi print, cursor biasanya pergi ke awal baris baru.

Karakter tab akan menggeser cursor ke kanan hingga mencapai satu tab stop. Tab berguna untuk membuat kolom dari baris teks, seperti terlihat pada output dari program sebelumnya:

0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128
8 256
9 512
10 1024
11 2048
12 4096

Karena ada karakter tab diantara kolom, posisi dari kolom kedua tidak bergantung pada jumlah digit dari kolom pertama.

7.11. Tabel dua dimensi

Tabel dua dimensi adalah tabel yang nilainya bisa dibaca pada interseksi dari baris dan kolomnya. Tabel perkalian adalah contoh yang bagus. Mari katakan kamu ingin mencetak tabel perkalian untuk nilai-nilai dari 1 hingga 6.

Cara yang bagus untuk memulainya adalah dengan menulis perulangan yang mencetak hasil perkalian dia, semuanya dalam satu baris:

for i in range(1, 7):
    print(2 * i, end="   ")
print()

Disini kita menggunakan fungsi range, tetapi untuk awal urutannya kita mulai dari 1. Ketika perulangannya dieksekusi, nilai dari i akan berubah dari 1 hingga 6. Ketika semua elemen dari range telah diberikan ke i, perulangan akan berakhir. Setiap kali perulangan berputar, ia akan menampilkan nilai dari 2 * 1, diikuti dengan tiga spasi.

Lagi, argumen tambahan end=" " pada fungsi print mengabaikan baris baru, dan menggunakan tiga spasi sebagai gantinya. Setelah perulangan selesai, pemanggilan print pada baris 3 akan mengakhiri baris sekarang, dan memulai baris baru di bawahnya.

Output dari program ini adalah :

2 4 6 8 10 12

Bagus sekali kita sudah sampai sejauh ini. Langkah selanjutnya adalah melakukan enkapsulasi dan generalisasi (encapsulate & generalize).

7.1.2. Enkapsulasi dan generalisasi

Enkapsulasi adalah proses pembalutan pototangan-potongan kode ke dalam sebuah fungsi, sehingga memungkinkan kita untuk mendapatkan keuntungan dari semua hal yang bisa dilakukan oleh fungsi tersebut. Kamu telah melihat beberapa contoh dari enkapsulasi, termasuk is_divisible pada bab sebelumnya.

Generalisasi berarti melakukan suatu hal khusus, seperti mencetak hasil perkalian dengan 2, lalu membuatnya menjadi lebih umum, seperti mencetak hasil perkaluan dengan integer berapapun.

Fungsi berukut akan mengenkapsulasi perulangan sebelumnya dan menggeneralisasikannya untuk mencetak hasil perkalian dengan n:

def print_multiples(n):
    for i in range(1, 7):
        print(n * i, end="   ")
    print()

Untuk enkapsulasi, semua yang perlu kita lakukan adalah menambahkan baris pertama, yang mendeklarasikan nama dari fungsi dan daftar parameternya. Untuk menggeneralisasi, semua yang perlu kita lakukan adalah mengganti nilai 2 dengan parameter n.

Jika kita memanggil fungsi ini dengan argumen 2, kita akan mendapatkan output yang sama seperti sebelumnya. Dengan argumen 3, outputnya adalah:

4 8 12 16 20 24

Sekarang kamu tentunya bisa menebak bagaimana cara mencetak tabel perkalian -- dengan memanggil print_multiples secara berulang dengan argumen-argumen yang berbeda. Tentunya, kita bisa menggunakan perulangan lain seperti:

for i in range(1, 7):
    print_multiples(i)

Perhatikan bagaimana miripnya perulangan ini dengan yang ada di dalam print_multiples. Semua yang kita lakukan adalah mengganti fungsi print dengan sebuah pemanggilan fungsi.

Output dari program ini adalah sebuah tabel perkalian:

1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
5 10 15 20 25 30
6 12 18 24 30 36

7.13. Enkapsulasi lebih lanjut

Untuk mendemonstrasikannya lagi, mari ambil kode dari sesi terakhir dan bungkus kedalam sebuah fungsi:

def print_mult_table():
    for i in range(1, 7):
        print_multiples(i)

Proses ini adalah rencana pengembangan (development plan) yang sangat umum. Kita mengembangkan kode dengan menulis baris-baris kode diluar fungsi apapun, atau menuliskannya langsung pada interpreter. Ketika kita sudah bisa membuat kodenya berjalan, baru kita mengekstraknya dan membungkusnya ke dalam sebuah fungsi.

Rencana pengembangan ini khususnya sangat berguna jika kamu tidak tahu bagaimana cara membagi program menjadi fungsi ketika kamu mulai menulis. Pendekatan ini akan membantu mu mendesain seiring dengan berkembangnya kode.

7.14. Variabel-variabel lokal

Kamu mungkin bertanya-tanya bagaimana kita dapat menggunakan variabel yang sama, i, pada kedua fungsi print_multiples dan print_mult_table. Bukankan hal tersebut dapat menjadi masalah ketika salah satu fungsi merubah nilai dari variablenya?

Jawabannya adalah tidak, karena i pada print_multiples dan i pada print_mult_table bukanlah variabel yang sama.

Variabel yang dibuat di dalam sebuah definisi fungsi akan bersifat lokal; kamu tidak bisa mengakses variabel lokal dari luar fungsi yang memiliki variabel tersebut. Itu artinya kamu bisa memiliki banyak variabel dengan nama yang sama selama variabel-variabel tersebut tidak berada dalam satu fungsi.

Python menilai semua pernyataan di dalam sebuah fungsi -- jika salah satu dari fungsi itu memberikan nilai pada variabel, itulah petunjuk yang digunakan oleh Python untuk membuat variabel menjadi sebuah variabel lokal.

Nilai dari i pada print_mult_table berubah dari 1 hingga enam. Pada diagram yang terjadi adalah 3. Saat selanjutnya setelah perulangan nilainya akan menjadi 4. Setiap kali saat perulangan, print_mult_table memanggil print_multiples dengan nilainya yang sekarang dari i sebagai sebuah argument. Nilai tersebut diberikan ke parameter n.

Di dalam print_multiples, nilai dari i berubah dari 1 hingga 6. Pada diagram, yang terjadi adalah 2. Merubah variabel ini tidak memiliki efek pada nilai dari i pada fungsi print_mult_table.

Merupakan hal umum dan diperbolehkan untuk memiliki variabel lokal berbeda namun dengan nama yang sama. Khususnya, nama seperti i dan j biasa digunakan sebagai variabel perulangan. Jika kamu menghindari penggunaannya hanya karena kamu sudah menggunakannya di tempat lain, kamu kemungkinan hanya akan membuat programmnya semakin sulit untuk dibaca.

7.15. Pernyataan break

Pernyataan break digunakan untuk meninggalkan body dari perulangan secara langsung. Kemudian, setelah perulangan ditinggalkan, pernyataan selanjutnya yang dieksekusi adalah penyataan pertama setelah body perulangan yang ditinggalkan.

for i in [12, 16, 17, 24, 29]:
    if i % 2 == 1: #Jika bilangan ganjil
        break      #... Langsung keluar dari perulangan
    print(i)
print("selesai")

Ini akan mencetak:

12
16
done

Perulangan pra-pengujian -- sifat perulangan standar
for dan while adalah perulangan yang melakukan pengujian kondisi pada saat dimulai, sebelum mengeksekusi bagian manapun pada body. Mereka dinamakan perulangan pra-pengujian (pre-test loops), karena pengujiannya berlangsung sebelum (pra) bagian body. Pernyataan break dan return adalah alat kita untuk menyesuaikan sifat standar ini.

7.1.6 Rasa lain dari perulangan

Terkadang kita akan memerlukan perulangan dengan pengujian di tengah (middle-test loop) dengan sebuah pengujian exit sebagai pengakhir, daripada pada bagian atas atau akhir. Atau sebuah pengujian diakhir (post-test loop) yang menempatkan pengujian akhirnya sebagai hal terkahir pada body. Bahasa lainnya memiliki syntax yang berbeda dan kata kunci yang berbeda pula untuk masing-masing rasa, tapi Python hanya menggunakan sebuah kombinasi while dan if condition: break untuk dapat menyelesaikan urusan ini.

Contoh biasanya adalah masalah dimana user mesti menginput angka yang akan dihitung. Untuk menandakan bahwa tidak ada input lagi yang perlu dimasukan, user mesti memasukan nilai spesial, nilai biasanya adalah -1, atau string kosong. Hal seperti ini memerlukan pola perulangan middle-exit: masukan bilangan selanjutnya, kemudian uji apakah selesai, atau lainnya proses bilangannya.

total = 0
while True:
    response = input("Masukan bilangan selanjutnya. (Kosong = selesai")
    if response == "":
        break
    total += int(response)
print("Total bilangan yang anda masukan adalah ", total)

Yakinkan diri mu kalau contoh di atas tepat dengan flowchart middle-exit: baris 3 melakukan pekerjaan yang sangat berguna, baris ke 4 dan 5 bisa mengeluarkan perulangan, dan jika mereka tidak baris ke 6 melakukan tugasnya dengan lebih berguna sebelum perulangan selanjutnya dimulai.

Bagian while bool: menggunakan ekspresi Boolean untuk menentukan apakah harus mengulang kembali. True adalah sebuah ekspresi Boolean yang sangat penting, jadi while True: artinya selalu lakukan perulangan lagi dan lagi. Ini adalah sebuah idiom bahasa -- sebuah kebiasaan yang kebanyakan programmer kenali secara langsung. Karena ekspresi pada baris 2 tidak akan mengakhiri perulangan, (itu hanyalan contoh acak) programmer harusnya mengatur sendiri bagian break (atau return) ditempat lain diluar body dari perulangan, dalam beberapa cara lain (misal, pada baris 4 dan 5 pada contoh ini), Seorang kompiler dan penterjemah cerdas akan memahami bahwa baris ke 2 adalah pengujian palsu yang pastinya akan selalui bernilai sukses, jadi ia tidak akan membuat test, dan flowchart kita bahkan tidak akan punya bentuk diamon sebagai dummy test pada bagian atas dari perulangan!

Begitu pula, dengan hanya memindahkan if condition: break ke bagian bawah dari body perulangan kita membuat pola untuk sebuah perulangan dengan post-test. Perulangan post-test digunakan ketika kamu ingin memastikan bahwa perulangan selalu mengeksekusi bodynya setidaknya satu kali (karena pengujian pertama hanya terjadi di akhir dari eksekusi dari perulangan body yang pertama). Teknik ini akan berguna, sebagai contoh, jika kita ingin bermain sebuah game interaktif dengan pengguna -- kita selalu ingin bermain setidaknya satu kali permainan:

while True:
    play_the_game_once()
    response = input("Main lagi? (ya / tidak)")
    if response != "ya":
        break
print("Dadahh!")
Petunjuk: Pikirkan dimana kamu ingin exit testnya terjadi
Setelah kamu paham bahwa kamu perlu sebuah perulangan untuk mengulang sesuatu, pikirkan tentang kondisi pengakirannya (terminating condition) -- kapankah saya ingin berhenti mengulangi? Kemudian tentukan apakah kamu perlu melakukan pengujian sebemul memulai perulangan yang pertama (dan setiap perulangan selanjutnya), atau diakhir dari yang pertama (dan setiap yang lainnya juga), atau mungkin di tengah dari setiap perulangan. Program interaktif yang memerlukan masukan dari pengguna atau membaca dari file-file sering perlu melakukan pengakhiran perulangan pada bagian tengah atau pada bagian akhir dari sebuah perulangan, ketika saatnya sudah pasti bahwa tidak ada lagi data yang harus diproses, atau pengguna sudah tidak ingin bermain lagi.

7.17. Sebuah Contoh

Program berikut mengimplementasikan sebuah permainan tebak-tebakan sederhana:

import random                   # Kita mencakupkan bilangan acak pada 
rng = random.Random()           #  bab modul, jadi mari lanjutkan
number = rng.randrange(1, 100) # Dapatkan bilangan acak antara [1 dan 100].

guesses = 0
msg = ""

while True:
    guess = int(input(msg + "\nTebak bilangan saya antara 1 dan 100: "))
    guesses += 1
    if guess > number:
       msg += str(guess) + " masih terlalu besar.\n"
    elif guess < number:
       msg += str(guess) + " masih terlalu kecil.\n"
    else:
       break

input("\n\nBagus, berhasil ditebak dalam {0} tebakan!\n\n".format(guesses))

Program ini menggunakan hukum matematika trichotomy (diberikan bilangan riil a dan b, dengan tepat salah satu ketiganya harus true: a > b, a < b, atau a == b).

Pada baris 18 terdapat pemanggilan ke fungsi input, tapi kita tidak melakukan apapun terhadap hasilnya, bahkan tidak memberikan nilai pada variabel. Hal seperti ini adalah legal di Python. Disini memiliki efek untuk memunculkan jendela dialog input dan menunggu pengguna untuk merespon sebelum programnya berakhir. Programmer sering kali menggunakan trik ini untuk melakukan beberapa masuka ekstra pada bagian akhir dari sebuah script, hanya untuk membuat jendelanya tetap terbuka atau programnya tidak langsung keluar.

Juga perhatikan penggunakan variabel msg, awalnya sebuah string kosong, pada baris 6, 12 dan 14. Setiap kali melalui perulangan kita menambahkan pesan yang ditampilkan: ini memungkinkan kita untuk menampilkan umpan dari program langsung pada tempat yang sama seiring dengan kita meminta tebakan selanjutnya.

7.18. Pernyataan continue

Pernyataan ini adalah pernyataan kontrol alur yang menyebabkan program secara langsung melompati pemrosesan dari sisa body perulangan, hanya untuk urutan perulangan yang sekarang sedang berlangsung. Tapi perulangan secara keseluruhan akan tetap berlanjut untuk sisa perulangan yang belum dieksekusi:

for i in [12, 16, 17, 24, 29, 30]:
    if i % 2 == 1:        # Jika bilangannya adalah ganjil
        continue          # Jangan diproses
    print(i)
print("done")

Ini akan mencetak:

12
16
24
30
done

7.19. Generalisasi lebih lanjut

Seperti contoh lain dari generalisasi, bayangkan kamu ingin sebuah program yang akan mencetak sebuah perkalian tabel berukuran apapun, tidak hanya tabel 6 kali 6. Kamu bisa menambahkan sebuah parameter ke print_mult_table:

def print_mult_table(high):
    for i in range(1, high+1):
        print_multiples(i)

Kita mengganti nilai 7 dengan ekspresi high+1. Jika kita memanggil print_mult_table dengan argument 7, ia akan menampilkan:

1      2      3      4      5      6
2      4      6      8      10     12
3      6      9      12     15     18
4      8      12     16     20     24
5      10     15     20     25     30
6      12     18     24     30     36
7      14     21     28     35     42

Ini adalah wajar, kecuali bahwa kita kemungkinan ingin tabelnya persegi -- dengan jumlah baris dan kolom sama. Untuk melakukan hal itu, kita menambahkan parameter lain ke print_multiples untuk menentukan seberapa banyak kolum yang harus dimiliki oleh tabel.

Untuk membuatnya sedikit menganggu, kita menamakan parameter ini high, mendemonstrasikan bahwa fungsi lain dapat memiliki parameter dengan nama yang sama (sama halnya dengan variabel lokal). Berikut programnya secara keseluruhan:

def print_multiples(n, high):
    for i in range(1, high+1):
        print(n * i, end="   ")
    print()

def print_mult_table(high):
    for i in range(1, high+1):
        print_multiples(i, high)

Perhatikan bahwa ketika kita menambahkan sebuah parameter baru, kita mesti merubah baris pertama dari fungsi (kepala fungsi), dan kita juga mesti merubah tempat dimana fungsi itu dipanggil pada print_mult_table.

Sekarang, ketika kita memanggil print_mult_table(7):

1      2      3      4      5      6      7
2      4      6      8      10     12     14
3      6      9      12     15     18     21
4      8      12     16     20     24     28
5      10     15     20     25     30     35
6      12     18     24     30     36     42
7      14     21     28     35     42     49

Ketika kamu menggeneralisir sebuah fungsi dengan tepat, kamu akan mendapatkan program dengan kemampuan yang tidak kamu rencanakan. Sebagai contoh, kamu mungkin menyadari bahwa, karena ab = ba, semua catatan pada table akan tampil dua kali. Kamu bisa mengurangi penggunaan tinta dengan mencetak hanya setengah dari tabel. Untuk melakukan itu, kamu hanya perlu mengganti satu baris dari print_mult_table. Ganti

print_multiples(i, high+1)

menjadi

print_multiples(i, i+1)

dan kamu akan mendapatkan:

1
2      4
3      6      9
4      8      12     16
5      10     15     20     25
6      12     18     24     30     36
7      14     21     28     35     42     49

7.20. Fungsi-fungsi

Sekarang telah beberapa kali, kita telah mengenal semua hal-hal bagus dalam penggunaan fungsi. Mulai dari sekarang, kamu mungkin bertanya-tanya apa sesungguhnya hal-hal itu sebenarnya. Berikut adalah beberapa dari mereka:

  1. Mengasah mental pembilahan mu. Memcah tugas rumit menjadi bilahan-bilahan tugas, dan memberikan bilahan tersebut nama yang berarti adalah teknik mental yang luar biasa. Lihat kembali ke contoh yang mengilustrasikan perulangan post-test: kita mengasumsikan bahwa kita memiliki fungsi yang bernama play_the_game_once. Bilahan ini memungkinkan kita untuk mengesampingkan detil dari permaian -- dan dengan mudah kita dapat fokus pada bagian khusus dari logika program kita -- yaitu untuk membiarkan pemain untuk memilih apakah mereka ingin bermain lagi atau tidak.
  2. Membagi program yang panjang menjadi fungsi-fungsi memungkinkan mu untuk memisahkan bagian-bagian program, melakukan debug dalam lingkungan terisolir, dan kemudian mengkomposisikan atau merangkainya menjadi satu kesatuan utuh.
  3. Fungsi-fungsi memfasilitasi penggunaan dari perulangan/iteration.
  4. Fungsi yang didesain dengan baik akan berguna untuk banyak programmer. Setelah kamu menulis dan men-debug salah satunya, kamu bisa menggunakannya lagi di tempat lain.

7.21. Data yang Berpasangan (Paired Data)

Kita sudah pernah melihat list dari nama-nama dan list dari bilangan-bilangan di Python. Sekarang kita melangkah maju pada teks book sedikit lebih jauh, dan memperlihatkan cara yang lebih lanjut dalam merepresentasikan data kita. Membuat hal-hal berpasangan di Python adalah sama mudahnya dengan menempatkan mereka dalam sebuah kurung, seperti ini:

tahun_lahir = ("Indonesia", 1945) 

Kita dapat menempatkan banyak pasangan (pair) kedalam list yang berisi pair-pair:

aspek_tuhan = [ ("Brahman", 1), ("Paramatma", 2), ("Bhagavan", 3) ] 

Berikut adalah contoh sederhana hal-hal yang bisa kita lakukan dengan data seperti ini, mencetak tahap menginsyafi Tuhan:

print(aspek_tuhan)
print(len(aspek_tuhan))
[("Brahman", 1), ("Paramatma", 2), ("Bhagavan", 3)] 
3

Perhatikan bahwa list aspek_tuhan hanya memiliki tiga elemen, setiap elemen adalah pasangan.

Sebagai catatan, seperti yang tertulis pada literatur tertua yang telah ada sejak awal sejarah, Tuhan dikenali dalam tiga tahapan oleh para murid yang mempelajari ilmu ketuhanan. Murid yang baru belajar memahami Tuhan pada aspek Beliau sebagai Brahman (Energy), atau Tuhan yang tidak berbentuk pribadi dan tidak memiliki sifat. Murid yang sudah sedikit lebih maju, memahami Tuhan pada aspek Beliau sebagai Paramatma (Localized), yaitu beliau ada di mana-mana, bersemayam di hati setiap mahluk hidup untuk menuntun mereka mengarungi lautan kehidupan material. Terakhir, murid yang paling maju, memahami aspek Tuhan sebagai Bhagavan (Personality), yaitu Tuhan secara pribadi. Murid kelas 3 ini adalah murid yang paling maju. Aspek tuhan ini diibaratkan seperti sinar matahari sebagai Brahman yang tidak bersifat pribadi, bola matahari sebagai paramatma yang menyinari hati setiap mahluk hidup, dan kegiatan yang ada di dalam bola matahari itu sendiri sebagai Bhagavan atau Kepribadian Tuhan Yang Maha Esa.

Sekarang kita mencetak nama dari aspek_tuhan yang paling awal sebelum tahapan ketiga:

for (aspek, tahapan) in aspek_tuhan:
    if tahapan < 3:
        print(aspek)
Brahman
Paramatma

Ini mendemonstrasikan sesuatu yang belum kita lihat pada perulangan for: daripada menggunakan kontrol variabel satu perulangan, kita lebih memilih menggunakan nama variabel berpasangan, (aspek, tahapan). Perulangannya dieksekusi tiga kali -- sekali untuk setiap pasang pada list, dan pada setiap perulangan kedua variabel diberikan nilai dari pasangan data yang sedang ditangani.

7.22. Perulangan Bersarang untuk Data Bersarang (Nested Loop for Nested Data)

Sekarang kita akan mencoba petualangan yang jauh lebih seru pada penggunaan list data terstruktur. Pada kasus ini, kita memiliki list dari murid-murid. Setiap murid memiliki nama yang dipasangkan dengan list subyek lainnya yang mereka ambil.

students = [
    ("John", ["CompSci", "Physics"]),
    ("Vusi", ["Maths", "CompSci", "Stats"]),
    ("Jess", ["CompSci", "Accounting", "Economics", "Management"]),
    ("Sarah", ["InfSys", "Accounting", "Economics", "CommLaw"]),
    ("Zuki", ["Sociology", "Economics", "Law", "Stats", "Music"])]

Disini kita memberikan sebuah list lima buat elemen. Mari cetak setiap nama murid, dan jumlah dari sbuyek (mata pelajaran) yang mereka ambil:

# Cetak semua murid dengan jumlah mata pelajarannya
for (name, subjects) in students:
    print(name, "takes", len(subjects), "courses")

Python akan merespon dengan output seperti berikut:

John takes 2 courses
Vusi takes 3 courses
Jess takes 4 courses
Sarah takes 4 courses
Zuki takes 5 courses

Sekarang kita ingin mengetahui berapa banyak murid yang mengambil CompSci. Ini memerlukan sebuah counter, dan untuk setiap murid kita perlu perulangan kedua yang menguji setiap subjectnya:

# Count how many students are taking CompSci
counter = 0
for (name, subjects) in students:
    for s in subjects:                 # A nested loop!
        if s == "CompSci":
           counter += 1

print("The number of students taking CompSci is", counter)
The number of students taking CompSci is 3

Kamu harus membuat sebuah list dari data mu sendiri yang menarik minat mu -- anggap sebuah list dari CD mu, masing-masing berisi daftar lagu-lagu pada CD, atau daftar judul film, masing-masing dengan bintang film yang memainkan filmnya. Kamu bisa kemudian menanyakan pertanyaan seperti "Film yang mana yang dibintangi oleh Gita Gutawa?"

7.23. Metode Newton untuk menemukan akar pangkat dua

Perulangan sering kali digunakan pada program yang menghitung hasil numerik yang dimulai dengan jawaban terdekat dan secara beruntun meningkatkan keakuratannya.

Sebagai contoh, sebelum kita memiliki kalkulator atau komputer, orang-orang harus menghitung akar pangkat dua secara manual. Newton menggunakan metode khusus yang sangat bagus (terdapat beberapa bukti bahwa metode ini telah diketahui untuk waktu yang lama sebelumnya). Anggap bahwa kamu ingin tahu bagaimana cara mengetahui akar pangkat dua dari n. jika kamu mulai dengan perkiraan apapaun, kamu bisa menghitung perkiraan yang lebih baik (yang paling dekat dengan jawaban yang sebenarnya) dengan formula berikut ini:

better = (approx + n/approx)/2

Ulangi perhitungan ini beberapa kali menggunakan kalkulator mu. Bisakan kamu melihat mengapa setiap perulangan memberikan mu perkiraan yang sedikit lebih dekat? Salah satu properti menakjubkan dari algoritma khusus ini adalah seberapa cepatnya ia berpusat ke jawaban yang akurat -- sebuah keuntungan yang besar ketimbang melakukannya secara manual.

Dengan menggunakan sebuah perulangan dan mengulang rumus ini hingga perkiraan yang lebih baik hingga cukup dekat dengan hasil yang sebelumnya, kita bisa menulis sebuah fungsi untuk menghitung akar pangkat dua. (Faktanya, ini adalah cara bagaimana kalkulator mu menemukan akar pangkat dua -- ia mungkin punya metode dan rumus yang jauh berbeda, tapi ia juga berdasarkan pada secara berulang meningkatkan tebakannya.)

Ini adalah sebuah contoh dari masalah pada perulangan indefinite: kita tidak bisa memprediksi lebih lanjut berapa kali kita ingin melakukan improvisasi pada tebakan kita -- kita hanya ingin terus bergerak lebih dekat dan lebih dekat. Kondisi pemberhentian dari perulangan kita akan berlaku ketika tebakan lama kita dan tebakan yang telah diimprovisasi sudah "cukup dekat" satu sama lain.

Idealnya, kita ingin yang lama dan yang baru untuk bernilai sama ketika kita berhenti. Tapi persamaan eksak adalah tuntuntan yang sulit pada aritmetika komputer ketika melibatkan bilangan riil. Karena bilangan riil tidak direpresentasikan secra absulut secara akurat (setelah semuanya, sebuah bilangan seperti pi atay akar kuadrat dua memiliki sebuah bilangan tak terhingga sekian desimal karena ia tidak rasional), kita perlu merumuskan pengujian pengakhir untuk perulangannya dengan pertanyaan "apakah a cukup dengan dengan b"? Kondisi pemberhentian ini bisa dikodekan seperti ini:

if abs(a-b) < 0.001:  # Buat nilainya makin kecil agar makin akurat
    break

Perhatikan bahwa kita mengambil nilai absolut dari selisi antara a dan b!

Masalah ini juga merupakan contoh yang bagus ketika sebuah perulangan middle-exit sudah cukup cocok:

def sqrt(n):
    approx = n/2.0     # Mulai dengan beberapa atau tebakan lainnya pada jawaban
    while True:
        better = (approx + n/approx)/2.0
        if abs(approx - better) < 0.001:
            return better
        approx = better

# Test cases
print(sqrt(25.0))
print(sqrt(49.0))
print(sqrt(81.0))

Outputnya adalah:

5.00000000002
7.0
9.0

Lihat apakah kamu bisa meningkatkan perkiraannya dengan mengubah kondisi stopnya. Juga, oprek lagi algoritmanya (mungkin dengan tangan, menggunakan kalkulator mu) untuk melihat seberapa banyak perulangan yang kita perlukan sebelum ia mencapai tahapan keakuratan untuk sqrt(25).

7.24. Algoritma

Metode Newton adalah sebuah contoh dari apa yang namanya algoritma: ia adalah sebuah proses mekanika untuk memecahkan sebuah katagori dari masalah (dalam kasus ini, menghitung akar kuadrat dua).

Beberapa jenis pengetahuan tidaklah algoritmik. Sebagai contoh, mempelajari tanggal dari sejarah atau tabel perkalian mu melibatkan proses mengingat dan menghafal mengenai solusi khsusus.

Tapi teknik yang telah kamu pelajari penambahan dengan membawa, pengurangan dengan meminjam, dan pembagian panjang semuanya adalah algoritma. Atau jika kami adalah seorang pemecah puzzle Sudoku, kamu mungkin punya beberapa set langkah-langkah yang selalu kamu ikuti.

Satu dari karakteristik algoritma adalah bahwa mereka tidak memerlukan kecerdasan apapun untuk muncul. Mereka adalah proses mekanika yang mana setiap langkahnya mengikuti dari akhir berdasarkan pada set aturan-aturan sederhana. Dan mereka didesain untuk memecahkan kelas umum atau kategori dari masalah-masalah, tidak hanya satu masalah saja.

Memahami bahwa masalah sulit bisa diselesaikan dengan proses algoritmik langkah demi langkah (dan memiliki teknologi untuk menjalankan algoritma tersebut untuk kita) adalah satu dari terobosan besar yang telah menghasilkan kuntungan yang besar. Jadi sementara eksekusi dari algoritma mungkin membosankan dan mungkin tidak memerlukan kecerdasan sama sekali, algoritmik atau pemikiran komputasional -- missal, menggunakan algoritma dan otomasi sebagai basis dalam pendekatan masalah -- adalah secara cepat merubah masyarakat kita. Beberapa mengklaim bahwa pergeseran ini terhadap pemikiran algoritmik dan prosesnya memiliki dampak yang jauh lebih besar pada masyarakat kita dari penemuan mesin cetak. Dan proses dari mendesain algoritma itu sangat menarik, menantang secara intelektual, dan bagian inti dari apa yang kita sebut dengan programming.

Beberapa dari hal-hal yang orang-orang lakukan secara alami, tanpa kesulitan atau pemikiran yang sadar, adalah algoritma yang paling sulit untuk diekspresikan. Memahami bahasa natural adalah salah satu contohnya. Kita semua melakukannya, tapi sejauh ini tak ada seorang pun yang telah dapat menjelaskan bagaimana kita melakukannya, setidaknya tidak dalam bentuk step-by-step algoritma mekanika.

7.25. Glosarium

algoritma
Step-by-step proses untuk memecahkan sebuah kategori dari masalah-masalah.

body
Pernyataan-pernyataan yang ada di dalam perulangan.

breakpoint
Titik pada kode program dimana eksekusi program akan pause (atau break), memungkinkan kamu untuk meninjau kondisi dari variabel-variabel program, atau melakukan single-step secara individual pada pernyataan-pernyataan, mengeksekusi mereka satu demi satu.

bump
Slang dikalangan programmer. Sinonim untuk increment.

continue statement
Sebuah pernyataam yang menyebabkan sisa dari perulangan yang sekarang dari sebuah perulangan untuk diloncati. Alur dari eksekusi pergi kembali ke awal perulangan, menguji kondisi, dan jika masih true maka urutan perulangan selanjutkan akan dieksekusi.

counter
Sebuah variabel yang digunakan untuk menghitung sesuatu, biasanya dimulai dengan nol dan di-increment pada body perulangan.

cursor
Tanda tak terlihat yang mencatan jalur dari karakter selanjutnya yang akan dicetak.

decrement
Kurangi dengan 1.

definite iteration
Perulangan dimana kita memiliki jumlah maksimal berapa kali body akan dieksekusi. Definite iteration biasanya paling baik dikodekan menggunakan perulangan for.

development plan
Sebuah proses untuk membangun program. Pada bab ini, kita mendemonstrasikan gaya dari pengembangan berdasarkan pada mengembangkan kode untuk hal sederhana, hal khusus dan kemudian membungkusnya dan menggeneralisasikan.

encapsulate
Untuk membagi program besar yang rumit menjadi komponen-komponen (seperti fungsi-fungsi) dan mengisolasi komponen-komponen satu sama lainnya (dengan menggunakan variabel lokal, sebagai contoh).

escape squence
Sebuah karakter escape, \, diikuti dengan satu atau lebih karakter yang bisa dicetak untuk mendesain karakter yang tidak bisa dicetak.

generalize
Untuk mengganti sesuatu yang secara khusus tidak perlu (seperti sebuah nilai konstan) dengan sesuatu yang lebih umum (seperti variabel atau parameter). Generalisasi membuat kode menjadi lebih serba guna, lebih bisa digunakan kembali, dan terkadang bahkan lebih mudah untuk ditulis.

increment
Keduanya sebagai kata benda dan kata kerja, increment berarti untuk ditambahkan dengan 1.

infinite loop
Perulangan yang mana kondisi pengakirannya tidak akan pernah tercapai.

indefinite interation
Perulangan dimana kita hanya perlu terus melanjutkan hingga beberapa kondisi tercapai. Pernyataan while digunakan untuk kasus seperti ini.

initialization (dari sebuah variabel)
Untuk memulai (inisialisasi) sebuah variable adalah dengan memberikannya sebuah nilai awal. Karena di Python variabel statusnya tidak ada hingga mereka diberikan sebuah nilai, mereka dimulai ketika mereka dibuat. Pada bahasa pemrograman lainnya ini tidaklah sama, dan variabel bisa dibuat tanpa diinisialisasi, yang mana mereka memiliki nilai default atau nilai sampah.

iteration
Eksekusi berulang dari set pernyataan pemrograman.

loop
Konstruksi yang memungkinkan kita untuk secara berulang mengeksekusi sebuah pernyataan atau grup dari pernyataan hingga kondisi pengakhiran tercapai.

loop variable
Variabel yang digunakan sebagai bagian dari kondisi pengkahiran dari sebuah perulangan.

meta-notation
Simbol tambahan atau notasi yang membantu memperjelas notasi lainnya. Disini kita memperkenalkan kurung siku, jorong / ellipses, italic, dan bold sebagai meta-notation untuk membantu memperjelas opsional, repeatable, substituable dan fixed part dari syntax Python.

middle-test loop
Perulangan yang mengeksekusi beberapa bagian dari body, kemudian menguji kondisi exit, lalu mungkin mengeksekusi beberap bagian body lainnya. Kita tidak punya konstruksi Python khusus untuk kasus ini, tapi kita bisa menggunakan while dan break secara bersamaan.

nested loop
Perulangan di dalam body dari perulangan yang lainnya.

newline
Karakter spesial yang menyebabkan cursor berpindah ke awal baris selanjutnya.

post-test loop
Perulangan yang mengeksekusi body, kemudian menguji kondisi exit. Kita tidak punya konstruksi Python khusus untuk kasus ini, tapi kita bisa menggunakan while dan break secara bersamaan.

single-step
Mode dari eksekusi interpreter dimana kamu dimungkinkan untuk mengeksekusi program mu langkah demi langkah, dan meninjau konsekuensi dari langkah tersebut. Berguna untuk debugging dan membangun mental model internal mu dari apa yang sedang berlangsung.

tab
Karakter spesial yang menyebabkan cursor bergerak ke tab stop dari baris sekarang.

trichotomy
Diberikan bilangan riil apapun a dan b, dengan tepat salah satu relasi berikut menahan: a < b, a > b, atau a == b. Maka ketika kamu bisa mendirikan bahwa dua diantara relasi adalah false, kamu bisa mengasumsikan sisanya adalah true.

trace
Untuk mengikuti alur dari eksekusi dari sebuah program menggunakan tangan, merekam perubahan dari kondisi dari variabel dan output apapun yang dihasilkan.

5.630
Daftar Artikel Terkait
Image

Aditya Suranata

Aditya suka menulis, bukan hanya sekedar hobi, menulis menjadi medianya untuk mencurahkan pikiran dan perasaan. Di TutorKeren.com kebanyakan menyumbang tulisan sesuai dengan minat dan keahliannya yaitu pada kategori pemrograman dan elektronika. Selain itu juga gemar menulis mengenai hal-hal umum, seperti ilmu alam, sosial dan beberapa pengalamannya yang mungkin bisa berguna untuk orang lain.

Artikel Menarik Lainnya
Mari Gabung

Halo Emo 51 , Ada yang ingin disampaikan? Jangan sungkan untuk gabung diskusi ini. Silahkan Login dulu atau Daftar baru.