İçeriğe geç
academia.sh

Ders 22 / 22

Hata Kurtarma

Başarısız bir araç çağrısının döngüye ne yaptığının üç kurtarma politikasıyla ölçülmesi: iki yüz kırk koşumluk üretim akışında ilk hatada durmak 0,7500 görev başarımı, 727 adım, 53 araç hatası ve 81996 belirteç veriyor; aynı aracı yeniden denemek başarımı 0,9375'e çıkarıyor ve adımı 900'e, hatayı 61'e, belirteci 106352'ye taşıyor. Başarısız aracı bırakıp başkasına geçmek beklenenin tersini yapıyor: araç hatası 64'e, adım 907'ye çıkıyor ve başarım 0,8917'ye düşüyor. Durdurmanın kazandırdığı adım verimliliği iki koşum bandının içinde kalıyor. Ders M28/K05 kursunun kapanışıdır ve yirmi iki dersin düzeneksiz ile düzenekli sayılarını tek tabloda toplar.

İçindekiler

Bir önceki dersin maliyet tablosunda bir sütun baştan sona sessiz kaldı: araç hatası. Altı düzenekte de hata oluştu, hiçbirinde ne yapılacağı yazılmadı. Ortak tanımın döngüsü hata gördüğünde aynı hedefe yeniden yöneliyor; bu bir davranıştır ama politika değildir, çünkü seçilmemiştir. Yeniden deneme, geri çekilme ve devre kesici yordamı Dayanıklılık ve Güvenilirlik kursunda ölçüldü; tekrarlanmaz. Ölçülen tek şey başarısız aracın döngüye ne yaptığıdır.

  • KL51. Ortam, araçlar, görevler ve döngü kurgudur. Üretim akışı bir önceki dersinkiyle aynıdır: yirmi dört görev on kez koşar, bütçe 6, toplam 240 koşum. Tohum 20260218 ve 20260219.
  • KL52. Durdur: ilk hatada döngü biter, taban budur. Yinele: hedef değişmez, bir sonraki adımda aynı hedefe yeniden yönelinir. Geç: hata döndüren araç koşumun geri kalanında seçilemez olur; çekiliş onu verirse listedeki bir sonraki araç kullanılır.
  • KL53. Kümede aynı işi gören ikinci araç yoktur; “başka araca geçmek” başarısız aracı bırakmak demektir ve plan onu gerektiriyorsa tamamlanamaz.

Üç Politika, Tek Akış

Blok ortak tanımı kurar: kurgu ortam, beş araç, yirmi dört görev ve döngü.

# KURGUDUR. Olcum aginin abone kayitlari, belge dagarcigi, bes arac ve yirmi dort
# gorev ders icinde tanimlanir; gercek bir uc nokta ya da arac sunucusu cagrilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in str(m).lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):
    h = 2166136261
    for c in str(m):
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
ABONE = {}
for i in range(60):
    r = uretec(TOHUM + 31 * i)
    onceki = 10000 + int(r() * 80000)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "onceki": onceki, "simdiki": onceki + int(r() * 70)}
BASAMAK, USTU = ((10, 4), (25, 7), (40, 11)), 16
ISYERI_KAT = 2
BELGE = {"TR01": "tarife basamaklari 10 25 40 metrekup ve ustu",
         "TR02": "isyeri abonesinde birim ucret iki katidir",
         "SY01": "endeks farki tuketimi verir sayac donusu 100000 eklenir",
         "AR01": "ariza kaydi acildiginda saha ekibi iki gun icinde gider",
         "KS01": "planli kesinti duyurusu bir hafta once yayimlanir"}

CAGRI = [0]                              # arac cagri sayaci


def _bedel(m3, tip):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    top += kalan * USTU
    return top * (ISYERI_KAT if tip == "isyeri" else 1)


def t_sayac_oku(abone=None, **_):
    a = ABONE.get(abone)
    if a is None:
        return {"hata": "abone yok"}
    return {"onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"], "bolge": a["bolge"]}


def t_tuketim(onceki=None, simdiki=None, **_):
    if onceki is None or simdiki is None:
        return {"hata": "eksik alan"}
    f = simdiki - onceki
    return {"m3": f + 100000 if f < 0 else f}


def t_tarife(m3=None, tip="mesken", **_):
    if m3 is None:
        return {"hata": "eksik alan"}
    return {"tutar": _bedel(m3, tip)}


def t_belge(anahtar=None, **_):
    if not anahtar:
        return {"hata": "eksik alan"}
    ab = set(belirtecle(anahtar))
    en, kod = -1, None
    for k, m in BELGE.items():
        o = len(ab & set(belirtecle(m)))
        if o > en:
            en, kod = o, k
    return {"kod": kod, "metin": BELGE[kod]} if en > 0 else {"hata": "bulunamadi"}


def t_kayit(abone=None, sutun=None, deger=None, **_):
    if not (abone and sutun and deger is not None):
        return {"hata": "eksik alan"}
    return {"yazildi": True, "abone": abone, "sutun": sutun, "deger": deger}


ARAC = {
    "sayac_oku":  {"islev": t_sayac_oku, "alan": ("abone",), "yan_etki": False},
    "tuketim":    {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False},
    "tarife":     {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False},
    "belge_ara":  {"islev": t_belge, "alan": ("anahtar",), "yan_etki": False},
    "kayit_yaz":  {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True},
}
ARAC_ADI = list(ARAC)


def cagir_arac(ad, durum):
    """Sema disindaki alanlar suzulur; eksik alan aracin kendi hatasidir."""
    CAGRI[0] += 1
    if ad not in ARAC:
        return {"hata": "arac yok"}
    kw = {a: durum[a] for a in ARAC[ad]["alan"] if a in durum}
    return ARAC[ad]["islev"](**kw)


GOREV = []
for i in range(24):
    r = uretec(TOHUM + 9973 * i)
    ab = f"A{1 + int(r() * 60):03d}"
    t = ayrik(r(), [0.30, 0.22, 0.20, 0.28])
    if t == 0:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "bedel", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem bedeli nedir",
                      "dizi": ("sayac_oku", "tuketim", "tarife")})
    elif t == 1:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "tuketim", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem tuketimi kac metrekup",
                      "dizi": ("sayac_oku", "tuketim")})
    elif t == 2:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "belge", "abone": ab,
                      "istek": "sayac donusunde endeks farki nasil hesaplanir",
                      "dizi": ("belge_ara",)})
    else:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "kayit", "abone": ab,
                      "istek": f"{ab} abonesinin bedelini hesapla ve kayda yaz",
                      "dizi": ("sayac_oku", "tuketim", "tarife", "kayit_yaz")})


def dogru_yanit(g):
    a = ABONE[g["abone"]]
    f = a["simdiki"] - a["onceki"]
    m3 = f + 100000 if f < 0 else f
    if g["tur"] == "tuketim":
        return m3
    if g["tur"] == "belge":
        return "SY01"
    return _bedel(m3, a["tip"])


def gorme(d):
    return max(0.34, 0.80 - 0.09 * (d - 1))       # dogru araci secme payi, derinlikle duser


def ajan(g, en_cok_adim=8, tohum=TOHUM, oz_elestiri=False, onay=False):
    """KURGU ajan dongusu. Gercek bir model cagrilmaz; arac secimi
    gorevin dizisine ve derinlige bagli tek bir cekilisten gelir."""
    r = uretec(tohum ^ izno(g["ad"]))
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    iz, adim, bel, hata = [], 0, 0, 0
    dizi, k = g["dizi"], 0
    while adim < en_cok_adim:
        adim += 1
        bel += 60 + 22 * len(iz)
        hedef = dizi[k] if k < len(dizi) else None
        if hedef is None:                          # is bitti , ajan durmali
            if r() < 0.88:
                return {"bitti": True, "adim": adim, "iz": iz, "belirtec": bel,
                        "hata": hata, "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}
            sec = ARAC_ADI[int(r() * len(ARAC_ADI))]
        else:
            sec = hedef if r() < gorme(k + 1) else ARAC_ADI[int(r() * len(ARAC_ADI))]
        if ARAC[sec]["yan_etki"] and onay:
            alan["onay"] = alan.get("onay", 0) + 1
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append((sec, "hata" in s))
        bel += 30
        if "hata" in s:
            hata += 1
            if oz_elestiri:
                bel += 40
            continue
        alan.update({kk: vv for kk, vv in s.items() if kk != "hata"})
        if sec == "tuketim":
            alan["sonuc"] = s["m3"]
        if sec == "tarife":
            alan["sonuc"] = s["tutar"]
        if sec == "belge_ara":
            alan["sonuc"] = s["kod"]
        if sec == hedef:
            k += 1
    return {"bitti": False, "adim": adim, "iz": iz, "belirtec": bel, "hata": hata,
            "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}

Politika yalnız hata dalını değiştirir.

# Kurtarma politikasi ortak dongunun yalniz hata dalini degistirir.
BUTCE, KOSUM = 6, 10
SONUC = {"tuketim": "m3", "tarife": "tutar", "belge_ara": "kod"}   # sonucu yazan araclar


def ajan_k(g, politika, en_cok_adim=BUTCE, tohum=TOHUM):
    r = uretec(tohum ^ izno(g["ad"]))
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    iz, adim, bel, hata, yasak = [], 0, 0, 0, set()
    dizi, k = g["dizi"], 0
    while adim < en_cok_adim:
        adim += 1
        bel += 60 + 22 * len(iz)
        hedef = dizi[k] if k < len(dizi) else None
        if hedef is None:
            if r() < 0.88:
                break
            sec = ARAC_ADI[int(r() * len(ARAC_ADI))]
        else:
            sec = hedef if r() < gorme(k + 1) else ARAC_ADI[int(r() * len(ARAC_ADI))]
        while sec in yasak and len(yasak) < len(ARAC_ADI):
            sec = ARAC_ADI[(ARAC_ADI.index(sec) + 1) % len(ARAC_ADI)]
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append((sec, "hata" in s))
        bel += 30
        if "hata" in s:
            hata += 1
            if politika == "durdur":
                break
            if politika == "gec":
                yasak.add(sec)
            continue
        alan.update({kk: vv for kk, vv in s.items() if kk != "hata"})
        if sec in SONUC:
            alan["sonuc"] = s[SONUC[sec]]
        if sec == hedef:
            k += 1
    return {"adim": adim, "belirtec": bel, "hata": hata, "yanit": alan.get("sonuc")}


ALAN = ("adim", "belirtec", "hata", "yanit")
print("yinele ortak ajanla ayni mi:",
      all(ajan_k(g, "yinele") == {a: ajan(g, BUTCE, TOHUM)[a] for a in ALAN} for g in GOREV))
print("\ntohum     politika  basarim  adim  hata  belirtec  dogru yanit basina adim")
for taban in (20260218, 20260219):
    for p in ("durdur", "yinele", "gec"):
        dogru, adim, bel, hata = 0, 0, 0, 0
        for d in range(KOSUM):
            for g in GOREV:
                s = ajan_k(g, p, BUTCE, taban + 7 * d)
                adim += s["adim"]
                bel += s["belirtec"]
                hata += s["hata"]
                dogru += s["yanit"] == dogru_yanit(g)
        n = KOSUM * len(GOREV)
        print(f"{taban}  {p:<8} {dogru / n:>8.4f} {adim:>5} {hata:>5} {bel:>9}"
              f" {adim / dogru:>23.2f}")
yinele ortak ajanla ayni mi: True

tohum     politika  basarim  adim  hata  belirtec  dogru yanit basina adim
20260218  durdur     0.7500   727    53     81996                    4.04
20260218  yinele     0.9375   900    61    106352                    4.00
20260218  gec        0.8917   907    64    108030                    4.24
20260219  durdur     0.7667   768    54     89180                    4.17
20260219  yinele     0.9542   944    66    114430                    4.12
20260219  gec        0.8625   954    73    116776                    4.61

Politikanın Kattığı ve Ödettiği

Çıktının ilk satırı bir doğrulamadır: kurs boyunca kullandığımız döngüde yazılmamış bir politika vardı, o da yinele’ydi.

Durdur bütün bedel sütunlarında en ucuzudur: 727 adım, 53 araç hatası, 81996 belirteç. Başarımı yinelenin 0,9375’inin 0,1875 altındadır; iki koşum farkı 0,0167 olduğundan düşüş bandın on katıdır. Doğru yanıt başına okunduğunda tasarruf kayboluyor: durdur 4,04, yinele 4,00 adım ve fark durdurun kendi koşum farkının (4,04’e karşı 4,17) içindedir. Durmak adım harcamasını düşürür, verimini değiştirmez.

Geç, kursun ikinci iddiasının örneğidir: sezgi hatanın azalmasını bekler, ölçüm tersini verir. Araç hatası 61’den 64‘e, ikinci koşumda 66’dan 73‘e çıkıyor; adım 907’ye yükseliyor, başarım 0,8917‘ye düşüyor. Mekanizma iki yönlüdür: yasaklanan araç çoğu zaman zaten yanlış seçilmiştir ve yerine geleni de yanlıştır, yani hata başka bir ada kayar; plandaki bir araç yasaklanırsa plan biter. Kayıp iki koşumda 0,0458 ve 0,0917’dir; en geniş band 0,0292 olduğundan ikisi de üstünde, ama ilki bandın bir buçuk katı.

Özet

  • Kurtarma politikası döngünün hata dalıdır; yazılmasa da bir politika koşar, burada koşan yineledir.
  • Durdur en ucuzudur (727 adım, 53 hata, 81996 belirteç), başarımı 0,1875 düşürür, adım verimliliğini iyileştirmez.
  • Başarısız aracı bırakmak araç hatasını 64’e çıkarır ve başarımı 0,8917’ye düşürür.

Kurs Kapanışı

Ders Düzeneksiz döngü Düzenekli döngü Bedel
ajan-mimarisi/01 — başarım araçsız 0,0417 döngü 0,9583 (+0,9166) adım 24’ten 97’ye
ajan-mimarisi/02 — doğru seçim payı derinlik 1: 0,8000 derinlik 4: 0,5000 (−0,3000) adım 2,86’dan 7,67’ye
ajan-mimarisi/03 — başarım tek döngü 0,9583 planlayıcı–yürütücü 0,8750 (−0,0833) adım 97’den 118’e
ajan-mimarisi/04 — başarım bütçe 2: 0,3750 bütçe 6: 1,0000 (+0,6250) belirteç 4758’den 10884’e
ajan-mimarisi/05 — başarım (24) tursuz 21/24 öz eleştiri 23/24 (+2) adım 84’ten 152’ye
ajan-mimarisi/06 — başarım (24) tek ajan 23/24 iki ajan 23/24 (0) adım 97’den 140’a
ajan-mimarisi/07 — yanlış kayıt onay kapalı 3 yan etkide onay 1 (−2) 7 onay noktası
araclar-ve-bellek/01 — geçerli çağrı oranı yalnız ad 0,2803 şema 0,8919 (+0,6116) araç hatası 113’ten 8’e
araclar-ve-bellek/02 — gözlem belirteci ham 770 özet 401 (−369) başarım aynı: 0,9583
araclar-ve-bellek/03 — kod görevi başarımı gevşek sınır 0,7778 orta sınır 0,3333 (−0,4445) 24 durdurulan çağrı
araclar-ve-bellek/04 — tamamlanan görev tam yetki 0,9583 izin listesi 0,8333 (−0,1250) 20 durdurulan çağrı
araclar-ve-bellek/05 — doğru yanıt dış bilgisiz 0,2083 birincil kaynak 0,7500 (+0,5417) çağrı 91’den 121’e
araclar-ve-bellek/06 — doğru yanıt sınırsız pencere 0,9583 pencere 120: 0,7083 (−0,2500) belirteç 9316’dan 12026’ya
araclar-ve-bellek/07 — kazanılan adım (48) belleksiz 0 seçici yazma 118 (+118) 24 kayıt
araclar-ve-bellek/08 — toplam belirteç sıkıştırmasız 21913 seçici 16569 (−5344) alanı atılan görev 8
araclar-ve-bellek/09 — bayat okuma payı eşiksiz 0,4528 eşik 1: 0,0000 (−0,4528) atılan geçerli kayıt 0,9701
ajan-kalitesi/01 — başarım araçsız taban 0,2917 kurs bütçesi 0,9583 (+0,6666) yanıt başına 3,4286’dan 4,2174’e
ajan-kalitesi/02 — yakalanan kusur (11) sınamasız 0 araç düzeyi 7 (+7) tanım kusurlarında 0,0000
ajan-kalitesi/03 — yakalanan kusur (11) araç düzeyi 7 iki katman 10 (+3) kalıntı D11
ajan-kalitesi/04 — nedeni bulunan pay yalnız sonuç 0,0000 tam gözlem 1,0000 (+1,0000) belirteç 2738’den 13623’e
ajan-kalitesi/05 — adım başına maliyet büyük sınıf 118,30 küçük sınıf 79,25 (−39,05) yanıt başına 453,5’ten 488,0’e
ajan-kalitesi/06 — başarım (240 koşum) durdur 0,7500 yeniden dene 0,9375 (+0,1875) adım 727’den 900’e

Kursun kuralı tabloda satır satır yazılıdır: bir ajanın sayısı tek bir yanıtın değil bütün döngünün sayısıdır ve durma koşulu yazılmayan ajan ölçülmemiş sayılır. Düzeneksiz sütunundaki sayılar kötü bir model yüzünden düşük değildir; döngünün nerede duracağı, aracın kendini nasıl tanıttığı, neyin hatırlanacağı ve bir adım bozulunca ne olacağı yazılmadığı için düşük çıkar.

İkinci iddia da aynı tablodan okunur: eklenen adım işi kötüleştirebilir. Adıyla yazan satırlar şunlardır: araclar-ve-bellek/02 (kırpma 0,9583’ü 0,2917’ye indirir, belirteci 15945’e çıkarır), /05 (ikincil sınıf 0,7500’ü 0,3750’ye indirir), /06 (daraltma belirteci 12026’ya çıkarır), /07 (yalnız sonuç 0,9167’yi 0,5833’e indirir), /08 (en sıkı özetleme tabanın 1,53 katını harcar), ajan-mimarisi/06 (ikinci ajan kazançsız), /07 (kapsamı yaymak soruyu 74’e çıkarır), ajan-kalitesi/05 (küçük sınıf yanıt başına pahalı) ve bu ders (geç hatayı 64’e çıkarır). Dokuz yerde eklenen adım, eklendiği için ödetti.

Ölçüm bandının altında kalan farklar da adıyla yazılır ve bulgu sayılmazlar: ajan-mimarisi/01’de tabanın tek isabeti, /02‘de komşu derinliklerin 0,0917 ve 0,0160’ı, /03‘te bölmenin 0,0833’ü, /04‘te altıdan sekize 0,0417’lik düşüş, /05’te tur farkları, araclar-ve-bellek/06’da 200 penceresindeki 0,0833, /09’da eşiği sekizin altına sıkmanın kazancı ve bu derste durdurun adım verimliliği. Hiçbiri sıfır, hiçbiri ölçülmüş değildir.

Yirmi iki derste ajan kuruldu, donatıldı ve ölçüldü. Bir şey hiç sorulmadı: her araç ders içinde elle tanımlandı. sayac_oku’nun adı, açıklaması ve şeması bu kursta yazıldı ve yalnız buradaki ajan gördü. Aynı aracın başka bir ajana, başka bir ekibe ya da başka bir uygulamaya nasıl verileceği, tanımın kimin elinde duracağı ve arayüz değiştiğinde kimin kırılacağı sorulmadı. Sonraki kurs araç tanımını bir ders içi sözlükten paylaşılan bir yüzeye dönüştürür ve bedelini sayar.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat