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’ın daha sade yazımına ve bir listenin ya da metnin elemanlarını sayaç tutmadan sırayla dolaşmasına bakacağız.
Bu bölümün kapsamı
if/elif/elsezincirinde sınır değerinin hangi dala düştüğü- Bir listenin ya da metnin elemanları üzerinde doğrudan dolaşma;
enumerate()vezip() range()bitişinin dışarıda kalması ve adım parametresiwhiledöngüsünde koşuldaki değeri değiştiren adımbreakilecontinuefarkı- String’in değiştirilemez olması
strip(),split()vejoin()ile bir metin kaydını parçalara ayırma ve birleştirme
lower()/upper()dönüşümünün TürkçeI/İsınırı- Unicode normalleştirme biçimleri ve yerel ayar (locale) kütüphaneleri
- Düzenli ifadeler
- Liste kavraması
Bu başlıklar konunun devamıdır; ileride karşınıza çıkar ama bu derste ezberlemeniz beklenmiyor.
Döngüyü sayaçla mı, değerle mi kurmalıyım?
C’de bir diziyi dolaşırken ilk aklınıza gelen, bir indeks değişkeni tutmaktır. Python’da ise çoğu zaman değerlerin kendisini sırayla alırız. Kod kısalır, ne yapmak istediğimiz de daha kolay okunur. İndeks gerçekten gerektiğinde enumerate() ve zip() var. Bölümün ikinci yarısında aynı soruyu metinler için soracağız.
if: parantez ve süslü parantez yok
Python’da koşulun sonuna : gelir; blok girintiyle belirlenir. else if yerine elif kullanılır.
Sınır değerini düşünün
score = 70 için sonuç ne olur? 69 için ne olur? Koşul zincirlerinde sınır değerlerini ayrıca test edin; doğru görünen koddaki gizli hatalar böyle yakalanır.
for: sayaç tutmadan dolaşmak
C’de bir string’i dolaşmak için indeks değişkeni kullanmaya alışmış olabilirsiniz. Python’da çoğu zaman elemana doğrudan erişebiliriz:
Bu kodda letter, her turda sıradaki karakteri alır. İndeks gerekmediği için ayrıca sayaç tutmuyoruz.
İndeks gerçekten gerekiyorsa range() kullanılabilir; fakat Python’da hem indeks hem değer gerektiğinde çoğu zaman enumerate() daha kısa bir yoldur:
Böylece range(len(word)) yazıp her turda word[i] ile elemana erişmek zorunda kalmazsınız.
İki diziyi aynı anda dolaşmak istediğimizde zip() kullanılabilir:
zip(), verilen listelerden en kısası bitince durur. Uzunlukların eşit olması gerekiyorsa bunu ayrıca kontrol etmelisiniz.
range() son değeri içermez
range(5) → 0, 1, 2, 3, 4. Son sınırın dışarıda kalması, C’deki i < 5 kalıbına benzer.
range(start, stop, step) biçimindeki üçüncü parametre adım değeridir. Geriye saymak için negatif adım kullanılır:
for number in range(10, 0, -1):
print(number)Adımın yönü başlangıçtan bitişe giden yönle uyuşmazsa aralık boş kalır. 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 daha doğal olabilir:
while kullanırken üç soruyu sorun:
- Döngü başlarken koşuldaki değişkenlerin değeri ne?
- Her turda hangi değer değişiyor?
- Bu değişiklikle döngüyü bitirecek koşul gerçekten oluşabilir mi?
Bu sorulardan birinin cevabı belli değilse döngü sonsuza kadar dönebilir.
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:
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. 0 ise yazdırılmadan atlanır. 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 indeksle (text[0]), bir parçasına dilimleyerek (text[:5]) erişebilirsiniz. String’lerin bir de hazır metotları vardır: text.strip() gibi, değerin arkasına nokta koyup çağırdığınız fonksiyonlar.
String değiştirilemez (immutable): oluşturulduktan sonra içindeki karakterler değişmez. text.upper() var olan string’i değiştirmez, yeni bir string döndürür.
Değiştirilebilir ile değiştirilemez arasındaki bu fark gelecek hafta önem kazanacak. Listeleri ve iki adın aynı nesneyi gösterdiği durumları o zaman göreceğiz.
Sık kullanılan string araçları
| Araç | Amaç | Örnek |
|---|---|---|
strip() |
baş/son boşlukları temizler | " a ".strip() |
split(sep) |
metni parçalara ayırır | "Ada,80".split(",") |
sep.join(parts) |
parçaları 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" |
5. haftada dosyadaki satırları parçalarken split() ve strip()’i sık kullanacağız.
Alıştırma: Koşulu tamamla
Bir kullanıcı adı en az 5 karakter olmalı ve boşluk içermemelidir.
len(username) >= 5 ile " " not in username ifadelerini and ile birleştirebilirsiniz.
valid = len(username) >= 5 and " " not in usernameAlıştırma: Doğrudan dolaşarak sayma
Aşağıdaki kod bir metindeki a harflerini sayıyor. Önce sonucu tahmin edin.
Burada ayrıca bir indeks sayacı tutmuyoruz; karakterler üzerinde doğrudan dolaşıyoruz. Ardından kodu, büyük ve küçük harfi ayırmadan sayacak biçimde değiştirin. Örneğin "Ankara" için hem A hem a sayılmalıdır. Sonra "Iğdır" ve "İzmir" gibi Türkçe örneklerde lower() ne yapıyor, bakın. Bu yöntemin her Türkçe metinde neden doğru sonuç vermediğini 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ı; ancak sonuç eksik çıkıyor.
Neden 10 işlenmiyor? Yalnızca gerekli tek değeri değiştirerek düzeltin.
Alıştırma: while döngüsünü güvenli hâle getir
Bu kodu çalıştırın. Sonra break satırını kaldırırsanız ne olacağını çalıştırmadan önce açıklayın. Web sürümünde sonsuz döngüyü gerçekten çalıştırmak yerine mantığını tartışmak yeterlidir.
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ı,
split()ile kelime sayısı,- Metnin başındaki ve sonundaki boşluklar
strip()ile temizlendikten sonra ilk ve son karakter.
Örnek metni değişken olarak verin; input() zorunlu değildir. Programda en az bir for, bir if, bir enumerate() ya da zip() ve iki farklı string metodu bulunsun.
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.
C’den Python’a düşünme farkı
Aşağıdaki iki döngü aynı işi yapar:
# İndeks temelli
for i in range(len(text)):
print(text[i])
# Değer temelli
for ch in text:
print(ch)İndekse ihtiyacınız yoksa ikinci döngü ne yapmak istediğinizi daha açık gösterir. Hem indeks hem değer gerekiyorsa üçüncü bir yol var: enumerate(text). Python öğrenirken C kodunu satır satır Python’a çevirmek yerine, o işin Python’da nasıl yazıldığını öğrenmeye çalışın.
Tek sayfa özet
if,forvewhileC’dekiyle aynı kavramlardır; Python’da yalnızca yazımları daha sadedir.foryalnızca sayı saymak için değildir; bir listenin ya da metnin elemanlarını sırayla alabilir.- Hem indeks hem değer gerektiğinde
enumerate(), iki listeyi birlikte dolaşırkenzip()kullanılır. breakdöngüyü bitirir;continueyalnızca mevcut turu atlar.range()son sınırı içermez ve üçüncü parametre adım değeridir.strip,splitvejoinile bir metin satırını temizleyip parçalara ayırır, parçaları yeniden birleştirirsiniz. Dosyadan okunan satırlarda bunları sık kullanacağız.- String değiştirilemez (immutable);
upper()gibi metotlar yeni bir string döndürür. - 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/elsezincirinde sınır değerinin hangi dala düştüğünü belirler.- Bir listenin ya da metnin elemanları üzerinde indeks kullanmadan dolaşır;
enumerate()ilezip()’in hangi durumda gerektiğini ayırt eder. range()bitiş değerinin dışarıda kaldığını bilir ve adım parametresini kullanır.whiledöngüsünde koşuldaki değeri her turda değiştiren adımın sonsuz döngüyü önlediğini açıklar.breakilecontinuearası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()vejoin()ile bir metin kaydını parçalara ayırır ve birleştirir.