Ek: Hatalı kod vakaları

Hatalı kod vakaları

Her vakada şu dört adımı izleyin:

  1. Programın ne yapması gerektiğini okuyun.
  2. Hatanın hangi satırda olduğunu bulun.
  3. Nedenini kendi cümlenizle açıklayın.
  4. Kodu olabildiğince az değiştirerek düzeltin, sonra en az bir sınır değeriyle yeniden deneyin.

A: Sınır ve off-by-one hataları (6 vaka)

Off-by-one hatası, döngünün ya da aralığın bir adım eksik veya bir adım fazla çalışmasıdır.

A1: 1’den 5’e kadar yazdır

Amaç: 1 2 3 4 5

for i in range(1, 5):
    print(i, end=" ")

Gözlenen: 1 2 3 4

A2: İlk eleman dâhil dört elemanı yazdır

Amaç: Listenin dört elemanını da yazdırmak.

sayilar = [10, 20, 30, 40]
for i in range(1, len(sayilar)):
    print(sayilar[i])

Gözlenen: 10 hiç yazdırılmıyor.

A3: Metnin son karakterini de al

Amaç: Python metninin tamamını yazdırmak.

metin = "Python"
print(metin[0:len(metin) - 1])

Gözlenen: Pytho; son karakter dilimin dışında kalıyor.

A4: Yaş 18 ise yetişkin kabul et

yas = 18
if yas > 18:
    print("Yetişkin")
else:
    print("Koşul sağlanmadı")

Gözlenen: Koşul sağlanmadı

A5: Listenin son indeksini aşma

Amaç: Her elemanı indeksle yazdırmak.

sayilar = [4, 8, 12]
i = 0
while i <= len(sayilar):
    print(sayilar[i])
    i += 1

Gözlenen: İlk üç değer yazıldıktan sonra IndexError.

A6: 0 ve 100 geçerli puan olsun

puan = 100
if 0 < puan < 100:
    print("Geçerli")
else:
    print("Geçersiz")

Gözlenen: 100 için Geçersiz.

  • A1: range(1, 6) kullanın; range üst sınırı dâhil etmez.
  • A2: range(len(sayilar)) ile 0’dan başlayın ya da Python’da daha yaygın olan for sayi in sayilar yazımını kullanın.
  • A3: Dilimin bitiş indeksi zaten dâhil edilmez, - 1 son karakteri de dışarıda bırakır. Metnin tamamı için metin[:] ya da metin[0:len(metin)] yazın.
  • A4: Sınır değeri dâhilse yas >= 18 yazılır.
  • A5: i < len(sayilar) olmalı, çünkü son geçerli indeks len(...) - 1’dir.
  • A6: 0 <= puan <= 100.

B: input() ve tür dönüşümü hataları (4 vaka)

B1: Yaşa 1 ekle

yas = input("Yaş: ")
print(yas + 1)

Gözlenen: TypeError.

B2: İki sayıyı topla

Örnek girdi: 10 ve 20; amaç 30.

a = input("A: ")
b = input("B: ")
print(a + b)

Gözlenen: 1020.

B3: Ondalıklı fiyatı dönüştür

fiyat = input("Fiyat: ")   # kullanıcı: 12.5
print(int(fiyat))

Gözlenen: ValueError.

B4: Aralık kontrolü harfli girdiyi yakalamıyor

puan = int(input("Puan: "))   # kullanıcı: abc
if 0 <= puan <= 100:
    print("Geçerli")
else:
    print("Geçersiz")

Gözlenen: if satırına gelmeden ValueError.

  • B1: yas = int(input(...)) yazın ya da dönüşümü ayrı bir satırda yapın.
  • B2: İki girdiyi de int() ile (ondalıklı sayı bekleniyorsa float() ile) dönüştürün.
  • B3: float(fiyat) kullanın. int(), "12.5" gibi ondalıklı bir metni tam sayıya çeviremez.
  • B4: int() hata verdiği için program if satırına hiç gelmez. 13. bölümde göreceğiniz try/except ValueError ile dönüşüm hatasını yakalayın, ardından 0–100 aralığını kontrol edin.

C: Aliasing ve kopyalama hataları (5 vaka)

C1: Yedek listeyi bağımsız tut

notlar = [70, 80]
yedek = notlar
yedek.append(90)
print(notlar)

Gözlenen: [70, 80, 90]; özgün liste de değişti.

C2: İki öğrencinin not listesi ayrı olsun

ortak = []
ada = ortak
ece = ortak
ada.append(100)
print(ece)

Gözlenen: [100].

C3: Sığ kopyanın sınırı

a = [[1, 2], [3, 4]]
b = a.copy()
b[0].append(9)
print(a)

Gözlenen: [[1, 2, 9], [3, 4]].

C4: Fonksiyon özgün listeyi değiştirmesin

def sirala(veri):
    veri.sort()
    return veri

sayilar = [3, 1, 2]
sonuc = sirala(sayilar)
print(sayilar)

Gözlenen: [1, 2, 3]; özgün liste de sıralandı.

C5: “Kopya” değişkeni aslında aynı nesne

a = [1, 2]
b = a
print(a is b)

Gözlenen: True; amaç bağımsız listeydi.

  • C1: yedek = notlar.copy() gibi bir sığ kopya oluşturun.
  • C2: ada = [] ve ece = [] diye iki ayrı liste oluşturun. Tek bir listeyi iki değişkene atamayın.
  • C3: Sığ kopya yalnız dış listeyi ayırır. İç listelerin de bağımsız olması gerekiyorsa her iç listeyi ayrıca kopyalamanız gerekir, örneğin [satir.copy() for satir in a] ile. Daha derin iç içe yapılarda derin kopya (deep copy) gerekip gerekmediğini ayrıca düşünün.
  • C4: Özgün liste korunacaksa return sorted(veri) yazın ya da sıralamadan önce kopya alın.
  • C5: b = a.copy() ya da b = a[:] gibi bir kopya gerekir.

D: Sonsuz döngü ve eksik ilerleme (4 vaka)

D1: Sayaç hiç değişmiyor

sayac = 1
while sayac <= 5:
    print(sayac)

Gözlenen: 1 sürekli yazdırılıyor.

D2: Yanlış yönde güncelleme

kalan = 3
while kalan > 0:
    print(kalan)
    kalan += 1

Gözlenen: 3, 4, 5, ... diye devam ediyor.

D3: Geçersiz girdi değişmiyor

puan = -1
while puan < 0 or puan > 100:
    print("Geçersiz")

Gözlenen: döngü bitmiyor.

D4: continue güncellemeyi atlıyor

i = 0
while i < 5:
    if i == 2:
        continue
    print(i)
    i += 1

Gözlenen: 0 ve 1 yazıldıktan sonra döngü hiç bitmiyor.

  • D1: Gövdeye sayac += 1 ekleyin.
  • D2: kalan -= 1 olmalı.
  • D3: Döngünün içinde yeni girdi alın ya da koşulu değiştirecek başka bir değişkeni güncelleyin.
  • D4: i değerini continue satırından önce artırın ya da döngüyü her turda i artacak biçimde yeniden yazın.

E: Kapsam ve dönüş değeri hataları (4 vaka)

E1: return unutulmuş

def kare(x):
    x * x

sonuc = kare(4)
print(sonuc)

Gözlenen: None.

E2: Yerel değişkeni dışarıda kullanma

def hesapla():
    toplam = 10 + 20

hesapla()
print(toplam)

Gözlenen: NameError.

E3: print ile return karıştırılmış

def topla(a, b):
    print(a + b)

sonuc = topla(2, 3)
print(sonuc * 2)

Gözlenen: önce 5, ardından TypeError (None * 2).

E4: Global adı değiştirmeye çalışırken UnboundLocalError

sayac = 0

def artir():
    sayac = sayac + 1
    return sayac

print(artir())

Gözlenen: UnboundLocalError.

  • E1: return x * x.
  • E2: toplam yalnız fonksiyonun içinde (yerel kapsamda) vardır. Değer dışarıda gerekiyorsa return toplam ile döndürün ve çağrının sonucunu bir değişkene atayın.
  • E3: Hesap yapan fonksiyon sonucu return a + b ile döndürmeli. Ekrana yazdırma işini fonksiyonu çağıran kod yapabilir.
  • E4: Önce global değişken kullanmadan çözmeyi deneyin: fonksiyon sayacı parametre olarak alsın, yeni değeri döndürsün. Global değişken gerçekten gerekiyorsa global sayac yazılır, ama küçük fonksiyonlarda gereksiz global değişkenden kaçının.

F: İndeks ve anahtar hataları (2 vaka)

F1: Son siparişi raporla

Amaç: Listedeki son sipariş kimliği olan S-103 değerini yazdırmak.

siparisler = ["S-101", "S-102", "S-103"]
son_indeks = len(siparisler)
print(siparisler[son_indeks])

Gözlenen: IndexError; len(siparisler) eleman sayısıdır, son geçerli indeks değildir.

F2: Yeni ürün gelirse stok kaydını başlat

Amaç: Gelen ürünleri mevcut stoğa eklemek; sözlükte olmayan ürünün stok sayısını 0’dan başlatmak.

stok = {"kalem": 5, "defter": 2}
gelenler = ["kalem", "silgi", "kalem"]

for urun in gelenler:
    stok[urun] += 1

print(stok)

Gözlenen: silgi işlenirken KeyError; program sonraki ürüne geçemiyor.

  • F1: Son eleman için siparisler[-1] ya da siparisler[len(siparisler) - 1] yazın. Liste boş olabiliyorsa önce eleman olup olmadığını kontrol edin.
  • F2: Bu problemde sözlükte olmayan bir ürünün gelmesi olağan bir durum, bu yüzden stok[urun] = stok.get(urun, 0) + 1 yazın. Eksik anahtarın gerçekten bir hata olduğu başka bir problemde ise köşeli parantezle erişimin KeyError vermesi işinize yarayabilir.

Son kontrol

Kod artık hata vermiyor diye işi bitmiş saymayın. Düzelttiğiniz her vakayı bir normal örnekle, mümkünse bir de sınır değeri ya da geçersiz girdiyle deneyin ve programın gerçekten yapması gereken işi yaptığını görün.

Back to top