Koşullar ve girdi doğrulama
Geçen hafta bir karşılaştırmanın sonucunun True ya da False olduğunu gördük. Bu hafta program bu sonuca bakıp hangi satırları çalıştıracağını seçecek.
Program her çalıştırmada aynı adımlardan geçmek zorunda değildir. Not geçme sınırının üstündeyse bir mesaj, altındaysa başka bir mesaj yazdırabilir. Kullanıcı geçersiz bir değer girdiyse hesaba devam etmek yerine uyarı verebilir. Bu kararları koşullarla veririz. Koşul, sonucu True ya da False olan bir ifadedir: puan >= 60 gibi.
Bu sayfadaki kod hücreleri kendiliğinden çalışmaz. Her hücrede önce çıktıyı tahmin edin, sonra Run Code düğmesine basın. Kodu değiştirip yeniden çalıştırabilir, Start Over ile ilk hâline döndürebilirsiniz.
Bu bölümün kapsamı
if/elseakışını izleme- Bağımsız
ifblokları ileif–elifzincirinin farkı elifsıralamasının sonucu belirlemesi ve erişilemez blok- Sınır değerinde
>ile>=farkı and,orvenotile bileşik koşul kurma- Girdiyi kullanmadan önce kabul aralığını doğrulama
booldeğeri doğrudan koşul olarak kullanma
- Karar tablosunun biçimsel çizim kuralları
- Üç ve daha fazla katmanlı iç içe koşul yapıları
Bu başlıklar konunun devamıdır. İleride karşınıza çıkar, ama bu derste ezberlemeniz beklenmiyor.
Otoparkın kurallarını nasıl yazardınız?
Bir alışveriş merkezinin otoparkında çıkışta bir görevli duruyor. Görevli fişe bakıp aracın kaç saat kaldığını okuyor ve ücreti söylüyor. Tarife şöyle:
| Kalınan süre | Ücret |
|---|---|
1 saate kadar |
30 TL |
1 saatten fazla, 3 saate kadar |
60 TL |
3 saatten fazla |
100 TL |
İki kural daha var. Abone kartı ya da engelli kartı olan sürücü ücret ödemez. Otopark her gece kapandığı için bir araç en çok 24 saat kalabilir.
Görevlinin yerine bir program yazılacak. Program yalnız ona yazdığınız kuralları bilecek, eksik bir kuralı kendi başına tamamlamayacak. 1. bölümde bir işin adımlarını sözde kodla yazmıştık. Görevlinin kurallarını da öyle, Türkçe ve madde madde yazın. Sonra kurallarınızı dört araçla deneyin:
- Araç yarım saat kaldı. Kurallarınızdan kaçı bu araca uyuyor?
- Araç tam
1saat kaldı. Kurallarınıza göre30TL mi öder,60TL mi? - Sürücünün abone kartı var, araç
5saat kaldı. Kurallarınız kaç TL istiyor? - Fiş okuyucu bozuk bir değer verdi:
-2saat. Kurallarınız ne yapıyor?
Python bilmeniz gerekmiyor: “Abone kartı varsa ücret yok” da bir kural. Kurallarınızı bir kenara yazın. Bölümde her birinin Python’da nasıl yazıldığını göreceğiz. Alıştırmalardan önce listenize döneceğiz.
if: koşul doğruysa çalıştır
En basit karar if ile yazılır. puan 75 iken hücre ne yazar? Çalıştırdıktan sonra puan’ı 45 yapıp yeniden deneyin.
Python önce puan >= 60 karşılaştırmasının sonucunu bulur. Sonuç True ise alttaki girintili satır çalışır. Sonuç False ise bu satır atlanır. Satırın başında bırakılan boşluğa girinti denir. Koşula bağlı girintili satırların hepsine birden blok denir.
Yazarken üç şeye dikkat edin:
- Koşul
ifanahtar sözcüğünden sonra gelir. - Koşul satırı
:ile biter. - Koşula bağlı kod içeri doğru girintilenir.
if koşul:
koşul doğruysa çalışacak kod
Python’da hangi satırın koşula bağlı olduğunu girinti belirler. if satırının altına girintili bir satır yazmazsanız Python hata verir. Aynı bloktaki satırlar aynı düzeyde, genellikle dört boşlukla girintilenir.
Tahmin et: hangi satırlar çalışır?
Aşağıdaki kod kaç satır yazar? Önce tahmin edin, sonra çalıştırın.
if bloğundan önceki ve sonraki print() çağrıları koşula bağlı değildir. Bu yüzden koşulun sonucu ne olursa olsun çalışırlar.
Şimdi sicaklik değerini 15 yapın. Çalıştırmadan önce düşünün: kaç satır kalır?
if–else: iki olasılıktan biri
İki olasılıktan biri mutlaka gerçekleşiyorsa (bakiye ya yeter ya yetmez) else kullanırız. Hücre hangi satırı yazar?
Bu yapıda iki bloktan yalnızca biri çalışır.
Alıştırma: sınırdaki değeri düşünün
Bir dersten geçme sınırı 60 olsun. Aşağıdaki program puan = 60 için ne yazdırmalı?
Programı, 60 puan alan öğrenci de geçecek biçimde düzeltin.
>= “büyük veya eşit” anlamına gelir.
puan = 60
if puan >= 60:
print("Geçti")
else:
print("Kaldı")Sınır değerini deneyin
Koşulun sonucu belli bir değerde False’tan True’ya döner. Programı denerken en çok bu değerin çevresine bakmak gerekir. Geçme sınırı 60 ise programı 80 ve 30 ile denemek > ile >= arasındaki farkı göstermez.
En az şu üç değeri deneyin:
| Puan | Beklenen |
|---|---|
59 |
Kaldı |
60 |
Geçti |
61 |
Geçti |
60 burada bir sınır değeridir. puan > 60 ile puan >= 60 yalnızca bu değerde farklı sonuç verir. Otoparkta tam 1 saat kalan araç da böyle bir değerdir.
Bir koşul yazdıktan sonra kendinize sorun: “Sınırın bir altında, sınırın kendisinde ve bir üstünde ne olur?”
elif: birden fazla seçenek
İkiden fazla durum olduğunda elif kullanılabilir. puan 82 iken hücre ne yazar?
Python koşullara yukarıdan aşağı bakar. İlk True olan koşulun bloğunu çalıştırır ve zincirin geri kalanını atlar.
Bağımsız if bloklarından birden fazlası çalışabilir
Sık yapılan bir hata, tek bir harf notu seçilecekken her notu ayrı bir if ile yazmaktır. puan 95 iken aşağıdaki kod kaç satır yazar?
Burada iki if bağımsızdır: Python ikisinin koşuluna da ayrı ayrı bakar.
95 >= 90 doğru olduğu için AA yazılır. İkinci if ilkinden bağımsızdır. 95 >= 80 de doğru olduğu için BA da yazılır. Çıktı iki satırdır.
Her öğrenciye tek bir harf notu vermek istiyorsak elif ile bir zincir kurarız. Bu kez kaç satır yazılır?
Zincirde ilk doğru dal çalıştıktan sonra kalan koşullara bakılmaz.
Bağımsız if her zaman yanlış değildir. Aynı öğrenci için birbirinden ayrı şeylere bakıyorsanız (devamsızlık sınırını aştı mı, ödevini teslim etti mi) her biri için ayrı if yazmak doğrudur. Yanlış olan, yalnızca biri seçilmesi gereken seçenekleri (harf notları gibi) ayrı if bloklarıyla yazmaktır.
elif zincirinde koşulların sırası da sonucu değiştirir. Aşağıdaki kod 95 puanı yanlış gruba koyar. Hangi satırı yazar?
95 >= 70 zaten True olduğu için ikinci koşula hiç sıra gelmez. Bu zincirde AA hiçbir puanda yazılmaz: 90’ı geçen her puan 70’i de geçer ve ilk koşulda yakalanır. Hiçbir değerde çalışmayan böyle bir bloğa erişilemez blok denir.
İncele ve düzelt: koşul sırası
Aşağıdaki program sıcaklığa göre bir etiket yazdırıyor. 32 derece için "Sıcak" yazmalı, ama koşulların sırası yüzünden yazmıyor.
Koşulları, 30 ve üzeri "Sıcak", 20–29 arası "Ilık", daha düşük değerler "Serin" olacak biçimde düzenleyin.
Önce en yüksek eşiği kontrol edin.
sicaklik = 32
if sicaklik >= 30:
print("Sıcak")
elif sicaklik >= 20:
print("Ilık")
else:
print("Serin")Bileşik koşullar
Bazen bir karar için iki karşılaştırma gerekir. Örneğin bir sınav puanı ancak hem 0 ya da daha büyük hem de 100 ya da daha küçükse geçerlidir. and iki koşul da True ise True verir. Hücre ne yazar?
Python’da aynı aralık kontrolü daha kısa da yazılabilir:
gecerli_mi = 0 <= puan <= 100İki yazımın anlamı aynıdır.
or ise koşullardan birinin doğru olması yettiğinde kullanılır. gun "Cumartesi" iken hücre bir şey yazar mı?
not, True değeri False, False değeri True yapar. Bu hücre bir şey yazar mı?
bool değeri doğrudan koşulda kullanın
Bir değişken zaten True ya da False tutuyorsa onu yeniden True ile karşılaştırmaya gerek yoktur:
Şu yazım çalışsa da gereksizdir:
if uye_mi == True:
print("Üye indirimi uygulanabilir")Değerin False olduğu durumu yakalamak için de == False yerine not yazmak daha kolay okunur:
if not uye_mi:
print("Standart ücret uygulanır")İç içe if: ikinci karar yalnızca ilkinden sonra anlamlıysa
Bazen ikinci koşula ancak ilk koşul doğruysa bakmak isteriz. Örneğin sisteme giriş yapmamış bir kullanıcının rolüne (yönetici mi, standart kullanıcı mı) bakmanın anlamı yoktur. Hücre ne yazar? Sonra rol değerini "ogrenci", ardından giris_yapti değerini False yapıp yeniden deneyin.
Burada içteki if, yalnızca giris_yapti doğru olduğunda çalışır.
İki koşul birlikte tek bir sonucu belirliyorsa and ile yazmak daha açık olabilir:
if giris_yapti and rol == "yonetici":
print("Yönetim ekranı")Başlangıç için şu kural yeter:
- İki koşul aynı sonucu birlikte belirliyorsa çoğu zaman
anddaha kısadır. - İkinci karar yalnızca birinci karar doğruyken anlamlıysa ya da her durum için ayrı bir mesaj gerekiyorsa iç içe
ifdaha açık olabilir.
İç içe if katmanlarını gereksiz yere artırmayın. Aynı karar okunaklı tek bir bileşik koşulla yazılabiliyorsa sade olanı seçin.
Önce doğrula, sonra işlem yap
Kullanıcı her zaman geçerli bir değer girmez. Sınav puanı 0 ile 100 arasında olmalıdır, ama biri yanlışlıkla 120 yazabilir. Program bu değeri kullanmadan önce kontrol etmelidir. Hücre ne yazar?
Bu hafta input() ile alınan metnin sayıya çevrilebildiğini varsayıyoruz. "abc" gibi bir metin int() ile çevrilirken hata verir. Bu hatayı yakalamayı 13. bölümde göreceğiz. Şimdilik yalnız sayı olan ama aralığın dışında kalan değerleri yakalıyoruz.
Alıştırma: yaş aralığını doğrulayın
Bir kayıt formunda yaşın 16 ile 120 arasında olması gerektiğini varsayalım.
if True: satırını uygun aralık koşuluyla değiştirin.
16 <= yas <= 120 biçimindeki zincirli karşılaştırmayı kullanabilirsiniz.
yas = 14
if 16 <= yas <= 120:
print("Geçerli yaş")
else:
print("Yaş 16 ile 120 arasında olmalı")Karar tablosundan koda
Kural sayısı artınca koşulları yazmadan önce kuralları bir tabloya dökün. Böylece atlanan bir durum kod yazılmadan görünür. Bu tabloya karar tablosu denir: her satır bir durumu ve o durumda ne yapılacağını gösterir. Bölümün başındaki otopark tarifesi de bir karar tablosudur.
Bir kargo uygulamasının basitleştirilmiş kuralı şöyle olsun:
| Sepet toplamı | Üyelik | Kargo ücreti |
|---|---|---|
500 TL veya üzeri |
fark etmez | 0 TL |
500 TL altı |
üye | 20 TL |
500 TL altı |
üye değil | 40 TL |
Tablonun Python karşılığı aşağıdaki hücrede. sepet 350 ve uye_mi True iken kargo ücreti kaç TL çıkar?
İlk koşul doğruysa üyelik bilgisine bakmaya gerek kalmaz. Ayrıca uye_mi zaten bir bool olduğu için elif uye_mi == True: yazmıyoruz.
Değiştir: karar tablosunu sınayın
Yukarıdaki hücrede sepet ve uye_mi değerlerini değiştirerek tablodaki üç satırı da deneyin. Özellikle şu üç durumu çalıştırın:
sepet = 500,uye_mi = Falsesepet = 499,uye_mi = Truesepet = 499,uye_mi = False
Bu değerler tablodaki 500 TL sınırının iki yanını ve üyelik farkını dener.
Soruya dönelim: otoparkın kuralları Python’da
Bölümün başında otopark görevlisinin kurallarını yazıp dört araçla denemiştiniz. Python’daki karşılıkları şöyle:
| Deneme | Sözde kodda | Python’da | Dikkat |
|---|---|---|---|
| Yarım saat: kaç kural uyuyor? | “1 saate kadarsa 30 TL, 3 saate kadarsa 60 TL, değilse 100 TL” | if saat <= 1:, elif saat <= 3:, else: zinciri |
Her kural ayrı if olursa yarım saat kalan araca hem 30 hem 60 TL’lik kural uyar. Zincirde yalnız ilk uyan kural çalışır |
Tam 1 saat |
“1 saate kadarsa 30 TL” | saat <= 1 |
saat < 1 yazılırsa tam 1 saat kalan araç 60 TL öder |
Abone kartı, 5 saat |
“Kartı varsa ücret yok” | if abone_mi or engelli_mi: zincirin ilk koşulu olur |
Kart kuralı zincirin sonuna yazılırsa erişilemez blok olur: her süre zaten bir ücret kuralına uyar |
-2 saat |
“Süre 0 ile 24 arasında değilse ücret hesaplama” | if 0 <= saat <= 24: ücret hesaplanır, else: uyarı yazılır |
Kontrol olmazsa -2 de saat <= 1 koşuluna uyar ve hata vermeden 30 TL yazılır |
Listenizi tabloyla karşılaştırın. Kurallarınızda “1 saatten azsa” gibi bir sınır varsa sınırın kendisinin hangi gruba düştüğüne bakın. Kart kuralını en sona yazdıysanız onu öne almanız gerekir. Bozuk fişi hiç düşünmediyseniz program da düşünmez: yazmadığınız kontrolü kendisi eklemez.
Üret: otopark ücretini hesaplayın
Bölümün başındaki tarifeyi koda çevirin. Önce kartları ve bozuk fişi düşünmeden yalnız süreye bakın:
| Süre | Ücret |
|---|---|
1 saate kadar |
30 TL |
1 saatten fazla, 3 saate kadar |
60 TL |
3 saatten fazla |
100 TL |
Programı, saat değerine göre doğru ücreti ucret değişkenine atayacak ve ekrana yazdıracak biçimde tamamlayın.
Kabul kriterleri:
- Tam
1saat ilk gruba girmeli. - Tam
3saat ikinci gruba girmeli. 3saatten uzun süreler üçüncü gruba girmeli.- Sonuç
ucretdeğişkeninde tutulmalı ve yazdırılmalı.
Önce saat <= 1, sonra saat <= 3 koşulunu düşünün. İlk koşul False olduysa ikinci koşula gelen değerin 1’den büyük olduğu zaten bellidir.
saat = 2.5
if saat <= 1:
ucret = 30
elif saat <= 3:
ucret = 60
else:
ucret = 100
print(ucret)Sıra sizde: kartlar ve bozuk fiş
Programınıza bölümün başındaki iki kuralı da ekleyin. Abone kartı ya da engelli kartı olan sürücü ücret ödemez. Süre 0 ile 24 saat arasında değilse program ücret hesaplamaz ve Fiş okunamadı yazar.
Programı açılış sorusundaki dört araçla, bir de 2.5 saatle deneyin. Beklenen sonuçlar:
saat |
abone_mi |
engelli_mi |
Beklenen |
|---|---|---|---|
0.5 |
False |
False |
30 TL |
1 |
False |
False |
30 TL |
5 |
True |
False |
0 TL |
-2 |
False |
False |
Fiş okunamadı |
2.5 |
False |
False |
60 TL |
Önce süreyi doğrulayın. Süre geçerliyse içeride ilk koşul kartlara baksın, ardından tarifenin zinciri gelsin.
saat = 2.5
abone_mi = False
engelli_mi = False
if 0 <= saat <= 24:
if abone_mi or engelli_mi:
ucret = 0
elif saat <= 1:
ucret = 30
elif saat <= 3:
ucret = 60
else:
ucret = 100
print("Ücret:", ucret, "TL")
else:
print("Fiş okunamadı")Tek sayfa özet
Bu hafta programın her çalıştırmada aynı satırlardan geçmek zorunda olmadığını gördük.
if, koşulTrueolduğunda altındaki girintili bloğu çalıştırır.elsebloğu, koşulFalseolduğunda çalışır.- Bağımsız
ifbloklarının her biri ayrı ayrı değerlendirilir; birden fazlası aynı çalıştırmada çalışabilir. elif, yalnızca birinin seçileceği olasılıkları sırayla sınar; koşulu ilkTrueolan blok çalışır.- Zaten
boololan değerlerif uye_mi:biçiminde doğrudan koşul olarak kullanılabilir. and,orvenotile bileşik koşullar kurulabilir.- İkinci karar yalnızca ilk karar sağlandığında anlamlıysa basit iç içe
ifkullanılabilir; tek bir ortak sonuç içinandçoğu zaman daha sadedir. >ile>=arasındaki fark sınır değerinde ortaya çıkar.- Girdiyi kullanmadan önce kabul edilen aralıkta olup olmadığını kontrol etmek gerekir.
- Hiçbir değerde çalışmayan bloğa erişilemez blok denir. Zincirde geniş koşul dar koşuldan önce gelirse dar koşulun bloğu erişilemez olur.
- Karar tablosu, birden fazla kuralı koda çevirmeden önce netleştirmeye yarar. Otopark tarifesi de bir karar tablosudur.
Bir sonraki bölümde aynı kararı bir kez değil, koşul doğru olduğu sürece tekrar tekrar uygulamayı öğreneceğiz.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
ifveelseile kurulan tek karar akışını izler.- Birbirinden bağımsız
ifbloklarıylaif–elifzincirini ayırt eder. elifsıralamasının sonucu nasıl belirlediğini çözümler.- Sınır değerinde
>ile>=arasındaki farkı gösterir. and,orvenotile bileşik koşul kurar.- Girdiyi kullanmadan önce kabul aralığında olup olmadığını doğrular.
- Zaten
boololan bir değeri doğrudan koşul olarak kullanır.