Bütünleştirici mikro uygulama

Bu bölümde yeni bir Python kavramı öğrenmeyeceğiz. Amaç, ilk 13 haftada öğrendiğimiz yapıları küçük ama gerçekçi bir problem üzerinde birlikte kullanmak ve aralarındaki bağlantıyı görünür hâle getirmektir.

Mikro uygulamamız bir kampüs kırtasiye satış raporu olacak. Bu kez veri kodun içine gömülü bir listeden gelmeyecek: CSV dosyasını okuyacak, ham kayıtları dönüştürecek, geçersiz kayıtları ayıracak, rapor üretecek ve temel davranışları küçük testlerle doğrulayacağız.

Bu uygulamada özellikle şunları yeniden kullanacağız:

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 anlamlı 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
  • üretilen kodu kabul ölçütleriyle değerlendirme
  • örnek uygulamanın dosya ve fonksiyon adlarının birebir ezberi
  • 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. Bu bölümün konusu tam olarak o bağlantı.

Gereksinim, kabul kriteri, kod değişikliği ve test arasındaki doğrulama zinciri.

Gereksinimden teste

Problem ve veri dosyası

Kırtasiye satışları satislar.csv adlı bir dosyada tutuluyor. Türkçe Excel kurulumlarında sık görülen bir biçimi özellikle kullanalım: alanlar noktalı virgülle ayrılmış, ondalık değerlerde virgül kullanılmış olsun.

urun;fiyat;adet
 Kalem ;12,5;3
Defter;45;2
İĞNE;5,5;4
iğne;5,5;2
Silgi;8;abc
Cetvel;10;0

Bu küçük veri kümesinde bilinçli olarak birkaç durum var:

  • " 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 dönüştürülemez; kontrollü biçimde ondalık virgülü ele almamız gerekir.
  • "abc" geçerli adet değildir.
  • 0 adetli satış, bu uygulamanın iş kuralına göre geçersizdir.

Beklenen ö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 örnekte 12,5 gibi tek ondalık virgül içeren kontrollü veriyi replace(",", ".") ile dönüştüreceğiz. 1.234,56 gibi daha karmaşık yerel sayı biçimleri için bu basit yöntem genel çözüm değildir.

Uygulamanın dosya yapısı

Bu bölümde önceki haftalarda ayrı ayrı gördüğümüz dosya, modül ve test fikirlerini aynı küçük proje içinde birleştiriyoruz:

hafta14/
├── satislar.csv
├── veri.py
├── rapor.py
├── main.py
└── test_kontrolleri.py

satislar.csv dosyasından veri.py ve rapor.py modüllerine, oradan main.py ile çıktı raporuna ve test kontrollerine giden akış.

Bütünleştirici mikro uygulamanın akışı

Akışın zihinsel modeli:

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

Buradaki amaç “çok dosyalı proje yapmak” değildir. Amaç sorumlulukları ayırmaktır: veriyi alma, hesaplama ve programı başlatma farklı işlerdir.

veri.py: CSV kayıtlarını okumak

  1. haftadaki Excel/CSV ayrıntılarını burada gerçekten kullanıyoruz:
import csv


def kayitlari_oku(dosya_yolu):
    kayitlar = []

    with open(
        dosya_yolu,
        "r",
        encoding="utf-8-sig",
        newline=""
    ) as dosya:
        okuyucu = csv.DictReader(dosya, delimiter=";")

        for satir in okuyucu:
            kayitlar.append(satir)

    return kayitlar

Burada veri.py henüz sayısal dönüşüm yapmıyor. CSV’den gelen ham alanları string olarak okuyor ve dönüştürme sorumluluğunu rapor.py dosyasına bırakıyor.

  • encoding="utf-8-sig", dosyanın başında BOM varsa ilk sütun adının \ufeffurun olmasını engeller.
  • delimiter=";", noktalı virgülle ayrılmış CSV’yi doğru sütunlara böler.
  • newline="", csv modülünün satır sonlarını kendisinin yönetmesini sağlar.

Türkçe ürün adını normalleştirmek

  1. haftada gördüğümüz önemli noktayı uygulamanın içine taşıyalım. Yalnızca .lower() kullanmak Türkçe İ için beklenmedik sonuç verebilir.
def urun_adi_temizle(urun):
    donusum = str.maketrans({"I": "ı", "İ": "i"})
    return urun.strip().translate(donusum).lower()

Kontroller:

assert urun_adi_temizle(" Kalem ") == "kalem"
assert urun_adi_temizle("İĞNE") == "iğne"
assert urun_adi_temizle("iğne") == "iğne"
assert urun_adi_temizle("ISPARTA") == "ısparta"

Böylece İĞNE ve iğne raporda iki ayrı anahtar hâline gelmez.

Warning

Bu normalleştirme Türkçe metin iş kuralına göre tasarlanmıştır. E-posta, kullanıcı adı veya uluslararası ürün kodlarında aynı dönüşüm otomatik olarak doğru kabul edilmemelidir.

Sayısal alanları güvenli çözmek

Fiyat için 0 değerini kabul edeceğiz; bu nedenle fonksiyonun adını sözleşmeyle uyumlu seçelim:

def negatif_olmayan_sayi_coz(metin):
    try:
        sayi = float(metin.strip().replace(",", "."))
    except (ValueError, AttributeError):
        return None

    if sayi < 0:
        return None

    return sayi

Adet ise gerçekten pozitif tam sayı olmalı; 0 adetli satış geçersizdir:

def pozitif_tam_sayi_coz(metin):
    try:
        sayi = int(metin.strip())
    except (ValueError, AttributeError):
        return None

    if sayi <= 0:
        return None

    return sayi

Bu adlandırma önemlidir. Önceki sürümde pozitif_sayi_coz("0") değeri 0 döndürüyor olsaydı, fonksiyon adı ile davranış arasında sözleşme çelişkisi oluşurdu.

None ve is None

  1. haftada None değerini “sonuç üretilemedi” sinyali olarak kullandık. Burada aynı kalıp var:
fiyat = negatif_olmayan_sayi_coz("abc")

if fiyat is None:
    print("Fiyat geçersiz")

None özel ve tekil bir Python nesnesidir. Bu nedenle None kontrolünde yaygın ve önerilen yazım:

if deger is None:
    ...

ve tersi:

if deger is not None:
    ...

şeklindedir.

Important

Bir fonksiyon geçersizlik için None döndürüyorsa çağıran kodun bunu kontrol etmesi gerekir. Kontrol edilmezse sorun daha sonra, örneğin None * 3 gibi daha anlaşılmaz bir yerde ortaya çıkabilir.

Bir ham kaydı dönüştürmek

Şimdi tek bir CSV kaydını program içi kayda dönüştürelim:

def kaydi_coz(kayit):
    urun_metni = kayit.get("urun")
    fiyat_metni = kayit.get("fiyat")
    adet_metni = kayit.get("adet")

    if urun_metni is None or fiyat_metni is None or adet_metni is None:
        return None

    urun = urun_adi_temizle(urun_metni)
    fiyat = negatif_olmayan_sayi_coz(fiyat_metni)
    adet = pozitif_tam_sayi_coz(adet_metni)

    if urun == "" or fiyat is None or adet is None:
        return None

    return {
        "urun": urun,
        "fiyat": fiyat,
        "adet": adet
    }

Burada üç ayrı doğrulama türü birleşiyor:

  • Beklenen sütun var mı?
  • Ürün adı boş mu?
  • Sayısal alanlar sözleşmeye uygun mu?

Tahmin et — hangi kayıtlar geçerli?

Aşağıdaki kodu çalıştırmadan önce her satırın sonucunu tahmin edin:

İlk iki kayıt sözlüğe dönüşmeli; son iki kayıt None üretmelidir.

Satır toplamı ve ürün bazında ciro

Geçerli bir kaydın ciro katkısı:

def satir_toplami(kayit):
    return kayit["fiyat"] * kayit["adet"]

Aynı ürünü hem adet hem ciro bakımından gruplayacağız:

urun_adetleri[urun] = urun_adetleri.get(urun, 0) + adet
urun_cirolari[urun] = urun_cirolari.get(urun, 0) + satir_cirosu

Bu, 10. ve 11. haftalardaki sözlük biriktirme kalıbının doğrudan uygulamasıdır.

Maksimum arama kalıbını yeniden kullanmak

Ciroya en fazla katkı yapan ürünü hazır max() kullanmadan, daha önce öğrendiğimiz maksimum arama kalıbıyla bulalım:

def en_yuksek_cirolu_urun(urun_cirolari):
    if len(urun_cirolari) == 0:
        return None

    en_urun = None
    en_ciro = None

    for urun, ciro in urun_cirolari.items():
        if en_ciro is None or ciro > en_ciro:
            en_urun = urun
            en_ciro = ciro

    return en_urun, en_ciro

Boş sözlükte anlamlı bir maksimum olmadığı için None döndürüyoruz. Bu tercih, “veri yok” durumunu 0 gibi gerçek bir sayısal sonuçla karıştırmaz.

rapor.py: ana rapor fonksiyonu

Parçaları birleştirelim:

def satis_raporu(ham_kayitlar):
    toplam_ciro = 0
    gecerli_sayisi = 0
    gecersiz_sayisi = 0
    urun_adetleri = {}
    urun_cirolari = {}

    for ham_kayit in ham_kayitlar:
        kayit = kaydi_coz(ham_kayit)

        if kayit is None:
            gecersiz_sayisi = gecersiz_sayisi + 1
            continue

        gecerli_sayisi = gecerli_sayisi + 1

        urun = kayit["urun"]
        adet = kayit["adet"]
        satir_cirosu = satir_toplami(kayit)

        toplam_ciro = toplam_ciro + satir_cirosu
        urun_adetleri[urun] = urun_adetleri.get(urun, 0) + adet
        urun_cirolari[urun] = urun_cirolari.get(urun, 0) + satir_cirosu

    return {
        "gecerli": gecerli_sayisi,
        "gecersiz": gecersiz_sayisi,
        "ciro": toplam_ciro,
        "urun_adetleri": urun_adetleri,
        "urun_cirolari": urun_cirolari,
        "lider": en_yuksek_cirolu_urun(urun_cirolari)
    }

Bu fonksiyonda yeni bir sözdizimi yoktur. Önceki haftalardan gelen kalıplar birleşmiştir:

  • 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

Gerçek projede satislar.csv dosyasını open() ile okuyacağız. Tarayıcı hücresinde ise aynı CSV metnini StringIO ile simüle edebiliriz:

Beklenen ana sonuçlar:

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

Gerçek dosyalarla çalışan ana program:

from veri import kayitlari_oku
from rapor import satis_raporu


def main():
    try:
        kayitlar = kayitlari_oku("satislar.csv")
    except FileNotFoundError as 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"] is not None:
        urun, ciro = rapor["lider"]
        print(f"Ciroya en fazla katkı: {urun} ({ciro:.2f} TL)")


if __name__ == "__main__":
    main()

Burada 13. haftadaki iki fikir birlikte görülür:

  • FileNotFoundError beklenen bir dosya problemi olarak ele alını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 bile kritik davranışları açık beklentilerle kontrol edelim:

assert urun_adi_temizle("İĞNE") == "iğne"
assert urun_adi_temizle("iğne") == "iğne"

assert negatif_olmayan_sayi_coz("12,5") == 12.5
assert negatif_olmayan_sayi_coz("0") == 0
assert negatif_olmayan_sayi_coz("-1") is None
assert negatif_olmayan_sayi_coz("abc") is None

assert pozitif_tam_sayi_coz("3") == 3
assert pozitif_tam_sayi_coz("0") is None
assert pozitif_tam_sayi_coz("-2") is None

assert kaydi_coz({"urun": " ", "fiyat": "10", "adet": "1"}) is None

rapor = satis_raporu([
    {"urun": "İĞNE", "fiyat": "5,5", "adet": "4"},
    {"urun": "iğne", "fiyat": "5,5", "adet": "2"},
])

assert rapor["gecerli"] == 2
assert rapor["gecersiz"] == 0
assert rapor["urun_adetleri"]["iğne"] == 6
assert abs(rapor["ciro"] - 33.0) < 0.001

Son satırda doğrudan == yerine tolerans kullanılması, 7. haftada gördüğümüz kayan noktalı sayı testleriyle aynı ilkedir.

Hata ayıklama senaryosu

Program beklenen 160.50 TL yerine başka bir sonuç verirse bütün kodu aynı anda değiştirmeyin.

Şu sırayı izleyin:

  1. CSV’de kaç satır olduğunu kontrol edin.
  2. kayitlari_oku() sonrasında ilk birkaç ham kaydı inceleyin.
  3. Her ham kayıt için kaydi_coz() sonucunu kontrol edin.
  4. Silgi ve Cetvel kayıtlarının neden geçersiz olduğunu doğrulayın.
  5. İĞNE ve iğne değerlerinin aynı anahtara dönüştüğünü kontrol edin.
  6. Her geçerli kayıt için satir_toplami() sonucunu hesaplayın.
  7. urun_cirolari sözlüğünün her turdaki durumunu izleyin.
  8. Tek bir hipotezi sınayacak küçük değişiklik yapın.
  9. Tüm assert kontrollerini yeniden çalıştırın.

Bu süreç, 13. haftadaki sistematik debugging yaklaşımını gerçek bir veri akışına uygular.

AI ile kontrollü kod inceleme

Bu aşamada AI’den küçük bir değişiklik veya alternatif çözüm istemek mümkündür; fakat çıktıyı doğrudan kabul etmek dersin hedefi değildir.

Örneğin AI şu değişikliği önerebilir:

def pozitif_tam_sayi_coz(metin):
    sayi = int(metin)
    if sayi < 0:
        return None
    return sayi

İlk bakışta kısa ve makul görünüyor. Ancak kabul kriterlerimize göre iki sorun vardır:

  • "abc" için ValueError üretir; kontrollü başarısızlık yoktur.
  • 0 değeri kabul edilir; oysa bu uygulamada adet pozitif olmalıdır.

Dolayısıyla AI çıktısını değerlendirirken şu üç soruyu kullanın:

  1. Sözleşmeye uyuyor mu?
  2. Sınır ve geçersiz durum testlerini geçiyor mu?
  3. Mevcut davranışlardan birini bozuyor mu?
Important

AI’nin ürettiği kodun daha kısa veya daha “profesyonel” görünmesi, doğru olduğu anlamına gelmez. Bu derste kabul ölçütü açıklanabilir ve doğrulanmış davranıştır.

Sınırlı özellik ekleme

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 için farklı fiyatlar gelirse bunu uyarı olarak raporlamak.

Özellik eklemeden önce kabul kriterini yazın ve en az bir başarısız örnek hazırlayın.

Örneğin:

Aynı ürün iki farklı fiyatla gelirse rapor bu ürünü "fiyat tutarsızlığı" olarak işaretlemeli.

Sonra veri örneği:

[
    {"urun": "Kalem", "fiyat": "10", "adet": "1"},
    {"urun": "Kalem", "fiyat": "12", "adet": "1"},
]

Ancak bundan sonra kodu değiştirin.

Yerel çalışma dosyaları

Bu bölümdeki çok dosyalı örneği kendi bilgisayarınızda çalıştırmak için proje dosyaları ders deposunda birlikte verilmiştir:

Aynı klasörde terminal açıp önce:

python test_kontrolleri.py

ardından:

python main.py

çalıştırabilirsiniz. Windows’ta kurulumunuza göre python yerine py kullanabilirsiniz.

Ders sonu kontrolü

Mikro uygulama için şu sorulara cevap verebilmelisiniz:

  1. satislar.csv verisi neden doğrudan hesaplamaya sokulmuyor?
  2. utf-8-sig ve delimiter=";" hangi gerçek dosya problemlerini çözüyor?
  3. urun_adi_temizle() neden yalnızca .lower() kullanmıyor?
  4. negatif_olmayan_sayi_coz() ile pozitif_tam_sayi_coz() sözleşmeleri neden farklıdır?
  5. None burada ne anlama geliyor ve neden is None ile kontrol ediliyor?
  6. 0 adetli satış neden bu uygulamada geçersiz kabul edildi?
  7. urun_adetleri ve urun_cirolari sözlükleri hangi biriktirme kalıbını kullanıyor?
  8. Maksimum ciro ürünü nasıl bulunuyor?
  9. FileNotFoundError hangi modülde ve neden ele alınıyor?
  10. AI tarafından üretilen bir değişikliği kabul etmeden önce hangi testleri çalıştırırsınız?

Deneme sınavı — 20 madde

Bu 20 madde final biçiminin birebir örneğidir: her madde beş şıklıdır ve dönemin tamamını tarar. Önce kendin çöz, sonra cevap anahtarındaki gerekçeleri oku.

1. Algoritma ile program arasındaki fark nedir?

  • A. Algoritma Python’da, program C gibi derlenen dillerde yazılır
  • B. Algoritma her zaman programdan kısadır
  • C. Algoritma kâğıda yazılır, program ekrana yazılır
  • D. İkisi aynı şeydir; biri Türkçe, diğeri İngilizce terimdir
  • E. Algoritma çözümün dilden bağımsız adımlarıdır; program aynı çözümün bilgisayarın çalıştırabileceği hâlidir

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

a = 10
b = a + 5
a = 20
print(a)
print(b)
  • A. 20 ve 15
  • B. 10 ve 25
  • C. 20 ve 20
  • D. 10 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. Kaldı
  • C. Geçti
  • D. Hata verir; puan karşılaştırmadan önce dönüştürülmelidir
  • E. Hiçbir şey yazmaz

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. Her yinelemeden önce; koşul yanlışsa gövde o tur hiç çalışmaz
  • D. Gövdenin ortasında, güncelleme satırından hemen sonra
  • 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, 5
  • C. 5, 4, 3, 2, 1
  • D. 1, 2, 3, 4
  • 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 parantezli, çağrı parantezsiz yazılır
  • C. İkisi aynı şeydir; def yazımı isteğe bağlıdır
  • D. Tanım dosyanın sonunda, çağrı başında yer alır
  • E. Tanım fonksiyonun ne yapacağını def ile belirler ama çalıştırmaz; çağrı fonksiyonu o anda çalıştırır

7. Bir fonksiyonun sözleşmesi hangi üç soruya cevap verir?

  • A. Hangi girdileri kabul eder, ne yapar ve ne döndürür
  • B. Hangi dosyada yer alır, kim yazmıştır ve ne zaman yazılmıştır
  • C. Ne kadar hızlı çalışır, ne kadar bellek kullanır ve kaç kez çağrılı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. P ve n
  • C. n ve P
  • D. y ve o
  • E. Hata verir; negatif indeks kullanılamaz

9. [10, 20, 30, 40][1:3] ne üretir?

  • A. 20 ve 30 ayrı ayrı
  • B. [20, 30, 40]
  • C. [20, 30]
  • D. [10, 20, 30]
  • E. [10, 20]

10. urun = {"ad": "Kalem", "fiyat": 15} iken urun["fiyat"] ifadesindeki "fiyat" nedir?

  • A. Sözlüğün adı
  • B. Bir metot çağrısı
  • C. İndeks; 1 numaralı elemanı gösterir
  • D. Anahtar; sözlükte değere ulaşmak için kullanılan addır
  • E. Değer

11. ogrenciler bir sözlük listesiyken ogrenciler[2]["puan"] ifadesi ne yapar?

  • A. puan adlı listenin 2 numaralı elemanını verir
  • B. Üçüncü kaydı siler
  • C. Listenin 2 numaralı elemanını puan değeriyle değiştirir
  • D. Bütün kayıtların puan alanlarını toplar
  • E. Önce listenin 2 numaralı kaydını seçer, sonra o kaydın puan alanını okur

12. "r", "w" ve "a" kipleri arasındaki fark nedir?

  • A. "r" okur; "w" var olan içeriği silip baştan yazar; "a" dosyanın sonuna ekler
  • B. Üçü de okuma kipidir; fark yalnızca hızdadır
  • C. "w" dosya yoksa hata verir
  • D. "r" okur; "w" sona ekler; "a" içeriği siler
  • E. "r" ve "w" metin, "a" ikili dosyalar içindir

13. Söz dizimi hatası, çalışma zamanı hatası ve mantık hatası nasıl ayrılır?

  • A. Mantık hatası her zaman bir hata mesajı üretir
  • B. Söz dizimi hatası kod okunurken, çalışma zamanı hatası yürütme sırasında ortaya çıkar; mantık hatası ise hata vermez ama yanlış sonuç üretir
  • C. Çalışma zamanı hatası kod yazılırken yakalanır
  • D. Üçü de programı hemen durdurur
  • E. Söz dizimi hatası yalnızca büyük programlarda çıkar

14. 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. Okuma, hesaplama ve çalıştırma sorumlulukları ayrılır; her parça tek başına denenip düzeltilebilir
  • D. Python büyük dosyaları çalıştıramadığı için
  • E. Her modül kendi hatalarını kendiliğinden yakaladığı için

15. Dönem boyunca kurulan çalışma biçiminde kodu yazmadan hemen önceki adım hangisidir?

  • A. Modüllere ayırmak
  • B. Programı çalıştırıp çıktıya bakmak
  • C. Değişken adlarını seçmek
  • D. Kabul kriterlerini ve sınır durumlarını belirlemek
  • E. Hata ayıklamak

16. CSV’den gelen "12,5" değeri uygulamada nasıl ele alınır?

  • A. Değer olduğu gibi toplanır
  • B. Değer int() ile çevrilir
  • C. Virgül silinip 125 elde edilir
  • D. Doğrudan float("12,5") çağrılır
  • E. Ondalık virgül noktaya çevrildikten sonra float() uygulanır; çevrilemeyen değerler geçersiz kayıt sayılır

17. Sayısal alanı güvenli çözen bir fonksiyon, dönüştürülemeyen bir değerle karşılaşınca ne yapmalıdır?

  • A. None döndürüp kaydı geçersiz olarak işaretlemeli; çağıran taraf bu kaydı rapora almamalı
  • B. Değeri rastgele bir sayıyla doldurmalı
  • C. Programı raise ile tamamen durdurmalı
  • D. 0 döndürüp hesaba katmalı
  • E. Değeri metin olarak bırakıp toplamaya çalışmalı

18. Ü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() Türkçe’ye özgü I / İ dönüşümünü yapmaz; normalleştirme kuralı bu harf çifti için ayrıca tanımlanmalıdır
  • C. lower() yeterlidir; Türkçe karakterlerde de doğru çalışır
  • D. Ürün adları sayıya çevrilmelidir
  • E. Gruplama için küme kullanılmalıdır

19. Ürün adı alanında " Kalem " değeri geldiğinde normalleştirmenin ilk adımı ne olmalıdır?

  • A. Değeri int() ile çevirmek
  • B. Değeri kısaltarak ilk beş karakteri almak
  • C. strip() ile baştaki ve sondaki boşlukları kırpmak
  • D. Değeri olduğu gibi anahtar yapmak
  • E. replace(" ", "") ile bütün boşlukları silmek

20. “Veri yok” durumunda en çok satan ürünü bulan fonksiyonun None döndürmesi neden 0 döndürmekten daha açıklayıcıdır?

  • A. None hesaplama hatalarını tamamen engeller
  • B. 0 döndürmek Python’da yasaktır
  • C. None her zaman 0dan daha iyidir
  • D. Hiç geçerli kayıt olmaması ile en yüksek cironun sıfır çıkması farklı durumlardır; None bu ayrımı korur
  • E. None bellekte daha az yer kaplar

1 — Doğru: E. Aynı algoritma Python’da da başka bir dilde de yazılabilir. Programı ayıran şey çalıştırılabilir olmasıdır.

  • A yanlış: Algoritmanın dili yoktur; belirli bir dile yazıldığı anda zaten program olur.
  • B yanlış: Uzunluk ölçüt değildir. Bir algoritma sayfalarca sürerken programı birkaç satır olabilir.
  • C yanlış: Yazıldığı yüzey farkı değildir. Algoritma bir çözüm planıdır ve bilgisayarda da tutulabilir.
  • D yanlış: Aynı şey değildir. Algoritma çözüm planı, program o planın çalışan hâlidir.

2 — Doğru: A. b hesaplandığı anda a hâlâ 10du, yani b 15 oldu. Sonradan anın değişmesi byi etkilemez.

  • B yanlış: Ne a eski değerinde kalır ne de b yeniden hesaplanır.
  • C yanlış: b ayrı bir değişkendir ve anın yeni değerini almaz.
  • D yanlış: Son atama a20 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: B. 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.
  • C yanlış: Koşul sağlanmıyor; if bloğu atlanır.
  • D yanlış: puan zaten bir sayı; dönüşüme gerek yok.
  • E yanlış: else bloğu her zaman bir çıkış yolu bırakır; en az bir satır yazılır.

4 — Doğru: C. 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’un 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.
  • D 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: D. Başlangıç dâhil, bitiş hariçtir; 5 üretilmez.

  • A yanlış: İki argüman verildiğinde ilki başlangıçtır; 0dan başlanmaz.
  • B yanlış: range() yalnızca uçları değil, aradaki bütün değerleri üretir.
  • C yanlış: Geriye saymak için negatif adım verilmesi gerekir.
  • E yanlış: Bitiş değeri hiçbir zaman üretilmez. 5i de istiyorsanız range(1, 6) yazılır.

6 — Doğru: E. def satırı yalnızca adı ve gövdeyi kaydeder. Gövde ancak ad parantezle çağrıldığında yürütülür.

  • A yanlış: Tanım hiç çalıştırmaz; ilk yürütme ilk çağrıda olur.
  • B yanlış: İkisinde de parantez vardır; tanımda parametreler, çağrıda argümanlar bulunur.
  • C yanlış: def olmadan fonksiyon oluşmaz; ikisi ayrı adımlardır.
  • D yanlış: Tam tersi güvenlidir: ad kullanılmadan önce tanımlı olmalıdır.

7 — Doğru: A. Sözleşme, fonksiyonu kullanacak kişinin gövdeyi okumadan bilmesi gereken üç şeydir.

  • B yanlış: Bunlar belgeleme bilgileridir, davranış sözleşmesi değil.
  • C yanlış: Başarım ölçütleri ayrı bir konudur.
  • D yanlış: Bunlar yararlı ayrıntılar olabilir ama sözleşmenin çekirdeği girdi, davranış ve sonuçtur.
  • E yanlış: Bunlar gövdenin iç ayrıntılarıdır; çağıranı ilgilendirmez.

8 — Doğru: B. İndeksler 0dan başlar; -1 ise sondan birinci karakteri gösterir.

  • A yanlış: -1 baştan değil sondan sayar.
  • C yanlış: İki sonuç ters yazılmış.
  • D yanlış: Bu [1] ve [-2] sonuçlarıdır; ilk indeks 0dır.
  • E yanlış: Python negatif indeksi destekler ve sondan erişim sağlar.

9 — Doğru: C. Dilimlemede başlangıç dâhil, bitiş hariçtir; 3 numaralı eleman alınmaz.

  • A yanlış: Dilim tek bir liste üretir; ayrı değerler değil.
  • B yanlış: Bitiş indeksi dilime girmez.
  • D yanlış: Başlangıç 1 olduğu için ilk eleman alınmaz.
  • E yanlış: Dilim 1den başlar, 0dan değil.

10 — Doğru: D. Sözlükte erişim konuma değil anahtara göre yapılır; 15 ise o anahtarın değeridir.

  • A yanlış: Sözlüğün adı urundur.
  • B yanlış: Metot çağrısı parantezle yazılır; buradaki köşeli parantez erişimdir.
  • C yanlış: Sözlükte sıra numarasıyla erişim yapılmaz.
  • E yanlış: Değer 15tir; "fiyat" ona ulaşmak için kullanılan addır.

11 — Doğru: E. İki farklı erişim art arda uygulanır: köşeli parantezin ilki indeks, ikincisi anahtardır.

  • A yanlış: İlk köşeli parantez ogrenciler listesine aittir.
  • B yanlış: Silme işlemi yapılmıyor.
  • C yanlış: Atama yok; yalnızca okuma yapılıyor.
  • D yanlış: Yalnızca tek bir kaydın alanı okunur.

12 — Doğru: A. "w" ile açmak dosyayı sıfırlar. Var olan veriyi korumak istiyorsanız "a" kullanılır.

  • B yanlış: Yalnızca "r" okuma kipidir.
  • C yanlış: "w" dosya yoksa oluşturur; hata veren "r"dir.
  • D yanlış: "w" ile "a" ters yazılmış.
  • E yanlış: İkili kip için "b" eklenir; "a" da metin kipidir.

13 — Doğru: B. En tehlikelisi mantık hatasıdır; çünkü program sorunsuz çalışır ve yanlışlık ancak sonuç denetlenirse fark edilir.

  • A yanlış: Mesaj üretmemesi tam da onu zor bulunur kılar.
  • C yanlış: Yazım sırasında yakalanan söz dizimi hatasıdır.
  • D yanlış: Mantık hatası programı durdurmaz.
  • E yanlış: Tek satırlık bir kodda da çıkabilir.

14 — Doğru: C. Yanlış bir ciro sonucunun kaynağı ya okuma ya da hesaplama katmanındadır; ayrım aramayı doğrudan daraltır.

  • A yanlış: Her modülün kendi ad alanı vardır; paylaşım kendiliğinden olmaz.
  • B yanlış: Hız kazancı yoktur.
  • D yanlış: Böyle bir sınır yoktur.
  • E yanlış: Hata yakalama yine açıkça yazılır.

15 — Doğru: D. Neyin doğru sayılacağı önceden yazılmazsa, sonradan çıkan sonuç “çalışıyor gibi” görünür ve doğrulanamaz.

  • A yanlış: Bölme, çözüm bir kez ortaya çıktıktan sonra yapılan bir düzenlemedir.
  • B yanlış: Çalıştırma kod yazıldıktan sonra gelir.
  • C yanlış: Adlandırma önemlidir ama kabul kriterlerinin yerini tutmaz.
  • E yanlış: Hata ayıklama, çalışan bir kod ve gözlenen bir sorun gerektirir.

16 — Doğru: E. Bu dar bir sözleşmedir ve yalnızca virgülün ondalık ayraç olduğu bilinen veride geçerlidir.

  • A yanlış: Metin değerler toplanamaz; + birleştirme yapar.
  • B yanlış: int() de virgüllü metni çeviremez; ayrıca ondalık kısım kaybolur.
  • C yanlış: Virgülü silmek değeri on kat büyütür.
  • D yanlış: Bu çağrı ValueError verir; Python ondalık ayracı olarak noktayı bekler.

17 — Doğru: A. Bozuk bir alanın sessizce 0 sayılması toplam ciroyu yanlış gösterir.

  • B yanlış: Uydurulmuş veri raporu büsbütün güvenilmez kılar.
  • C yanlış: Tek bozuk satır yüzünden bütün raporu iptal etmek çoğu durumda istenmez.
  • D yanlış: Bu, eksik veriyi geçerli bir ölçüm gibi gösterir.
  • E yanlış: Metin toplanamaz; hata bir adım sonra çıkar.

18 — Doğru: B. Genel harf dönüşümü noktalı ve noktasız i ayrımını gözetmez; casefold() de bunu tek başına çözmez.

  • A yanlış: Normalleştirmeden aynı ürün birden çok gruba dağılır.
  • C yanlış: I / İ çiftinde beklenen karşılığı vermez.
  • D yanlış: Ad bir metindir; sayıya çevrilemez.
  • E yanlış: Küme benzersizlik sağlar ama harf durumu farkını yine gidermez.

19 — Doğru: C. Görünmeyen boşluklar, gözle aynı görünen iki değeri farklı gruplara düşürür.

  • A yanlış: Ad bir metindir.
  • B yanlış: Farklı ürünler aynı önekle başlayabilir; bu kayıpsız bir kural değildir.
  • D yanlış: Boşluklu ve boşluksuz yazımlar ayrı gruplara düşer.
  • E yanlış: Bu, iki kelimeli ürün adlarını da bozar.

20 — Doğru: D. Rapor okuyan kişi “dosya boş” ile “hiç satış yapılmamış” arasındaki farkı görebilmelidir.

  • A yanlış: Çağıran taraf is None denetimini atlarsa yine hata çıkar.
  • B yanlış: Yasak değildir; bu bir tasarım kararıdır.
  • C yanlış: Her zaman değil; bedeli çağıranın ek bir denetim yapmasıdır.
  • E yanlış: Bellek bu kararın gerekçesi değildir.

Dönem özeti

Bu ders boyunca programlamayı yalnızca Python sözdizimi olarak ele almadık. Şu çalışma biçimini geliştirdik:

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

Öğrendiğimiz Python araçları bu yaklaşımı uygulamak için kullandığımız araçlardır:

  • 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.

Daha ileri derslerde yeni yapılar ve daha güçlü geliştirme araçları göreceksiniz. AI ve coding agent’lar da daha fazla sorumluluk üstlenebilir. Ancak temel ilke değişmez: üretilen kodu anlayabilmek, davranışını açıklayabilmek ve doğrulayabilmek.

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.
  • Üretilen kodu kabul ölçütleriyle değerlendirir.
  • Rapor döngüsünde continue ve get() kalıplarını uygular.
Back to top