Neden önemli?
Şimdiye kadar yazdığın programlar yukarıdan aşağıya, hiç sapmadan çalıştı. Oysa gerçek iş kuralları hep "eğer ... ise" diye başlar: Eğer sepet tutarı 500 TL'yi geçerse kargo bedava. Eğer başvuranın yaşı 18'in altındaysa krediyi reddet. Eğer stok sıfırsa "tükendi" yaz. Ilgaz Bank'ta bir kredi uzmanının her gün uyguladığı kuralı Python'a öğretmek için koşul (condition) yapısına ihtiyacın var.
if, elif, else
Python'da bir blok yalnızca koşul True olduğunda çalışır. Blok girintiyle (4 boşluk) belirlenir; süslü parantez yok.
sepet_tutari = 640
if sepet_tutari >= 500:
kargo = 0
elif sepet_tutari >= 200:
kargo = 29.90
else:
kargo = 49.90
print("Kargo ücreti:", kargo)
Üç kuralı aklında tut:
- if zorunlu, elif (else if) istediğin kadar, else en fazla bir tane ve en sonda.
- Dallar yukarıdan aşağıya denenir; ilk doğru olan çalışır, gerisi atlanır. Bu yüzden sıralama önemlidir: önce
>= 200yazsaydın 640 de o dala girerdi. - Her koşul satırı iki nokta
:ile biter.
Karşılaştırma operatörleri
| Operatör | Anlamı | Örnek | Sonuç |
|---|---|---|---|
== | eşit mi | 5 == 5.0 | True |
!= | eşit değil mi | "a" != "A" | True |
< <= | küçük / küçük eşit | 3 <= 3 | True |
> >= | büyük / büyük eşit | "b" > "a" | True (alfabetik) |
in | içinde mi | "İzmir" in ["Ankara", "İzmir"] | True |
is | aynı nesne mi | x is None | None kontrolü için |
if yas = 18: yazarsan Python sözdizimi hatası verir; bu iyi bir şey, çünkü hatayı anında görürsün.Python'da karşılaştırmaları zincirleyebilirsin; bu matematikteki gibi okunur:
kredi_notu = 720
if 650 <= kredi_notu < 750:
print("Orta risk grubu")
print(18 <= 25 < 65) # True
Mantık operatörleri: and, or, not
Birden fazla koşulu birleştirmek için and (ve), or (veya), not (değil) kullanılır. Öncelik sırası: not > and > or. Emin değilsen parantez koy; parantez hem güvenli hem okunaklıdır.
yas = 34
aylik_gelir = 42000
kara_listede = False
mevcut_kredi = 1
uygun = yas >= 18 and aylik_gelir >= 25000 and not kara_listede
print("Temel şartlar:", uygun)
# Parantezin farkı
print(True or False and False) # and önce: True or False -> True
print((True or False) and False) # parantez önce: True and False -> False
a and b ifadesinde a yanlışsa Python b'ye hiç bakmaz. Bu, liste and liste[0] == 5 gibi "önce boş mu diye bak, sonra elemana eriş" kalıplarını güvenli kılar.Truthiness: her şey bir koşul olabilir
if yalnızca True/False beklemez; herhangi bir değer koyabilirsin. Python değeri "doğru gibi" ya da "yanlış gibi" sayar:
- Yanlış sayılanlar (falsy):
False,None,0,0.0, boş metin"", boş liste[], boş sözlük{}, boş demet(). - Doğru sayılanlar (truthy): geri kalan her şey;
-1," "(boşluk karakteri),[0]bile.
sepet = []
if sepet:
print("Sepette ürün var")
else:
print("Sepet boş")
ad = ""
print("Ad girildi" if ad else "Ad boş")
print(bool(0), bool("0"), bool([]), bool([0]))
Son satırdaki x if kosul else y yapısına koşullu ifade (conditional expression, "ternary") denir; tek satırda iki değerden birini seçer.
İç içe koşul ve erken dönüş
Koşul içine koşul yazabilirsin ama girinti derinleştikçe kod zorlaşır. Fonksiyon içindeysen (bir sonraki modülde ayrıntısıyla göreceksin) olumsuz durumları başta eleyip return ile çıkmak, kodu düz ve okunur tutar. Buna erken dönüş (early return) ya da "guard clause" denir.
def kredi_karari(yas, gelir, kredi_notu, kara_listede):
"""Ilgaz Bank bireysel kredi ön değerlendirme kuralı."""
if kara_listede:
return "RED: kara liste"
if yas < 18:
return "RED: yaş"
if gelir < 25000:
return "RED: gelir yetersiz"
if kredi_notu >= 700:
return "ONAY: standart faiz"
if kredi_notu >= 600:
return "ONAY: yüksek faiz"
return "RED: kredi notu düşük"
print(kredi_karari(34, 42000, 720, False))
print(kredi_karari(34, 42000, 640, False))
print(kredi_karari(17, 42000, 720, False))
print(kredi_karari(40, 90000, 800, True))
Aynı kuralı iç içe if ile yazsaydın dört seviye girinti olurdu. Erken dönüşte her satır tek bir kuralı anlatır; kredi uzmanı bile okuyup "evet, kuralımız bu" diyebilir.
pass yaz; hiçbir şey yapmaz ama sözdizimini tamamlar.match ile çoklu dallanma (Python 3.10+)
Bir değeri birçok sabitle karşılaştırıyorsan match daha temiz olabilir:
durum = "kargoda"
match durum:
case "hazirlaniyor":
print("Depoda paketleniyor")
case "kargoda" | "dagitimda":
print("Yolda")
case "teslim":
print("Teslim edildi")
case _:
print("Bilinmeyen durum")
and ve or aslında ne döndürür?
Ders boyunca and ve or'u True/False üreten operatörler gibi kullandın. Gerçekte ikisi de işlenenlerden birini döndürür: a or b, a doğru (truthy) ise a'yı, değilse b'yi; a and b, a yanlış (falsy) ise a'yı, değilse b'yi verir. Kısa devre de buradan gelir: sonucu belli olan ifadede ikinci tarafa hiç bakılmaz.
print("" or "Misafir") # boş metin falsy → "Misafir"
print("Ayşe" or "Misafir") # "Ayşe"
print(5 and 0) # 5 truthy → ikinci taraf: 0
print(None and 1 / 0) # None falsy → bölmeye hiç bakılmaz
ad = ""
gorunen = ad or "Misafir" # varsayılan değer kalıbı
print(gorunen)
kupon = 0 # "indirim yok" anlamında bilinçli 0
indirim = kupon or 10 # TUZAK: 0 falsy, 10 seçilir
print(indirim)
indirim = 10 if kupon is None else kupon
print(indirim)
x or varsayilan yalnızca x'in hiçbir falsy değerinin anlamlı olmadığı durumlarda güvenlidir (ör. boş ad). 0, 0.0, boş liste gibi değerler geçerli bir girdi olabiliyorsa "verilmedi" bilgisini None ile taşı ve is None ile kontrol et.Öncelik sırası ve De Morgan
Karmaşık koşullarda hangi işlemin önce yapıldığını bilmek zorundasın. Karşılaştırmalar mantık operatörlerinden önce, not and'den önce, and de or'dan önce değerlendirilir.
| Öncelik (yüksekten düşüğe) | Operatör | Örnek | Nasıl okunur |
|---|---|---|---|
| 1 | Aritmetik | a + b > 100 | (a + b) > 100 |
| 2 | Karşılaştırma, in, is | x in s and y | (x in s) and y |
| 3 | not | not a and b | (not a) and b |
| 4 | and | a or b and c | a or (b and c) |
| 5 | or | a and b or c | (a and b) or c |
Şüphedeysen parantez kullan; okuyan kişiye de yardım eder. Bir koşulun tersini yazarken De Morgan kuralı işini görür: not (a and b) ile not a or not b aynıdır; not (a or b) ile not a and not b aynıdır. "Kart aktif VE bakiye yeterli değilse" demek, "kart pasif YA DA bakiye yetersiz" demektir.
kart_aktif, bakiye, tutar = True, 300, 500 print(not (kart_aktif and bakiye >= tutar)) print(not kart_aktif or bakiye < tutar) # aynı sonuç premium, kampanya, tutar = False, True, 150 print(premium or kampanya and tutar > 200) # and önce: False or (True and False) print((premium or kampanya) and tutar > 200) # farklı anlam, aynı sonuç burada print((premium or kampanya) and tutar > 100) # True
Çoklu or yerine in; any ve all
sehir == "İzmir" or sehir == "Manisa" or sehir == "Aydın" yerine sehir in {"İzmir", "Manisa", "Aydın"} yaz: daha kısa, daha hızlı ve kural kümesi bir değişkene taşınabilir. Bir listedeki elemanlardan en az biri koşulu sağlıyor mu sorusu için any, hepsi sağlıyor mu için all var.
ege = {"İzmir", "Manisa", "Aydın"}
print("Manisa" in ege, "Bursa" in ege)
tutarlar = [120, 4800, 75, 9200]
print(any(t > 5000 for t in tutarlar)) # en az biri 5000'i geçiyor mu?
print(all(t > 0 for t in tutarlar)) # hepsi pozitif mi?
print(all([]), any([])) # boş listede: True False
Parantez içindeki t > 5000 for t in tutarlar yapısı bir üreteç ifadesidir (generator expression); her eleman için koşulu sırayla üretir. Comprehension dersinde ayrıntısını göreceksin; şimdilik "her t için şu koşul" diye oku. any ilk True'da, all ilk False'ta durur.
all([]) True döner ("hepsi sağlıyor" iddiasını çürüten eleman yok). "Tüm taksitler ödendi mi?" sorusunda taksit listesi boşsa bunu ayrıca kontrol etmezsen, hiç taksidi olmayan hesap "kapandı" görünür.Kayan nokta ve metin karşılaştırma
Ondalıklı sayılar ikili tabanda tam temsil edilemez; 0.1 + 0.2 == 0.3 False'tur. Para ya da ölçüm karşılaştırırken math.isclose ya da bir tolerans kullan. Metinlerde ise karşılaştırma harf kodlarına göredir: büyük harfler küçüklerden, rakam içeren metinler de sayısal değil harf harf karşılaştırılır.
import math
print(0.1 + 0.2 == 0.3)
print(math.isclose(0.1 + 0.2, 0.3))
print(abs(1000.10 - 1000.1000001) < 0.005) # kuruş toleransı
print("10" < "9") # metin: "1" < "9" → True
print(int("10") < int("9")) # sayı: False
print("Zeytin" < "ayva") # büyük harf önce gelir: True
print("EVET".lower() == "evet")
Kullanıcı girdisini karşılaştırmadan önce strip() ile boşlukları, lower() ya da casefold() ile büyük/küçük harf farkını temizle. Türkçe "İ/ı" harflerinin küçültmede sürprizleri var; Unicode ve metin dersinde ayrıntılı gördün.
Uzun elif zinciri yerine tablo
Eşik tabanlı kurallar (kargo, indirim, vergi dilimi) değiştikçe elif zincirini düzenlemek hataya açıktır. Kuralları bir veri yapısına, karar mantığını tek bir döngüye koyarsan kural değişikliği yalnız veriyi değiştirir. Walrus operatörü (:=) ise bir değeri hem hesaplayıp hem koşulda kullanmanı sağlar.
KARGO = [(500, 0.0), (200, 29.9), (0, 49.9)] # büyükten küçüğe
def kargo(tutar):
for esik, ucret in KARGO:
if tutar >= esik:
return ucret
return None # negatif tutar
print(kargo(750), kargo(250), kargo(50), kargo(-5))
sepet = ["çay", "kahve", "şeker", "su"]
if (n := len(sepet)) > 3:
print(f"{n} ürün: toplu indirim uygulanır")
> mi >= mi, 500 TL tam sınırda kargo ücretli mi?İş kuralını koddan ayır
Gerçek sistemlerde "kredi için en az 25.000 TL gelir" gibi eşikler kodun içine gömülmez; sabit (constant) olarak en üste ya da bir ayar dosyasına yazılır: MIN_GELIR = 25000. Kural değiştiğinde tek satırı değiştirirsin ve kodun geri kalanını test etmen gerekmez.
Karmaşık koşulu adlandır
if yas >= 18 and gelir >= MIN_GELIR and not kara_listede and kredi_notu >= 600: satırı doğrudur ama okunmaz. Önce temel_sartlar = yas >= 18 and gelir >= MIN_GELIR gibi anlamlı ara değişkenler üret, sonra if temel_sartlar and risk_uygun: yaz. Bir koşulu okurken üç kere nefes almak gerekiyorsa bölünmelidir.
None ile is kullan
"Değer gelmedi" durumunu None ile temsil ederiz ve if x is None yazarız, == None değil. is aynı nesne olup olmadığına bakar; None tek bir nesne olduğu için en güvenli yoldur. Aynı mantıkla if not x ile if x is None farklıdır: ilki 0 ve boş listeyi de yakalar, ikincisi yalnızca None'ı.