while döngüsü ve kod izleme
Geçen hafta koşulun sonucuna göre hangi bloğun çalışacağını seçtik. Seçilen blok en fazla bir kez çalıştı. Oysa bazı işlerde aynı adımları koşul doğru olduğu sürece tekrar etmek gerekir.
Kullanıcı geçerli bir değer girene kadar yeniden sormak, en fazla üç deneme hakkı vermek, ölçümleri sırayla tek tek işlemek ya da birikim hedefe ulaşana kadar her hafta para eklemek bu türden işlerdir. Python’da koşula bağlı tekrar için while döngüsü kullanılır.
Bu hafta söz diziminden çok şuna çalışacağız: döngü her döndüğünde, yani her yinelemede, değişkenlerin nasıl değiştiğini izlemek ve döngünün neden durduğunu açıklamak.
Bu bölümün kapsamı
whilekoşulunun her yinelemeden önce sınanması- Koşul başta yanlışsa gövdenin hiç çalışmaması
- Başlangıç, koşul ve güncellemenin birlikte kurulması
- Sonsuz döngünün nedeni
- Kod izleme tablosuyla her yinelemedeki değerleri izleme
- Sınırın koşula dâhil edilip edilmemesinden doğan
off-by-onehatası - Sayaç ile biriktiricinin ayrımı
- Döngülerin çalışma süresi ve hız karşılaştırması
- Çalışan programı
Ctrl+Cile kesme (derste kullanılır, sınavda sorulmaz) whileile birlikte kullanılanelsebloğu
Bu başlıklar konunun devamıdır; ileride karşınıza çıkar ama bu derste ezberlemeniz beklenmiyor.
Bu döngü kaç kez çalışır?
Döngünün kaç tur döneceğini üç şey belirler: nereden başladığı, ne zaman duracağı ve her turda neyin değiştiği. Bu üçü birbirini tutmazsa döngü ya bir eksik ya bir fazla çalışır ya da hiç durmaz.
while: koşul doğru olduğu sürece tekrar et
En basit hâli şöyledir:
sayac = 1
while sayac <= 3:
print(sayac)
sayac = sayac + 1Programın çalışma sırası:
sayac <= 3koşulu kontrol edilir.- Koşul
Trueise döngü gövdesi çalışır. sayacbir artırılır.- Program yeniden
whilesatırına döner. - Koşul
Falseolduğunda döngü biter.
Program şunu yazdırır:
1
2
3
while koşulu her yinelemeden önce kontrol edilir. Bu nedenle başlangıçta koşul False ise döngü gövdesi hiç çalışmaz.
Tahmin et: döngü kaç kez çalışır?
Aşağıdaki kodu çalıştırmadan önce çıktı satırlarını tahmin edin:
Döngü gövdesi sayac değerleri 2, 4 ve 6 iken çalışır. sayac 8 olduğunda koşul False olur.
Yalnızca kaç satır yazdırıldığını saymayın. Her yinelemede şu üç şeye bakın:
- Döngü başındaki
sayacdeğeri - Koşulun sonucu
- Gövdenin sonunda
sayacın aldığı yeni değer
Kod izleme tablosu
Kısa döngülerde değişkenleri akılda tutabiliriz, ama döngü uzadıkça yanılmak kolaylaşır. O zaman bir kod izleme tablosu çizeriz: her satır bir yinelemeyi, her sütun bir değişkenin o andaki değerini gösterir.
Şu programı izleyelim:
sayac = 1
toplam = 0
while sayac <= 4:
toplam = toplam + sayac
sayac = sayac + 1
print(toplam)İzleme tablosu:
| Yineleme | Döngü başında sayac |
toplam sonrası |
Gövde sonunda sayac |
|---|---|---|---|
| 1 | 1 | 1 | 2 |
| 2 | 2 | 3 | 3 |
| 3 | 3 | 6 | 4 |
| 4 | 4 | 10 | 5 |
Sonraki kontrolde 5 <= 4 sonucu False olur ve döngü biter. Ekrana 10 yazdırılır.
Döngüde hata ararken yalnızca sonuca bakmayın. İlk birkaç yinelemede değişken değerlerini tabloya yazarsanız hatanın hangi adımda başladığını görürsünüz.
Sayaç neden güncellenir?
Sayaç, döngünün kaçıncı turda olduğunu gösterir. Döngünün bir gün durması şu satıra bağlıdır:
sayac = sayac + 1Bu satır olmasaydı sayac sürekli 1 kalır ve sayac <= 3 koşulu hep True olurdu.
İncele ve düzelt: sonsuz döngü
Aşağıdaki programdaki hata bilerek bırakıldı. Program 1, 2, 3 değerlerini yazdırıp durmalı.
Eksik sayaç güncellemesini ekleyin.
print(sayac) satırından sonra sayac = sayac + 1 ekleyebilirsiniz.
sayac = 1
while sayac <= 3:
print(sayac)
sayac = sayac + 1Bu sayfadaki hücrelerin bir süre sınırı var. Kendi bilgisayarınızda ise sonsuz döngü işlemciyi boş yere meşgul edebilir. Program terminalde (VS Code terminali dâhil) durmuyorsa Ctrl+C ile çalışan Python programını kesebilirsiniz. Python bu durumda çoğunlukla KeyboardInterrupt yazar. VS Code’un çalıştırma görünümündeki Stop düğmesi de aynı işi görür.
Döngü yazarken kendinize mutlaka sorun: “Bu koşulu bir gün False yapacak değişiklik nerede?” Ctrl+C koddaki hatayı düzeltmez, yalnızca yanlışlıkla başlattığınız programı durdurur.
off-by-one hatası
Döngünün istenenden bir kez fazla ya da bir kez az çalışmasına off-by-one hatası denir.
Örneğin 1’den 5’e kadar sayıları yazdırmak istiyoruz:
sayac = 1
while sayac < 5:
print(sayac)
sayac = sayac + 1Bu program 5 değerini yazdırmaz. Koşul sayac <= 5 olmalıdır.
Sınır değerlerini düşünmek burada da işe yarar:
- İlk çalışması gereken değer:
1 - Son çalışması gereken değer:
5 - İlk çalışmaması gereken değer:
6
Alıştırma: geri sayımı düzeltin
Amaç 5, 4, 3, 2, 1 değerlerini yazdırmaktır. Mevcut kod 1 değerini atlıyor.
Koşulu düzeltin.
> yerine >= kullanmayı düşünün.
sayac = 5
while sayac >= 1:
print(sayac)
sayac = sayac - 1Başlangıç değeri de sonucu etkiler
Döngünün koşulu doğru olsa bile başlangıç değeri yanlışsa sonuç yine hatalı olabilir.
sayac = 0
while sayac <= 5:
print(sayac)
sayac = sayac + 1Bu program 0’ı da yazdırır. 1–5 aralığını yazdırmak istiyorsak sorun koşulda değil, başlangıç değerindedir.
Bu yüzden sayaç döngülerinde üç parçayı birlikte kontrol edin:
başlangıç değeri → devam koşulu → güncelleme
Bunlardan biri yanlışsa döngü beklenenden farklı sayıda çalışabilir.
Değiştir: deneme hakkını izleyin
Bir giriş ekranının kullanıcıya en fazla 3 deneme hakkı verdiğini düşünelim. Burada parola sormuyoruz, yalnızca denemeleri sayıyoruz.
Şunları sırayla deneyin:
- En fazla
5deneme olacak biçimde değiştirin. - İlk satırda
Deneme: 0yazdıracak bir başlangıç değeri verin. Kaç satır yazdırıldığına bakın. - Koşulu
< 3yapın. Kaç deneme yazdırılacağını tahmin edin. - Her değişiklikte programı çalıştırmadan önce kaç yineleme olacağını yazın.
Hedefe ulaşana kadar değer biriktirmek
Döngüde yalnızca sayaç yazdırmayız. Her yinelemede başka bir değeri de güncelleyebiliriz.
Örneğin her hafta 250 TL biriktiren birinin 1000 TL’ye kaç haftada ulaştığını izleyelim:
Burada iki değişken değişir:
birikim: şimdiye kadar biriken parayı tutar.hafta: kaç yineleme yapıldığını sayar.
hafta bir sayaçtır: her turda 1 artar. birikim ise bir biriktiricidir (accumulator): her turda üstüne yeni bir değer eklenir ve biriken sonucu tutar.
Döngü birikim < 1000 koşulu False olduğunda biter.
Alıştırma: hedefe kaç günde ulaşılır?
Bir kişi her gün 1200 adım atıyor ve toplamda 6000 adıma ulaşmak istiyor. Programı, bu hedefe kaç günde ulaşılacağını hesaplayacak biçimde tamamlayın.
Gövde içinde iki güncelleme gerekir: toplam_adim = toplam_adim + 1200 ve gun = gun + 1.
toplam_adim = 0
gun = 0
while toplam_adim < 6000:
toplam_adim = toplam_adim + 1200
gun = gun + 1
print("Gün:", gun)
print("Toplam adım:", toplam_adim)Kullanıcı girdisini tekrar istemek
while ile kullanıcıya geçerli bir değer girene kadar yeniden sorabiliriz. Örneğin yalnızca 1–5 arasında puan kabul eden bir program:
puan = int(input("1-5 arasında puan: "))
while puan < 1 or puan > 5:
print("Geçersiz değer")
puan = int(input("1-5 arasında puan: "))
print("Kabul edilen puan:", puan)Bu örnekte ilk girdi geçerliyse döngü hiç çalışmaz. Geçersizse yeni değer alınır ve koşul yeniden sınanır.
Aynı input() satırı iki kez yazıldı: döngüden önce ve döngünün içinde. Öndeki satır, while koşulu ilk kez sınanırken puan değişkeninin bir değeri olsun diye var. Bu kalıp çok kullanılır ama aynı satırı iki kez yazmayı gerektirir.
Beşinci bölümde break öğrendiğimizde aynı problemi while True: ile tek bir input() satırı kullanarak yazabileceğiz: girdiyi al, geçerliyse döngüden çık, değilse yeniden dene. break henüz işlenmediği için bu hafta bu biçimi bilerek kullanıyoruz.
Bu hafta girdinin int() ile dönüştürülebilen bir sayı olduğunu varsayıyoruz. "abc" gibi sayıya çevrilemeyen girdileri istisnalar konusuna geldiğimizde ele alacağız.
Üret: cihaz şarjını hedefe ulaştırın
Bir cihazın şarjı başlangıçta %20 olsun. Her şarj adımında seviye 15 puan artsın. Şarj seviyesi en az %80 olduğunda döngü durmalı.
Aşağıdaki başlangıç kodunu tamamlayın:
Kabul kriterleri:
- Döngü
sarj < 80olduğu sürece çalışmalı. - Her yinelemede
sarjdeğeri15artmalı. adimdeğeri her yinelemede1artmalı.- Döngü sonunda
sarjen az80olmalı.
Döngü while sarj < 80: satırıyla başlar. Gövdede iki ayrı değişkeni güncelleyin.
sarj = 20
adim = 0
while sarj < 80:
sarj = sarj + 15
adim = adim + 1
print("Son şarj:", sarj)
print("Adım sayısı:", adim)Tek sayfa özet
Bu hafta bir işi, koşul doğru olduğu sürece while ile tekrarladık.
whilekoşulu her yinelemeden önce kontrol edilir.- Koşul başlangıçta
Falseise gövde hiç çalışmaz. - Sayaç, döngünün kaçıncı adımda olduğunu izlemek için kullanılabilir.
- Başlangıç değeri, devam koşulu ve güncelleme birlikte düşünülmelidir.
- Döngü koşulunu değiştirecek bir güncelleme yoksa sonsuz döngü oluşabilir; kendi bilgisayarınızda durmayan programı
Ctrl+Cile kesebilirsiniz. off-by-onehataları çoğunlukla sınırın koşula dâhil edilip edilmemesinden ya da yanlış başlangıç değerinden kaynaklanır.- Kod izleme tablosunda her yinelemede değişkenlerin nasıl değiştiği görülür.
- Döngüde sayacın yanında birikim ya da toplam gibi biriktiriciler ve başka değişkenler de güncellenebilir.
- Geçerli girdi gelene kadar sorma kalıbında
input()satırı iki kez yazılıyor;breaköğrendikten sonra bu tekrarı kaldıracağız.
Bir sonraki bölümde, kaç kez tekrar edileceği baştan belli olan işler için for ve range() kullanacağız. Sayaç, biriktirici, arama ve sayma gibi döngü kalıplarını da orada çalışacağız.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
whilekoşulunun her yinelemeden önce sınandığını gösterir.- Başlangıç değeri, devam koşulu ve güncellemeyi birlikte kurar.
- Güncellemesi eksik ya da yanlış yönde olan döngünün hiç bitmeyeceğini tanır.
- Kod izleme tablosuyla her yinelemedeki değişken değerlerini takip eder.
- Sınırın koşula dâhil edilip edilmemesinden doğan
off-by-onehatasını açıklar. - Sayaç ile biriktiriciyi birbirinden ayırır.