---
title: 'Yaşam Döngüsü'
source: 'https://academia.sh/tr/kurslar/veri-muhendisligine-giris/yasam-dongusu'
course: 'Veri Mühendisliğine Giriş'
language: tr
updated: '2026-08-17T18:08:52+00:00'
license: 'CC BY-SA 4.0'
---

# Yaşam Döngüsü

Altı bozulma sınıfının aynı beş aşamalı hattan geçirilip her aşamanın kendi bozulmaya açıklığının sayılması: ayıklama yalnız alan adı değişimini, tekilleştirme yalnız çift kaydı görüyor, tüketim aşaması eksik satırın bedelini tam iki katına çıkarıyor (40 satır 80'e, 46 satır 92'ye, 200 satır 400'e), özet aşamasında hücre sayısı 55'ten 45 ve 53'e düşüyor, sunma aşaması ise altı sınıfın hiçbirinde beş değerden başka bir şey üretmiyor. Üç sınıf sunulan sayıyı birebir aynı bırakıyor: yinelenen tekilleştirmede yutuluyor, kayan_tip hattın kendi tür dönüşümüyle sessizce onarılıyor, birim_degisti ise özetin on hücresini yıktığı hâlde iki dönem birbirini götürdüğü için sunulan değeri değiştirmiyor. gec_gelen ve birim_degisti tam olarak aynı sayıda özet hücresini bozuyor, biri sunumu değiştiriyor öbürü değiştirmiyor.

Önceki ders hattı sağlam bir kaynakla koşturdu ve iz tablosu her aşamada beklenen sayıyı verdi:
2400, 2400, 2200, 55, 5. Kaynağın sağlam gelmesi bir varsayımdı ve üretimde bu varsayım tutmaz.
Bir dönemin kayıtları geç gelir, aynı kayıt iki kez yazılır, bir alanın adı değişir, bir okuma
başka bir birimle gönderilir, bir bölgenin bölümü hiç yazılmaz, sayı alanı metne döner.

Bu dersin sorusu şudur: bu kazalar aynı hattan geçtiğinde **hangi aşamada** iz bırakır. Beş aşamanın
her biri belirli bir hataya karşı yapısal olarak duyarlı, geri kalanına yapısal olarak kördür ve bu
körlük hattın tasarımından gelir, bir eksiklikten değil. Ölçülecek şey her aşamanın kendi
**bozulmaya açıklığıdır**.

- **YD9.** Hat, kaynak ve tohum önceki dersle aynıdır. Değişen tek şey **kaynağın kendisidir**:
  bozulma hatta değil, hatta girmeden önce uygulanır.
- **YD10. Altı bozulma sınıfının hiçbiri saldırı değildir.** Hepsi üretici tarafında olan günlük
  kazalardır: bir toplama işi geç bitmiştir, bir yeniden gönderim iki kez yazmıştır, bir alan adı
  yeniden adlandırılmıştır, bir sahadaki dönüştürücü değişmiştir, bir bölümün yazımı atlanmıştır,
  bir dışa aktarım her alanı metin olarak vermiştir.
- **YD11.** Her sınıf **tek bir dönemi** bozar (`2026-07`); kalan on bir dönem sağlam kalır. Bu,
  bozulmanın etkisini yalıtmak içindir: iz tablosundaki her fark tek dönemin farkıdır.
- **YD12.** Sınıfların bozduğu satır sayısı tanım gereğidir: `gec_gelen` bu dönemde ilk kırk
  abonenin kaydını hiç getirmez (**40**), `yinelenen` ilk altmış abonenin kaydını iki kez yazar
  (**60** fazla satır), `sema_degisti` `endeks` alanının adını değiştirir (**200**),
  `birim_degisti` okumayı bine katlar ama **birim etiketini `m3` bırakır** (**200**),
  `eksik_bolum` bir bölgenin bölümünü hiç yazmaz (**46**), `kayan_tip` sayı alanını metne çevirir
  (**200**).
- **YD13. Bu derste hiçbir denetim yoktur.** Taban çizgisi denetimsiz hattır: yakalanan bozulma
  **0**, yakalama gecikmesi **tanımsız**. Ölçülen tek şey hattın kendi izidir.
- **YD14.** Ölçü birimi **satır** ve **özet hücresidir**. Süre yazılmaz. Hat belirlenimci olduğu
  için ikinci koşum aynı tabloyu verir; aşağıdaki her fark bozulmadan gelir, oynaklıktan değil.
- **YD15.** Çözünürlük önceki dersteki gibidir: satır oranında **0,0004**, özet hücresinde
  **0,0182**, sunum değerinde **0,2000**. **Sunum üzerinde oran basılmaz.**

## Altı Sınıfın İzi

Aşağıdaki blok önceki dersin hattını aynen kurar, üzerine altı bozulma sınıfını ekler ve her sınıfı
ayrı ayrı aynı hattan geçirir. İki tablo basılır: aşamalardan **kaç satır çıktığı** ve her aşamanın
**kaç satır düşürdüğü**.

```python
# KURGU hat ve KURGU bozulma siniflari -- gercek bir depo ya da orkestrator 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


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():
    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


# Hicbiri bir saldiri degildir; hepsi uretici tarafi kazalaridir.
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


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):
    """Donem farkindan tuketim. Onceki donem yoksa satir hesaplanamaz."""
    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 = {}
    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)]


def hat(kayit):
    iz, veri = [], kayit
    for ad, f in ASAMA:
        veri, dusen = f(veri)
        n = len(veri) if hasattr(veri, "__len__") else 0
        iz.append({"asama": ad, "kalan": n, "dusen": dusen})
    return veri, iz


kaynak = kaynak_uret()
_, taban_iz = hat(kaynak)
BAS = ("ayikla", "tekille", "tuketim", "ozet", "sun")
print(f"{'sinif':<14}{'bozulan':>8}" + "".join(f"{a:>9}" for a in BAS))
print(f"{'saglam':<14}{0:>8}" + "".join(f"{a['kalan']:>9}" for a in taban_iz))
for s in BOZULMA:
    kb, n = boz(kaynak, s)
    print(f"{s:<14}{n:>8}" + "".join(f"{a['kalan']:>9}" for a in hat(kb)[1]))
print()
print(f"{'sinif':<14}" + "".join(f"{a:>9}" for a in BAS[:3]) + f"{'ikincil':>10}")
for s in BOZULMA:
    kb, n = boz(kaynak, s)
    iz = hat(kb)[1]
    print(f"{s:<14}" + "".join(f"{a['dusen']:>9}" for a in iz[:3])
          + f"{taban_iz[2]['kalan'] - iz[2]['kalan']:>10}")
```

```
sinif          bozulan   ayikla  tekille  tuketim     ozet      sun
saglam               0     2400     2400     2200       55        5
gec_gelen           40     2360     2360     2120       55        5
yinelenen           60     2460     2400     2200       55        5
sema_degisti       200     2200     2200     1800       45        5
birim_degisti      200     2400     2400     2200       55        5
eksik_bolum         46     2354     2354     2108       53        5
kayan_tip          200     2400     2400     2200       55        5

sinif            ayikla  tekille  tuketim   ikincil
gec_gelen             0        0       40        80
yinelenen             0       60        0         0
sema_degisti        200        0      200       400
birim_degisti         0        0        0         0
eksik_bolum           0        0       46        92
kayan_tip             0        0        0         0
```

İkinci tablo her aşamanın **neye açık olduğunu** birebir yazıyor. `ayikla` aşaması yalnız tek bir
sınıfı görüyor: `sema_degisti`, çünkü alan adı değiştiğinde satır zorunlu alan listesini
karşılamıyor. Kalan beş sınıfın hiçbiri bu aşamada bir satır düşürmüyor. `tekille` aşaması da
yalnız bir sınıf görüyor: `yinelenen`, altmış çift kayıt. Bu iki aşamanın açıklığı **dar ve
kesindir**; gördükleri şeyi kaçırmazlar, görmedikleri şeye tamamen kördürler.

`tuketim` aşaması farklı davranıyor. Kendi başına hiçbir bozulmayı tanımıyor, ama üç sınıfın
etkisini **taşıyor**: `gec_gelen` için 40, `sema_degisti` için 200, `eksik_bolum` için 46 satır bu
aşamada düşüyor. Bu satırlar bozuk değildir; önceki dönemleri kaybolduğu için farkları
hesaplanamayan **sağlam** satırlardır. Bir aşamanın düşürdüğü satırın kendi hatası olmayabilir.

Son iki sütun ise okumanın sonucudur. `ozet` aşamasında hücre sayısı yalnız iki sınıfta düşüyor:
`sema_degisti` on hücre kaybettiriyor (45), `eksik_bolum` iki hücre (53). Ve `sun` sütunu **altı
satırın hepsinde 5**. Sunma aşamasının çıktı sayısı bölge sayısına bağlıdır, kaynağın durumuna
değil; bu yüzden hattın en çok bakılan katmanı, bozulmayı satır sayısıyla **hiçbir koşulda** haber
veremez.

## Bir Satırın İki Satıra Mal Olması

Birinci tablonun `ikincil` sütunu ayrı bir nicelik ölçüyor: bozulma sonucu **tüketim çıkışında**
eksilen satır. `gec_gelen` kaynaktan 40 satır eksiltiyor, tüketim çıkışında **80** satır eksiliyor.
`eksik_bolum` 46 eksiltiyor, çıkışta **92**. `sema_degisti` 200 eksiltiyor, çıkışta **400**.
Katsayı üçünde de tam olarak **iki**.

Bu katsayı bir ölçüm sonucu değil, tanımın sonucudur ve koşum yapılmadan türetilir. Tüketim iki
komşu dönemin endeks farkıdır; `2026-07` kaydı kaybolduğunda o abonenin **hem temmuz farkı hem de
ağustos farkı** hesaplanamaz hâle gelir, çünkü ağustosun önceki dönemi temmuzdur. Bir satırın
kaybı iki çıkış satırını götürür. Aynı gerekçe katsayının **neden ikiden büyük olmadığını** da
söyler: eylülün önceki dönemi ağustostur ve ağustos kaydı yerindedir, zincir orada kapanır.

Bu, veri hatlarında sık karşılaşılan bir yanılgıyı düzeltir. Bir kaynak eksikliği raporlandığında
etkisi genellikle eksilen kaynak satırıyla yazılır. Aşama zinciri satırlar arasında **bağ** kuran
bir dönüşüm içeriyorsa gerçek etki bu sayıdan büyüktür ve büyüme çarpanı hattın tanımından
okunabilir. Burada çarpan iki; komşu üç dönemi birleştiren bir dönüşümde üç olurdu.

## Özet Bozulurken Sunumun Bozulmaması

Şimdiye kadarki iki tablo yalnız **satır ve hücre sayısına** baktı. Sayı aynı kalırken **değerin**
değişmiş olması hâlâ mümkündür. Aşağıdaki blok özet hücrelerini ve sunulan değerleri sağlam hatla
karşılaştırır.

```python
def son_iki(kayit):
    v1, _ = a1_ayikla(kayit)
    v2, _ = a2_tekille(v1)
    v3, _ = a3_tuketim(v2)
    oz, _ = a4_ozet(v3)
    return oz, a5_sun(oz)[0]


t_ozet, t_sunum = son_iki(kaynak)
print(f"{'sinif':<14}{'hucre':>7}{'degisen':>9}{'eksik':>7}{'sunum ayni':>12}")
for s in BOZULMA:
    oz, sn = son_iki(boz(kaynak, s)[0])
    dg = sum(1 for a in oz if a in t_ozet and oz[a] != t_ozet[a])
    ek = sum(1 for a in t_ozet if a not in oz)
    print(f"{s:<14}{len(oz):>7}{dg:>9}{ek:>7}"
          + f"{('evet' if sn == t_sunum else 'hayir'):>12}")
b_ozet, b_sunum = son_iki(boz(kaynak, "birim_degisti")[0])
print("\nbirim_degisti , kuzey ozet hucreleri")
for d in ("2026-06", "2026-07", "2026-08", "2026-09"):
    print(f"  {d}  taban {t_ozet[('kuzey', d)]:>5}   bozuk {b_ozet[('kuzey', d)]:>12}")
print("  11 hucrenin toplami  taban", sum(v for (b, d), v in t_ozet.items() if b == "kuzey"),
      " bozuk", sum(v for (b, d), v in b_ozet.items() if b == "kuzey"))
print("  sunulan kuzey degeri  taban", t_sunum["kuzey"], " bozuk", b_sunum["kuzey"])
```

```
sinif           hucre  degisen  eksik  sunum ayni
gec_gelen          55       10      0       hayir
yinelenen          55        0      0        evet
sema_degisti       45        0     10       hayir
birim_degisti      55       10      0        evet
eksik_bolum        53        0      2       hayir
kayan_tip          55        0      0        evet

birim_degisti , kuzey ozet hucreleri
  2026-06  taban  1041   bozuk         1041
  2026-07  taban  1251   bozuk   1812946491
  2026-08  taban  1119   bozuk  -1812944121
  2026-09  taban  1300   bozuk         1300
  11 hucrenin toplami  taban 13338  bozuk 13338
  sunulan kuzey degeri  taban 1212.55  bozuk 1212.55
```

Son sütun bu müfredatın en önemli iddiasını taşıyor: **altı sınıfın üçü sunulan beş değeri birebir
aynı bırakıyor.** Üçünün mekanizması da farklıdır. `yinelenen` tekilleştirme aşamasında yutuluyor;
altmış çift kayıt düşüyor ve geriye tam olarak sağlam küme kalıyor. `kayan_tip` hattın kendi tür
dönüşümüyle sessizce onarılıyor; `tuketim` aşaması metni sayıya çeviriyor, dönüşüm başarılı oluyor
ve ne satır ne değer değişiyor. Bu ikinci durum özellikle yanıltıcıdır, çünkü onarım yalnız
rakamdan oluşan metinler için işler; alandan boş ya da biçimsiz bir değer geldiğinde aynı satır
sessizce düşerdi ve yine hiçbir yerde yazılmazdı.

Üçüncüsü, `birim_degisti`, ayrı bir sınıftır. Tabloda **on özet hücresi değişiyor**, yani elli beş
hücrenin 0,1818'i; buna karşılık sunulan beş değerin hiçbiri oynamıyor. Mekanizma alt tabloda
açıkça görülüyor: `kuzey` bölgesinin temmuz toplamı 1251'den **1812946491**'e, ağustos toplamı
1119'dan **eksi 1812944121**'e gidiyor. Temmuz okuması bine katlandığı için temmuz farkı devasa
pozitif, ağustos farkı ise aynı büyüklükte negatif oluyor. On bir hücrenin toplamı iki durumda da
**13338**; sunulan değer iki durumda da **1212,55**. İki bozuk dönem birbirini **tam olarak** iptal
ediyor, çünkü toplam ardışık farklardan oluşuyor ve zincirin uçları bozulmamış.

Tablonun en keskin karşılaştırması ilk ve dördüncü satırdır. `gec_gelen` ile `birim_degisti`
**tam olarak aynı sayıda** özet hücresini bozuyor: onar hücre. Biri sunulan değeri değiştiriyor,
öbürü değiştirmiyor. Bozulan ara hücre sayısı, bozulmanın sunuma ulaşıp ulaşmayacağını
söylemiyor; belirleyen şey bozulmanın **işareti ve dağılımıdır**. Buradan müfredatın üçüncü
iddiası doğrudan çıkar: **çıktıya bakmak yetmez.** Sunulan sayının doğru görünmesi, hattın doğru
çalıştığının değil, yalnız o sayının o bozulmaya duyarsız olduğunun kanıtıdır.

## Özet

- Altı bozulma sınıfının hiçbiri saldırı değildir; hepsi üretici tarafında olan kazalardır ve her
  biri tek bir dönemi bozar.
- `ayikla` yalnız `sema_degisti`'yi, `tekille` yalnız `yinelenen`'i görüyor; iki aşamanın açıklığı
  dar ve kesindir, geri kalan sınıflara tamamen kördürler.
- `tuketim` aşaması kendi başına hiçbir bozulmayı tanımıyor ama üç sınıfın etkisini taşıyor ve
  eksik satırın bedelini **tam iki katına** çıkarıyor: 40 satır 80'e, 46 satır 92'ye, 200 satır
  400'e. Katsayı tanımdan türetilir, koşumdan değil.
- `sun` aşaması altı sınıfın hiçbirinde 5'ten başka bir sayı üretmiyor; hattın en çok bakılan
  katmanı bozulmayı satır sayısıyla hiçbir koşulda haber veremez.
- Üç sınıf sunulan değeri birebir aynı bırakıyor: `yinelenen` tekilleştirmede yutuluyor,
  `kayan_tip` hattın kendi tür dönüşümüyle onarılıyor, `birim_degisti` ise iki dönem birbirini
  iptal ettiği için sunuma hiç ulaşmıyor.
- `gec_gelen` ve `birim_degisti` aynı sayıda özet hücresini (onar hücre) bozuyor, biri sunumu
  değiştiriyor öbürü değiştirmiyor; bozulan ara hücre sayısı sunuma ulaşmanın ölçüsü değildir.

## Sonraki Adım

Bu dersin tabloları hattı tek bir gözden okudu: kaç satır girdi, kaç satır çıktı, hangi hücre
değişti. Üretimde bu hattın çevresinde tek bir göz yoktur. Hattın aşamalarını yazan ve iz tablosuna
bakan bir rol vardır; hattın sonundaki tabloyu öznitelik olarak alıp üzerine model kuran ve
başarım sayısına bakan başka bir rol vardır. İki rol aynı hattın farklı yerlerinde durur ve aynı
bozulmayı **farklı ölçülerle** görür. Sonraki ders bu iki ölçüyü yan yana koyar: aynı altı sınıf
için satır izi ile model başarımı ayrı ayrı basılır. Sonuç iki rolün de rahat edemeyeceği bir
tablodur, çünkü bir sınıf **ikisinde de** hiçbir iz bırakmıyor.
