İçeriğe geç
academia.sh

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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat