Bana kod yazmayı öğret baba – Bölüm 7
Türkçe’de kelimenin anlamını değiştiren eklere yapım eki, değiştirmeyenlere de çekim eki denir. Çekim eklerine bir örnek verir misiniz hocam? Tabii ki:
-(i)ken
Cümle içinde de kullanalım:
Hâl böyleyken.
Okula giderken.
Ben 3 yaşındayken.
Hocam bu cümleleri İngilizce’ye de çevirebilir misiniz?
While hâl is boyle.
While I am going to school.
While I was three years old.
Hocaya bak Türkçe başladı İngilizce devam ediyor. Bugünkü dersimizin konuğu, Türkçe’nin popüler çekim eki -(i)ken, yani ingilizcesi ve Python’da kullanılan haliyle “while” While’i Python’da tam olarak şu mantıkla kullanacağız:
while(bir koşul): koşul doğru "iken" burada kal
Kendisine kanlı canlı bir örnek verelim derhal. Unutanlar için compiler’ımız burada. Ne yapıyorduk? Kopyala, yapıştır ve de çalıştır.
x = 1 y = 0 print("while'a girmek uzereyiz. Kemerleri baglayin.") while(x < 10): x = x + 1 y = y + x print("while'in icindeyiz ve x=" +str(x) + ", y=" + str(y)) print("while'dan da sag ciktik. Hamdolsun.") print("x'in simdiki degeri: ", str(x))
Şu ana kadar hiç görmediğimiz bir şey yaşandı. Yazdığımız tek satır “print(“while’in icindeyiz ve x=” +str(x) + “, y=” + str(y))” satırı x’in değeri 10’a çıkana kadar 9 kere çalıştırıldı. Bu olayın mekaniklerine bir göz gezdirelim şimdi:
Burada ilk dikkatimizi çeken while’ın if’teki gibi yukarıda kırmızıyla gösterilen bir egemenlik alanı olduğu. Aynen if’te olduğu gibi gibi while’i bir koşul (boolean değişken) takip ediyor. Sonra da bir “:”. Hemen arkasından, bir alt satırda bir girinti seviyesi içeriden devam ediyoruz ki burada while’ın egemenlik alanı başlamış oluyor. If’te olduğu gibi bu girinti seviyesinde devam ettiğimiz sürece while’ın egemenlik alanı sürüyor ve normal girinti seviyesine döndüğümüz 8inci satırda artık while’ın egemenlik alanı bitmiş oluyor. Şimdi 4 ve 8’inci satırlar arasında compiler’imizin aklından geçenleri yazıya dökerek while’ın çalışma prensibini anlamaya çalışalım. Mikrofonlarıız Python’da:
4’üncü satıra geldim. Burada while ve içinde bir koşul var. x 10’dan küçük mü diye soruyor. x şu an 1’e eşit. Yani koşul doğru. O zaman while’ın egemenlik alanına girebilirim. Satır 5’e geldim. x’e 1 ekliyorum. x 2 oldu. Satır 6’ya geldim y’ye de x, yani 2 ekliyorum. O da 2 oldu. Satır 7’ye geldim, şu yazmam istenen string’i ekrana yazdım. Hooop burada while’ın egemenlik alanı bitmiş. O zaman ne yapıyorduk? while’ın başına, 4’üncü satıra dönüyorum. Koşulumuz x 10’dan küçük mü diye soruyor. x şu an 2’ye eşit. Yani koşul doğru. O zaman while’ın egemenlik alanına girebilirim. Satır 5’e geldim. x’e 1 ekliyorum. x 3 oldu. Satır 6’ya geldim, y’ye de x yani 3 ekliyorum. O da 5 oldu. Satır 7’ye geldim, şu yazmam istenen string’i ekrana yazdım. Hooop burada while’ın egemenlik alanı bitmiş. O zaman ne yapıyorduk? while’ın başına 4üncü satıra dönüyorum. Koşulumuz x 10’dan küçük mü diye soruyor…
Compiler’imiz takılmış bozuk plak gibi kendini tekrarlıyor adeta. Ama her defasında x ve y değerleri gitgide büyüyor. Yaşananlara bakacak olursak while’ın olduğu 4’üncü satırda yaşananlar aynen if’te yaşananlara benziyor. while içindeki koşul doğruysa kendisinin egemenlik alanına giriyoruz, doğru değilse oraya hiç girmeden 8’inci satırdan devam ediyoruz. İçeri girip devam ettiğimizde olaylar 7’nci satır tamamlandığında değişiyor ve gerisin geriye 4’üncü satıra dönüyoruz. Tekrar koşulun doğruluğuna bakıp içeri girip girmeyeceğimizi tespit ediyoruz. Bu parça kodda while yerine if olsaydı hiç böyle bir şey yapmadan 8’inci satırdan devam edecektik (bi’ deneyin hemen). while ise koşulu doğru olduğu sürece bizi kendi içine hapsedip her defasında başa döndürüyor. Bu döngüden ne zaman çıkıyoruz? Onun yaşandığı an için mikrofonumuzu tekrar Python’a uzatalım:
… Koşulumuz x 10’dan küçük mü diye soruyor. x şu an 9’a eşit. Yani koşul doğru. O zaman while’ın egemenlik alanına girebilirim. Satır 5’e geldim. x’e 1 ekliyorum. x 10 oldu. Satır 6’ya geldim y’ye de x yani 10 ekliyorum. O da 54 oldu. Satır 7’ye geldim, şu yazmam istenen string’i ekrana yazdım. Hooop burada while’ın egemenlik alanı bitmiş. O zaman ne yapıyorduk? while’ın başına 4üncü satıra dönüyorum. Koşulumuz x 10’dan küçük mü diye soruyor. x şu an 10’a eşit. Yani koşul doğru değil. Hele şükür. Bir while’ın daha sonuna geldik. Önümüzdeki while’larda görüşmek üzere dışarı çıkıp 8’inci satırdan devam ediyorum…
Artık x 10’a eşitlendiğinde while’ın koşulu yanlış oluyor ve kendisinin egemenlik alanına bu sefer girmiyoruz ve 8’inci satırdan devam ediyoruz.
While’ın mekaniklerine dikkatle bakacak olursak şöyle özetleyebiliriz. While’ın en başta belirlediği bir koşul var (x < 10). While’ın içinde yaptığımız işlemlerde bu koşulu kontrol eden x değişkenini değiştiriyoruz. x’i değiştire değiştire öyle bir noktaya getiriyoruz ki en sonunda while’ın koşulu doğru olmamaya başlıyor. İşte bu noktada while’i terk edip yolumuza devam ediyoruz. While döngüsünü kullanırken her zaman böyle bir mekanizma kullanmalıyız. Eğer kullanmazsak while’ın içine girip hiç çıkmamak da var bu yolun sonunda. Mesela yukarıdaki örnekte x=x+1 satırını kaldırırsak x program boyunca 1 olarak kalacak ve de while’ın içinden sonsuza dek çıkamayacağız (lütfen evde denemeyiniz). İşbu duruma programlama literatüründe sonsuz döngü (infinite loop) denmektedir.
Şimdi bir düşünün bakalım, while kullanarak ne kadar enteresan şeyler kodlayabilirsiniz. Merak etmeyin, ben vereceğim ödevlerle hemen bu konudaki hayal gücünüzü güçlendireceğim.
Ödevlere başlamadan bir not. Bu ders ödev bombardımanına uğratacağız sizleri. Çünkü while gibi döngüler programlama dillerinin en temelinde yatan, öğrenilmesi ve iyice anlaşılması epey kritik olan şeyler. Ayrıca unutmadan tekrar belirtelim. Hiçbir ödevin tek bir çözümü yok. Aynı algoritmayı pek çok farklı şekilde kodlayabilirsiniz. Şu an itibariyle yazdığınız kodun kısa/uzun, hızlı/yavaş olmasının çok bir önemi yok. Tek önemli olan kıstas, doğru çalışması.
Ödev 7.1: Ekrana 478 kere “Naber la?” yazan bir kod yazın.
Ödev 7.2: Kullanıcıdan bir sayı girmesini isteyen, sayıyı girdikten sonra ekrana girdiği sayı kadar “Naber la?” yazan bir kod yazın.
Ödev 7.3: Kullanıcıdan bir sayı girmesini isteyen, sayıyı girdikten sonra o sayıya kadar 3’er 3’er sayıp ekrana saydığı sayıları yazan bir kod yazın.
Ödev 7.4: Kullanıcıdan bir sayı girmesini isteyen, sayıyı girdikten sonra o sayıdan 0’a kadar geriye 5’er 5’er sayıp ekrana saydığı sayıları yazan bir kod yazın.
Ödev 7.5: Kullanıcıdan bir sayı girmesini isteyen, sayıyı girdikten sonra o sayıdan küçük tüm tam sayıları toplayıp ekrana yazan bir kod yazın.
Ödev 7.6: Kullanıcıdan bir sayı girmesini isteyen, sayıyı girdikten sonra o sayıdan ve de 38’den küçük tüm tek sayıları toplayıp ekrana yazan bir kod yazın.
Bu arada while’ın dışına çıkmanın tek yolu en baştaki koşulun yanlış olması değil. “Kır zincirlerini” tadında bir yöntemimiz daha var: “break”
x = 1
y = 0
print("while'a girmek uzereyiz. Kemerleri baglayin.")
while(x < 10):
x = x + 1
y = y + x
print("while'in icindeyiz ve x=" +str(x) + ", y=" + str(y))
if x == 6:
break
print("while'dan da sag ciktik. Hamdolsun.")
print("x'in simdiki degeri: ", str(x))
Görüldüğü üzere bu örnekte break yani kır komutunun kırdığı şey “döngü.” Kendisi adeta “döngüyü kır ve dışarı çık” diyor. Yazdığınız döngüleri kontrol etmenin muhteşem bir yolu daha. Peki yukarıdaki örneği bir koşul girmeden sadece break ile kontrol ederek yazabilir miydik? Neden olmasın?
x = 1 y = 0 print("while'a girmek uzereyiz. Kemerleri baglayin.") while(True): x = x + 1 y = y + x print("while'in icindeyiz ve x=" +str(x) + ", y=" + str(y)) if x == 10: break print("while'dan da sag ciktik. Hamdolsun.") print("x'in simdiki degeri: ", str(x))
Çok seksi olmadı mı ya? Sizi bilemem ama bence oldu. Koşul kullanmadık diyoruz ama aslında kullanıyoruz. “True,” hatırlayanlarımız olacaktır her zaman doğru bir boolean. While’ın istediği de koşul olarak bir boolean zaten. While(True) yüzünden hiç bir zaman While’ın içindeki koşulu kullanarak döngüyü kırıp dışarı çıkamayacağız. Döngüyü kırmamızı ise “break” sağlayacak ve bunu da yine benzer bir şekilde if(x==10) diyerek x 10’a ulaştığında gerçekleştiriyoruz. Yani aynı mantığı farklı bir şekilde harekete geçiriyoruz.
Ezberciliğe kaymak hiç istemem ama aslında burada şöyle güzel bir yapı yakaladık:
while(True): burada tekrarlanması gereken bir takım komutlar if(tekrarlanan komutların ne zaman bitmesi gerektiğini söyleyen koşul): break
Eh, bunu bir ödevde kullanmanın zamanı gelmiş o zaman:
Ödev 7.7: Kullanıcıdan 100 ve 200 arasında bir sayı gimesini isteyin. Küçük bir sayı girdiği sürece, “bu sayı 100’den küçük,” büyük bir sayı girdiği sürece de “bu sayı 200’den büyük” diyerek istenen sayı girilene kadar tekrar tekrar soran bir program yazın. Ayrıca, program biterken kullanıcının toplamda kaç tane sayı girdiğini yazsın.
Şimdi gelelim sadede. Geçen derste neden o kadar algoritma geyiği yaptık? Çünkü while ile kodlayabileceğiniz hemen hemen her şey aslında basit birer algoritma ve de şimdi geçen ders algoritmasını yazdığımız problemleri Python’da hayata geçireceğiz. En basittinden başlayalım mı, ne dersiniz?
Problem: Bir sayının tek veya çift olduğunu tespit etmek.
Pseudo-code:
- Adım 1: Elindeki sayıyı al, 2 çıkar. Adım 2’ye git.
- Adım 2: Yeni bulduğun sayı 2’den küçük mü? Evetse Adım 3’e git. Yoksa Adım 1’e dön.
- Adım 3: Dur. Son bulduğun sayı 1’se tek, 0’sa sayımız çift.
Adım adım yukarıdaki yazdığımız pseudo-code’u bir hayata geçirelim. Öncelikle kullanıcıdan bir sayı isteyelim ve o sayıyı integer’a çevirelim her zaman yaptığımız gibi:
sayi = input("Bir sayi giriniz lutfen:") sayi = int(sayi)
An itibariyle kullanıcının girdiği sayıyı “sayı” diye bir integer değişkene kaydettik. Pseudo-code’umuza başlayabiliriz. Pseudo-code’umuza bakarsak şöyle bir yapıyla karşılaşıyoruz: Elimizde bir sayı var. Bu sayı 2’den küçük kalana kadar devamlı kendisinden 2 çıkartıyoruz. Bu az önce yaptığımız while loop’una benzemiyor mu? Onda da x değişkeni 10’a ulaşana kadar devamlı kendisine 1 ekliyorduk. O zaman şöyle devam edelim:
while(True): sayi = sayi - 2 if sayi < 2: break
Veya biraz daha kısa ve öz olsun diyorsanız böyle.
while(sayi > 1): sayi = sayi - 2
İlk yazdığımız koda bakarsak:
- Adım 1: “sayı = sayı – 2” komutu
- Adım 2: “if sayı < 2” koşulu. Bu if her zaman olduğu gibi trafik polisliği görevini üstlenip kodumuzu eğer koşul doğruysa if’in içine yani Adım 3’e, eğer değilse if’in dışına ve de dolayısıyla while(True) loopunun başına yani Adım 1’e yönlendiriyor.
- Adım 3: “break” komutu.
Tek bir eksiğimiz kaldı. Son olarak dışarıda kendini break’ten sonra while dışına atmış “sayı” değişkenine bakıp ilk girilen sayımızın tek mi çift mi olduğunu anlamak. Onu da halledelim:
if sayi == 1: print("Girdiginiz sayi tek") else: print("Girdiginiz sayi cift")
Böylelikle yazdığımız kodun tamamı işte böyle bir şey olmalı:
sayi = input("Bir sayi giriniz lutfen:") sayi = int(sayi) while(True): sayi = sayi - 2 if sayi < 2: break if sayi == 1: print("Girdiginiz sayi tek") else: print("Girdiginiz sayi cift")
Bi deneyin bakalım çalışıyor mu? Çalışıyorsa buyurun ödevimize:
Ödev 7.8: Yukarıdaki kodu öyle bir düzenleyin ki sonuçta “Girdiğiniz sayı [buraya ilk girilen sayı gelecek] çift/tek” yazsın.
Ödev 7.9: Kullanıcıdan iki sayı girmesini isteyen ve yukarıdaki gibi ilk girdiği sayının ikincisinden kalanını hesaplayan bir kod yazın.
While konusunu kapatmadan bir de geçen derste yazdığımız bir algoritmayı daha Python’a çevirelim. Pseudo-code’un nasıl Python’a koduna dönüştüğünü görmek için renklere dikkat edin.
Problem: Verilen bir sayının 1000’den küçük en büyük tam sayı katını bulmak. Sayının 1000’den küçük olduğunu varsayalım.
Pseudo-code:
- Adım 1: Verilen sayıyı kaydet. Çarpım sayısını 1’e eşitle.
- Adım 2: Çarpım sayısını 1 artır.
- Adım 3: Verilen sayıyı çarpım sayısıyla çarp. Sonucu kaydet. Sonuç 1000’den büyükse Adım 4’e git. Değilse Adım 2’ye git.
- Adım 4: Cevap en son kaydettiğin sayı.
Python’da ise:
verilen_sayi = input("Bir sayi giriniz lutfen:") verilen_sayi = int(verilen_sayi) carpim_sayisi = 1 while(True): carpim_sayisi = carpim_sayisi + 1 sonuc = carpim_sayisi * verilen_sayi if sonuc > 1000: break print("Cevab: " + str(sonuc))
Yanlış hatırlamıyorsam bu pseudo-code’da ufak bir hata vardı. O yüzden kodumuzun da yanlış sonuç vermesi lazım dostlar. Bunu düzeltmek bir sonraki ilk ödevimiz olacak ama yazdığımız kodda pseudo-code’u nasıl bire bir kopyaladığımızı dikkatle izleyin. çarpım sayısı’nı çarpım_sayısı diye bir değişken yaptık. sonuç’u sonuc diye bir değişkenin içine kaydettik ve de işlemleri teker teker uyguladık. İşte bu yüzden önce algoritma -> pseudo-code ve sonra kod diyoruz. İzlememiz gereken yol aynen böyle olmalı.
While konusunu kapatmadan önce bir de yazdığınız kodu test etmenin önemine değinelim. Sevgili dostlar, kod yazarken lütfen korkmayın çekinmeyin, adım adım neleri hesapladığınızı gerekirse yazın. Mesela:
verilen_sayi = input("Bir sayi giriniz lutfen:") verilen_sayi = int(verilen_sayi) carpim_sayisi = 1 while(True): carpim_sayisi = carpim_sayisi + 1 sonuc = carpim_sayisi * verilen_sayi print("an itibariyle carpim sayisi:" + str(carpim_sayisi) + " sonuc: " + str(sonuc)) if sonuc > 1000: print("iste sonuc 1000'den buyuk cikti:" + str(sonuc)) break print("Cevab: " + str(sonuc))
Yani elinizi korkak alıştırmayın. Kodunuzu doğru çalıştığına emin olana kadar print falan kullanın sonuçları an be an yazdırın. Bu hem kodunuzu test etmenizi hem de yazdıklarınız daha iyi anlamanızı sağlayacaktır. İleride büyük bir coder olursanız birer debugger kullanarak daha güzel test yöntemleri kullanabilirsiniz ama şu an için böyle idare edin.
Bu bölümü kapatmadan sizleri bir takım ödev bombardımanına tabi tutacağız. Üstelik bunu, üşengeçlik yapıp geçen derste verilen ödevlerden araklayarak yapacağız. Bir sonraki derste görüşmek üzere! Bu arada ödevleri aksatmayın lütfen!
Ödev 7.10: Yukarıdaki kodu düzelterek algoritmanın doğru cevabı bulmasını sağlayın.
Ödev 7.11: Kullanıcının girdiği bir x sayısının tam kare bir sayı olup olmadığını tespit eden bir algoritmanın kodunu yazın.
Ödev 7.12: Ödev 7.7’de programınıza ayrıca kullanıcının girdiği tüm sayılardan en büyüğünü bularak “Şu ana kadar girdiğiniz en büyük sayı: ” şeklinde ekrana yazdırın.
Ödev 6.1 çözüm:
- Adım 3: Verilen sayıyı çarpım sayısıyla çarp. Sonuç 1000’den küçükse kaydet. Sonuç 1000’den büyükse Adım 4’e git. Değilse Adım 2’ye git.
Ödev 6.2 çözüm:
- Adım 1: y’nin değerini 1’e eşitle.
- Adım 2: y’nin karesi x’ten büyükse cevap hayır, x’e eşitse cevap evet, x’ten küçükse Adım 3’e git.
- Adım 3: y’yi 1 artır. Adım 2’ye git.
Ödev 6.3 çözüm:
- Adım 1: Verilen kelimenin ilk sesli harfini bul. Bu sesli harf a, i, o, u ise kelime tipi değişkenini “kalın”a, değilse “ince”ye eşitle.
- Adım 2: Kelimenin bir sonraki sesli harfine git. O harf a, i, o, u ise ve kelime tipi “ince”yse dur. Cevap büyük ünlü uyumuna uygun değil. O harf a, i, o, u değilse ve kelime tipi “kalın”sa dur. Cevap büyük ünlü uyumuna uygun değil. Diğer koşullarda Adım 3’e git.
- Adım 3: Kelimede başka sesli harf kalmadıysa cevap “büyük ünlü uyumuna uygun.” Kaldıysa Adım 2’ye git.
Ödev 6.4 çözüm:
- Adım 1: Bölme sayısını 2’ye eşitle.
- Adım 2: Elinizdeki sayı bölme sayısına tam bölünebiliyorsa cevap: hayır asal değil. Bölünemiyorsa Adım 3’e git.
- Adım 3: Bölme sayısını 1 artır. Bölme sayısı elimizdeki sayıdan küçükse Adım 2’ye git, eğer elimizdeki sayıya eşitse dur. Cevap: evet asal.
Ödev 6.5 çözüm:
-
- Adım 1: Şu anki hızı 7’ye, geçen zamanı 0’a, koşulan yolu da 0’a eşitleyin.
-
- Adım 2: Koşulan yol’a 0.1 (km’ye çeviriyoruz dikkat) eklediğinizde x’i geçiyorsanız durun (demek ki bu hızda x km’ye ulaşıyoruz, şimdi zaman hesabını yapmak lazım). (x – koşulan yol)/şu anki hız denklemini kullanarak bu hızda koşmanız gereken kalan süreyi bulun ve buna, geçen zamanı ekleyin. Cevabı buldunuz. Koşulan yol’a 0.1 eklediğinizde x’i geçmiyorsanız Adım 3’e gidin.
- Adım 3: Koşulan yolu 0.1 artırın. Geçen zamanı 0.1/şu anki hız kadar artırın ve şu anki hızı 0.1 artırın. Adım 2’ye gidin.
Hafız Lakyab
Yazar: Hafız Lakyab (tümünü gör)
- Dev Kütleli Bir Kara Deliğin Olması Gereken Yer, Galaksisinin Merkezi midir? - 17 Eylül 2019
- Bana kod yazmayı öğret baba – Bölüm 9 - 10 Mart 2019
- Bana kod yazmayı öğret baba – Bölüm 8 - 24 Şubat 2019
- Bana kod yazmayı öğret baba – Bölüm 7 - 10 Şubat 2019
- Bana kod yazmayı öğret baba – Bölüm 6 - 27 Ocak 2019