Ders 20 / 22
Çıktı Doğrulama
Şema doğrulaması ve iş kuralı denetiminin ayrı ayrı sayılması ve üzerine bir yeniden deneme döngüsü kurulması: 120 kurgu yanıtın 24'ü şemaya uymuyor, şemadan geçen 96 kaydın 24'ü iş kuralına takılıyor ve doğrulama yokken hatalı kayıt oranı 0,4000. İki denetim birlikte kabul oranını 0,6000'a indiriyor, bir yeniden deneme 26 kaydı kurtarıp 0,8167'ye çıkarıyor ve 48 ek çağrıya mal oluyor. İkinci deneme sekiz kayıt daha kurtarıyor ama kazancı 0,0666 ile iki koşum farkı 0,0667'nin altında kalıyor. Hatayı isteme yazan deneme 23 kayıt kurtarıyor ve 514 belirteç ekliyor.
İçindekiler
Önceki ders çıktının biçimini üç düzeyde ölçtü ve doğrulayıcıyı yalnız bir sayaç olarak kullandı: kaç yanıtın düştüğünü saydı, düşenleri attı. Kapanışında iki eksik yazılıydı. Birincisi, bir üretim hattında düşen kaydı atmak bir seçenek değildir. İkincisi, şemadan geçen bir kayıt da yanlış olabilir: önceki dersin biçim tarifi satırında şemadan geçen kayıtların on üçü, isteme yazılan numaranın yerine kayıtlı olmayan bir talep numarası taşıyordu ve doğrulayıcı bunu hiç görmedi.
Bu ders iki denetimi ayırır ve üzerine bir yeniden deneme döngüsü kurar. Girdi doğrulama, şema ve iş kuralı yordamı M16’nın API sözleşmesi kursunda ve M24’te ölçüldü; burada tekrarlanmaz. Eklenen tek şey üreticinin belirsiz olmasıdır: reddedilen bir kayıt yeniden istenebilir ve ikinci istek başka bir yanıt verebilir. Ölçülecek olan da budur — doğrulamanın yakaladığı, yeniden denemenin kurtardığı ve bunun kaç çağrıya mal olduğu.
- CD25. Kod bir benzeticidir; gerçek bir uç nokta çağrılmaz. Talepler, alanlar ve kurallar kurgudur, tohum 20260218.
- CD26. Başlangıç istemi önceki dersin biçim tarifi istemidir; şema dayatması bilerek kullanılmaz, çünkü bu ders hatalı çıktının ne yapıldığını ölçer.
- CD27. İki denetim ayrıdır. Şema doğrulaması alanların varlığına ve değer kümelerine bakar. İş kuralı denetimi yalnız şemadan geçmiş kayıtlara uygulanır ve kurumun kurallarına bakar.
- CD28. Üç iş kuralı kurgudur: yüksek öncelikli bir kayıt bilgilendirmeyle kapatılamaz, kesinti konulu bir kayıt tek başına kayıtla kapatılamaz, ve talep numarası kayıtlı talepler kümesinde olmalıdır. Üçünü de şema göremez.
- CD29. Yeniden deneme aynı isteği yeni bir tohumla tekrar eder. Model belirsiz olduğu için ikinci yanıt başka çıkabilir; bu, düzeltmenin tek dayanağıdır.
- CD30. Bir değişke, hatayı isteme yazar: reddedilen yanıtın hata adı isteme eklenir. Bu, giriş belirtecini artırır.
- CD31. Sisteme giren hatalı kayıt ayrıca sayılır: doğrulama olmadığında kabul oranı 1,0000 görünür ama kaydın bir bölümü bozuktur.
- CD32. Bedel ek çağrı sayısı ve toplam belirteç olarak yazılır; iki koşum farkı için ikinci koşum tohum 20260219 ile alınır.
Şemanın Göremediği Hata
Şema bir kaydın biçimini tanımlar: hangi alanlar var, değerler hangi kümeden. Bir kurumun kuralları ise kaydın anlamına bakar ve şemanın diliyle yazılamaz. Bu ders üç kurgu kural tanımlar ve üçünün de kusursuz biçimli kayıtlarda tetiklendiğini gösterir.
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Sema dogrulamasi # ve is kurali denetimi ders icinde yazilir; disaridan kitaplik kullanilmaz. 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): # KURGU belirtecleyici, parca en cok bes damga b = [] for s in 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 m: h = ((h ^ ord(c)) * 16777619) & M32 return h KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"] ONCELIK, AKSIYON = ["dusuk", "orta", "yuksek"], ["kayit", "yonlendirme", "bilgi"] SEMA = {"talep_no": "sayi", "konu": KONU, "oncelik": ONCELIK, "aksiyon": AKSIYON} KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"), ("faturami odedim ama sistemde borc gorunuyor", "fatura"), ("fatura ayrintisini nereden gorebilirim", "fatura"), ("evde su akmiyor bir ariza var galiba", "ariza"), ("baglanti bozuk oldu ve hic calismiyor", "ariza"), ("ariza kaydi actim ama ekip gelmedi", "ariza"), ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"), ("sayac degisimi icin randevu istiyorum", "sayac"), ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"), ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"), ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"), ("birim ucret abone tipine gore degisiyor mu", "tarife"), ("mahallede kesinti var ne zaman gelecek", "kesinti"), ("planli kesinti duyurusu nereden takip edilir", "kesinti"), ("aksamdan beri kesinti yasiyoruz", "kesinti")] TALEP = [] for i in range(120): # 120 KURGU destek talebi r = uretec(TOHUM + i) k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])] TALEP.append({"no": 4001 + i, "konu": k, "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]}) IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac", "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti"} TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura", "ekip": "kesinti", "takip": "tarife", "giril": "fatura"} # yaniltici baglar SAYAC = [0] def ayristir(metin): """Anahtar=deger cifti ayristirici. Ayrilamayan yanit icin None doner.""" if "=" not in metin: return None kayit = {} for parca in metin.split(";"): if "=" not in parca: return None a, _, d = parca.partition("=") kayit[a.strip()] = d.strip() return kayit def dogrula(kayit): """Sema dogrulama: eksik anahtar, fazladan anahtar, gecersiz deger.""" if kayit is None: return ["ayristirilamadi"] hata = [f"eksik:{a}" for a in SEMA if a not in kayit] hata += [f"fazla:{a}" for a in kayit if a not in SEMA] for a, kural in SEMA.items(): if a not in kayit: continue d = kayit[a] if kural == "sayi" and not d.isdigit(): hata.append(f"sayi_degil:{a}") elif kural != "sayi" and d not in kural: hata.append(f"gecersiz:{a}") return hata def cekilis(istem, tohum, tuz): """Her karar icin ayri tuzlanmis tek cekilis; kararlar birbirine baglanmaz.""" return uretec((tohum + tuz) ^ izno(istem))() def cagir(istem, talep, tohum=TOHUM): """Onceki dersin bicim tarifi istemi; yanitin bir payi tarife uymaz.""" SAYAC[0] += 1 bel = belirtecle(istem) p = {k: 0.15 for k in KONU} for t in belirtecle(talep["metin"]): # konu yalniz talep metninden okunur for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)): if tablo.get(t) in p: p[tablo[t]] += w k = max(sorted(p), key=lambda a: p[a]) o = ONCELIK[ayrik(cekilis(istem, tohum, 11), [0.31, 0.44, 0.25])] a = AKSIYON[ayrik(cekilis(istem, tohum, 29), [0.46, 0.32, 0.22])] duz = f"talep_no={talep['no']} ; konu={k} ; oncelik={o} ; aksiyon={a}" egilim = 0.62 if "bicim" in bel else 0.0 # istemdeki bicim tarifi if "hatal" in bel: # hatayi isteme yazan deneme egilim += 0.14 if cekilis(istem, tohum, 53) < egilim: return duz bozuk = ayrik(cekilis(istem, tohum, 71), # tarife uymayan yanit [0.22, 0.20, 0.18, 0.16, 0.24]) if bozuk == 0: return f"talebiniz {k} konusunda kaydedildi ve {a} adimi baslatildi" if bozuk == 1: return f"talep_no={talep['no']} ; konu={k} ; aksiyon={a}" if bozuk == 2: return f"talep_no={talep['no']} ; konu={k} ; oncelik=acil ; aksiyon={a}" if bozuk == 3: return f"talep_no=TL{talep['no']} ; konu={k} ; oncelik={o} ; aksiyon={a}" return f"talep_no={talep['no'] + 500} ; konu={k} ; oncelik={o} ; aksiyon={a}" TARIF = ("Yaniti su bicimde yaz: talep_no=<sayi> ; konu=<fatura|ariza|sayac|" "tarife|kesinti> ; oncelik=<dusuk|orta|yuksek> ; aksiyon=<kayit|" "yonlendirme|bilgi> . ") def istemi(onek, x): return onek + f"Talep {x['no']} : {x['metin']}" KAYITLI = {t["no"] for t in TALEP} def is_kurali(kayit): """Semadan gecen kaydin kurum kurallari. Sema bunlarin hicbirini goremez.""" hata = [] if kayit.get("oncelik") == "yuksek" and kayit.get("aksiyon") == "bilgi": hata.append("yuksek_oncelik_bilgi_ile_kapanamaz") if kayit.get("konu") == "kesinti" and kayit.get("aksiyon") == "kayit": hata.append("kesinti_kayitla_kapanamaz") if kayit.get("talep_no", "").isdigit() and int(kayit["talep_no"]) not in KAYITLI: hata.append("kayitli_olmayan_talep_no") return hata sem, isk, gorulen = 0, 0, {} for x in TALEP: y = cagir(istemi(TARIF, x), x) kayit = ayristir(y) h = dogrula(kayit) if h: sem += 1 continue k = is_kurali(kayit) isk += bool(k) if k: gorulen.setdefault(k[0], y) print(f"KURGU talep {len(TALEP)}: semaya takilan {sem}, is kuraline takilan {isk}") for e, y in sorted(gorulen.items()): print(f" {e}\n {y}")
KURGU talep 120: semaya takilan 24, is kuraline takilan 24
kayitli_olmayan_talep_no
talep_no=4505 ; konu=sayac ; oncelik=orta ; aksiyon=kayit
kesinti_kayitla_kapanamaz
talep_no=4015 ; konu=kesinti ; oncelik=dusuk ; aksiyon=kayit
yuksek_oncelik_bilgi_ile_kapanamaz
talep_no=4022 ; konu=tarife ; oncelik=yuksek ; aksiyon=bilgi
İki sayı birbirine eşit ve bu eşitlik dersin çıkış noktasıdır: 24 yanıt şemaya uymuyor, şemadan geçen 96 yanıtın 24’ü iş kuralına takılıyor. Yani biçim denetimi hatanın ancak yarısını görüyor. Üç örneğin üçü de kusursuz biçimlidir; ayrıştırıcı ve doğrulayıcı hiçbirinde bir şey bulmaz. Birincisinde talep numarası istemde yazılı olmayan bir sayıdır, ikincisinde kesinti kaydı yanlış aksiyonla kapatılmıştır, üçüncüsünde yüksek öncelikli bir kayıt bilgilendirmeye bağlanmıştır.
Bu üç kural şemanın diline çevrilemez, çünkü hiçbiri tek bir alanın değeriyle ilgili değildir. İlk ikisi alanlar arası bir tutarlılıktır, üçüncüsü ise kaydın dış dünyayla tutarlılığıdır. Belirsiz bir üreticinin çıktısında bu iki sınıf ayrı ayrı sayılmadan doğrulama ölçülmüş sayılmaz.
Yeniden Denemenin Kurtardığı
Altı hat aynı 120 talepte koşturulur. İlk üçünde yeniden deneme yoktur ve yalnız denetimin neyi elediği ölçülür; son üçü reddedilen kaydı yeniden ister.
HAT = [("dogrulama yok", False, False, 0, False), ("yalniz sema", True, False, 0, False), ("sema + is kurali", True, True, 0, False), ("+ 1 yeniden deneme", True, True, 1, False), ("+ 2 yeniden deneme", True, True, 2, False), ("+ 1 deneme, hata istemde", True, True, 1, True)] def denetle(kayit, semali, kurali): h = dogrula(kayit) if semali else [] if not h and kurali and kayit is not None: h = is_kurali(kayit) return h def hat(semali, kurali, deneme, hatayi_yaz, tohum=TOHUM): SAYAC[0] = 0 ilk_sema = ilk_kural = kurtarilan = kabul = hatali = ek = bel = 0 for x in TALEP: istem = istemi(TARIF, x) y = cagir(istem, x, tohum) bel += len(belirtecle(istem)) + len(belirtecle(y)) kayit = ayristir(y) ilk_sema += bool(dogrula(kayit)) ilk_kural += not dogrula(kayit) and bool(is_kurali(kayit)) h = denetle(kayit, semali, kurali) for d in range(deneme): if not h: break ek += 1 i2 = istem + f" Onceki yanit hatali: {h[0]} ." if hatayi_yaz else istem y = cagir(i2, x, tohum + 1 + d) bel += len(belirtecle(i2)) + len(belirtecle(y)) kayit = ayristir(y) h = denetle(kayit, semali, kurali) kurtarilan += not h kabul += not h hatali += (not h) and bool(dogrula(kayit) or is_kurali(kayit)) return (ilk_sema, ilk_kural, kurtarilan, kabul / 120, hatali / 120, ek, bel) print("hat sema kural kurtarilan kabul hatali ek cagri belirtec") for ad, s, k, d, w in HAT: a = hat(s, k, d, w) print(f"{ad:<25} {a[0]:>4} {a[1]:>5} {a[2]:>10} {a[3]:>6.4f} {a[4]:>6.4f}" f" {a[5]:>8} {a[6]:>8}") b = hat(True, True, 1, False, TOHUM + 1) print(f"ikinci kosum (+ 1 yeniden deneme): kabul {b[3]:.4f}, kurtarilan {b[2]}, " f"ek cagri {b[5]}")
hat sema kural kurtarilan kabul hatali ek cagri belirtec dogrulama yok 24 24 0 1.0000 0.4000 0 7403 yalniz sema 24 24 0 0.8000 0.2000 0 7403 sema + is kurali 24 24 0 0.6000 0.0000 0 7403 + 1 yeniden deneme 24 24 26 0.8167 0.0000 48 10350 + 2 yeniden deneme 24 24 34 0.8833 0.0000 70 11716 + 1 deneme, hata istemde 24 24 23 0.7917 0.0000 48 10864 ikinci kosum (+ 1 yeniden deneme): kabul 0.7500, kurtarilan 26, ek cagri 56
İlk üç satır tek bir çağrıyla üretilmiştir ve belirteç sütunu üçünde de aynıdır: 7403. Değişen tek şey kabulden önce yapılan denetimdir. Doğrulama yokken kabul oranı 1,0000 görünür ve kayıt sistemine giren yanlış kayıt oranı 0,4000’dır. Yani hiçbir şey ölçülmediğinde sistem kusursuz görünür ve her beş kayıttan ikisi bozuktur. Şema eklendiğinde hatalı kayıt 0,2000’a, iş kuralı da eklendiğinde 0,0000’a iniyor.
Bunun bedeli kabul oranıdır: 1,0000’dan 0,6000’a. Doğrulama hiçbir kaydı düzeltmez, yalnız görünür kılar. Üçüncü satırdaki sistem birincisinden daha iyidir ama daha az iş yapar; 48 talep elde kalır. Doğrulamanın ölçüsü kabul oranı değil, kabul edilenlerin ne kadarının doğru olduğudur.
Kurtarmanın Bedeli
Dördüncü satır yeniden denemeyi ekliyor. 26 kayıt kurtarılıyor ve kabul oranı 0,6000’dan 0,8167’ye çıkıyor; hatalı kayıt oranı 0,0000’da kalıyor, çünkü kurtarma denetimin önüne değil arkasına konmuştur. Bedel 48 ek çağrı ve 2947 belirteçtir: kurtarılan kayıt başına 1,85 çağrı ve 113,3 belirteç. Kazanç 0,2167 ve iki koşum farkı 0,0667 olduğu için bu satır rahatça ölçülebilir.
Beşinci satır kursun kuralının en keskin uygulandığı yerdir. İkinci deneme sekiz kayıt daha kurtarıyor ve kabul oranını 0,8833’e çıkarıyor. Kazanç 0,0666. Aynı hattın iki koşum farkı ise 0,0667: birinci koşumda 0,8167, ikinci koşumda 0,7500. Kazanç farktan büyük değil, dolayısıyla ölçülmemiş sayılır. Bu satır için ödenen bedel ise kesindir: 22 ek çağrı ve 1366 belirteç, kurtarılan kayıt başına 2,75 çağrı. Ölçülemeyen bir kazanç, ölçülebilir bir bedelle satın alınmıştır.
Altıncı satır sezgiye en uygun düzeltmeyi sınıyor: reddedilen yanıtın hatasını isteme yazmak. Sonuç 26 yerine 23 kurtarma ve kabul oranında 0,7917. Aradaki 0,0250, iki koşum farkı 0,0667’nin çok altında kaldığı için bu satırla dördüncü satır arasında ölçülebilir bir fark yoktur. Bedel ise ölçülebilir: aynı 48 çağrıyla belirteç 10350’den 10864’e çıkıyor, yani 514 belirteç eklenmiştir. Hataları isteme yazmak burada bir iyileştirme değil, ölçülmemiş bir tahmindir.
Üç sayıyla toparlanır. Önceki istem biçim tarifi istemidir: kabul 0,6000, hatalı kayıt 0,0000, 7403 belirteç, 120 çağrı. Değiştirilmiş hat bir yeniden deneme ekler: kabul 0,8167, aynı hatalı kayıt oranı, 10350 belirteç, 168 çağrı. Bedel 48 çağrı ve 2947 belirteçtir; bu kursta ilk kez bir düzenek çağrı sayısını oynatıyor ve bedelin belirteçten büyük olan kısmı orada duruyor.
Özet
- Şema doğrulaması 24 yanıtı eliyor, iş kuralı denetimi şemadan geçen 96 yanıtın 24’ünü daha eliyor: biçim denetimi hatanın yarısını görüyor.
- Üç iş kuralının üçü de kusursuz biçimli kayıtlarda tetikleniyor; ikisi alanlar arası tutarlılık, biri kaydın dış dünyayla tutarlılığıdır.
- Doğrulama yokken kabul oranı 1,0000 ve sisteme giren hatalı kayıt 0,4000’dır; iki denetim hatalıyı 0,0000’a indirirken kabulü 0,6000’a düşürür. Doğrulama düzeltmez, görünür kılar.
- Bir yeniden deneme 26 kaydı kurtarır ve kabulü 0,8167’ye çıkarır; bedeli 48 ek çağrı ve 2947 belirteçtir, kurtarılan kayıt başına 1,85 çağrı.
- İkinci denemenin kazancı 0,0666, hattın iki koşum farkı 0,0667’dir: kazanç ölçülmemiş sayılır ve karşılığında 22 çağrı ile 1366 belirteç ödenir.
- Hatayı isteme yazmak 26 yerine 23 kayıt kurtarır ve 514 belirteç ekler; iki hat arasında ölçülebilir bir fark yoktur.
Sonraki Adım
Bu derste kurtarma tek bir kaldıraçla yapıldı: aynı isteği yeniden sormak. Kurtarılamayan 14 kayıt ise hiç incelenmedi. Onların bir kısmı ne kadar denenirse denensin düzelmez, çünkü sorun yanıtın çekilişinde değil, modelin bilmediği bir şeydedir. Bir talebin hangi tarife basamağına girdiği isteme yazılmamışsa, daha iyi bir yönerge bunu üretemez. Sonraki ders bu ayrımı sayar: aynı yanlış yanıt bazen daha iyi bir yönergeyle, bazen yalnız eksik bilginin sağlanmasıyla düzelir. Hangi hatanın hangisiyle düzeldiği ayrı ayrı sayılır ve ikisinin bedeli karşılaştırılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.