İçeriğe geç
academia.sh

Ders 07 / 22

İnsanı Döngüde Tutmak

Yan etkili aracın önüne konan onay noktasının ölçülmesi: onay kapalıyken yirmi dört kurgu görevde beş kayıt yazılıyor ve üçü yanlış, ikinci koşumda sekiz kayıt yazılıyor ve altısı yanlış. Onay yalnız yan etkili çağrıda açıldığında yazılan kayıt üçe, yanlış kayıt bire iniyor; bedel yedi ve on bir soru. Onay her adıma yayıldığında durdurulan yazım hiç değişmiyor ama soru sayısı 74 ve 76'ya, belirteç 12103'ten 14448'e çıkıyor. Görev başarımı üç kapsamda da 23/24'te sabit kalıyor, yani başarım yan etkiyi ölçmüyor. Durdurulan çağrı sayısı engellenen kayıt sayısından büyüktür, çünkü durdurulan çağrıların bir kısmı zaten eksik alanla düşecekti.

İçindekiler

Önceki iki derste ajan kendi izine baktı, sonra ikinci bir ajan devreye girdi; ikisinde de son söz düzenekteydi. Kurgu ortamın beş aracından dördü okur, biri yazar: kayit_yaz geri alınmayan bir iz bırakır ve şimdiye kadar öbür dördüyle aynı muameleyi gördü.

Bu ders o aracın önüne bir onay noktası koyar: onay açıkken ve kapalıyken kaç kayıt yazılıyor, kaçı yanlış ve insana kaç kez soruluyor. Durakları adım aralığına göre koymak Model API’leri ile Uygulama Geliştirme kursunda ölçüldü — her adımda durmak 480 adımın 478’ini, sekiz adımda bir durmak 355’ini doğru getiriyor. O yordam tekrarlanmaz; buradaki durak aralığa göre değil, yan etkiye göre konuyor.

  • AM53. Kurulum ortaktır: ölçüm ağının kurgu abone kayıtları, kurgu belge dağarcığı, beş kurgu araç, yirmi dört kurgu görev ve ders içinde yazılmış bir ajan benzeticisi. Gerçek bir model ucu ya da araç sunucusu çağrılmaz.
  • AM54. Taban çizgisi düzeneksiz döngüdür: onay kapalı, sekiz adımlık bütçe.
  • AM55. Bir yazım iki durumda yanlıştır: istek yazma istemiyorsa (istenmeyen yan etki) ya da yazılan değer doğru yanıt değilse (yanlış değer).
  • AM56. Onay noktasında teklif edilen kayıt gösterilir. İki denetim kuralla yapılır (istek yazma istiyor mu, değer var mı), üçüncüsü yeniden hesaplamadır ve 0,60 payla yapılır.
  • AM57. Reddedilen çağrı hiç yürütülmez; ajan adımını harcar ve devam eder. Her soru ayrıca 35 belirteç durum özeti götürür.
  • AM58. Yan etki kapsamı yalnız kayit_yaz öncesi sorar; her adım kapsamı her adım öncesi sorar ama yine yalnız yan etkili çağrıyı durdurabilir.
  • AM59. İkinci koşum tohum 20260219; iki koşum farkı bu kümede bir görevdir (0,0417) ve altındaki her fark ölçülmemiş sayılır.

İki Yazım, İki Sonuç

Önce iki görev üç kapsamda koşturulur. G09 bir belge görevidir ve yazma istemez, G23 bir kayıt görevidir.

# ORTAK KURGU KURULUM -- olcum aginin 60 kurgu abonesi, 5 kurgu belge,
# 5 kurgu arac, 24 kurgu gorev ve ders icinde yazilmis ajan benzeticisi.
# Gercek bir model ucu, arac sunucusu ya da calisma zamani 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


# ---- KURGU ortam: olcum aginin kayitlari
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)


# ---- KURGU gorevler: her biri bilinen bir arac dizisiyle cozulur
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"])


# ---- KURGU ajan: her adimda bir arac secer ya da biter
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)}



# ---- Bu derste eklenen parca: yan etkili aracin onunde onay noktasi

GOR_DEGER = 0.60


def yanlis_mi(g, deger):
    """Yazim yanlistir: istek yazma istemiyorsa ya da deger dogru yanit degilse."""
    return "yaz" not in g["istek"] or deger != dogru_yanit(g)


def onay_ver(g, deger, r):
    """Onay noktasinda teklif edilen kayit gosterilir. Iki denetim kuralla,
    ucuncusu yeniden hesapla yapilir; hesaplamayan insan onaylar."""
    if "yaz" not in g["istek"]:
        return False
    if deger is None:
        return False
    if r() < GOR_DEGER:
        return deger == dogru_yanit(g)
    return True


def onayli_ajan(g, en_cok_adim, tohum, kapsam="kapali"):
    """Ortak dongu. kapsam 'yan_etki' ise yalniz yan etkili cagri oncesi,
    'her_adim' ise her adim oncesi insana sorulur; durdurma yalniz yan etkide."""
    r = uretec(tohum ^ izno(g["ad"]))
    ri = uretec(tohum ^ izno("insan|" + g["ad"]))
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    iz, adim, bel, k = [], 0, 0, 0
    s_ = {"yazim": 0, "yanlis_yazim": 0, "durdurulan": 0,
          "durdurulan_yanlis": 0, "soru": 0, "yazilan": None}
    while adim < en_cok_adim:
        adim += 1
        bel += 60 + 22 * len(iz)
        hedef = g["dizi"][k] if k < len(g["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))]
        yan = ARAC[sec]["yan_etki"]
        if kapsam == "her_adim" or (kapsam == "yan_etki" and yan):
            s_["soru"] += 1
            bel += 35
            if yan and not onay_ver(g, alan.get("sonuc"), ri):
                s_["durdurulan"] += 1
                s_["durdurulan_yanlis"] += yanlis_mi(g, alan.get("sonuc"))
                iz.append(sec)
                continue
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append(sec)
        bel += 30
        if s.get("yazildi"):
            s_["yazim"] += 1
            s_["yazilan"] = s["deger"]
            s_["yanlis_yazim"] += yanlis_mi(g, alan.get("deger"))
        if "hata" in s:
            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
    s_.update(adim=adim, bel=bel, yanit=alan.get("sonuc"))
    return s_


print("gorev  tur    kapsam    soru  yazim  yanlis  durdurulan  yazilan deger")
for i in (8, 22):
    g = GOREV[i]
    print(f"-- {g['ad']} dogru yanit {dogru_yanit(g)}")
    for ad in ("kapali", "yan_etki", "her_adim"):
        s = onayli_ajan(g, 8, TOHUM, ad)
        print(f"{g['ad']:<7}{g['tur']:<7}{ad:<10}{s['soru']:>4}{s['yazim']:>7}"
              f"{s['yanlis_yazim']:>7}{s['durdurulan']:>12}   {s['yazilan']}")
gorev  tur    kapsam    soru  yazim  yanlis  durdurulan  yazilan deger
-- G09 dogru yanit SY01
G09    belge  kapali       0      1      1           0   SY01
G09    belge  yan_etki     1      0      0           1   None
G09    belge  her_adim     2      0      0           1   None
-- G23 dogru yanit 1132
G23    kayit  kapali       0      1      1           0   TR01
G23    kayit  yan_etki     1      1      1           0   TR01
G23    kayit  her_adim     8      1      1           0   TR01

İki blok iki ayrı yanlışı gösteriyor. G09 bir belge sorusudur; ajan doğru yanıtı bulduktan sonra dolaşıp kayit_yaz çağırıyor ve hiç istenmemiş bir kayıt bırakıyor. Yazılan değer doğrudur, yanlış olan yazmanın kendisidir. Onay noktası bunu kuralla durduruyor: istek yazma istemiyorsa teklif reddedilir, hesap gerekmez.

G23 ötekidir. İstek yazma istiyor ve ortada bir değer var, yani iki kural denetimi de geçiyor. Ama ajan yazmadan önce dolaşıp belge_ara çağırmış ve biriken sonucu bir belge koduyla ezmiş: kayda 1132 yerine TR01 yazılıyor. Kural denetimi değerin varlığına bakar, türüne bakmaz; bunu görmenin tek yolu yeniden hesaplamaktır ve insan bu koşumda hesaplamıyor. Kayıt üç kapsamda da yazılıyor. Kural yanlışı bedava yakalar, değer yanlışı ancak yeniden hesapla yakalanır.

Kapsamın bedeli soru sütunundadır: G23’te her adımda sormak sekiz kez, yan etki kapsamı bir kez soruyor ve sonuç aynı.

Onayın Durdurduğu ve Ödettiği

Şimdi bütün küme üç kapsamda koşturulur.

def kosum(tohum, kapsam, en_cok_adim=8):
    CAGRI[0] = 0
    d = {"dogru": 0, "adim": 0, "bel": 0, "soru": 0, "yazim": 0,
         "yanlis_yazim": 0, "durdurulan": 0}
    for g in GOREV:
        s = onayli_ajan(g, en_cok_adim, tohum, kapsam)
        d["dogru"] += s["yanit"] == dogru_yanit(g)
        d["adim"] += s["adim"]
        d["bel"] += s["bel"]
        for a in ("soru", "yazim", "yanlis_yazim", "durdurulan"):
            d[a] += s[a]
    d["cagri"] = CAGRI[0]
    return d


for t in (TOHUM, TOHUM + 1):
    print(f"\ntohum {t}")
    print("kapsam    basarim   adim  cagri  belirtec  soru  yazim  yanlis"
          "  durdurulan")
    for kapsam in ("kapali", "yan_etki", "her_adim"):
        d = kosum(t, kapsam)
        print(f"{kapsam:<10}{d['dogru']:>4}/24{d['adim']:>7}{d['cagri']:>7}"
              f"{d['bel']:>10}{d['soru']:>6}{d['yazim']:>7}"
              f"{d['yanlis_yazim']:>8}{d['durdurulan']:>12}")
tohum 20260218
kapsam    basarim   adim  cagri  belirtec  soru  yazim  yanlis  durdurulan
kapali      23/24     97     74     11978     0      5       3           0
yan_etki    23/24     97     70     12103     7      3       1           4
her_adim    23/24     97     70     14448    74      3       1           4

tohum 20260219
kapsam    basarim   adim  cagri  belirtec  soru  yazim  yanlis  durdurulan
kapali      23/24     98     74     11994     0      8       6           0
yan_etki    23/24    100     68     12605    11      3       1           8
her_adim    23/24    100     68     14880    76      3       1           8

Birinci satır taban çizgisidir: onay kapalıyken küme beş kayıt bırakıyor ve üçü yanlış; ikinci koşumda sekiz kayıt, altısı yanlış. Aynı satırda görev başarımı 23/24. İki sayı yan yana durduğunda ders açıktır: görev başarımı yan etkiyi ölçmez. Ajan doğru yanıtı verirken ortama üç yanlış kayıt bırakıyor ve başarım bunu görmüyor.

Yan etki kapsamı açıldığında yazılan kayıt üçe, yanlış kayıt bire iniyor; ikinci koşumda da üçe ve bire. Durdurulan yanlış yazım iki koşumda 2 ve 5, ikisi de ölçüm bandının üstünde. Bedel yedi ve on bir sorudur — durdurulan yanlış yazım başına 3,5 ve 2,2 soru. Belirteç 11978’den 12103’e çıkıyor, çağrı 74’ten 70’e iniyor.

Durdurulan sütunu ile yazım sütunu arasındaki fark önemlidir. Onay noktası birinci koşumda dört çağrıyı durduruyor ama engellediği kayıt ikidir; kalan iki çağrı elinde değer olmadığı için zaten aracın hatasına düşecekti. Durdurulan çağrı, engellenen kayıt değildir.

Üçüncü satır kursun ikinci iddiasının bir örneğidir. Her adımda sormak yazılan kaydı, yanlış kaydı ve durdurulan çağrıyı hiç değiştirmiyor — üç sütun da yan etki kapsamıyla birebir aynı. Değişen tek şey bedeldir: soru 7’den 74‘e, belirteç 12103’ten 14448’e. On kat soru, sıfır kazanç. Durdurulabilecek tek çağrı türü yan etkilidir; kalan altmış yedi soruda insanın verebileceği tek yanıt onaydır.

Özet

  • Yan etkili araç ayrı ele alınmalıdır: kayit_yaz çağrıldığı anda geri alınmayan bir iz bırakır.
  • Onay kapalıyken küme beş kayıt bırakıyor ve üçü yanlış (ikinci koşumda sekiz ve altı) — ama aynı koşumda görev başarımı 23/24. Görev başarımı yan etkiyi ölçmez.
  • Onay yan etkili çağrıda açıldığında yazılan kayıt üçe, yanlış kayıt bire iniyor; durdurulan yanlış yazım iki koşumda 2 ve 5, bedeli yedi ve on bir soru.
  • Kural yanlışı bedavaya yakalanır; değer yanlışı ancak yeniden hesaplamayla yakalanır. Durdurulan çağrı sayısı da engellenen kayıt sayısından büyüktür (dörde karşı iki).
  • Onay kapsamını her adıma yaymak durdurulan yazımı hiç değiştirmiyor, soruyu 7’den 74’e ve belirteci 12103’ten 14448’e çıkarıyor.

Sonraki Adım

Yedi derste bir ajan kuruldu: döngü, adım derinliği, işin bölünmesi, durdurma ölçütü, kendi izine bakan bir tur, ikinci bir ajan ve yan etkinin önündeki onay noktası. Her derste bedel yazıldı ve eklenen adımın işi kötüleştirdiği yerler sayıyla gösterildi.

Bütün bu ölçümlerin altında sessiz bir varsayım duruyor: araç hazırdı ve doğruydu. sayac_oku her zaman aynı alanları döndürdü, tarife varsayılanına düştüğünde bile bir sayı verdi, kayit_yaz istendiği anda yazdı. Ajanın bu araçları nasıl seçebildiği hiç sorulmadı: adı, açıklaması ve şeması ne söylüyordu, sonuç modele hangi biçimde geri veriliyordu, aracın çalıştığı yerin bir sınırı var mıydı. Sonraki konu aracın kendisine bakar ve ilk soru tanımdır: bir aracın adı, açıklaması ve şeması geçerli çağrı oranını ne kadar oynatıyor.

İ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