Bu bölümde yeni bir Python kavramı yok. İlk 13 haftada öğrendiğimiz yapıları küçük ama gerçek hayattan bir problemde birlikte kullanacak, birbirine nasıl bağlandıklarını göreceğiz.
Mikro uygulamamız kampüsteki kırtasiyenin satış raporunu hazırlayacak. Bu kez veri kodun içindeki bir listeden gelmeyecek. Satışları bir CSV dosyasından okuyacağız. Ham kayıtları (dosyadan okunduğu gibi, henüz işlenmemiş satırları) sayıya çevirecek, geçersiz olanları ayıracak, raporu yazdıracak ve önemli davranışları küçük testlerle doğrulayacağız.
Uygulamada şu konular yeniden karşınıza çıkacak:
String temizleme ve Türkçe metin normalleştirme,
csv.DictReader ile dosyadan veri okuma,
Tür dönüşümü ve try / except,
None ile başarısız dönüşümü bildirme,
Liste ve sözlüklerle kayıt işleme,
Sayaç, biriktirici, gruplama ve maksimum arama kalıpları,
Fonksiyonlar, modüller ve main guard,
assert ile küçük regresyon kontrolleri,
F-string ile iki ondalık basamaklı raporlama.
Bu bölümün kapsamı
NoteSınavda sorulur
Dönemin tamamı; final bu bölümün kapsamıyla sınırlı değildir
Kodu modüllere ayırmanın gerekçesi
CSV alanlarını güvenli çözme ve geçersiz kaydı ayıklama
Türkçe metin normalleştirmesinin gruplamaya etkisi
“veri yok” durumunu None ile raporlama
Değişiklik sonrası eski doğrulama kontrollerini yeniden çalıştırma
AI’ın önerdiği kodu kabul kriterleriyle değerlendirme
NoteSınav dışı (bilgi amaçlı)
Örnek uygulamadaki dosya ve fonksiyon adlarını ezberlemek
Uygulamaya eklenebilecek ileri özelliklerin tasarımı
Bu başlıklar konunun devamıdır; ileride karşınıza çıkar ama bu derste ezberlemeniz beklenmiyor.
Bütün bu araçlar tek bir programda nasıl birleşir?
Dönem boyunca her aracı ayrı ayrı gördük: tür dönüşümü bir bölümde, sözlük başka bir bölümde. Gerçek bir programda hepsi aynı anda ve birbirine bağlı çalışır. Aşağıdaki şema, bir gereksinimin kabul kriterine, koda ve teste nasıl dönüştüğünü gösteriyor.
Gereksinimden teste
Problem ve veri dosyası
Kırtasiyenin satışları satislar.csv dosyasında. Dosya için Türkçe ayarlı Excel’de sık görülen biçimi seçtik: alanlar noktalı virgülle ayrılmış, ondalık sayılarda virgül kullanılmış.
Bu küçük veri kümesine bilerek şu durumları koyduk:
" Kalem " başta ve sonda boşluk içeriyor.
İĞNE ve iğne aynı ürün olarak gruplanmalı.
"12,5" ve "5,5" doğrudan float() ile sayıya çevrilemez; önce ondalık virgülü noktaya çevirmemiz gerekir.
"abc" geçerli bir adet değildir.
Bu uygulamanın kuralına göre 0 adetli satış geçersizdir.
Programın yazdırması gereken özet:
Geçerli kayıt sayısı: 4
Geçersiz kayıt sayısı: 2
Toplam ciro: 160.50 TL
Ürün adetleri: {'kalem': 3, 'defter': 2, 'iğne': 6}
Ciroya en fazla katkı: defter (90.00 TL)
Note
Bu örnekteki verinin biçimini biliyoruz: 12,5 gibi her sayıda yalnızca bir ondalık virgül var. Bu yüzden replace(",", ".") ile çevirmek yeterli. 1.234,56 gibi binlik ayracı da içeren sayılarda bu basit yöntem işe yaramaz.
Uygulamanın dosya yapısı
Proje bir veri dosyası ile dört Python dosyasından oluşuyor:
satislar.csv
↓
veri.py: CSV'yi oku
↓
rapor.py: temizle → dönüştür → doğrula → özetle
↓
main.py: programı çalıştır ve raporu yazdır
↓
test_kontrolleri.py: temel davranışları doğrula
Tip
Kodu dosyalara bölmemizin nedeni, her dosyaya tek bir iş vermektir: veriyi okumak, hesaplamak ve programı başlatmak ayrı işlerdir. Bir sonuç yanlış çıktığında hangi dosyaya bakacağınızı bilirsiniz.
veri.py: CSV kayıtlarını okumak
12. haftada gördüğümüz Excel/CSV ayrıntıları burada işe yarıyor:
Böylece İĞNE ile iğne raporun sözlüklerinde iki ayrı anahtar olmaz.
Warning
Bu dönüşüm Türkçe metinler için yazıldı. E-posta adresi, kullanıcı adı ya da uluslararası ürün kodu gibi alanlarda aynı dönüşümün doğru sonuç vereceğini varsaymayın.
Sayısal alanları güvenli çözmek
Fiyat 0 olabilir ama negatif olamaz. Fonksiyonun adı da bunu söylesin:
Python’da tek bir None nesnesi vardır. Bu yüzden None kontrolü şöyle yazılır:
if deger isNone: ...
Tersi için:
if deger isnotNone: ...
Important
Bir fonksiyon geçersiz girdide None döndürüyorsa çağıran kod sonucu kontrol etmek zorundadır. Kontrol etmezse hata daha sonra, örneğin None * 3 gibi nereden geldiği belli olmayan bir satırda çıkabilir.
Bir ham kaydı dönüştürmek
Şimdi CSV’den gelen tek bir ham kaydı, hesapta kullanabileceğimiz bir sözlüğe çevirelim:
Sözlük boşsa en büyük değerden söz edilemez; bu yüzden None döndürüyoruz. 0 döndürseydik “hiç veri yok” durumu, “en yüksek ciro 0” gibi gerçek bir sonuçla karışırdı.
Bu fonksiyonda yeni bir söz dizimi yok; önceki haftalarda gördüğümüz şu kalıplar bir araya geliyor:
for ile kayıtları dolaşma,
None kontrolü,
continue,
Sayaç ve biriktirici,
Sözlükle gruplama,
Fonksiyon çağrıları,
Maksimum arama.
Tarayıcıda bütün akışı deneyin
Kendi bilgisayarınızda satislar.csv dosyasını open() ile açarsınız. Kod hücresinde ise aynı CSV metnini StringIO ile dosyaymış gibi okuyabiliriz:
Beklenen çıktı:
Geçerli kayıt sayısı: 4
Geçersiz kayıt sayısı: 2
Toplam ciro: 160.50 TL
Ürün adetleri: {'kalem': 3, 'defter': 2, 'iğne': 6}
Ciro lideri: ('defter', 90.0)
main.py: dosya hatasını yönetmek ve raporlamak
Asıl dosyayı okuyan ana program:
from veri import kayitlari_okufrom rapor import satis_raporudef main():try: kayitlar = kayitlari_oku("satislar.csv")exceptFileNotFoundErroras hata:print("Satış dosyası bulunamadı:", hata)return rapor = satis_raporu(kayitlar)print("Geçerli kayıt sayısı:", rapor["gecerli"])print("Geçersiz kayıt sayısı:", rapor["gecersiz"])print(f"Toplam ciro: {rapor['ciro']:.2f} TL")print("Ürün adetleri:", rapor["urun_adetleri"])if rapor["lider"] isnotNone: urun, ciro = rapor["lider"]print(f"Ciroya en fazla katkı: {urun} ({ciro:.2f} TL)")if__name__=="__main__": main()
Burada 13. haftadan iki konu bir arada:
Dosyanın bulunamaması önceden beklenen bir durumdur; FileNotFoundError yakalanır ve bir mesaj yazdırılır.
Main guard sayesinde main.py doğrudan çalıştırıldığında main() çağrılır.
Küçük regresyon kontrolleri
Kod çalışıyor görünse de önemli davranışları assert ile sınayalım. Bu kontroller kodu sonradan değiştirdiğinizde de işe yarar: daha önce doğru çalışan bir davranış bir değişiklikten sonra bozulursa (buna regresyon denir) hemen fark edersiniz.
0 değeri kabul edilir; oysa bu uygulamada adet pozitif olmalıdır.
AI’ın önerdiği kodu değerlendirirken şu üç soruyu sorun:
Sözleşmeye uyuyor mu?
Sınır ve geçersiz durum testlerini geçiyor mu?
Daha önce doğru çalışan bir davranışı bozuyor mu?
Important
AI’ın yazdığı kod daha kısa ya da daha “profesyonel” görünebilir; bu, doğru olduğunu göstermez. Bu derste bir kodu kabul etmeniz için ne yaptığını açıklayabilmeniz ve doğrulamış olmanız gerekir.
Uygulamaya tek bir özellik eklemek
Hazır projeye aşağıdakilerden yalnızca birini eklemeyi deneyin:
Fiyatı 0 olan kayıtları ayrıca saymak,
Belirli bir ciro eşiğinin üzerindeki ürünleri listelemek,
Raporu rapor.txt dosyasına yazmak,
Geçersiz kayıtların nedenlerini ayrı sayaçlarda toplamak,
Aynı ürün farklı fiyatlarla gelirse rapora uyarı eklemek.
Özellik eklemeden önce kabul kriterini yazın. Sonra şu anki kodun bu kriteri karşılamadığı en az bir örnek hazırlayın.
Örneğin:
Aynı ürün iki farklı fiyatla gelirse rapor bu ürünü "fiyat tutarsızlığı" olarak işaretlemeli.
Windows’ta klasörü Dosya Gezgini’nde açın, adres çubuğuna cmd yazıp Enter’a basın; komut istemi o klasörde açılır. Önce testleri çalıştırın:
python test_kontrolleri.py
Kontrollerin hepsi geçerse ekranda Bütün kontroller geçti. yazısı görünür. Ardından programı çalıştırın:
python main.py
Kurulumunuza göre python yerine py yazmanız gerekebilir.
Ders sonu kontrolü
Mikro uygulama için şu sorulara cevap verebilmelisiniz:
satislar.csv verisi neden okunduğu gibi hesapta kullanılmıyor?
utf-8-sig ve delimiter=";" hangi gerçek dosya problemlerini çözüyor?
urun_adi_temizle() neden yalnızca .lower() kullanmıyor?
negatif_olmayan_sayi_coz() ile pozitif_tam_sayi_coz() sözleşmeleri neden farklıdır?
None burada ne anlama geliyor ve neden is None ile kontrol ediliyor?
0 adetli satış neden bu uygulamada geçersiz kabul edildi?
urun_adetleri ve urun_cirolari sözlükleri hangi biriktirme kalıbını kullanıyor?
Ciroya en çok katkı yapan ürün nasıl bulunuyor?
FileNotFoundError hangi modülde ve neden yakalanıyor?
AI’ın önerdiği bir değişikliği kabul etmeden önce hangi testleri çalıştırırsınız?
Deneme sınavı: 25 madde
Bu 25 soru, finalin nasıl olacağını birebir gösterir: final de 25 sorudur, her soru beş şıklıdır ve her kazanımdan en fazla bir soru gelir. Önce kendiniz çözün, sonra cevap anahtarındaki gerekçeleri okuyun.
1. Algoritma ile program arasındaki fark nedir?
A. Algoritma Python’da, program ise C gibi derlenen dillerde yazılır
B. Algoritma çözümün adımlarıdır, program bu adımların çalıştırılabilir kodudur
C. Algoritma her zaman programdan kısadır, çünkü ayrıntı içermez
D. Algoritma kâğıda yazılır, program ise bilgisayarda yazılır
E. İkisi aynı şeydir; biri Türkçe, öteki İngilizce kökenli bir terimdir
2. Aşağıdaki program ne yazdırır?
a =10b = a +5a =20print(a)print(b)
A.10 ve 25
B.20 ve 20
C.10 ve 15
D.20 ve 15
E.20 ve 25
3.puan = 45 iken aşağıdaki program ne yazdırır?
if puan >=50:print("Geçti")else:print("Kaldı")
A. Önce Geçti, sonra Kaldı
B.Geçti
C. Hata verir; puan karşılaştırmadan önce dönüştürülmelidir
D. Hiçbir şey yazmaz
E.Kaldı
4.while döngüsünde koşul ne zaman sınanır?
A. Her yinelemeden sonra; gövde en az bir kez çalışır
B. Yalnızca döngüye ilk girişte
C. Gövdenin ortasında, güncelleme satırından hemen sonra
D. Her yinelemeden önce; koşul yanlışsa gövde o tur hiç çalışmaz
E. Program başlarken bir kez, sonra sonuç saklanır
5.range(1, 5) hangi değerleri üretir?
A.0, 1, 2, 3, 4
B.1, 2, 3, 4
C.1, 5
D.5, 4, 3, 2, 1
E.1, 2, 3, 4, 5
6. Fonksiyon tanımı ile fonksiyon çağrısı arasındaki fark nedir?
A. Tanım fonksiyonu bir kez çalıştırır, çağrı ise tekrar çalıştırır
B. Tanım fonksiyonu kaydeder, çağrı onu çalıştırır
C. Tanım parantezli, çağrı parantezsiz yazılır
D. İkisi aynı şeydir; def yazımı isteğe bağlıdır
E. Tanım dosyanın sonunda, çağrı başında yer alır
7. Bir fonksiyonun sözleşmesi hangi üç soruya cevap verir?
A. Hangi dosyada yer alır, kim yazmıştır ve ne zaman yazılmıştır
B. Ne kadar hızlı çalışır, ne kadar bellek kullanır ve kaç kez çağrılır
C. Hangi girdileri kabul eder, ne yapar ve ne döndürür
D. Hangi hataları verir, hangi sürümde çalışır ve hangi modülü kullanır
E. Kaç satır uzunluktadır, hangi döngüyü kullanır ve kaç değişken tanımlar
8."Python"[0] ve "Python"[-1] sırasıyla hangi karakterleri verir?
A.P ve P
B.n ve P
C.P ve n
D.y ve o
E. Hata verir; negatif indeks kullanılamaz
9.[10, 20, 30, 40][1:3] ifadesinin sonucu nedir?
A.20 ve 30 ayrı ayrı
B.[20, 30, 40]
C.[10, 20, 30]
D.[20, 30]
E.[10, 20]
10.append() ve remove() sırasıyla ne yapar?
A.append() sona ekler, remove() verilen değeri siler
12.urun = {"ad": "Kalem", "fiyat": 15} iken "Kalem" in urun sonucu nedir?
A.None döner; eşleşen anahtar bulunmaz
B.KeyError oluşur; "Kalem" bir anahtar değil
C."ad"; eşleşen anahtarı döndürür
D.True; Kalem sözlüğün içindedir
E.False; in yalnız anahtarlara bakar
13.ogrenciler bir sözlük listesiyken ogrenciler[2]["puan"] ifadesi ne yapar?
A.puan adlı listenin 2 numaralı elemanını verir
B. Önce listenin 2 numaralı kaydını seçer, sonra o kaydın puan alanını okur
C. Üçüncü kaydı siler
D. Listenin 2 numaralı elemanını puan değeriyle değiştirir
E. Bütün kayıtların puan alanlarını toplar
14.gecenler.append(ogrenci) satırı neden yeni bir sözlük kopyası oluşturmaz?
A.append() aynı sözlüğe bir referans ekler
B.append() yalnızca sayıları kopyalar
C. Kopya oluşur ama bellekte aynı yerde tutulur
D. Kopya oluşur; iki liste bağımsızdır
E. Sözlükler değiştirilemez olduğu için kopyalanmaz
15."r", "w" ve "a" kipleri arasındaki fark nedir?
A. Üçü de okuma kipidir; fark yalnızca hızdadır
B."r" okur; "w" ve "a" dosya yoksa hata verir
C."r" okur, "w" sona ekler, "a" içeriği siler
D."r" okur, "w" baştan yazar, "a" sona ekler
E."r" ve "w" metin, "a" ikili dosyalar içindir
16.read() ile readlines() hangi türde değer döndürür?
A.read() liste, readlines() tek metin döndürür
B. İkisi de satırlardan oluşan bir liste döndürür
C.read() sayı, readlines() metin döndürür
D.read() tek bir metin, readlines() satır listesi döndürür
E. İkisi de dosyanın tamamını tek metin olarak döndürür
17. Söz dizimi hatası, çalışma zamanı hatası ve mantık hatası nasıl ayrılır?
A. Söz dizimi hatası yalnızca büyük ve karmaşık programlarda çıkar
B. Mantık hatası da çalışırken çıkar ve her zaman bir mesaj verir
C. Söz dizimi hatası kod çalışmadan, çalışma zamanı hatası çalışırken çıkar; mantık hatası mesaj vermez
D. Çalışma zamanı hatası kod çalışmadan, söz dizimi hatası çalışırken çıkar; mantık hatası mesaj vermez
E. Üçü de programı hemen durdurur; yalnızca mesajları farklıdır
18. Aşağıdaki kod neden sorunludur?
try: puan =int(satir["puan"])except: puan =0
A. Sorun yok; geniş except daha güvenlidir
B.try bloğu tek satırdan oluştuğu için
C.except tür belirtmediği için her istisnayı yakalar
D.puan değişkeni iki farklı yerde atandığı için
E.int() çağrısı try içinde kullanılamaz
19. Bütünleştirici uygulamada kodun veri.py, rapor.py ve main.py olarak ayrılmasının gerekçesi nedir?
A. Modüller arasında değişkenler paylaşıldığı için
B. Üç dosya bir dosyadan daha hızlı çalıştığı için
C. Python büyük dosyaları çalıştıramadığı için
D. Her modül kendi hatalarını kendiliğinden yakaladığı için
E. Okuma, hesaplama ve çalıştırma ayrı sınanabildiği için
20. CSV’den gelen "12,5" değeri uygulamada nasıl işlenir?
A. Virgül noktaya çevrilip float() uygulanır
B. Değer metin olarak bırakılıp olduğu gibi toplanır
C. Değer int() ile tam sayıya çevrilir
D. Virgül silinip 125 elde edilir
E. Doğrudan float("12,5") çağrılır
21. Ürün adlarını gruplarken "İĞNE" ve "iğne" değerlerinin aynı gruba düşmesi için neye dikkat edilmelidir?
A. Ürün adları hiç normalleştirilmemelidir
B.lower() yeterlidir; Türkçe karakterlerde de doğru çalışır
C. Ürün adları sayıya çevrilmelidir
D. Gruplama için küme kullanılmalıdır
E.I ve İ için ayrı bir dönüşüm kuralı tanımlanmalıdır
22. “Veri yok” durumunda en yüksek ciroyu yapan ürünü bulan fonksiyonun None döndürmesi neden 0 döndürmekten daha açıklayıcıdır?
A.None, “kayıt yok” ile “ciro sıfır” ayrımını korur
B.None hesaplama hatalarını tamamen engeller
C.0 döndürmek Python’da yasaktır
D.None her durumda 0’dan daha iyi bir dönüş değeridir
E.None bellekte daha az yer kaplar
23. Uygulamaya yeni bir özellik ekledikten sonra eski assert kontrollerini de yeniden çalıştırmak neden gerekir?
A. Yeni kod eski bir davranışı bozmuş olabilir
B. Gerekmez; yalnızca yeni davranışı sınamak yeterlidir
C.assert satırları zamanla geçersiz olur
D. Python eski sonuçları önbelleğe alır
E. Yeni özellik eski kontrolleri siler
24. AI’ın verdiği bir çözüm çalışıyor görünse bile hangi nedenle reddedilebilir?
A. AI tarafından üretildiği için; kaynak tek başına yeterli bir gerekçedir
B. Kısa olduğu için
C. Ne yaptığı açıklanamıyorsa ya da sınır durumlarında davranışı doğrulanmamışsa
D. Kendi yazdığınız koddan farklı göründüğü için
E. Yorum satırı içermediği için
25. Rapor döngüsünde geçersiz kayıtlar için continue kullanmanın amacı nedir?
A. Döngüyü tamamen bitirip rapora geçmek
B. Bozuk kaydı atlayıp sonraki kayda geçmek
C. Bozuk kaydı listeden kalıcı olarak silmek
D. Bozuk kaydı düzeltip yeniden denemek
E. Kayıt için ekrana bir hata mesajı yazdırmak
TipCevaplar ve gerekçeler
1. Doğru: B. Algoritma dilden bağımsızdır; aynı adımlar Python’da da başka bir dilde de yazılabilir. Programı ayıran şey, bir programlama diliyle yazılmış ve çalıştırılabilir olmasıdır.
A yanlış: Bu derste Python kullandığımız için ilk akla gelen dil odur. Ama algoritma belirli bir programlama diline bağlı değildir; bir programlama diliyle yazıldığında program olur.
C yanlış: Kulağa doğru gelir, çünkü algoritma çoğu zaman özet gibi yazılır. Ama uzunluk ölçüt değildir. Algoritma da ayrıntılı olabilir; bir algoritma sayfalarca sürerken programı birkaç satır olabilir.
D yanlış: Algoritmayı çoğu zaman kâğıtta kurduğumuz için akla yatkın gelir. Ama fark nereye yazıldıkları değildir. Algoritma bir çözüm planıdır ve bilgisayarda da tutulabilir.
E yanlış: İki sözcük günlük konuşmada sık sık birbirinin yerine kullanıldığı için akla yatkın gelir. Ama algoritma çözüm planı, program o planın çalışan hâlidir.
2. Doğru: D.b hesaplandığı anda a hâlâ 10’du, yani b 15 oldu. Sonradan anın değişmesi byi etkilemez.
A yanlış: Ne a eski değerinde kalır ne de b yeniden hesaplanır.
B yanlış:b ayrı bir değişkendir ve anın yeni değerini almaz.
C yanlış: Son atama ayı 20 yaptı; print(a) güncel değeri yazar.
E yanlış:b ile a arasında kalıcı bir bağ kurulmaz; b yalnızca hesaplandığı andaki sonucu tutar.
3. Doğru: E.45 >= 50 yanlış olduğu için else bloğu çalışır.
A yanlış:if ve else birbirini dışlar; ikisi aynı çalıştırmada birden çalışamaz.
B yanlış: Koşul sağlanmıyor; if bloğu atlanır.
C yanlış:puan zaten bir sayı; dönüşüme gerek yok.
D yanlış:if ile else bloklarından biri mutlaka çalışır; burada ikisi de bir satır yazdırır.
4. Doğru: D. Koşul başta sınandığı için döngü gövdesi sıfır kez de çalışabilir.
A yanlış: Bu, bazı dillerdeki do-while davranışıdır. Python’ın while yapısı koşulu başta sınar.
B yanlış: Koşul her turun başında yeniden sınanır; yoksa döngü hiç bitmezdi.
C yanlış: Koşul gövdenin içinde değil, başında yer alır.
E yanlış: Sonuç saklanmaz; değişkenler değiştikçe koşul yeniden değerlendirilir.
5. Doğru: B. Başlangıç dâhil, bitiş hariçtir; 5 üretilmez.
A yanlış: İki argüman verildiğinde ilki başlangıçtır; 0’dan başlanmaz.
C yanlış:range() yalnızca uçları değil, aradaki bütün değerleri üretir.
D yanlış: Geriye saymak için negatif adım verilmesi gerekir.
E yanlış: Bitiş değeri hiçbir zaman üretilmez. 5’i de istiyorsanız range(1, 6) yazılır.
6. Doğru: B.def satırı yalnızca adı ve gövdeyi kaydeder; gövdeyi çalıştırmaz. Gövde ancak fonksiyon adı parantezle çağrıldığında, o anda çalışır.
A yanlış:def satırı da yürütülen bir satır olduğu için gövdenin o anda çalıştığı sanılabilir. Ama tanım gövdeyi hiç çalıştırmaz; gövde ilk kez ilk çağrıda çalışır.
C yanlış: İki satırın yazımı farklı olduğu için parantezin yalnızca birinde bulunduğu sanılabilir. Ama ikisinde de parantez vardır; tanımda parametreler, çağrıda argümanlar bulunur.
D yanlış:print() gibi yerleşik fonksiyonları def yazmadan kullandığımız için def gereksiz görünebilir. Ama kendi fonksiyonunuz def olmadan oluşmaz; tanım ve çağrı ayrı adımlardır.
E yanlış: Programın asıl işi çağrıda yapıldığı için onun başa konacağı düşünülebilir. Ama sıra tam tersi olmalıdır: ad kullanılmadan önce tanımlanır.
7. Doğru: C. Sözleşme, fonksiyonu kullanacak kişinin gövdeyi okumadan bilmesi gereken üç şeydir.
A yanlış: Bunlar belgeleme bilgileridir, davranış sözleşmesi değil.
B yanlış: Hız ve bellek kullanımı başka bir konudur; sözleşme fonksiyonun ne yaptığını anlatır.
D yanlış: Bunlar yararlı ayrıntılar olabilir ama sözleşmenin özü girdi, davranış ve sonuçtur.
E yanlış: Bunlar gövdenin iç ayrıntılarıdır; çağıranı ilgilendirmez.
8. Doğru: C. İndeksler 0’dan başlar; -1 ise son karakteri gösterir.
A yanlış:-1 baştan değil sondan sayar.
B yanlış: İki sonuç ters yazılmış.
D yanlış: Bu [1] ve [-2] sonuçlarıdır; ilk indeks 0’dır.
E yanlış: Python negatif indeksi kabul eder; negatif indeks metnin sonundan sayar.
9. Doğru: D. Dilimlemede başlangıç dâhil, bitiş hariçtir; 3 numaralı eleman alınmaz.
A yanlış: Dilimin sonucu tek bir listedir; ayrı değerler değil.
B yanlış: Bitiş indeksi dilime girmez.
C yanlış: Başlangıç 1 olduğu için ilk eleman alınmaz.
E yanlış: Dilim 1’den başlar, 0’dan değil.
10. Doğru: A.append() elemanı listenin sonuna ekler. remove() indekse değil değere göre çalışır ve yalnızca ilk eşleşmeyi kaldırır.
B yanlış: Ekleme ile silmenin listenin iki ayrı ucunda yapıldığı düşünülünce simetrik görünür. Ama append() sona ekler; son elemanı silmek pop() işidir.
C yanlış: İki metot da listeyi değiştirdiği için listeyi değiştiren öteki metotlarla karışabilir. Ama sıralama sort(), boşaltma clear() işidir.
D yanlış: String metotları yeni değer döndürdüğü için liste metotlarının da öyle yaptığı sanılır. Ama ikisi de listeyi yerinde değiştirir ve None döndürür.
E yanlış: Listelerde çoğu işlem indeksle yapıldığı için remove()un da indeks aldığı sanılır. Ama remove() indeks değil değer alır; indeksle silmek için del ya da pop() kullanılır.
11. Doğru: E. Sözlükte erişim konuma değil anahtara göre yapılır. "fiyat" değere ulaşmak için kullanılan addır, 15 ise o anahtarın değeridir.
A yanlış: Tırnak içinde bir ad olduğu için sözlüğün adı sanılabilir. Ama sözlüğün adı urundur.
B yanlış: Fiyat gerçekten okunuyor, bu yüzden bir çağrı gibi görünür. Ama metot çağrısı parantezle yazılır; buradaki köşeli parantez erişimdir.
C yanlış: Listede köşeli parantez indeks alır ve "fiyat" ikinci sırada durduğu için akla yatkın gelir. Ama sözlükte sıra numarasıyla erişim yapılmaz.
D yanlış: Köşeli parantezin içine yazılan şey okunan veri gibi görünür. Ama değer 15’tir; "fiyat" ona ulaşmak için kullanılan addır.
12. Doğru: E.in sözlükte anahtarları arar, değerlere bakmaz. "Kalem" bir değerdir; anahtarlar "ad" ve "fiyat"tır. Değerlerde aramak için in urun.values() yazılır.
A yanlış:get() bulamadığı anahtarda None döndürdüğü için bu davranış akla gelir. Ama in işleminin sonucu her zaman bir bool değeridir.
B yanlış:urun["Kalem"] yazılsaydı gerçekten KeyError alınırdı. Ama in hata vermez; çoğu zaman tam da hatadan kaçınmak için kullanılır.
C yanlış:"Kalem" gerçekten "ad" anahtarının değeridir, bu yüzden bu eşleşme akla gelir. Ama in anahtar döndürmez; sonucu True ya da False olur.
D yanlış:"Kalem" sözlüğü yazdırınca gerçekten görünür, bu yüzden akla yatkın gelir. Ama bir değer olarak durur; in varsayılan olarak anahtarlara bakar.
13. Doğru: B. İki erişim art arda yapılır: ilk köşeli parantezde indeks, ikincisinde anahtar vardır.
A yanlış: İlk köşeli parantez ogrenciler listesine aittir.
C yanlış: Hiçbir şey silinmiyor.
D yanlış: Atama yok; değer yalnızca okunuyor.
E yanlış: Yalnızca tek bir kaydın alanı okunur.
14. Doğru: A.append() kaydın kopyasını değil, o kayda giden referansı ekler; iki liste aynı sözlüğü paylaşır. Filtrelenmiş listedeki bir kaydı değiştirirseniz ilk listedeki kayıt da değişir. Bağımsız kayıt gerekiyorsa ogrenci.copy() kullanılır.
B yanlış: Sayılarla çalışırken paylaşım fark edilmediği için böyle sanılabilir. Ama append() hiçbir türü kopyalamaz; her zaman referans ekler.
C yanlış: İki listenin aynı kaydı göstermesini açıklamaya çalışır, bu yüzden akla yatkın gelir. Ama kopya hiç oluşmaz; tek bir sözlük vardır.
D yanlış: İki liste gerçekten ayrı nesnelerdir, bu yüzden içleri de bağımsız sanılır. Ama içlerindeki kayıtlar ortaktır.
E yanlış: Kopyalanmayan şeyin değişmez olduğu düşünülebilir. Ama sözlük değiştirilebilirdir ve copy() ile kopyalanabilir.
15. Doğru: D."w" ile açılan dosyanın eski içeriği silinir ve dosya baştan yazılır. Var olan veriyi korumak istiyorsanız "a" kullanılır; yeni içerik dosyanın sonuna eklenir.
A yanlış: Üçü de open() çağrısında aynı yere yazıldığı için benzer işler sanılabilir. Ama yalnızca "r" okuma kipidir.
B yanlış:"r" dosya yoksa gerçekten hata verir, bu yüzden öteki kiplerin de öyle davranacağı sanılır. Ama "w" ve "a" dosya yoksa oluşturur.
C yanlış: Kip harflerinin anlamı akılda kalmazsa "w" ile "a" kolayca yer değiştirir. Ama "w" baştan yazar, "a" (“append”, eklemek) sona ekler; hiçbir kip içeriği yalnızca silmek için açılmaz.
E yanlış: Kip harflerinin bir kısmı ikili dosyalarla ilgili olduğu için karışabilir. Ama ikili kip için "b" eklenir; "a" da metin kipidir.
16. Doğru: D.read() dosyanın tamamını tek bir metin olarak verir. readlines() ise her satırı bir eleman olan bir liste döndürür. Satır satır işlemek istiyorsanız readlines() ya da doğrudan dosya üzerinde for kullanılır.
A yanlış: İki ad birbirine benzediği için türler kolayca karışır. Ama iki tür ters yazılmış; çoğul ad readlines() listeyi verir.
B yanlış: Dosya satırlardan oluştuğu için her okumanın satır listesi vereceği sanılabilir. Ama read() tek bir string döndürür.
C yanlış: Dosyada sayılar yazılıysa read() sonucunun sayı olacağı düşünülebilir. Ama dosyadan okunan içerik her zaman metindir.
E yanlış: İkisi de dosyanın bütün içeriğini okuduğu için akla yatkın gelir. Ama readlines() bu içeriği satırlara bölüp liste döndürür.
17. Doğru: C. Söz dizimi hatasında Python kodu çalıştırmaya hiç başlamaz. Çalışma zamanı hatası kod çalışırken çıkar. Mantık hatası mesaj vermez ama sonuç yanlış olur. En tehlikelisi mantık hatasıdır, çünkü program sorunsuz çalışıyor gibi görünür ve yanlışlık ancak sonuç denetlenirse fark edilir.
A yanlış: Uzun kodda yazım yanlışı yapmak daha kolay olduğu için akla yatkın gelir. Ama söz dizimi hatası tek satırlık bir kodda da çıkabilir.
B yanlış: “Hata” sözcüğü bir mesaj beklentisi doğurur. Ama mantık hatası mesaj vermez; bu yüzden bulunması da zordur.
D yanlış: İki hata da traceback ile görüldüğü için hangisinin ne zaman çıktığı karışabilir. Ama roller ters yazılmış: kod çalışmaya başlamadan yakalanan, söz dizimi hatasıdır. Çalışma zamanı hatası ancak kod çalışırken çıkar.
E yanlış: İlk iki hata gerçekten programı durdurduğu için üçüncüsünün de öyle davranacağı sanılır. Ama mantık hatası programı durdurmaz ve mesaj vermez.
18. Doğru: C. Yanlış yazılmış bir değişken adından bellek sorununa kadar her istisna yakalanır; gerçek hatalar fark edilmeden gizlenir. Beklenen istisnalar açıkça yazılmalıdır, örneğin except (ValueError, KeyError):. Yoksa bambaşka bir hata da 0 puana dönüşür.
A yanlış: Program hiç durmadığı için güvenli görünür. Ama geniş except hataları gizler ve yanlış sonucu fark etmeyi zorlaştırır.
B yanlış: Kısa bir try bloğu eksik yazılmış gibi görünebilir. Ama tek satırlık try bloğu önerilen bir uygulamadır; sorun exceptte.
D yanlış: Aynı ada iki atama görmek çakışma gibi görünür. Ama atama iki ayrı kolda yazılmış; hangisi çalışırsa puan onun değerini alır. Bunda sorun yok.
E yanlış: Hata verebilecek bir çağrının korumalı bloğa konamayacağı düşünülebilir. Ama tersine, int() çağrısı hata verebileceği için zaten try içine alınır.
19. Doğru: E. Üç sorumluluk ayrı dosyalara ayrılır; her parça tek başına denenip düzeltilebilir. Ciro yanlış çıkarsa sorun ya okuyan ya da hesaplayan dosyadadır; dosyalar ayrı olduğu için arama bu iki yerle sınırlı kalır.
A yanlış: Üç dosya aynı uygulamanın parçası olduğu için adları ortak kullanacağı sanılabilir. Ama her modülün kendi ad alanı vardır; paylaşım kendiliğinden olmaz.
B yanlış: Düzenli kodun daha hızlı çalışacağı düşünülebilir. Ama modüllere ayırmak hız kazandırmaz.
C yanlış: Uzun bir dosyada çalışmak zorlaştığı için Python’ın da zorlandığı sanılabilir. Ama böyle bir sınır yoktur.
D yanlış: Küçük modüllerin daha güvenli olduğu fikri bu şıkkı cazip kılar. Ama hata yakalama yine açıkça yazılır.
20. Doğru: A. Ondalık virgül noktaya çevrildikten sonra float() uygulanır; çevrilemeyen değerler geçersiz kayıt sayılır. Bu dar bir sözleşmedir ve yalnızca virgülün ondalık ayraç olduğu bilinen veride geçerlidir.
B yanlış: Değer ekranda sayı gibi göründüğü için dönüşüm gereksiz sanılabilir. Ama metinler sayı gibi toplanmaz; + onları yan yana ekler.
C yanlış:int() en sık kullanılan dönüşüm olduğu için ilk akla gelir. Ama int() de virgüllü metni çeviremez; ayrıca ondalık kısım kaybolur.
D yanlış: Virgül sorun çıkardığı için onu silmek en kısa çözüm gibi görünür. Ama virgülü silmek değeri on kat büyütür.
E yanlış: Türkçede 12,5 doğru bir sayı yazımı olduğu için akla yatkın gelir. Ama bu çağrı ValueError verir; Python ondalık ayracı olarak noktayı bekler.
21. Doğru: E.lower() Türkçeye özgü I ve İ dönüşümünü yapmaz; normalleştirme kuralı bu harf çifti için ayrıca tanımlanmalıdır. Genel harf dönüşümü noktalı ve noktasız i ayrımını gözetmez; casefold() de bunu tek başına çözmez.
A yanlış: Dönüşüm sorun çıkardığı için hiç yapmamak güvenli görünebilir. Ama normalleştirmeden aynı ürün birden çok gruba dağılır.
B yanlış:lower()Ğ gibi harflerde doğru çalıştığı için güvenilir görünür. Ama "I".lower() sonucu "i" olur; Türkçede beklenen "ı"dır.
C yanlış: Sayılar harf sorunu yaşamadığı için kaçış yolu gibi görünebilir. Ama ad bir metindir; sayıya çevrilemez.
D yanlış: Küme aynı değeri iki kez tutmadığı için yinelenenleri birleştireceği sanılır. Ama "İĞNE" ile "iğne"yi zaten farklı değer sayar.
22. Doğru: A. Hiç geçerli kayıt olmaması ile en yüksek cironun sıfır çıkması farklı durumlardır. Raporu okuyan kişi “hiç geçerli kayıt yok” ile “kayıt var ama en yüksek ciro 0” durumlarını ayırt edebilmelidir.
B yanlış:None boş listede hesabı hiç yapmadığı için güvenli görünür. Ama çağıran taraf is None denetimini atlarsa yine hata çıkar.
C yanlış: Önerilmeyen bir seçimin yasak olduğu düşünülebilir. Ama yasak değildir; bu bir tasarım kararıdır.
D yanlış: Bu soruda None gerçekten daha açıklayıcı olduğu için genelleme cazip gelir. Ama her zaman değil; bedeli çağıranın ek bir denetim yapmasıdır.
E yanlış:None “boş” anlamı taşıdığı için daha hafif sanılabilir. Ama bellek bu kararın gerekçesi değildir.
23. Doğru: A. Yeni kod daha önce doğru çalışan bir davranışı bozmuş olabilir; bunu eski kontroller yakalar. Kontroller silinmeyip saklanırsa, bir değişikliğin fark edilmeden bozduğu davranış da görülür.
B yanlış: Değişen yer yeni kod olduğu için yalnız onu sınamak akla yatkın gelir. Ama yeterli değildir; bozulan eski davranış gözden kaçar.
C yanlış: Eski kodun “eskidiği” düşüncesi akla yatkın gelir. Ama assert satırları geçersizleşmez; her çalıştırmada yeniden sınanırlar.
D yanlış: Bazı araçlar sonuçları sakladığı için Python’ın da öyle yapacağı sanılabilir. Ama böyle bir önbellek yoktur.
E yanlış: Kod değişince eski satırların da gittiği düşünülebilir. Ama kontroller siz silmedikçe yerinde durur.
24. Doğru: C. Yalnızca kodun çalışıp çalışmadığına değil, ne yaptığının açıklanıp açıklanamadığına ve nasıl doğrulandığına da bakılır.
A yanlış: Kodu kimin yazdığı ölçüt değildir; ölçüt, kodun anlaşılabilmesi ve doğrulanabilmesidir.
B yanlış: Kısalık bir kusur değildir.
D yanlış: Farklı bir yaklaşım doğru da olabilir.
E yanlış: Yorum eksikliği tek başına ret gerekçesi değildir.
25. Doğru: B.continue bozuk kaydı hesaba katmadan turun kalanını atlar. Geçersiz kaydı baştan atlayınca, geçerli kayıtlar için yazılan kod iç içe if bloklarına girmez.
A yanlış:continue ile break döngüyü değiştiren iki komut olduğu için karışır. Ama döngüyü bitiren breaktir; tek bozuk kayıt yüzünden raporun kalanı kaybolurdu.
C yanlış: Atlanan kayıt raporda görünmediği için silinmiş sanılabilir. Ama continue listeden bir şey silmez.
D yanlış: Geçersiz kayıtla bir şey yapılması gerektiği düşünülebilir. Ama continue düzeltme yapmaz; yalnızca turu atlar.
E yanlış: Bozuk kayıtta çoğu zaman bir uyarı yazdırıldığı için akla yatkın gelir. Ama continue kendiliğinden bir şey yazmaz; mesaj için ayrıca print() gerekir.
Dönem özeti
Bu derste Python’ın söz diziminin yanında bir çalışma sırası da öğrendik:
problemi anla
↓
girdi–işlem–çıktıyı belirle
↓
kabul kriterlerini ve sınırları düşün
↓
küçük çözüm adımları oluştur
↓
kodu oku ve tahmin et
↓
çalıştır ve gözlemle
↓
hataları ve veri kalitesini kontrol et
↓
küçük fonksiyonlara ve gerekirse modüllere ayır
↓
veriyi uygun yapıda tut
↓
sonucu testlerle doğrula
Python araçlarını da bu sırayı izlemek için kullandık:
Değişkenler ve veri türleri,
İfadeler ve tür dönüşümleri,
Koşullar,
while ve for,
Fonksiyonlar, kapsam ve varsayılan parametreler,
String işlemleri ve metin normalleştirme,
Liste, demet, sözlük ve küme,
Dosya ve CSV,
İstisnalar, modüller ve main guard,
assert, sınır durumları ve sistematik hata ayıklama.
İleriki derslerde yeni yapılar ve daha güçlü geliştirme araçları göreceksiniz. AI araçları ve kodlama agent’ları (coding agent: kodu kendi başına yazıp çalıştırabilen AI aracı) daha çok iş üstlenebilir. Ama ilke aynı kalır: kodu kim yazmış olursa olsun, onu anlayabilmeli, ne yaptığını açıklayabilmeli ve doğrulayabilmelisiniz.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
Dönem boyunca öğrenilen araçları tek bir küçük uygulamada birlikte kullanır.
CSV alanlarını güvenli biçimde çözer ve geçersiz kaydı ayıklar.
Türkçe metin normalleştirmesini ürün adlarına uygular.
“Veri yok” durumunu None ile raporlar.
Değişiklikten sonra eski doğrulama kontrollerini yeniden çalıştırır.
AI’ın önerdiği kodu kabul kriterleriyle değerlendirir.
Rapor döngüsünde continue ve get() kalıplarını uygular.