--- baslik: Hata yönetimi: sonuc ve ? bolum: Hatalar ve dosyalar ozet: Başarı ya da hata döndüren fonksiyonlar, ? ile hata iletmek ve belki --- Programlar her zaman yolunda gitmez: kullanıcı yaş yerine "otuz" yazar, bir sayı sıfıra bölünür, aranan kayıt bulunamaz. KabaLang'de beklenebilir hatalar **dönüş değeriyle** bildirilir: fonksiyon ya başarıyı ya da hatayı döndürür ve çağıran taraf ikisini de ele almak zorundadır. ## sonuc: başarı ya da hata Dönüş türü `sonuc` olan bir fonksiyon başarıda `tamam(deger)`, başarısızlıkta `hata("mesaj")` döndürür. ```kbl fonksiyon bol(a: sayi, b: sayi) -> sonuc: eger b == 0: don hata("sıfıra bölünemez") don tamam(a // b) r = bol(20, 4) eger r.tamam_mi(): yazdir(f"Sonuç: {r.deger()}") h = bol(5, 0) eger h.hatali_mi(): yazdir("Hata: " + h.hata().mesaj()) ``` ```cikti Sonuç: 5 Hata: sıfıra bölünemez ``` | Yazım | Anlamı | |---|---| | `tamam(deger)` | başarı döndür | | `hata("mesaj")` | hata döndür | | `.tamam_mi()` / `.hatali_mi()` | hangisi olduğunu sor | | `.deger()` | başarıdaki değeri al | | `.hata().mesaj()` | hatanın açıklamasını al | | `.deger_veya(yedek)` | hata varsa yedek değeri ver | ## Yedek değerle devam etmek Hatanın nedeni seni ilgilendirmiyorsa `deger_veya()` ile bir yedek değer verirsin. ```kbl fonksiyon bol(a: sayi, b: sayi) -> sonuc: eger b == 0: don hata("sıfıra bölünemez") don tamam(a // b) yazdir(bol(20, 4).deger_veya(0)) yazdir(bol(20, 0).deger_veya(0)) ``` ```cikti 5 0 ``` ## Girdiyi denetleyen bir fonksiyon Kullanıcıdan gelen bir yaşı denetleyelim: boş olmasın, yalnız rakam içersin, gerçekçi olsun. ```kbl fonksiyon yas_coz(girdi: metin) -> sonuc: temiz = girdi.kirp() eger temiz.bos_mu(): don hata("yaş boş bırakılamaz") dongu harf icinde temiz: eger degil "0123456789".icerir(harf): don hata(f"'{temiz}' bir sayı değil") yas = sayi(temiz) eger yas > 130: don hata(f"{yas} yaş gerçekçi değil") don tamam(yas) dongu g icinde ["34", " 7 ", "", "otuz", "250"]: r = yas_coz(g) eger r.tamam_mi(): yazdir(f"✓ {r.deger()}") degilse: yazdir(f"✗ {r.hata().mesaj()}") ``` ```cikti ✓ 34 ✓ 7 ✗ yaş boş bırakılamaz ✗ 'otuz' bir sayı değil ✗ 250 yaş gerçekçi değil ``` ## ? ile hatayı yukarı iletmek Her çağrıdan sonra `eger hatali_mi()` yazmak yorucudur. Çağrının sonuna `?` koyarsan şu anlama gelir: "hata varsa bu fonksiyondan da aynı hatayla hemen çık; yoksa içindeki değeri ver." ```kbl fonksiyon bol(a: sayi, b: sayi) -> sonuc: eger b == 0: don hata("sıfıra bölünemez") don tamam(a // b) fonksiyon kisi_basi(toplam: sayi, kisi: sayi, gun: sayi) -> sonuc: kisi_payi = bol(toplam, kisi)? gunluk = bol(kisi_payi, gun)? don tamam(gunluk) yazdir(kisi_basi(12000, 4, 5).deger()) yazdir(kisi_basi(12000, 0, 5).hata().mesaj()) ``` ```cikti 600 sıfıra bölünemez ``` > **Dikkat:** `?`'yi yalnız dönüş türü kendisi de `sonuc` olan bir fonksiyonun içinde kullan. Hata ancak o zaman yukarı iletilebilir; programın ana akışında ya da dönüş türü olmayan bir fonksiyonda `?` yerine `tamam_mi()` / `deger_veya()` kullan. ## Sonucu yok saymak yasaktır `sonuc` döndüren bir fonksiyonu çağırıp sonucu hiç kullanmazsan program derlenmez. ```kbl goster fonksiyon kaydet() -> sonuc: don tamam(1) kaydet() # hata: bu çağrı bir 'sonuc' döndürüyor ve sonuç yok sayılıyor ``` Sonucu bilerek atmak istiyorsan bunu açıkça yazarsın: `_ = kaydet()`. ## belki: değer var ya da yok Hatanın bir nedeni yoksa, yalnız "bulundu / bulunamadı" ayrımı gerekiyorsa `belki` kullanılır: `dolu(deger)` ya da `bos`. ```kbl fonksiyon ilk_uzun_kelime(kelimeler: liste, en_az: sayi) -> belki: dongu k icinde kelimeler: eger k.uzunluk() >= en_az: don dolu(k) don bos liste_ = ["kar", "yağmur", "fırtına"] b = ilk_uzun_kelime(liste_, 6) eger b.var_mi(): yazdir(b.deger()) yazdir(ilk_uzun_kelime(liste_, 10).deger_veya("yok")) ``` ```cikti yağmur yok ``` ## Alıştırma ```alistirma `karekok_tam(n: sayi) -> sonuc` fonksiyonunu yaz: n negatifse `"negatif sayının karekökü yok"` hatası döndürsün; değilse karesi n'yi geçmeyen en büyük tam sayıyı (`k * k <= n` olan en büyük k) döndürsün. Verilen değerler için sonucu ya da hata mesajını yazdır. %%% # buraya yaz dongu n icinde [49, 50, -4]: r = karekok_tam(n) eger r.tamam_mi(): yazdir(r.deger()) degilse: yazdir(r.hata().mesaj()) %%% fonksiyon karekok_tam(n: sayi) -> sonuc: eger n < 0: don hata("negatif sayının karekökü yok") k = 0 iken (k + 1) * (k + 1) <= n: k += 1 don tamam(k) dongu n icinde [49, 50, -4]: r = karekok_tam(n) eger r.tamam_mi(): yazdir(r.deger()) degilse: yazdir(r.hata().mesaj()) %%% 7 7 negatif sayının karekökü yok ``` ```alistirma Verilen `stok_bul` fonksiyonunu kullanan `toplam_stok(a: metin, b: metin) -> sonuc` fonksiyonunu `?` ile yaz: iki ürünün stoklarını toplayıp döndürsün. %%% fonksiyon stok_bul(urun: metin) -> sonuc: eger urun == "kalem": don tamam(40) eger urun == "defter": don tamam(25) don hata(f"{urun} bulunamadı") # buraya yaz yazdir(toplam_stok("kalem", "defter").deger()) yazdir(toplam_stok("kalem", "silgi").hata().mesaj()) %%% fonksiyon stok_bul(urun: metin) -> sonuc: eger urun == "kalem": don tamam(40) eger urun == "defter": don tamam(25) don hata(f"{urun} bulunamadı") fonksiyon toplam_stok(a: metin, b: metin) -> sonuc: x = stok_bul(a)? y = stok_bul(b)? don tamam(x + y) yazdir(toplam_stok("kalem", "defter").deger()) yazdir(toplam_stok("kalem", "silgi").hata().mesaj()) %%% 65 silgi bulunamadı ```