Looping dan Debugging

Looping atau perulangan adalah konsep pemrograman yang memberikan perintah kepada komputer untuk menjalankan suatu proses secara berulang-ulang selama kondisi atau kriteria yang diberikan masih valid. Pada chapter ini, kita akan belajar bagaimana membuat looping pada Python dengan sintaks while dan for, dan juga belajar bagaimana cara melakukan debugging untuk mengecek kesalahan dan memperbaiki kode kita.

While

Sintaks dasar pembuatan looping dengan while dapat dilihat pada contoh berikut:

while condition:
    # Kode yang dijalankan apabila condition bernilai True

Untuk lebih jelasnya, perhatikan contoh kode di bawah ini:

# Contoh 1.a
number_of_loops = 3

while number_of_loops > 0:
    print('I am inside a loop.')
    number_of_loops = number_of_loops - 1

# output:
# 'I am inside a loop.'
# 'I am inside a loop.'
# 'I am inside a loop.'

Apabila kode pada Contoh 1.a dijalankan, komputer akan mengeksekusi kode yang ada di dalam loop secara berulang-ulang selama variable number_of_loops bernilai lebih dari 0. Namun, pada akhirnya loop akan berhenti pada iterasi ketiga karena di dalam loop ada kode yang melakukan operasi pengurangan terhadap nilai number_of_loops di setiap perulangan. Sehingga, output akan mencetak string ‘I am inside a loop.’ sebanyak 3 kali.

flowchart TD
    A[Start] --> B{number_of_loops > 0?}
    B -- True --> C[Print 'I am inside a loop.']
    C --> D[Decrease number_of_loops by 1]
    D --> B
    B -- False --> E[End]

Ilustrasi diagram untuk Contoh 1.a

Melakukan operasi pengurangan terhadap nilai number_of_loops di dalam blok kode while adalah penting agar kondisi stopnya bisa tercapai dan proses loop bisa berhenti melakukan eksekusi kode. Apabila operasi pengurangan ini dihilangkan, maka kondisi stopnya tidak akan terpenuhi dan program Python akan terus menjalankan baris kode di dalam while tanpa berhenti. Hal ini disebut dengan istilah infinite looping.

# Contoh 1.b
# Perhatian:
# Kode di bawah akan mencetak string secara berulang-ulang tanpa berhenti.
# Untuk menghentikannya, tekan Ctrl-C pada keyboard.
number_of_loops = 3

while number_of_loops > 0:
    print('I am inside a loop.')

# output:
# 'I am inside a loop.'
# 'I am inside a loop.'
# 'I am inside a loop.'
# 'I am inside a loop.'
# 'I am inside a loop.'
# ...

Kita juga bisa membuat conditional di dalam blok kode while untuk mengontrol perulangan. Perhatikan contoh di bawah ini:

# Contoh 1.b
number_of_loops = 5
stop_loop = False

while number_of_loops > 0 and stop_loop == False:
    print('I am inside a loop.')
    number_of_loops = number_of_loops - 1
    if number_of_loops == 3:
        stop_loop = True

# output:
# 'I am inside a loop.'
# 'I am inside a loop.'

Apabila kode pada contoh 1.b dijalankan, program Python hanya akan mencetak string sebanyak 2 kali. Hal ini disebabkan kondisi pada while melakukan pengecekan terhadap nilai dari variable stop_loop. Pada saat yang bersamaan, di dalam blok kode while ada conditional yang melakukan perubahan nilai stop_loop dari False menjadi True apabila variable number_of_loops-nya bernilai 3. Sehingga, saat nilai stop_loop menjadi True, kondisi pada while akan menghasilkan nilai False dan akhirnya mengakibatkan loop berhenti.

flowchart TD
    A[Start] --> B{number_of_loops > 0 and stop_loop is False?}
    B -- True --> C[Print 'I am inside a loop.']
    C --> D[Decrease number_of_loops by 1]
    D --> E{number_of_loops == 3}
    E -- True --> F[stop_loop = True]
    F --> B
    E -- False --> B
    B -- False --> G[End]

Ilustrasi diagram untuk Contoh 1.b

Selain conditional, kita juga dapat membuat while di dalam blok kode while untuk membuat nested loop.

# Contoh 1.c
number_of_loops = 3

while number_of_loops > 0:
    number_of_nested_loops = 3

    while number_of_nested_loops > 0:
        print('I am inside a loop.')
        number_of_nested_loops = number_of_nested_loops - 1

    number_of_loops = number_of_loops - 1

# output:
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
# "I am inside a loop."
flowchart TD
    A[Start] --> B{number_of_loops > 0?}
    B -- True --> C[Set number_of_nested_loops with value]
    C --> D{number_of_nested_loops > 0?}
    D -- True --> E[Print 'I am inside a loop']
    E --> F[Decrease number_of_nested_loops by 1]
    F --> D
    D -- False --> G[Decrease number_of_loops by 1]
    G --> B
    B -- False --> H[Done]

Ilustrasi diagram untuk Contoh 1.c

For

Sintaks dasar pembuatan looping dengan for dapat dilihat pada contoh berikut:

for item in data_structure:
    # Kode yang dijalankan selama masih ada item yang belum dikunjungi dari data_structure

Untuk lebih jelasnya, perhatikan contoh kode di bawah ini:

# Contoh 2.a
fruits = ['apple', 'banana', 'grapes', 'oranges', 'strawberry']

for fruit in fruits:
    print(f'I like {fruit}.')

# output:
# 'I like apple.'
# 'I like banana.'
# 'I like grapes.'
# 'I like oranges.'
# 'I like strawberry.'

Ada perbedaan mendasar antara penggunaan for dengan while untuk pembuatan looping. Looping dengan while memerlukan kondisi yang eksplisit untuk menentukan apakah iterasi masih berjalan atau stop. Sedangkan looping dengan for tidak memerlukan kondisi yang eksplisit. Sebagai gantinya, for harus selalu dipasangkan dengan suatu data structure, seperti pada Contoh 2.a yang menggunakan list.

Algoritma for akan mengunjungi satu per satu item yang terdapat pada list mulai dari item pada index yang pertama hingga item pada index yang terakhir. Itulah mengapa apabila dijalankan, kode pada Contoh 2.a akan mencetak string ‘I like …’ sebanyak 5 kali dengan nama buah yang bergantian dan berurutan sesuai urutan item dalam list.

flowchart TD
    A[Start] --> B{Is there any fruit next?}
    B -- Yes --> C[Print 'I like --next fruit--.']
    C --> B
    B -- No --> D[Done]

Ilustrasi diagram untuk contoh 2.a

Kita juga bisa membuat kode seperti pada Contoh 2.a dengan menggunakan sintaks while. Coba bandingkan contoh berikut dengan kode sebelumnya:

# Contoh 2.b
fruits = ['apple', 'banana', 'grapes', 'oranges', 'strawberry']
index = 0

while index < len(fruits):
    fruit = fruits[index]
    print(f'I like {fruit}.')
    index = index + 1

# output:
# 'I like apple.'
# 'I like banana.'
# 'I like grapes.'
# 'I like oranges.'
# 'I like strawberry.'

Apabila kita ingin membuat looping dengan angka yang fix, kita dapat menggunakan fungsi range seperti contoh di bawah ini:

# Contoh 2.c
number_of_loops = 3

for index in range(number_of_loops):
    print(f'I am inside a loop (index: {index}).')

# output:
# 'I am inside a loop (index: 0).'
# 'I am inside a loop (index: 1).'
# 'I am inside a loop (index: 2).'

Apabila diperhatikan pada Contoh 2.c, looping akan menjalankan fungsi cetak sebanyak 3 kali. Pada awal looping, variable index bernilai 0 dan pada setiap looping, nilai index akan bertambah 1. Pada akhir looping, variable index bernilai number_of_loops - 1.


Selain list, kita juga bisa melakukan looping terhadap data structure dictionary. Perhatikan contoh berikut:

# Contoh 2.d
payment_config = {
    'base_price': 50000,
    'delivery_fee': 5000,
    'discount_rate': 0.25
}

for key, value in payment_config.items():
    print(f'The value of {key} is {value}.')

# output:
# 'The value of base_price is 50000.'
# 'The value of delivery_fee is 5000.'
# 'The value of discount_rate is 0.25.'

Pada Contoh 2.d, kita bisa mendapatkan key dan value secara bersamaan dan dapat digunakan di dalam blok kode for.


Seperti halnya list, kita juga bisa membuat nested loop menggunakan for seperti pada contoh di bawah ini:

# Contoh 2.e
bucket_of_words = [
    ['I', 'like', 'learning', 'new', 'stuffs'],
    ['However,', 'it', 'is', 'not', 'always', 'easy'],
    ['I', 'believe', 'if', 'I', 'consistently', 'practice,',
    'I', 'can', 'get', 'a', 'valuable', 'skill', 'faster']
]

for words in bucket_of_words:
    sentence = ''
    for word in words:
        sentence = sentence + word + ' '
    print(sentence)

Debugging

Debugging adalah proses mencari error dan memperbaiki kode agar dapat berjalan dengan semestinya. Kemampuan debugging bagi seorang programer itu penting. Hal ini karena seiring berjalannya waktu, kita akan berhadapan dengan kode yang semakin rumit dan kompleks yang lebih beresiko menimbulkan error atau output yang salah.

Untuk melakukan debugging, kita perlu menganalisis bagaimana proses eksekusi tiap baris kode kita dari awal sampai akhir. Pahami konsep-konsep yang sudah kita pelajari sampai saat ini: tipe data (number, string, dan boolean), if...else, dan data structure (list dan dictionary), lalu coba memvisualisasikan bagaimana kode kita menghasilkan output dari input dan data yang kita sediakan.

Untuk mempermudah kita melakukan debugging, kita bisa memanfaatkan fungsi print pada Python. Perhatikan contoh kode berikut ini:

# Contoh 3.a
bucket_of_words = [
    ['I', 'like', 'learning', 'new', 'stuffs'],
    ['However,', 'it', 'is', 'not', 'always', 'easy'],
    ['I', 'believe', 'if', 'I', 'consistently', 'practice,',
    'I', 'can', 'get', 'a', 'valuable', 'skill', 'faster']
]
found_words = []

for words in bucket_of_words:
    found = False
    index = 0
    while not found:
        word = words[index]
        if word[0] == 'I' or word[0] == 'i':
            found_words.append(word)
            found = True
        index = index + 1

print(found_words)

Kode pada Contoh 3.a bisa dibilang cukup rumit karena sudah melibatkan nested loop, conditional, manipulasi data structure, pembuatan banyak variable dan juga modifikasi nilai dari variable. Fungsi print dapat ditambahkan pada kode ini untuk bisa memperjelas cara kerja dari kode ini. Salah satu contoh implementasinya adalah seperti berikut.

# Contoh 3.b
bucket_of_words = [
    ['I', 'like', 'learning', 'new', 'stuffs'],
    ['However,', 'it', 'is', 'not', 'always', 'easy'],
    ['I', 'believe', 'if', 'I', 'consistently', 'practice,',
    'I', 'can', 'get', 'a', 'valuable', 'skill', 'faster']
]
found_words = []

for words in bucket_of_words:
    found = False
    index = 0

    print(f'Found is {found} and index is {index}.')

    while not found:
        word = words[index]

        print(f'Current word is {word}.')

        if word[0] == 'I' or word[0] == 'i':
            found_words.append(word)
            found = True
        index = index + 1

        print(found_words)

print(found_words)

Pada Contoh 3.b, kita menaruh tiga pemanggilan fungsi print dengan posisi yang berbeda-beda. Penempatan fungsi print ini kurang lebih ditentukan oleh dimana kira-kira point of interests yang ingin kita perhatikan. Dalam kasus ini, kita ingin memantau nilai dari variable found, index, word dan found_words. Apabila kode yang baru ini dijalankan, kita bisa melihat perubahan nilai dari variable yang kita cetak menggunakan fungsi print.

Selain dengan memanfaatkan fungsi print, kita juga bisa menggunakan fitur breakpoint pada IDE yang kita pakai. Biasanya breakpoint ini bisa kita aktifkan dengan melakukan klik pada bagian line numbers. Apabila kita menjalankan kode yang sudah ditandai oleh breakpoint, IDE akan menghentikan sementara program kita pada baris kode yang breakpoint-nya aktif. Selagi program kita terhenti, kita bisa mengecek nilai dari variable-variable yang sudah tereksekusi untuk memastikan apakah algoritma yang dibuat sudah sesuai atau tidak dengan rancangan kita.