Dersler ve Temeller; web örnekleri PORT ortam değişkenini okur
- dersler/: 29 kısa ders (açıklama, çalıştırılabilir örnek, alıştırma). Her örneğin ve alıştırma çözümünün çıktısı Online IDE'nin hazırlık adımında gerçekten koşulup dosyadakiyle karşılaştırılır; biçim dersler/BICIM.md. - temeller/: tek konulu 12 başlangıç programı. - web/anket, web/kisalt, web/pano: port PORT ortam değişkeninden okunur (Online IDE önizlemesi 8080 verir), yoksa eski sabit port. - README: öğrenme bölümü, Online IDE bağlantısı.
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
---
|
||||
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<sayi, Hata>` 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<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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<T>` kullanılır: `dolu(deger)` ya da `bos`.
|
||||
|
||||
```kbl
|
||||
fonksiyon ilk_uzun_kelime(kelimeler: liste<metin>, en_az: sayi) -> belki<metin>:
|
||||
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<sayi, Hata>` 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<sayi, Hata>:
|
||||
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<sayi, Hata>` fonksiyonunu `?` ile yaz: iki ürünün stoklarını toplayıp döndürsün.
|
||||
%%%
|
||||
fonksiyon stok_bul(urun: metin) -> sonuc<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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<sayi, Hata>:
|
||||
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ı
|
||||
```
|
||||
Reference in New Issue
Block a user