İçeriğe geç
academia.sh

Ders 06 / 18

Koşullu Dallanma

Koşula bağlı yürütme, çok yollu seçim, koşulların okunabilir yazımı ve eşleme tabanlı dağıtım.

İçindekiler

Buraya kadar yazılan programlar baştan sona tek bir yolu izledi: her deyim, sırası gelince bir kez yürütüldü. Oysa çoğu problem, duruma göre farklı davranış gerektirir. Bir ölçüm sınırın üzerindeyse uyarı verilmeli, altındaysa sessiz kalınmalıdır.

Bu ders, akışın koşula göre ayrılmasını ele alır. Önceki kursta bunun donanımdaki karşılığı görülmüştü: karşılaştırma komutu bayrakları kurar, koşullu dallanma komutu program sayacını yalnızca koşul sağlanıyorsa değiştirir. Buradaki her yapı, sonunda o komutlara indirgenir.

Tek Yollu ve İki Yollu Seçim

En basit biçim, bir bloğun yalnızca koşul sağlandığında yürütülmesidir:

olcum = 25
SINIR = 20

if olcum > SINIR:
    print("sınır aşıldı")        # sınır aşıldı

Koşul, mantıksal bir değer üreten herhangi bir ifadedir. Sağlanmazsa blok atlanır ve akış bloğun altından devam eder.

İki yollu seçimde, koşul sağlanmadığında yürütülecek bir blok da tanımlanır:

if olcum > SINIR:
    durum = "yüksek"
else:
    durum = "normal"

print(durum)                     # yüksek

Blokların hangi deyimleri kapsadığı dile göre farklı gösterilir: kimi diller süslü parantez kullanır, kimi diller anahtar sözcükle bloğu kapatır, Python girintiyi kullanır. Gösterim değişir; anlam aynıdır — koşula bağlı olarak yürütülecek deyimler kümesi işaretlenmiştir.

Girinti kullanan dillerde bir uyarı gerekir: girinti yalnızca biçim değil, anlamdır. Bloğun içinde sanılan ama girintisi kaydırılmış bir deyim, koşuldan bağımsız olarak her zaman çalışır. Bu, ilk derste tanımlanan mantık hatası sınıfının sık görülen bir örneğidir.

Çok Yollu Seçim

İkiden fazla durum varsa koşullar zincirlenir. Zincirde ilk sağlanan koşul kazanır; kalanlar hiç sınanmaz.

def sinifla(olcum: int) -> str:
    if olcum < 10:
        return "düşük"
    elif olcum < 20:
        return "orta"
    elif olcum < 30:
        return "yüksek"
    else:
        return "aşırı"

print(sinifla(7), sinifla(12), sinifla(25), sinifla(40))
# düşük orta yüksek aşırı

Zincirin sırası, koşulların anlamını belirler. İkinci daldaki olcum < 20 koşulu, tek başına okunduğunda 55 değeri için de doğrudur; ancak oraya ulaşıldığında ilk koşulun sağlanmadığı bilinir, yani olcum en az 1010’dur. Her dal, kendinden öncekilerin olumsuzlanmasını örtük olarak taşır.

Bu nedenle sıra değiştirildiğinde program bozulur. Aşağıdaki zincir her zaman “aşırı” üretir, çünkü ilk koşul neredeyse tüm değerler için doğrudur:

def yanlis_sinifla(olcum: int) -> str:
    if olcum >= 10:              # geniş koşul en başta
        return "aşırı"
    elif olcum < 20:
        return "orta"
    else:
        return "düşük"

print(yanlis_sinifla(12))        # aşırı  — beklenen "orta"
print(yanlis_sinifla(25))        # aşırı  — bu değer için doğru

Pratik kural: koşullar, en dar durumdan en geniş duruma doğru sıralanır; en genel durum else dalında toplanır. Zincirin sonunda else dalı yoksa, hiçbir koşulun sağlanmadığı girdi sessizce hiçbir şey yapmadan geçer — bu, gözden kaçan durumların tipik saklandığı yerdir. Her zincirin son dalı, beklenmeyen girdinin ne olacağını açıkça söylemelidir.

Koşulları Okunabilir Yazmak

Koşul karmaşıklaştıkça kodun okunabilirliği hızla düşer. Üç alışkanlık bunu önler.

Mantıksal değeri doğrudan kullanmak. if kosul == True yazımı gereksizdir; kosul zaten mantıksal bir değerdir. Karşılaştırma eklemek, ifadeyi uzatır ve yanlışlıkla atamaya dönüşme riski taşır.

Koşula ad vermek. Uzun bir koşul, anlamını söyleyen bir değişkene bağlanır:

olcum, sicaklik = 25, 80

# Okunması güç:
if olcum > 20 and sicaklik > 75 and not (olcum > 40):
    print("uyarı")

# Adlandırılmış:
sinir_asildi = olcum > 20
asiri_sicak = sicaklik > 75
guvenli_aralikta = olcum <= 40

if sinir_asildi and asiri_sicak and guvenli_aralikta:
    print("uyarı")               # uyarı

Olumsuzlamayı sadeleştirmek. İç içe olumsuzlamalar, De Morgan kurallarıyla düzleştirilir: not (a and b) ifadesi (not a) or (not b) ile eşdeğerdir. İki yazımdan hangisinin seçileceği, hangisinin problemi daha doğrudan anlattığına bakılarak kararlaştırılır.

Koşullu İfade

Koşullu dallanma bir deyimdir: bir eylem yapar, değer üretmez. Buna karşılık birçok dil, koşula göre değer üreten bir biçim de sunar. İki yazımın farkı, ilk dersteki deyim– ifade ayrımının doğrudan uygulamasıdır.

olcum = 25

# Deyim biçimi: durum değişkeni iki dalda ayrı ayrı bağlanır.
if olcum > 20:
    durum = "yüksek"
else:
    durum = "normal"

# İfade biçimi: tek bağlama, koşul değeri seçer.
durum = "yüksek" if olcum > 20 else "normal"
print(durum)                     # yüksek

İfade biçimi, bir değerin iki seçenekten birine bağlandığı kısa durumlarda okunabilirliği artırır: değişken bir kez yazılır ve bağlamanın tek bir yerde olduğu görülür.

Sınırı da vardır. Dallar uzunsa, iç içe geçmişse veya yan etki içeriyorsa ifade biçimi okunmaz hâle gelir. Ölçüt şudur: koşul bir değer seçiyorsa ifade, bir eylem seçiyorsa deyim biçimi kullanılır.

İç İçe Koşullar

Koşullar birbirinin içine yerleştirilebilir. Derinlik arttıkça okuma zorlaşır; her düzey, okuyucunun akılda tutması gereken bir varsayım ekler.

Üç düzeyden derin koşul yığınları, genellikle iki ayrı sorunun aynı yerde çözülmeye çalışıldığının işaretidir. Derinliği azaltmanın standart yolu, geçersiz durumları başta eleyip erken çıkmaktır. Bu yazım, fonksiyonlar konusunda koruma cümlesi adıyla tekrar ele alınacaktır; buradaki karşılığı, iç içe geçmiş dalların düz bir zincire dönüştürülmesidir.

Eşleme Tabanlı Dağıtım

Koşul zinciri, tek bir değerin sabitlerle karşılaştırılmasından ibaretse, birçok dil bunun için ayrı bir yapı sunar — anahtar temelli seçim veya desen eşleme. Yapının adı ve yetenekleri dile göre değişir.

Zincire alternatif bir yaklaşım, seçimi veriye taşımaktır:

BIRIM_CARPANI = {"mm": 0.001, "cm": 0.01, "m": 1.0}

def metreye_cevir(deger: float, birim: str) -> float:
    if birim not in BIRIM_CARPANI:
        raise ValueError(f"bilinmeyen birim: {birim}")
    return deger * BIRIM_CARPANI[birim]

print(metreye_cevir(25, "cm"))   # 0.25
print(metreye_cevir(1500, "mm")) # 1.5

Bu yazımın üstünlüğü, yeni bir birim eklemenin kod değil veri değişikliği olmasıdır. Koşul zinciri her yeni durumda uzarken, eşleme tablosu aynı kalır. Karar sayısı arttıkça bu fark belirginleşir; yazılım tasarımı müfredatında aynı fikir, koşulların çok biçimlilikle değiştirilmesi başlığı altında genişletilir.

Seçim ölçütü şudur: durumlar sabit ve az sayıdaysa koşul zinciri açıktır; durumlar büyüyorsa veya çalışma anında değişiyorsa eşleme tercih edilir.

Özet

  • Koşullu dallanma, bir kod bloğunu yalnızca koşul sağlandığında yürütür; koşul mantıksal değer üreten bir ifadedir.
  • Blok sınırı dile göre farklı gösterilir; girinti kullanan dillerde girinti anlamın parçasıdır.
  • Çok yollu seçimde ilk sağlanan koşul kazanır; her dal, kendinden öncekilerin olumsuzlanmasını örtük taşır ve sıra değişimi programı bozar.
  • Koşullar adlandırılarak ve olumsuzlamalar sadeleştirilerek okunabilir kılınır; mantıksal değer == True ile karşılaştırılmaz.
  • Tek bir değerin sabitlerle karşılaştırıldığı durumlarda eşleme tablosu, uzayan koşul zincirinin yerini alabilir.

Sonraki Adım

Dallanma, akışın hangi yoldan gideceğini belirler ama her yolu yalnızca bir kez yürütür. Ortak problemdeki ölçüm dizisi ise her eleman için aynı işi gerektirir. Sonraki ders, aynı bloğun tekrar tekrar yürütülmesini sağlayan döngüleri ve döngünün sonlanma güvencesini ele alacak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat