Ders 04 / 10
Kaynak Sistemler
Üç kaynak sınıfının bozulma profilinin çıkarılması ve her bozulma sınıfının kaç aşama sonra yakalandığının sayılması: sağlam teslimde üçü de 2400 satır veriyor ve aynı beş sunum değerini üretiyor, hiçbir denetim ateşlemiyor. Bozulma geldiğinde ayrılıyorlar: uygulama veritabanı altı sınıfın üçünü taşıyor ve toplam gecikmesi 4 aşama, günlük beşini taşıyor ve toplam gecikmesi 8, dış servis altısını da taşıyor ve toplam gecikmesi yine 8. Hoşgörülü ayrıştırma tür kaymasını iki kaynakta da görünmez kılıyor: 200 satır bozuluyor, yakalayan denetim yok, sunulan beş değer birebir aynı kalıyor. Satır sayısı denetimi 0,05 toleransla üç sınıfın hiçbirini yakalamıyor çünkü en büyük satır farkı 60, yani 0,0250; tolerans 0,0100'e indirildiğinde üçünü de yakalıyor ama dayanağı üreticinin kendi beyanı olduğunda hiçbir toleransla yakalamıyor.
İçindekiler
Önceki üç ders hattı verinin geldiği yerden değil, elde olduğu yerden kurdu: iki bin dört yüz satır ortada duruyordu, beş aşamadan geçiyordu ve her aşamanın düşürdüğü satır sayılıyordu. O satırların nereden geldiği sorulmadı. Oysa bozulma hattın içinde doğmaz; üretici tarafında doğar ve hatta teslim edilir.
Bir kaynak sistem (source system) ölçü açısından bir ürün değil üç şeydir: veriyi hangi biçimde teslim ettiği, hangi bozulma sınıflarını üretebildiği ve hangi denetimin ona dayanacak bir referans bulabildiği. Üç kaynak sınıfı bu üçlüyle tanımlanır; her biri için kaç bozulma sınıfı taşındığı ve her sınıfın kaç aşama sonra yakalandığı sayılır.
- YD41. Kod kurgudur; gerçek bir depo, motor ya da orkestratör çağrılmaz. Kaynak bir ölçüm ağının kurgu sayaç okumalarıdır: 200 abone, 12 dönem, 2400 satır, tohum 20260218.
- YD42. Kaynak sınıfı bir ürün değil bir güvence kümesidir; ürün adı yazılmaz, sınıflar türleriyle anılır.
- YD43. Bir kaynak sınıfının taşımadığı bozulma sınıfı koşturulmaz; taşıma kararı güvenceden çıkar. Bildirimli sütun türü olan kaynak tür kayması, birincil anahtarı zorlayan kaynak yinelenen satır üretemez.
- YD44. Bozulma sınıfları saldırı değil üretici tarafı kazasıdır; her biri yalnız 2026-07 dönemini bozar.
- YD45. Yedi denetim her kaynakta açıktır; yok sayılan tek şey dayanağı olmayan denetimdir.
- YD46. Yakalama gecikmesi aşama olarak yazılır; yakalayan yoksa tanımsızdır ve toplama katılmaz. Satır oranının adımı 1/2400, yani 0,0004; sunum üzerinde oran basılmaz.
Üç Kaynak Sınıfı ve Sağlam Teslim
Aşağıdaki blok ortak tanımı kurar — kurgu kaynak, beş aşamalı hat, altı bozulma sınıfı, yedi denetim — ve üzerine üç bağdaştırıcı ekler. Uygulama veritabanı bildirimli şema ile sütun türü taşır ve birincil anahtarı zorlar. Günlük eklemeli metin satırıdır: alan adlarını ayrıştırıcı verir, tür hoşgörülü okunur. Dış servis sayısal alanı metin teslim eder.
# KURGUDUR. Gercek bir depo, motor ya da orkestrator cagrilmaz; olcum aginin # sayac okumalari kurgudur, tohum 20260218. 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 BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"] TIP = ["mesken", "isyeri"] DONEM = [f"2026-{a:02d}" for a in range(1, 13)] ABONE = {} for i in range(200): r = uretec(TOHUM + 37 * i) ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)], "baslangic": 10000 + int(r() * 60000)} def kaynak_uret(): # her donem her abone icin bir okuma kayit = [] for i, (ab, a) in enumerate(ABONE.items()): e = a["baslangic"] for d in DONEM: r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d)) e += 4 + int(r() * 46) kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"], "endeks": e, "birim": "m3"}) return kayit # ---- Alti bozulma sinifi. Hicbiri saldiri degil; hepsi uretici tarafi kazasi. BOZULMA = ["gec_gelen", "yinelenen", "sema_degisti", "birim_degisti", "eksik_bolum", "kayan_tip"] def boz(kayit, sinif, donem="2026-07"): """Tek bir donemi bozar , kalan donemler saglam kalir.""" yeni, sayac = [], 0 for k in kayit: if k["donem"] != donem: yeni.append(k) continue if sinif == "gec_gelen": if k["abone"] <= "A040": # bu donemde 40 abone hic gelmedi sayac += 1 continue yeni.append(k) elif sinif == "yinelenen": yeni.append(k) if k["abone"] <= "A060": # 60 kayit iki kez geldi yeni.append(dict(k)) sayac += 1 elif sinif == "sema_degisti": y = dict(k) y["endeks_degeri"] = y.pop("endeks") # alan adi degisti sayac += 1 yeni.append(y) elif sinif == "birim_degisti": y = dict(k) y["endeks"] = k["endeks"] * 1000 # m3 yerine litre y["birim"] = "m3" # ETIKET DEGISMEDI , sessiz bozulma sayac += 1 yeni.append(y) elif sinif == "eksik_bolum": if k["bolge"] == "kuzey": # bir bolgenin bolumu hic yazilmadi sayac += 1 continue yeni.append(k) elif sinif == "kayan_tip": y = dict(k) y["endeks"] = str(k["endeks"]) # sayi metne dondu sayac += 1 yeni.append(y) return yeni, sayac # ---- HAT: bes asama, her asama kendi dusurdugu satiri sayar. def a1_ayikla(kayit): ZOR = ("abone", "donem", "bolge", "endeks", "birim") tut = [k for k in kayit if all(a in k for a in ZOR)] return tut, len(kayit) - len(tut) def a2_tekille(kayit): gor, tut = set(), [] for k in kayit: ad = (k["abone"], k["donem"]) if ad in gor: continue gor.add(ad) tut.append(k) return tut, len(kayit) - len(tut) def a3_tuketim(kayit): tablo = {(k["abone"], k["donem"]): k for k in kayit} cikti, dusen = [], 0 for k in kayit: i = DONEM.index(k["donem"]) if i == 0: continue onceki = tablo.get((k["abone"], DONEM[i - 1])) if onceki is None: dusen += 1 continue try: f = int(k["endeks"]) - int(onceki["endeks"]) except (TypeError, ValueError): dusen += 1 continue cikti.append(dict(k, m3=f)) return cikti, dusen def a4_ozet(kayit): top = {} for k in kayit: ad = (k["bolge"], k["donem"]) top[ad] = top.get(ad, 0) + k["m3"] return top, 0 def a5_sun(ozet): # bolge basina donem ortalamasi bolge = {} for (b, d), v in ozet.items(): bolge.setdefault(b, []).append(v) return {b: round(sum(v) / len(v), 2) for b, v in bolge.items()}, 0 ASAMA = [("ayikla", a1_ayikla), ("tekille", a2_tekille), ("tuketim", a3_tuketim), ("ozet", a4_ozet), ("sun", a5_sun)] # ---- Yedi denetim, her biri belirli bir asamadan SONRA kosar. def d_sema(veri, alanlar=("abone", "donem", "bolge", "endeks", "birim")): return any(any(a not in k for a in alanlar) for k in veri) def d_tip(veri): return any(not isinstance(k.get("endeks"), int) for k in veri) def d_tekillik(veri): ad = [(k["abone"], k["donem"]) for k in veri] return len(ad) != len(set(ad)) def d_satir_sayisi(veri, beklenen, pay=0.05): return abs(len(veri) - beklenen) / beklenen > pay def d_bolum_tamligi(veri): """KUSURLU DENETIM: bolge kumesine bakar , donemi gormez.""" return set(k["bolge"] for k in veri) != set(BOLGE) def d_bolum_tamligi_donem(veri): gor = set((k["bolge"], k["donem"]) for k in veri) return gor != set((b, d) for b in BOLGE for d in DONEM) def d_dagilim(ozet, taban, pay=0.25): for ad, v in ozet.items(): t = taban.get(ad) if t and abs(v - t) / max(abs(t), 1) > pay: return True return False DENETIM = [("sema", 0, lambda v, t: d_sema(v)), ("tip", 0, lambda v, t: d_tip(v)), ("tekillik", 0, lambda v, t: d_tekillik(v)), ("satir_sayisi", 0, lambda v, t: d_satir_sayisi(v, t["beklenen_satir"])), ("bolum", 0, lambda v, t: d_bolum_tamligi(v)), ("bolum_donem", 0, lambda v, t: d_bolum_tamligi_donem(v)), ("dagilim", 4, lambda v, t: d_dagilim(v, t["taban_ozet"]))] def denetimli_hat(kayit, taban, acik): """Ilk yakalayan denetimi ve yakalama gecikmesini (asama numarasi) dondurur.""" veri, yakalayan, gecikme = kayit, None, None for adim in range(len(ASAMA) + 1): if adim > 0: veri, _ = ASAMA[adim - 1][1](veri) for dad, dasama, df in DENETIM: if dad in acik and dasama == adim and df(veri, taban) and yakalayan is None: yakalayan, gecikme = dad, adim return veri, yakalayan, gecikme def taban_kur(teslim): v, _ = a1_ayikla(teslim) v, _ = a2_tekille(v) v, _ = a3_tuketim(v) oz, _ = a4_ozet(v) sun, _ = a5_sun(oz) return {"beklenen_satir": len(teslim), "taban_ozet": oz, "taban_sunum": sun} # ---- Uc kaynak sinifi: bagdastirici , tasidigi sinif kumesi , dayanakli denetim kumesi. ALAN = ("abone", "donem", "bolge", "tip", "endeks", "birim") def u_veritabani(teslim): """Bildirimli sema ve sutun turu ; birincil anahtar zorlanir.""" tek = {} for k in teslim: tek[(k.get("abone"), k.get("donem"))] = k return list(tek.values()) def u_gunluk(teslim): """Eklemeli metin satiri ; alan adini ayristirici verir , tur hosgorulu.""" satir = ["|".join(str(k.get(a, "")) for a in ALAN) for k in teslim] okunan = [] for s in satir: p = dict(zip(ALAN, s.split("|"))) p["endeks"] = int(p["endeks"]) if p["endeks"].isdigit() else p["endeks"] okunan.append(p) return okunan def u_dis_servis(teslim): """Sayisal alan metin gelir ; ayristirici hosgorulu cevirir.""" okunan = [] for k in teslim: y = dict(k) if isinstance(y.get("endeks"), int): y["endeks"] = str(y["endeks"]) # servisin serilestirme bicimi if isinstance(y.get("endeks"), str) and y["endeks"].isdigit(): y["endeks"] = int(y["endeks"]) okunan.append(y) return okunan YEDI = ["sema", "tip", "tekillik", "satir_sayisi", "bolum", "bolum_donem", "dagilim"] KAYNAK = {"uygulama vt": (u_veritabani, ["sema_degisti", "birim_degisti", "eksik_bolum"], YEDI), "gunluk": (u_gunluk, ["gec_gelen", "yinelenen", "birim_degisti", "eksik_bolum", "kayan_tip"], [a for a in YEDI if a != "satir_sayisi"]), "dis servis": (u_dis_servis, BOZULMA, YEDI)} ham = kaynak_uret() print("kaynak", len(ham), "satir =", len(ABONE), "abone x", len(DONEM), "donem") for ad, (u, tasidigi, acik) in KAYNAK.items(): teslim = u(ham) tb = taban_kur(teslim) s, y, g = denetimli_hat(teslim, tb, acik) print(f"{ad:<12} teslim {len(teslim)} satir sunum {s == tb['taban_sunum']} " f"acik denetim {len(acik)} tasidigi sinif {len(tasidigi)} yakalayan {y}") print("saglam sunum", taban_kur(ham)["taban_sunum"]) print("dis servis ham teslimde tip denetimi", d_tip([dict(k, endeks=str(k["endeks"])) for k in ham]))
kaynak 2400 satir = 200 abone x 12 donem
uygulama vt teslim 2400 satir sunum True acik denetim 7 tasidigi sinif 3 yakalayan None
gunluk teslim 2400 satir sunum True acik denetim 6 tasidigi sinif 5 yakalayan None
dis servis teslim 2400 satir sunum True acik denetim 7 tasidigi sinif 6 yakalayan None
saglam sunum {'merkez': 1321.45, 'kuzey': 1212.55, 'dogu': 881.36, 'bati': 833.09, 'guney': 1065.55}
dis servis ham teslimde tip denetimi True
Sağlam teslimde üç kaynak sınıfı ayırt edilemez: üçü de 2400 satır veriyor, aynı beş sunum değerini üretiyor ve hiçbirinde denetim ateşlemiyor. Görünen tek fark günlükte açık denetim sayısının yediden altıya inmesidir, çünkü orada beklenen satır sayısı diye bir referans yoktur.
Son satır kaynak sınıfının denetime nasıl karıştığını gösteriyor. Dış servis sayısal alanı metin teslim ettiği için hiçbir bozulma yokken, on iki dönemin hepsinde tür denetimi kırmızıdır. Sürekli kırmızı bir denetim kapalı bir denetimdir. Onu yeşile döndürmenin tek yolu ayrıştırıcıda hoşgörülü çevirimdir ve bedeli aşağıda ödenir.
Kaynak Sınıfı Başına Bozulma Profili
Aşağıdaki blok her kaynak sınıfı için yalnız o sınıfın taşıyabildiği bozulmaları koşturur.
profil, ozet = {}, {} for ad, (u, tasidigi, acik) in KAYNAK.items(): tb = taban_kur(u(ham)) top, yok, dip, sessiz = 0, 0, 0, 0 for sinif in BOZULMA: if sinif not in tasidigi: continue bozuk, n = boz(ham, sinif) teslim = u(bozuk) s, y, g = denetimli_hat(teslim, tb, acik) profil[(ad, sinif)] = (n, abs(len(teslim) - 2400), y, g, s == tb["taban_sunum"]) sessiz += s == tb["taban_sunum"] if y is None: yok += 1 else: top, dip = top + g, dip + (g >= 4) ozet[ad] = (len(tasidigi), top, yok, dip, sessiz) print("bozulma uygulama vt gunluk dis servis") for sinif in BOZULMA: h = [] for ad in KAYNAK: v = profil.get((ad, sinif)) h.append("." if v is None else ("yakalanmiyor" if v[2] is None else f"{v[2]}/{v[3]}")) print(f"{sinif:<14} {h[0]:>13} {h[1]:>14} {h[2]:>15}") print("\nkaynak sinifi sinif bozulan satir toplam gecikme yakalanmayan " "4. asamaya inen sunumu degismeyen") for ad, v in ozet.items(): bs = sum(profil[(ad, s)][0] for s in BOZULMA if (ad, s) in profil) print(f"{ad:<14} {v[0]:>5} {bs:>14} {v[1]:>15} {v[2]:>13} {v[3]:>16} {v[4]:>18}") print("\nsatir sayisi denetimi pay 0.0500 -> 120 satir") print("sinif satirfark oran pay 0.0500 pay 0.0100 dayanak uretici") for sinif in ("gec_gelen", "yinelenen", "eksik_bolum"): t = boz(ham, sinif)[0] f = abs(len(t) - 2400) d = ["yakalamaz", "yakalar"] print(f"{sinif:<14} {f:>9} {f / 2400:>7.4f} " f"{d[d_satir_sayisi(t, 2400)]:>11}{d[d_satir_sayisi(t, 2400, 0.01)]:>12}" f"{d[d_satir_sayisi(t, len(t), 0.01)]:>17}")
bozulma uygulama vt gunluk dis servis gec_gelen . dagilim/4 dagilim/4 yinelenen . tekillik/0 tekillik/0 sema_degisti sema/0 . sema/0 birim_degisti dagilim/4 dagilim/4 dagilim/4 eksik_bolum bolum_donem/0 bolum_donem/0 bolum_donem/0 kayan_tip . yakalanmiyor yakalanmiyor kaynak sinifi sinif bozulan satir toplam gecikme yakalanmayan 4. asamaya inen sunumu degismeyen uygulama vt 3 446 4 0 1 1 gunluk 5 546 8 1 2 3 dis servis 6 746 8 1 2 3 satir sayisi denetimi pay 0.0500 -> 120 satir sinif satirfark oran pay 0.0500 pay 0.0100 dayanak uretici gec_gelen 40 0.0167 yakalamaz yakalar yakalamaz yinelenen 60 0.0250 yakalamaz yakalar yakalamaz eksik_bolum 46 0.0192 yakalamaz yakalar yakalamaz
Profilin Okunması
Birinci tablo bir kaynak sınıfının neyi üretemediğini okutuyor. Uygulama veritabanının satırındaki üç nokta üç güvencedir: tutarlı okuma geç gelen satırı, birincil anahtar yinelenen satırı, bildirimli sütun türü tür kaymasını üretici tarafında olanaksız kılar. Bu güvenceler bedava değildir, ama hattın ölçmesi gereken sınıf sayısını yarıya indirir: altıdan üçe, toplam gecikme 8 aşamadan 4 aşamaya.
Günlük ile dış servis aynı toplam gecikmeyi, 8 aşamayı, farklı sınıflardan topluyor. Günlük şema değişimi taşımaz, çünkü alan adlarını üretici değil ayrıştırıcı verir; dış servis altı sınıfın hepsini taşır ve şema değişimini aşama 0’da yakalatır. Tek bir toplam sayı kaynak seçimini gerekçelendirmez; tablonun satırları gerekçelendirir.
Son satır dersin en sessiz sonucudur. Tür kayması iki hoşgörülü kaynakta da yakalanmıyor: 200 satır bozuluyor, ayrıştırıcı metni sayıya çeviriyor, tür denetimi yeşil kalıyor ve sunulan beş değer birebir aynı çıkıyor. İzi yok, çünkü onu görecek denetimin dayanağını ayrıştırıcı silmiş. Bu iki kaynakta sunumu değişmeyen sınıf sayısı üçtür: yinelenen, birim değişimi ve tür kayması.
Dayanağı Üreticiden Gelen Denetim
Üçüncü tablo satır sayısı denetimini tek başına sınıyor. Öntanımlı tolerans 0,05, yani 120 satırdır. Satır sayısını değiştiren üç sınıfın en büyüğü yalnız 60 satır, yani 0,0250 oynatır: tolerans, ölçmek istediği en büyük sinyalin iki katıdır. Bu denetim üçünün hiçbirini yakalamaz ve on iki dönem boyunca yeşil kalır; bir denetimin yeşil olması ölçüldüğü anlamına gelmez.
Toleransı 0,0100‘e indirmek üçünü de aşama 0’da yakalatır ve geç gelen satırın gecikmesini dörtten sıfıra çeker; yanlış alarm bedeli de yoktur, çünkü sağlam teslim tam 2400 satırdır. Yine de bu düzeltme üç kaynağın yalnız birinde uygulanabilir: günlükte referans yoktur, dış serviste vardır ama üreticinin kendi beyanıdır — servis kaç satır gönderdiğini söyler, alınan da odur, oran 0,0000 çıkar. Bir denetimin değeri eşiğinden değil dayanağının nereden geldiğinden gelir.
Özet
- Bir kaynak sınıfı ürün adıyla değil üç şeyle tanımlanır: bağdaştırıcısı, taşıyabildiği bozulma sınıfları ve dayanağı olan denetimler. Sağlam teslimde üçü de aynı sayıyı verir; bedeli ancak bozulma geldiğinde görünür.
- Üretici tarafındaki güvence taşınan sınıf sayısını düşürür: bildirimli tür, birincil anahtar ve tutarlı okuma uygulama veritabanını altı sınıftan üçe indirir, toplam gecikmesi 8 yerine 4 olur.
- Günlük ile dış servis aynı toplam gecikmeyi farklı sınıflardan toplar; kaynak seçimi toplam sayıyla değil profilin satırlarıyla gerekçelendirilir.
- Hoşgörülü ayrıştırma tür denetiminin dayanağını siler: 200 satır bozulur, yakalayan olmaz, sunulan beş değer aynı kalır; sunumu değiştirmeyen sınıf sayısı üçe çıkar.
- Satır sayısı denetimi 0,05 toleransla hiçbir sınıfı yakalamaz, çünkü en büyük satır farkı 0,0250 oynatır; dayanak üreticinin beyanıysa hiçbir tolerans yakalatmaz.
Sonraki Adım
Bu dersin profili on iki dönemin hepsi elde varken çıkarıldı: bozulmuş dönem hattın içinde duruyordu ve denetimler onu kalan on bir dönemle karşılaştırabiliyordu. Bir hat böyle çalışmaz; bir çizelgeye bağlıdır ve çizelge bozulmuş dönemin ne zaman görüneceğini belirler. Sonraki ders aynı hattı iki kipte koşturur: on iki dönemi tek seferde işleyen toplu kip ile dönemi geldiğinde işleyen akış kipi. Ölçülecek takas şudur: toplu kipte bozulma bir dönem sonra görünür, akışta aynı dönemde; karşılığında akış hattın aşama sayısını ve taşınan durumu büyütür.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.