Koşullar, döngüler ve string işlemleri

C’de kullandığınız if yapısını ve döngüleri bu hafta Python’da yazacağız. Bu kavramları baştan anlatmayacağız, Python’da nerede farklı yazıldıklarına bakacağız. Python’da bir listenin ya da bir metnin elemanlarını sayaç tutmadan sırayla dolaşabilirsiniz. Bölümün ikinci yarısında metinlerle, yani string’lerle çalışacağız: bir metin satırını parçalara ayıracak, parçaları yeniden birleştireceğiz. Python’da metnin türü str’dir.

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ı

NoteSınavda sorulur
  • if / elif / else zincirinde sınır değerinin hangi dala düştüğü
  • Bir listenin ya da metnin elemanları üzerinde doğrudan dolaşma; enumerate() ve zip()
  • range() bitişinin dışarıda kalması ve adım parametresi
  • while döngüsünde koşuldaki değeri değiştiren adım
  • break ile continue farkı
  • String’de indeksleme ve dilimleme: text[1:5], text[::2], text[::-1]
  • String’in değiştirilemez olması
  • strip(), split() ve join() ile bir metin kaydını parçalara ayırma ve birleştirme
  • lower() / upper() dönüşümünün Türkçe I / İ sınırı
  • Unicode normalleştirme biçimleri ve yerel ayar (locale) kütüphaneleri
  • Düzenli ifadeler (regular expressions)
  • Liste kavraması (list comprehension)

Bu başlıklar konunun devamıdır. İleride karşınıza çıkar, ama bu derste ezberlemeniz beklenmiyor.

Bu C döngüsü Python’da nasıl yazılır?

Programlama Temelleri’nde buna benzer döngüler yazdınız. Program bir dizideki notları sırayla okuyor, her öğrencinin harf notunu yazıyor ve kaç öğrenciyi değerlendirdiğini sayıyor. Dizide 0 sınava girmeyen öğrenciyi, -1 ise verinin bittiğini gösteriyor:

#include <stdio.h>

int main(void) {
    int scores[] = {85, 70, 0, 64, -1, 90};
    int count = 0;

    for (int i = 0; scores[i] != -1; i++) {
        if (scores[i] == 0) {
            continue;  // sınava girmedi
        }
        if (scores[i] >= 85) {
            printf("%d. öğrenci: AA\n", i + 1);
        } else if (scores[i] >= 70) {
            printf("%d. öğrenci: BB\n", i + 1);
        } else {
            printf("%d. öğrenci: kaldı\n", i + 1);
        }
        count++;
    }
    printf("Değerlendirilen: %d\n", count);
    return 0;
}

Bu program ne yazar? Üçüncü öğrenci için bir satır çıkar mı, 90 notuna sıra gelir mi? Önce tahmin edin, sonra çıktıyı açın.

1. öğrenci: AA
2. öğrenci: BB
4. öğrenci: kaldı
Değerlendirilen: 3

Bu programı Python’a çevirdiğinizi düşünün. i sayacı Python’da da gerekir mi? -1 kontrolü yine döngünün koşulunda mı durur? Hangi satırlar kısalır, hangileri başka bir yapıya dönüşür? Okumaya devam etmeden önce aklınıza gelenleri bir kenara yazın.

Bir fark daha var. Gerçek bir programda bu notlar bir dosyadan 85,70,0,64,-1,90 gibi tek bir metin satırı olarak gelir. C’de bu satırı sayılara ayırmak için strtok() ve atoi() gibi fonksiyonlarla uğraşırdınız. Örneği kısa tutmak için notları diziye biz yazdık. Python’da satırı parçalamak iki metotla biter.

Bölüm bu soruların cevabını sırayla veriyor. Sonunda programın Python hâlini birlikte okuyacağız, notları da metin satırından alacağız.

if: parantez ve süslü parantez yok

Aşağıdaki hücre bir notu harf notuna çeviriyor. Hücrede score değeri 72. Hangi sonuç yazılır?

Python’da koşulun sonuna : gelir, bloğu girinti belirler. else if yerine elif yazılır.

Zincirdeki koşullar yukarıdan aşağı sırayla sınanır. İlk doğru koşulun bloğu çalışır, zincirin geri kalanına hiç bakılmaz. Aynı koşulları ayrı ayrı if satırlarıyla yazsaydınız her if kendi başına sınanırdı ve birden çok blok çalışabilirdi.

Sınır değerini düşünün

score = 70 için sonuç ne olur? 69 için ne olur? Önce tahmin edin, sonra hücredeki değeri değiştirip yeniden çalıştırın. İkinci koşulda >= yerine > yazılsaydı 70 hangi dala düşerdi? Bunu da hücrede deneyebilirsiniz. Koşul zincirini sınarken sınır değerini ve iki yanındaki değerleri (69, 70, 71) ayrıca deneyin. Doğru görünen koddaki hatalar çoğu zaman bu değerlerde ortaya çıkar.

Liste: birden çok değeri sırayla tutmak

Bu bölümün örneklerinde köşeli parantez içinde yazılmış değerler göreceksiniz, [80, 95, 70] gibi. Bu bir listedir (list). Liste, birden çok değeri sırayla tutan bir Python değeridir ve C’deki diziye benzer. Elemanlara 0’dan başlayan indeksle ulaşırsınız, len() eleman sayısını verir. C dizisinden iki farkı var: boyutu baştan yazmazsınız ve append() metoduyla listenin sonuna yeni eleman ekleyebilirsiniz.

Hücrenin son iki satırı ne yazar?

Bu hafta listeyi iki yerde kullanacağız: for ile elemanlarını dolaşırken ve split() metodunun döndürdüğü değer olarak. Listenin öteki işlemlerini ve iki adın aynı listeyi gösterdiği durumları gelecek hafta göreceğiz.

for: sayaç tutmadan dolaşmak

C’de bir diziyi ya da metni dolaşırken bir indeks değişkeni tutardınız. Python’da for elemanları sırayla kendisi verir:

İndeksle dolaşma ile bir dizinin değerlerini for döngüsüyle doğrudan dolaşmayı karşılaştıran diyagram.

Değer üzerinde doğrudan dolaşma

Bu kodda letter her turda sıradaki karakteri alır. İndeks gerekmediği için sayaç tutmuyoruz.

İndeks gerçekten gerekiyorsa range(len(word)) ile indeksleri dolaşıp her turda word[i] yazabilirsiniz. Hem indeks hem değer gerektiğinde ise enumerate() daha kısa bir yoldur. enumerate() her turda iki değer verir: sıra numarasını ve elemanı. İlk satırda sıra numarası 0 mı olur, 1 mi?

for index, letter in yazımı her turdaki iki değeri iki ayrı ada bağlar.

İki listeyi aynı anda dolaşmak için zip() kullanılır. zip() her turda iki listeden aynı sıradaki elemanları alıp eşler:

zip(), listelerden en kısası bitince durur ve hata vermez. Uzunlukların eşit olması gerekiyorsa bunu ayrıca kontrol etmelisiniz.

range() son değeri içermez

range fonksiyonunda bitiş değerinin aralığa dâhil edilmediğini gösteren sınır diyagramı.

range() sınırı

range(start, stop, step) en çok üç değer alır: başlangıç, bitiş ve adım. Tek değer verirseniz başlangıç 0, adım 1 olur. Geriye saymak için adım negatif verilir. Hücredeki üç satırın her biri hangi sayıları yazar? En çok üçüncü satır üzerinde düşünün:

Bitiş değeri hiçbir satırda listeye girmez, tıpkı C’deki for (i = 0; i < 5; i++) döngüsünde 5’in girmediği gibi. Geriye sayarken de bitiş dışarıda kalır. Hücredeki list() yalnız sayıları ekranda görmek için var, for içinde gerekmez.

Aşağıdaki döngü 10’dan geriye sayar. Son satırda hangi sayı yazar?

Adımın yönü başlangıçtan bitişe giden yönle uyuşmazsa aralık boş kalır: range(1, 5, -1) hiç sayı vermez. Emin değilseniz küçük bir list(range(...)) denemesiyle bakın.

while: koşula bağlı tekrar

Tekrar sayısı baştan belli değilse while kullanılır. Döngü, koşul doğru olduğu sürece döner. Hücre kaç satır yazar, son satırda kalan bakiye kaç olur?

while kullanırken üç soruyu sorun:

  1. Döngü başlarken koşuldaki değişkenlerin değeri ne?
  2. Her turda hangi değer değişiyor?
  3. Bu değişiklikle döngüyü bitirecek koşul gerçekten oluşabilir mi?

Bu sorulardan birinin cevabı belli değilse döngü hiç bitmeyebilir. Buna sonsuz döngü denir.

break ve continue

break, içinde bulunduğu en yakın döngüyü hemen bitirir. continue ise o turun kalanını atlayıp sonraki tura geçer. Hücre hangi sayıları yazdırır?

Bu örnekte -1, verinin bittiğini bildiren bir işaret değeri (sentinel) gibi döngüyü bitirir. C’de “-1 girilene kadar oku” diye yazdığınız döngüler bu kalıptır. continue satırı bu listede hiç çalıştı mı? -1’i listenin sonuna taşıyıp hücreyi yeniden çalıştırın. break ve continue’yu her yerde kullanmayın. Kodun amacını daha açık gösterdikleri yerde işe yararlar.

String bir karakter dizisidir

Bir string’in tek bir karakterine, listede olduğu gibi, 0’dan başlayan indeksle erişirsiniz. Python’da negatif indeks de vardır ve sondan sayar: -1 son karakter, -2 sondan ikinci karakterdir. C’de -1 indeksi dizinin dışına taşardı. "Python" metninin indeksleri şöyle:

  P   y   t   h   o   n
  0   1   2   3   4   5
 -6  -5  -4  -3  -2  -1

word = "Python" için word[0] P, word[-1] ise n karakteridir. İndeks metnin dışına çıkarsa, örneğin word[6] yazarsanız, IndexError alırsınız.

Dilimleme: metnin bir parçasını almak

Köşeli parantezin içine iki nokta koyarsanız tek bir karakter yerine metnin bir parçasını alırsınız. Buna dilimleme (slicing) denir. word[başlangıç:bitiş] yazımı range() gibi çalışır: başlangıç dâhil, bitiş hariç. Başlangıcı yazmazsanız metnin başından, bitişi yazmazsanız metnin sonuna kadar alınır.

Yukarıdaki indeks tablosuna bakın. Hücredeki dört satır ne yazar?

Dilimin de range() gibi üçüncü bir değeri var: adım. word[başlangıç:bitiş:adım] yazımında adım 2 ise bir karakter alınır, bir karakter atlanır. Adım negatifse dilim sondan başa doğru ilerler. Başlangıç ve bitiş boş kalırsa bütün metin dolaşılır. Bu üç satır ne yazar?

Tersten okunuşu kendisiyle aynı olan sözcüğe palindrom denir, kek ve ses gibi. Hücreye print(word == word[::-1]) satırını ekleyin, word değerini önce "kek", sonra "kel" yapıp çalıştırın.

Tek indeks metnin dışına çıkınca hata verir. Dilimin sınırı metnin dışına çıkarsa ne olur? Önce tahmin edin:

Dilim, metnin dışına taşan sınırı metnin ucunda keser ve hata vermez. Alınacak karakter kalmazsa boş bir string döndürür. Tek indeks ise metnin içinde olmak zorundadır.

Dilim de yeni bir string döndürür, word değişmez. Dilimleme listelerde de aynı biçimde çalışır: scores[1:] ilk eleman dışındaki elemanlarla yeni bir liste döndürür.

String metotları yeni bir string döndürür

String’lerin hazır metotları da vardır. Metot, bir değerin arkasına nokta koyup çağırdığınız fonksiyondur, text.strip() gibi. Aşağıdaki metnin başında ve sonunda ikişer boşluk var. Son satır ne yazar?

String değiştirilemez (immutable): oluşturulduktan sonra içindeki karakterler değişmez. text[0] = "P" yazarsanız TypeError alırsınız. text.upper() de var olan string’i değiştirmez, büyük harfli yeni bir string döndürür. Bunu bilerek tahmin edin: hücredeki iki print() ne yazar?

İkinci satırdaki text.upper() yeni bir string döndürür, ama hücre bu değeri hiçbir ada bağlamıyor. Sonucu saklamak için dördüncü satırdaki gibi text = text.upper() yazılır.

Listelerde durum farklı. Liste bölümündeki append() yeni bir liste döndürmedi, var olan listeyi değiştirdi, çünkü listeler değiştirilebilir. Bu farkı ve iki adın aynı listeyi gösterdiği durumları gelecek hafta göreceğiz.

Sık kullanılan string araçları

Araç Ne yapar Örnek
strip() baştaki ve sondaki boşlukları, satır sonunu siler " a \n".strip()
split(sep) metni sep geçen yerlerden böler, parçaları liste olarak döndürür "Ada,80".split(",")
split() ayırıcı verilmezse metni boşluklardan böler "bir iki üç".split()
sep.join(parts) parçaları aralarına sep koyarak birleştirir ", ".join(names)
replace(a, b) a geçen her yere b koyar text.replace("-", " ")
startswith(prefix) metnin verilen parçayla başlayıp başlamadığına bakar name.startswith("A")
in bir parçanın metinde geçip geçmediğine bakar "py" in "python"

Bir satırı parçalayın, sonra birleştirin

Dosyadan okunan bir satırın başında ya da sonunda çoğu zaman boşluk, en sonunda da satır sonu karakteri (\n) bulunur. Satırı önce strip() ile temizler, sonra split() ile bölersiniz. Çalıştırmadan önce düşünün: listedeki 80 bir sayı mı olur, metin mi?

line.strip().split(",") satırında önce strip() çalışır, split() temizlenmiş metni böler. Parçalar yine metindir: '80' bir sayı değil, iki karakterlik bir string. Hesap yapacaksanız int() ile çevirirsiniz. join() ters yönde çalışır ve listedeki parçaları aralarına " | " koyarak tek bir metinde birleştirir. join() ayırıcının metodudur, bu yüzden ayırıcı başta yazılır.

5. haftada dosyadan okunan satırları parçalarken strip() ve split()’i sık kullanacağız.

Türkçede büyük ve küçük harf dönüşümü (sınav dışı)

Python’ın lower() ve upper() metotları Unicode kurallarına göre çalışır. Unicode, dünyadaki bütün harflerin bilgisayarda nasıl tutulacağını belirleyen standarttır. Bu metotlar Türkçeye özgü yerel ayar (locale) kurallarını uygulamaz. Bu yüzden I ile ı ve İ ile i çiftlerinde Türkçede beklediğiniz sonucu alamazsınız. Üç satırın Türkçeye göre ne yazması gerekir? Çalıştırıp karşılaştırın:

"I".lower(), ı yerine i verir. "i".upper(), İ yerine I verir. "İ".lower() ise i harfinin üstüne ayrı bir nokta işareti ekler. Sonuç ekranda i gibi görünse de iki karakterdir. Bunu görmek için hücreye print(len("İ".lower())) satırını ekleyin.

Türkçe metinleri büyük ve küçük harf ayrımı yapmadan karşılaştırırken lower() çağrısının her durumu çözdüğünü varsaymayın. Bu derste ayrıntıya girmeyeceğiz. Böyle bir sorunun var olduğunu bilmeniz yeter.

Açılıştaki döngünün Python hâli

Bölümün başındaki program Python’da şöyle yazılır. Notlar bu kez bir metin satırından geliyor:

Çalıştırın ve çıktıyı açılıştaki C programının çıktısıyla karşılaştırın. Kodda değişen yerler şunlar:

  • i sayacı yok. enumerate() her turda sıra numarasını ve parçayı birlikte verir. Sıra numarası 0’dan başladığı için ekrana index + 1 yazılır.
  • -1 kontrolü döngünün koşulundan çıkıp gövdeye girdi. for satırı bir koşul almaz, verinin sonuna kadar dolaşır. -1’de durmak için break gerekir, sonraki 90’a sıra gelmez.
  • continue C’deki gibi çalışır ve sınava girmeyen öğrencinin turunu atlar.
  • else if yerine elif yazılır. 70, score >= 70 dalına düşer ve BB alır.
  • count++ yerine count += 1 yazılır.
  • Dizi yok. line.strip().split(",") satırı temizler ve virgüllerden böler. Parçalar metin olduğu için her biri int() ile sayıya çevrilir.

Bölümün başında yazdığınız listeyle karşılaştırın. C kodunu satır satır çevirmek yerine işin Python’da nasıl yazıldığına bakın. İndekse ihtiyacınız yoksa değerleri doğrudan dolaşın, hem indeks hem değer gerekiyorsa enumerate() kullanın.

Alıştırma: Koşulu tamamla

Bir kullanıcı adı en az 5 karakter olmalı ve boşluk içermemelidir. Boşluğa bir ifade yazın: iki koşul da sağlanıyorsa valid True, sağlanmıyorsa False olsun. Sonra username değerini "ece" ve "emre can" yapıp yeniden çalıştırın.

len(username) >= 5 ile " " not in username ifadelerini and ile birleştirebilirsiniz.

valid = len(username) >= 5 and " " not in username

Alıştırma: Doğrudan dolaşarak sayma

Aşağıdaki kod bir metindeki a harflerini sayıyor. Çalıştırmadan önce sonucu tahmin edin.

count bir sayaç, ama indeks tutmuyor. Kaç tane a bulduğumuzu sayıyor, karakterleri ise for kendisi veriyor. Sonra şunları deneyin:

  1. Kodu büyük ve küçük harfi ayırmadan sayacak biçimde değiştirin. "Ankara" için sonuç 3 olmalı.
  2. text değerini "Iğdır" ve "İzmir" yapın, print(text.lower()) ile ne çıktığına bakın.
  3. Bu yöntemin Türkçe metinlerde neden her zaman doğru sonuç vermediğini bir cümleyle açıklayın.

Alıştırma: Off-by-one hatasını düzelt

Aşağıdaki program 1’den 10’a kadar sayıların toplamını hesaplamalı, ama sonuç eksik çıkıyor. Bu tür hataya off-by-one hatası denir: sınır bir eksik ya da bir fazla alınmıştır.

Neden 10 işlenmiyor? Yalnızca tek bir değeri değiştirerek düzeltin. Doğru toplam 55’tir.

Alıştırma: while döngüsünü güvenli hâle getir

Aşağıdaki kod yanlış tahminleri sayıyor ve üçüncü denemede duruyor. Önce çalıştırın.

Sonra şu iki soruyu cevaplayın:

  1. break satırını silerseniz ne olur? Koşuldaki hangi değer döngü içinde hiç değişmiyor?
  2. Aynı sınırı break kullanmadan nasıl koyarsınız? while satırındaki koşula and ile attempts < 3 ekleyin, if ve break satırlarını silin.

İkinci değişikliği hücrede deneyin, çıktı yine üç satır olmalı. Birinci soruyu hücrede denemeyin, çalıştırmadan cevaplayın. Sonsuz döngü durmadan yazdırır ve sayfayı yenilemeniz gerekebilir.

Sıra sizde: Metin özeti

Bir metnin aşağıdaki bilgilerini yazdıran bir program yazın:

  • Toplam karakter sayısı
  • Boşluk sayısı
  • Sesli harf sayısı (bir karakterin sesli harf olup olmadığına ch in "aeıioöuüAEIİOÖUÜ" ile bakabilirsiniz)
  • split() ile kelime sayısı
  • İlk boşluğun indeksi (enumerate() ile dolaşın, ilk boşlukta break ile durun, boşluk yoksa bunu yazdırın)
  • strip() ile baştaki ve sondaki boşluklar temizlendikten sonra ilk ve son karakter

Metni bir değişkene yazın, input() kullanmanız gerekmez. Programda en az bir for, bir if, bir enumerate() ve iki farklı string metodu bulunsun.

Warning

Temizlenmiş metin boşsa text[0] veya text[-1] yazmak IndexError verir. Yalnızca boşluklardan oluşan bir metin de strip() sonrasında boş kalır. İlk ve son karaktere erişmeden önce metnin boş olup olmadığını kontrol edin.

Çalışır kod görevi: Programınızı en az normal metin, boş string ve yalnızca boşluklardan oluşan metinle çalıştırın. Üçünde de programın hata vermeden bitip beklenen sonucu yazdığını gösterin.

Sınav provası

Önce kendi cevabınızı seçin; sonra cevap anahtarında her şıkkın neden doğru veya yanlış olduğunu okuyun. Çeldiriciler uydurma değil, bu konuda gerçekten yapılan hatalardır. Sınav maddeleri de bu mantıkla yazılır.

Madde 1. Aşağıdaki program score = 70 iken ne yazdırır?

if score >= 85:
    result = "AA"
elif score >= 70:
    result = "BB"
else:
    result = "Başarısız"

print(result)
  • A. BB
  • B. Hiçbir şey yazmaz
  • C. BB ve Başarısız
  • D. Başarısız
  • E. AA

Madde 2. Aşağıdaki iki yazım score = 90 için neden farklı sonuç verir?

# A
if score >= 50:
    durum = "Geçti"
if score >= 85:
    durum = "Yüksek"

# B
if score >= 50:
    durum = "Geçti"
elif score >= 85:
    durum = "Yüksek"
  • A. B söz dizimi hatası verir; elif daha dar bir koşulla kullanılamaz
  • B. İkisi de Yüksek verir; elif yalnızca yazım kısaltmasıdır
  • C. Fark yalnızca score 50’nin altındayken görülür
  • D. A Yüksek, B Geçti verir; B’de elif hiç sınanmaz
  • E. İkisi de Geçti verir

Madde 3. Aşağıdaki program ne yazdırır?

word = "abc"
for letter in word:
    print(letter)
  • A. Alt alta a, b, c
  • B. Alt alta 0, 1, 2
  • C. abc
  • D. Hata verir; string üzerinde doğrudan dolaşılamaz
  • E. Alt alta a b, b c, c

Madde 4. Hem indeks hem değer gerektiğinde en doğrudan yazım hangisidir?

  • A. for i in range(len(word)): ve gövdede word[i]
  • B. for index, letter in zip(word):
  • C. for index in word:
  • D. for letter in word.index():
  • E. for index, letter in enumerate(word):

Madde 5. list(range(2, 7)) ne verir?

  • A. [3, 4, 5, 6, 7]
  • B. [0, 1, 2, 3, 4, 5, 6]
  • C. [2, 3, 4, 5, 6, 7]
  • D. [2, 7]
  • E. [2, 3, 4, 5, 6]

Madde 6. Aşağıdaki program 1’den 10’a kadar sayıların toplamını yazdırmalı ama 45 yazıyor. Hangi düzeltme doğrudur?

total = 0
for number in range(1, 10):
    total += number
print(total)
  • A. range(0, 10) yazılmalıdır
  • B. range(1, 11) yazılmalıdır
  • C. for yerine while kullanılmalıdır
  • D. total = 1 ile başlanmalıdır
  • E. total += number + 1 yazılmalıdır

Madde 7. Aşağıdaki döngü neden hiç bitmez?

attempts = 0
password = "1234"
guess = "0000"

while guess != password:
    attempts += 1
    print("Yanlış deneme:", attempts)
  • A. print() çağrısı döngüyü yavaşlattığı için
  • B. attempts += 1 satırı koşulu sıfırladığı için
  • C. while döngüleri Python’da break olmadan bitemez
  • D. != operatörü stringlerde çalışmaz
  • E. Koşuldaki guess döngü içinde hiç değişmez

Madde 8. Aşağıdaki program ne yazdırır?

values = [10, 20, -1, 30, 0, 40]

for value in values:
    if value == -1:
        break
    if value == 0:
        continue
    print(value)
  • A. 10, 20 ve 30
  • B. 10, 20, -1, 30 ve 40
  • C. 10 ve 20
  • D. 10, 20, 30 ve 40
  • E. Hiçbir şey yazmaz

Madde 9. Aşağıdaki program ne yazdırır?

text = "python"
text.upper()
print(text)
  • A. PYTHON
  • B. python
  • C. Python
  • D. Hata verir; upper() sonucu kullanılmalıdır
  • E. None

Madde 10. Aşağıdaki program ne yazdırır?

line = " Ada Yılmaz,80,90 \n"
parts = line.strip().split(",")
print(parts)
  • A. ['Ada', 'Yılmaz', '80', '90']
  • B. ['Ada Yılmaz', 80, 90]
  • C. ['Ada Yılmaz', '80', '90']
  • D. Ada Yılmaz 80 90
  • E. [' Ada Yılmaz', '80', '90 \n']

Madde 11. Aşağıdaki program ne yazdırır?

word = "Programlama"
print(word[1:5])
  • A. ra
  • B. rogra
  • C. Progr
  • D. rogr
  • E. Prog

Madde 1. Doğru: A. İlk koşul yanlıştır; ikinci koşulda 70 >= 70 doğru olduğu için zincir orada durur.

  • B yanlış: else dalı da bulunduğu için result her durumda bir değere bağlanır.
  • C yanlış: elif zincirinde yalnızca bir dal çalışır; ilk doğru koşuldan sonra zincir biter.
  • D yanlış: else yalnızca önceki koşulların hepsi yanlışsa çalışır.
  • E yanlış: 70 >= 85 yanlıştır; ilk dal seçilmez.

Madde 2. Doğru: D. A’daki iki if deyiminin koşulları ayrı ayrı sınanır, bu yüzden ikinci atama birinciyi ezer. B’de ilk koşul doğru olunca zincir durur ve elif koşuluna hiç bakılmaz.

  • A yanlış: Koşulların sırası mantıksız göründüğü için kodun hatalı olduğu düşünülebilir. Oysa bir koşulun öncekinden dar ya da geniş olması söz dizimini ilgilendirmez; B geçerli bir koddur.
  • B yanlış: elif, else if yazımının kısaltmasına benzediği için yalnız yazım farkı sanılabilir. Oysa elif akışı değiştirir: önceki koşul doğruysa elif koşulu hiç sınanmaz.
  • C yanlış: Sınır değerine bakma alışkanlığı akla önce 50’nin altını getirir. Oysa orada iki kodda da hiçbir dal çalışmaz. Fark, iki koşulun birlikte doğru olduğu değerlerde ortaya çıkar.
  • E yanlış: B’nin sonucunu A’ya da genellemek kolaydır. Ama A’daki ikinci if bağımsızdır ve doğru olduğu için değeri değiştirir.

Madde 3. Doğru: A. for doğrudan değerler üzerinde dolaşır; letter her turda sıradaki karakterdir.

  • B yanlış: İndeksler ancak range(len(word)) veya enumerate() ile elde edilir.
  • C yanlış: Her tur ayrı bir print çağrısıdır; çıktı alt alta gelir.
  • D yanlış: for bir string’in karakterlerini sırayla dolaşabilir.
  • E yanlış: for her turda ikişer karakter almaz; her turda tek bir karakter verir.

Madde 4. Doğru: E. enumerate() her turda sıra numarası ile değeri birlikte verir; ne yapmak istediğiniz koddan kolayca okunur.

  • A yanlış: Çalışır ama indeksi siz yönetirsiniz; enumerate() aynı işi daha kısa yoldan yapar.
  • B yanlış: zip() iki ayrı dizinin elemanlarını eşler; tek bir diziye indeks eklemez.
  • C yanlış: Bu yazım değerleri verir, indeksleri değil.
  • D yanlış: index() aranan değerin konumunu tek bir sayı olarak döndürür; for ile dolaşılacak bir dizi vermez.

Madde 5. Doğru: E. Başlangıç dâhil, bitiş hariçtir. Bu, C’deki i < 7 kalıbına karşılık gelir.

  • A yanlış: Başlangıç değeri dâhildir.
  • B yanlış: Tek argümanlı range(7) bu listeyi verirdi; burada başlangıç 2’dir.
  • C yanlış: Bitiş değeri aralığa dâhil değildir; en sık yapılan hata budur.
  • D yanlış: İki argüman sınırları verir, yalnız o iki sayıyı değil.

Madde 6. Doğru: B. Bitiş değeri aralığa dâhil olmadığı için 10 hiç işlenmiyor. Klasik off-by-one hatasıdır; üst sınırı bir artırmak eksik turu geri getirir.

  • A yanlış: Aralığı değiştirmek doğru yere dokunmak gibi görünür. Ama bu 0 ekler ve 10’u hâlâ dışarıda bırakır; toplam yine 45 kalır.
  • C yanlış: Döngü hatalarında akla önce döngü türünü değiştirmek gelir. Oysa döngü türü sorun değildir; sorun aralığın üst sınırındadır.
  • D yanlış: Eksik toplamı başlangıç değeriyle kapatmak kolay bir yama gibi görünür. Ama bu biriktiriciyi bozar: 1 iki kez sayılır ve sonuç 46 olur.
  • E yanlış: Her terimi biraz büyütmek eksik değeri kapatacakmış gibi görünür. Ama toplam 54 olur; eksik olan tek bir turdur.

Madde 7. Doğru: E. Bir while döngüsünün bitmesi için koşulda geçen değerin her turda değişmesi gerekir. Burada yalnız attempts değişiyor ve o koşulun parçası değil.

  • A yanlış: Ekrana durmadan yazı akması döngünün takıldığı izlenimini verir. print() döngüyü yavaşlatır ama koşulu değiştirmez; döngü yine bitmez.
  • B yanlış: Döngü içinde değişen tek satır bu olduğu için suç ona atılır. Ama attempts koşulda geçmez; koşulu etkilemez.
  • C yanlış: Sonsuz döngü örnekleri çoğunlukla break ile bittiği için böyle bir kural sanılabilir. Oysa koşul yanlış olduğunda döngü kendiliğinden biter; break zorunlu değildir.
  • D yanlış: C’de string’ler strcmp() ile karşılaştırıldığı için bu beklenti doğar. Python’da != string’lerde çalışır ve burada her turda True verir.

Madde 8. Doğru: C. -1 değerinde break döngüyü tümüyle bitirir; 30, 0 ve 40 hiç işlenmez.

  • A yanlış: break sonrasında hiçbir tur açılmaz; 30’a sıra gelmez.
  • B yanlış: -1 yazdırılmadan önce break çalışır.
  • D yanlış: Bu, -1 için de continue yazılmış olsaydı çıkardı; break döngüyü sonlandırır.
  • E yanlış: İlk iki değer break satırına gelmeden yazdırılır.

Madde 9. Doğru: B. String değiştirilemez. upper() yeni bir string döndürür; sonuç bir ada atanmadığı için kaybolur.

  • A yanlış: Bunun için text = text.upper() yazılması gerekirdi.
  • C yanlış: upper() yalnızca ilk harfi değil bütün harfleri büyütür; ayrıca sonucu hiçbir ada atanmıyor.
  • D yanlış: Dönüş değerini kullanmamak hata vermez; kullanılmayan değer kaybolur.
  • E yanlış: Metodun metni yerinde değiştirip bir şey döndürmediği düşünülürse None beklenir. Oysa print(text) text adına bağlı değeri yazdırır ve bu değer hiç değişmedi.

Madde 10. Doğru: C. Önce strip() baştaki ve sondaki boşlukları, satır sonunu da temizler. Sonra split(",") metni yalnız virgüllerden böler. Parçalar metin olarak kalır.

  • A yanlış: Ayırıcı olarak virgül verildi. Addaki boşluk bir bölme noktası değildir.
  • B yanlış: split() her zaman metin parçaları döndürür. Sayıya çevirmek için ayrıca int() gerekir.
  • D yanlış: split() bir liste döndürür, birleştirilmiş bir metin değil. Birleştirmek join()’in işidir.
  • E yanlış: Bu, strip() hiç çağrılmasaydı görülecek sonuçtur. Zincirde strip() bölmeden önce çalışır.

Madde 11. Doğru: D. İndeks 0’dan başlar, 1 ikinci karakterdir. Dilim 1, 2, 3 ve 4 indekslerini alır, 5 dışarıda kalır.

  • A yanlış: İki nokta iki ayrı indeksi seçiyormuş gibi okunursa yalnız word[1] ve word[5] alınır. Dilim, iki sınır arasındaki bütün karakterleri alır.
  • B yanlış: Bitiş değerinin de dilime girdiği düşünülürse 5 indeksindeki a eklenir. Dilim, range() gibi bitişi dışarıda bırakır.
  • C yanlış: Birden saymak ile bitişi dâhil etmek bir araya gelince ilk beş karakter seçilir. İki varsayım da Python’un kuralına uymaz.
  • E yanlış: Karakterler birden başlayarak sayılırsa ilk dört karakter seçilir. Python’da indeks 0’dan başlar, word[1] ikinci karakterdir.

Tek sayfa özet

  • if ve while C’dekiyle aynı işi yapar, yalnız yazımları daha sadedir. else if yerine elif yazılır.
  • elif zincirinde yalnız ilk doğru koşulun bloğu çalışır. Ayrı ayrı yazılan if satırlarının her biri kendi başına sınanır.
  • Liste köşeli parantezle yazılır ve değerleri sırayla tutar. İndeks 0’dan başlar, append() sona eleman ekler.
  • for bir listenin ya da metnin elemanlarını sırayla verir. İndeks gerekmiyorsa sayaç tutmazsınız.
  • Hem indeks hem değer gerektiğinde enumerate(), iki listeyi birlikte dolaşırken zip() kullanılır.
  • break döngüyü bitirir; continue yalnızca mevcut turu atlar.
  • range() son sınırı içermez ve üçüncü parametre adım değeridir.
  • Dilimleme text[başlangıç:bitiş:adım] biçiminde yazılır ve range() gibi bitişi dışarıda bırakır. Negatif indeks sondan sayar, text[::-1] metni ters çevirir.
  • strip() satırı temizler, split() parçalara ayırır, join() parçaları yeniden birleştirir. split() her zaman metin parçaları döndürür, sayı için int() gerekir.
  • String değiştirilemez (immutable). upper() gibi metotlar yeni bir string döndürür, sonucu saklamak için bir ada bağlamanız gerekir.
  • Python’da da sınır değerlerine ve off-by-one hatalarına dikkat etmek gerekir.

Gelecek hafta listeleri ve öteki Python koleksiyonlarını göreceğiz. İki değişkenin aynı listeyi gösterdiği durumlar (referans) ve bir değerin yerinde değiştirilip değiştirilemeyeceği (değiştirilebilirlik) nesne tabanlı programlamada sık karşımıza çıkacak.

Bu bölümün kazanımları

Bu bölümü bitiren öğrenci:

  • if/elif/else zincirinde sınır değerinin hangi dala düştüğünü belirler.
  • Bir listenin ya da metnin elemanları üzerinde indeks kullanmadan dolaşır; enumerate() ile zip()’in hangi durumda gerektiğini ayırt eder.
  • range() bitiş değerinin dışarıda kaldığını bilir ve adım parametresini kullanır.
  • while döngüsünde koşuldaki değeri her turda değiştiren adımın sonsuz döngüyü önlediğini açıklar.
  • break ile continue arasındaki farkı gösterir.
  • String’in değiştirilemez olduğunu ve upper() gibi metotların yeni bir string döndürdüğünü açıklar.
  • strip(), split() ve join() ile bir metin kaydını parçalara ayırır ve birleştirir.
  • Dilimlemede başlangıç, bitiş ve adım değerlerinin metnin hangi karakterlerini seçtiğini belirler.
Back to top