9. Menggabungkan Kondisi dengan Logika Boolean
Di Bab 7, kita belajar tentang nilai boolean dan kondisi sederhana menggunakan operator perbandingan. Di Bab 8, kita memakai kondisi-kondisi ini untuk membuat keputusan dengan pernyataan if. Namun program di dunia nyata sering perlu memeriksa beberapa kondisi sekaligus. Apakah kita harus memberi akses jika pengguna punya kata sandi yang benar dan sedang login? Apakah kita harus menampilkan peringatan jika suhu terlalu panas atau terlalu dingin? Apakah kita harus melanjutkan jika file tidak kosong?
Python menyediakan tiga operator logika (logical operators) yang memungkinkan kita menggabungkan dan memodifikasi nilai boolean: and, or, dan not. Operator-operator ini adalah blok penyusun untuk mengekspresikan logika pengambilan keputusan yang kompleks di programmu.
9.1) Operator Logika and, or, dan not
Ketiga operator logika bekerja dengan nilai boolean (atau nilai yang bisa diperlakukan sebagai boolean) untuk menghasilkan hasil boolean yang baru.
9.1.1) Operator and
Operator and mengembalikan True hanya ketika kedua operand bernilai benar. Jika salah satu operand bernilai salah, seluruh ekspresi bernilai salah.
# Kedua kondisi harus True
age = 25
has_license = True
can_rent_car = age >= 21 and has_license
print(can_rent_car) # Output: True
# Jika salah satu kondisi False, hasilnya False
age = 18
can_rent_car = age >= 21 and has_license
print(can_rent_car) # Output: FalseAnggap and seperti penjaga gerbang yang ketat: semua kondisi harus lolos agar pemeriksaan keseluruhan berhasil.
Tabel Kebenaran untuk and:
| Operand Kiri | Operand Kanan | Hasil |
|---|---|---|
True | True | True |
True | False | False |
False | True | False |
False | False | False |
9.1.2) Operator or
Operator or mengembalikan True ketika setidaknya satu operand bernilai benar. Operator ini hanya mengembalikan False ketika kedua operand bernilai salah.
# Setidaknya satu kondisi harus True
is_weekend = True
is_holiday = False
can_sleep_in = is_weekend or is_holiday
print(can_sleep_in) # Output: True
# Kedua kondisi False
is_weekend = False
is_holiday = False
can_sleep_in = is_weekend or is_holiday
print(can_sleep_in) # Output: FalseAnggap or seperti penjaga gerbang yang longgar: kamu hanya perlu memenuhi satu kondisi untuk bisa lewat.
Tabel Kebenaran untuk or:
| Operand Kiri | Operand Kanan | Hasil |
|---|---|---|
True | True | True |
True | False | True |
False | True | True |
False | False | False |
Berikut contoh praktis untuk sistem kelayakan diskon:
# Pelanggan dapat diskon jika mereka mahasiswa ATAU warga senior
age = 68
is_student = False
gets_discount = is_student or age >= 65
print(f"Eligible for discount: {gets_discount}") # Output: Eligible for discount: True
# Pelanggan lain
age = 30
is_student = False
gets_discount = is_student or age >= 65
print(f"Eligible for discount: {gets_discount}") # Output: Eligible for discount: FalsePelanggan pertama memenuhi syarat karena mereka memenuhi salah satu kriteria (warga senior), meskipun mereka bukan mahasiswa.
9.1.3) Operator not
Operator not adalah operator unary (unary operator, bekerja pada satu operand) yang membalik nilai boolean. Operator ini mengubah True menjadi False dan False menjadi True.
is_raining = False
is_sunny = not is_raining
print(is_sunny) # Output: True
is_raining = True
is_sunny = not is_raining
print(is_sunny) # Output: FalseTabel Kebenaran untuk not:
| Operand | Hasil |
|---|---|
True | False |
False | True |
Operator not sangat berguna ketika kamu ingin memeriksa kebalikan dari sebuah kondisi:
# Periksa apakah file TIDAK kosong
file_size = 0
is_empty = file_size == 0
is_not_empty = not is_empty
print(f"File has content: {is_not_empty}") # Output: File has content: False
# Periksa apakah pengguna TIDAK sedang login
is_logged_in = False
needs_login_prompt = not is_logged_in
print(f"Show login prompt: {needs_login_prompt}") # Output: Show login prompt: True9.1.4) Menggabungkan Beberapa Operator Logika
Kamu bisa menggabungkan beberapa operator logika dalam satu ekspresi untuk membuat kondisi yang lebih canggih:
# Toko online: gratis ongkir jika pesanan di atas $50 ATAU pelanggan adalah member premium
# DAN barang tersedia
order_total = 45.00
is_premium = True
in_stock = True
gets_free_shipping = (order_total >= 50 or is_premium) and in_stock
print(f"Free shipping: {gets_free_shipping}") # Output: Free shipping: TrueMari telusuri evaluasinya:
order_total >= 50dievaluasi menjadiFalse(45.00 bukan >= 50)is_premiumbernilaiTrueFalse or Truedievaluasi menjadiTruein_stockbernilaiTrueTrue and Truedievaluasi menjadiTrue
Berikut contoh lain dengan kontrol akses:
# Pengguna bisa mengakses panel admin jika mereka adalah admin
# DAN (mereka berada di jaringan internal ATAU menggunakan VPN)
is_admin = True
on_internal_network = False
using_vpn = True
can_access_admin = is_admin and (on_internal_network or using_vpn)
print(f"Can access admin panel: {can_access_admin}") # Output: Can access admin panel: TruePerhatikan tanda kurung di sekitar (on_internal_network or using_vpn). Ini penting karena mengontrol urutan evaluasi, sama seperti tanda kurung dalam ekspresi aritmetika.
9.2) Prioritas Operator dalam Ekspresi Boolean (Urutan Not, And, Or)
Ketika kamu menggabungkan beberapa operator logika tanpa tanda kurung, Python mengikuti aturan prioritas tertentu untuk menentukan urutan evaluasi. Memahami aturan ini membantu kamu menulis kondisi yang benar dan menghindari bug yang halus.
9.2.1) Hierarki Prioritas
Python mengevaluasi operator logika dalam urutan ini (prioritas tertinggi ke terendah):
not(prioritas tertinggi)and(prioritas menengah)or(prioritas terendah)
Ini berarti not dievaluasi terlebih dahulu, kemudian and, dan terakhir or.
# Tanpa tanda kurung, prioritas menentukan urutan
result = True or False and False
print(result) # Output: True
# Cara Python mengevaluasi ini:
# Langkah 1: False and False → False (and punya prioritas lebih tinggi daripada or)
# Langkah 2: True or False → TrueMari lihat ini langkah demi langkah dengan contoh yang lebih detail:
is_weekend = False
is_holiday = True
has_work = True
# Ekspresi: not has_work or is_weekend and is_holiday
free_time = not has_work or is_weekend and is_holiday
# Urutan evaluasi:
# Langkah 1: not has_work → not True → False
# Langkah 2: is_weekend and is_holiday → False and True → False
# Langkah 3: False or False → False
print(f"Has free time: {free_time}") # Output: Has free time: False9.2.2) Menggunakan Tanda Kurung untuk Kejelasan
Bahkan ketika kamu memahami aturan prioritas, memakai tanda kurung membuat kode kamu lebih jelas dan mencegah kesalahan. Tanda kurung menimpa prioritas bawaan dan membuat maksudmu eksplisit.
# Ambigu tanpa tanda kurung
result = True or False and False
print(result) # Output: True
# Jelas dengan tanda kurung - sebenarnya kita maksudnya apa?
result = (True or False) and False
print(result) # Output: False
result = True or (False and False)
print(result) # Output: TrueKedua ekspresi ini menghasilkan hasil yang berbeda! Tanda kurung benar-benar mengubah maknanya.
9.2.3) Operator Perbandingan dan Operator Logika Bersama
Operator perbandingan (seperti <, >, ==, !=) punya prioritas lebih tinggi daripada operator logika. Ini berarti perbandingan dievaluasi sebelum operasi logika.
age = 25
income = 50000
# Tidak perlu tanda kurung di sekitar perbandingan
eligible = age >= 18 and income >= 30000
print(f"Eligible for loan: {eligible}") # Output: Eligible for loan: True
# Python mengevaluasinya sebagai:
# Langkah 1: age >= 18 → True
# Langkah 2: income >= 30000 → True
# Langkah 3: True and True → True9.3) Evaluasi Short-Circuit
Python menggunakan evaluasi short-circuit (short-circuit evaluation) saat mengevaluasi ekspresi boolean dengan and dan or. Artinya Python berhenti mengevaluasi begitu ia sudah tahu hasil akhirnya, sehingga berpotensi melewati evaluasi operand yang lebih belakang. Perilaku ini adalah optimasi performa sekaligus teknik pemrograman yang berguna.
9.3.1) Bagaimana and Melakukan Short-Circuit
Dengan operator and, jika operand kiri bernilai False, Python tahu seluruh ekspresi pasti False (karena kedua operand harus benar agar and mengembalikan True). Karena itu, Python sama sekali tidak mengevaluasi operand kanan.
# Demonstrasi sederhana
x = 5
result = x < 3 and x > 10
print(result) # Output: False
# Evaluasi Python:
# Langkah 1: x < 3 → 5 < 3 → False
# Langkah 2: Karena sisi kiri False, jangan evaluasi x > 10
# Langkah 3: Kembalikan FalseBerikut contoh praktis yang menunjukkan kenapa evaluasi short-circuit penting:
# Mengecek apakah suatu angka habis dibagi - menghindari pembagian dengan nol
numerator = 100
denominator = 0
# Ini aman karena evaluasi short-circuit
# Jika denominator adalah 0, pembagian tidak pernah terjadi
is_divisible = denominator != 0 and numerator % denominator == 0
print(f"Is divisible: {is_divisible}") # Output: Is divisible: False
# Tanpa evaluasi short-circuit, ini akan menyebabkan error:
# denominator = 0
# result = numerator % denominator # ZeroDivisionError!Ekspresi denominator != 0 dievaluasi menjadi False, jadi Python tidak pernah mengevaluasi numerator % denominator, yang akan menyebabkan error pembagian dengan nol.
Mari lihat contoh lain dengan operasi string:
# Mengecek properti string dengan aman
text = ""
# Periksa apakah text tidak kosong DAN karakter pertama adalah huruf besar
# Aman karena jika text kosong, kita tidak pernah mencoba mengakses text[0]
has_uppercase_start = len(text) > 0 and text[0].isupper()
print(f"Starts with uppercase: {has_uppercase_start}") # Output: Starts with uppercase: False
# Jika kita mencoba ini tanpa pengecekan panjang:
# text = ""
# result = text[0].isupper() # IndexError: string index out of range9.3.2) Bagaimana or Melakukan Short-Circuit
Dengan operator or, jika operand kiri bernilai True, Python tahu seluruh ekspresi pasti True (karena setidaknya satu operand bernilai benar sudah cukup). Karena itu, Python tidak mengevaluasi operand kanan.
# Demonstrasi sederhana
x = 15
result = x > 10 or x < 5
print(result) # Output: True
# Evaluasi Python:
# Langkah 1: x > 10 → 15 > 10 → True
# Langkah 2: Karena sisi kiri True, jangan evaluasi x < 5
# Langkah 3: Kembalikan True9.3.3) Penerapan Praktis Evaluasi Short-Circuit
Menghindari Error:
# Mengakses elemen list dengan aman
numbers = [1, 2, 3]
index = 5
# Periksa apakah index valid sebelum mengakses
is_valid = index < len(numbers) and numbers[index] > 0
print(f"Valid and positive: {is_valid}") # Output: Valid and positive: False
# Tanpa short-circuit, ini akan crash:
# is_valid = numbers[index] > 0 # IndexError!Mengecek Banyak Kondisi Secara Efisien:
# Validasi form - berhenti pada error pertama
email = "user@example.com"
password = "pass"
age = 25
# Periksa setiap syarat berdasarkan kemungkinan gagal
valid_form = (
len(email) > 0 and # Pengecekan cepat
"@" in email and # Pengecekan cepat
len(password) >= 8 and # Pengecekan cepat
age >= 18 # Pengecekan cepat
)
print(f"Form valid: {valid_form}") # Output: Form valid: False
# Berhenti pada pengecekan panjang password, tidak mengevaluasi age9.4) Apa yang Dikembalikan Operator and dan or pada Operand Non-Boolean, dan Jebakan Umum Ekspresi Boolean
Sejauh ini, kita sudah melihat and, or, dan not bekerja dengan nilai boolean. Namun operator logika Python punya perilaku yang menarik: operator-operator ini bisa bekerja dengan nilai apa pun, bukan hanya True dan False. Memahami perilaku ini membantu kamu menulis kode yang lebih ringkas dan menghindari kesalahan umum.
9.4.1) Memahami Truthiness dan Falsiness (Tinjauan)
Seperti yang kita pelajari di Bab 7, Python memperlakukan banyak nilai non-boolean sebagai "truthy" atau "falsy" dalam konteks boolean:
Nilai falsy (diperlakukan sebagai False):
FalseNone0(nol dari tipe numerik apa pun)""(string kosong)[](list kosong){}(dictionary kosong)()(tuple kosong)
Nilai truthy (diperlakukan sebagai True):
True- Angka non-nol apa pun
- String non-kosong apa pun
- Koleksi non-kosong apa pun
# Mendemonstrasikan sifat truthy/falsy
if "hello":
print("Non-empty strings are truthy") # Output: Non-empty strings are truthy
if 0:
print("This won't print") # Nol adalah falsy
else:
print("Zero is falsy") # Output: Zero is falsy
if [1, 2, 3]:
print("Non-empty lists are truthy") # Output: Non-empty lists are truthy9.4.2) Apa yang Sebenarnya Dikembalikan and
Operator and tidak selalu mengembalikan True atau False. Sebaliknya, operator ini mengembalikan salah satu operandnya:
- Jika operand kiri falsy,
andmengembalikan operand kiri (tanpa mengevaluasi yang kanan) - Jika operand kiri truthy,
andmengembalikan operand kanan
# and mengembalikan nilai falsy pertama, atau nilai terakhir jika semuanya truthy
result = 5 and 10
print(result) # Output: 10
result = 0 and 10
print(result) # Output: 0
result = "hello" and "world"
print(result) # Output: world
result = "" and "world"
print(result) # Output: (empty string)
result = None and "world"
print(result) # Output: NoneMari telusuri contoh-contoh ini:
# Contoh 1: Keduanya truthy
result = 5 and 10
# Langkah 1: 5 adalah truthy, jadi evaluasi sisi kanan
# Langkah 2: Kembalikan nilai sisi kanan: 10
print(result) # Output: 10
# Contoh 2: Sisi kiri falsy
result = 0 and 10
# Langkah 1: 0 adalah falsy, jadi langsung kembalikan nilainya
# Langkah 2: Jangan evaluasi sisi kanan
print(result) # Output: 0
# Contoh 3: Keduanya string truthy
result = "hello" and "world"
# Langkah 1: "hello" adalah truthy, jadi evaluasi sisi kanan
# Langkah 2: Kembalikan nilai sisi kanan: "world"
print(result) # Output: world9.4.3) Apa yang Sebenarnya Dikembalikan or
Demikian juga, operator or mengembalikan salah satu operandnya:
- Jika operand kiri truthy,
ormengembalikan operand kiri (tanpa mengevaluasi yang kanan) - Jika operand kiri falsy,
ormengembalikan operand kanan
# or mengembalikan nilai truthy pertama, atau nilai terakhir jika semuanya falsy
result = 5 or 10
print(result) # Output: 5
result = 0 or 10
print(result) # Output: 10
result = "" or "default"
print(result) # Output: default
result = "hello" or "world"
print(result) # Output: hello
result = None or 0
print(result) # Output: 0Mari telusuri contoh-contoh ini:
# Contoh 1: Sisi kiri truthy
result = 5 or 10
# Langkah 1: 5 adalah truthy, jadi langsung kembalikan nilainya
# Langkah 2: Jangan evaluasi sisi kanan
print(result) # Output: 5
# Contoh 2: Sisi kiri falsy
result = 0 or 10
# Langkah 1: 0 adalah falsy, jadi evaluasi sisi kanan
# Langkah 2: Kembalikan nilai sisi kanan: 10
print(result) # Output: 10
# Contoh 3: Keduanya falsy
result = None or 0
# Langkah 1: None adalah falsy, jadi evaluasi sisi kanan
# Langkah 2: Kembalikan nilai sisi kanan: 0 (meskipun ini juga falsy)
print(result) # Output: 09.4.4) Penggunaan Praktis or untuk Nilai Default
Salah satu pola yang umum adalah menggunakan or untuk menyediakan nilai default:
# Preferensi pengguna dengan default
user_theme = "" # Pengguna belum mengatur tema
theme = user_theme or "light"
print(f"Theme: {theme}") # Output: Theme: light
user_theme = "dark"
theme = user_theme or "light"
print(f"Theme: {theme}") # Output: Theme: dark
# Nilai konfigurasi
max_retries = None # Belum dikonfigurasi
retries = max_retries or 3
print(f"Retries: {retries}") # Output: Retries: 3
max_retries = 5
retries = max_retries or 3
print(f"Retries: {retries}") # Output: Retries: 5Pola ini bekerja karena jika sisi kiri falsy (string kosong, None, 0, dll.), or mengembalikan sisi kanan (nilai default).
9.4.12) Ringkasan Apa yang Dikembalikan Operator
Berikut ringkasan lengkap tentang apa yang dikembalikan setiap operator logika:
Operator and:
- Mengembalikan operand falsy pertama
- Jika semua operand truthy, mengembalikan operand terakhir
- Menggunakan evaluasi short-circuit (berhenti pada nilai falsy pertama)
Operator or:
- Mengembalikan operand truthy pertama
- Jika semua operand falsy, mengembalikan operand terakhir
- Menggunakan evaluasi short-circuit (berhenti pada nilai truthy pertama)
Operator not:
- Selalu mengembalikan boolean (
TrueatauFalse) notmengonversi operand menjadi boolean, lalu menegasikannya
# Mendemonstrasikan ketiga operator
print(5 and 10) # Output: 10 (keduanya truthy, kembalikan yang terakhir)
print(0 and 10) # Output: 0 (falsy pertama, kembalikan itu)
print(5 or 10) # Output: 5 (truthy pertama, kembalikan itu)
print(0 or 10) # Output: 10 (falsy pertama, evaluasi yang kedua)
print(not 5) # Output: False (5 adalah truthy, not mengembalikan boolean)
print(not 0) # Output: True (0 adalah falsy, not mengembalikan boolean)
print(not "") # Output: True (string kosong adalah falsy)
print(not "hello") # Output: False (string non-kosong adalah truthy)Memahami perilaku-perilaku ini membantu kamu menulis kode yang lebih ringkas dan Pythonic, tetapi selalu utamakan kejelasan. Jika memakai fitur-fitur ini membuat kode kamu lebih sulit dipahami, lebih baik kamu menuliskannya secara eksplisit.
Di bab ini, kita telah mengeksplorasi cara menggabungkan kondisi sederhana menjadi logika boolean yang kompleks menggunakan operator and, or, dan not di Python. Kita telah belajar tentang prioritas operator, evaluasi short-circuit, dan perilaku mengejutkan operator logika pada nilai non-boolean. Kita juga telah meninjau jebakan umum dan praktik terbaik untuk menulis ekspresi boolean yang jelas dan benar.
Alat-alat ini memungkinkan kamu mengekspresikan logika pengambilan keputusan yang canggih di programmu. Jika digabungkan dengan pernyataan if dari Bab 8, sekarang kamu bisa menangani hampir semua logika kondisional yang dibutuhkan programmu. Di bab berikutnya, kita akan mengeksplorasi ekspresi kondisional, yang menyediakan cara ringkas untuk memilih antara dua nilai berdasarkan sebuah kondisi.