---
title: 'Kod İnceleme ve Ekip Süreci'
source: 'https://academia.sh/tr/kurslar/kod-inceleme'
language: tr
updated: '2026-08-17T04:42:48+00:00'
license: 'CC BY-SA 4.0'
lessons: 15
outcomes:
    - 'Bir değişiklik isteğini anlam, uygulama, test ve belge eksenlerinde inceler'
    - 'Yapıcı ve eyleme dönük geri bildirim yazar'
    - 'İnceleme sürecinin ölçülebilir sağlık göstergelerini yorumlar'
---

# Kod İnceleme ve Ekip Süreci

İnceleme yalnız baktığı eksende ve okuduğu kadarında görür; kurs her yapılandırmayı bulunan kusur, kaçan kusur ve hiçbir eksenin aramadığı sınıf üzerinden ölçer.

## İnceleme Ekseni

İncelemenin amacı, genel arayüzün sözleşmesi ve geriye dönük uyumluluk, doğruluk ile kenar durumlar, testlerin anlamlılığı ve kırılganlığı, değişikliğin belgeye yansıması, ve biçim tartışmasının araca devredilmesi.

### Kod İncelemenin Amacı

Source: https://academia.sh/tr/kurslar/kod-inceleme/kod-incelemenin-amaci

Aynı değişiklikte üç inceleyen aynı eksende 6, üç inceleyen ayrı eksende 15, tek inceleyen beş eksende 22 kusur bulur; beş inceleyen beş eksende yine 22 bulur ve iki eksik gereksinim kusuru dört yapılandırmanın dördünde de kaçar.

İleri Git kursu on iki ders boyunca tek bir birimle çalıştı: bir işlemin dokunduğu nesne
sayısı. Yeniden yazma 5640 nesneye dokunuyordu, ikili arama on bir adımda bitiyordu, bir
kanca engeli erken ya da geç koyuyordu. Kapanış bu sayıların yanıtlamadığı soruyu bıraktı:
**araç tarihçeyi değiştirir, kararı insan verir.** Bir dönüşümün bedelini bilmek, o
dönüşümün yapılıp yapılmayacağını söylemez.

Bu kurs kararın verildiği yere bakar ve ölçülen birim değişir. Orada sayılan **aracın
dokunduğu nesneydi**; burada sayılan **insanın baktığı yer** — ve baktığı yerin dışında
kalan. Sorunun kendisi de değişir: bir değişikliği kaç kişinin okuduğu değil, o okumanın
neyi bulduğu ve neyi bulamadığı sorulur.

#### İncelemenin Üç İşi

**Kod inceleme (code review)**, bir değişikliğin birleştirilmeden önce onu yazmayan biri
tarafından okunması ve okunanın kayda geçirilmesidir. Üç işi vardır ve üçü aynı şey
değildir.

Birincisi **hata bulmadır**: gönderilen değişiklikte doğru olmayan bir şeyi, birleştirilmeden
önce görmek. İkincisi **bilgi yaymadır**: değişikliği yalnız yazanın bilmesini engellemek;
okuyan kişi o kodun ikinci sahibi olur. Üçüncüsü **tasarım hizalamadır**: değişikliğin
deponun geri kalanıyla aynı yönde durup durmadığına bakmak.

Bu kursun ölçtüğü şey birincisidir, çünkü sayılabilen odur. Ama üçü birbirinden bağımsız
değildir: bir sonraki bölümde kurulan **inceleme ekseni (review axis)** kavramı üçüne birden
uygulanır. Kimin hangi eksene baktığı hem bulunan hatayı hem yayılan bilgiyi hem de
hizalamanın hangi düzeyde yapıldığını belirler.

Değişiklik isteğinin mekaniği — öneri, tartışma, birleştirme döngüsü — Dallanma ve İşbirliği
kursunda kuruldu ve orada inceleme ekseni açıkça buraya bırakıldı; burada tekrarlanmaz.
Güvenlik gözüyle okuma Güvenli Kodlama kursunun konusudur ve bu kursun eksen listesinde
güvenlik yoktur. Ekip yapısının ve karar hakkının kurumsal tartışması Süreç, Ekip ve Teslimat
kursundadır. Burada kalan tek şey incelemenin kendi sayılarıdır.

#### İki Sınır: Eksen ve Dikkat

Bir inceleyen sınırsız değildir. İki sınırla çalışır ve kursun bütün ölçümleri bu ikisinin
üzerine kurulur.

**Ekseni:** bir okuma her şeye birden bakmaz. Arayüze bakan göz imzayı, adlandırmayı ve
sözleşmeyi arar; gerçekleştirime bakan göz döngü sınırını ve kenar durumu arar; teste bakan
göz iddianın gerçekten bir şey doğrulayıp doğrulamadığına bakar. Aynı satırın üzerinden geçen
iki göz iki ayrı kusur görür, çünkü ikisi ayrı şey aramaktadır. Bu kurs beş eksen tanımlar:
**arayüz, gerçekleştirim, test, belge, biçim.**

**Dikkati:** bir inceleyen bir turda sınırlı miktarda metin okur. Okuma birimi **öbek
(chunk)** olarak adlandırılır ve bir öbek elli satırdır. Bir turda gerçekten okunan öbek
sayısı sabittir; değişiklik bundan büyükse geri kalanı okunmaz. Bu dersin ölçümünde
değişiklik tam olarak dikkat kadardır, yani **bu derste hiçbir kusur okunmadığı için
kaçmaz.** Kaçan her kusurun tek bir nedeni olacaktır: bakılmayan eksen.

#### Beş Eksen Ne Arar

Eksenler soyut değildir; her biri belirli bir soruyu sorar ve bulgusunu belirli bir biçimde
yazar. Aşağıdaki notlar aynı değişikliğe beş ayrı eksenden bakan beş okumanın ürünüdür.

```text
# ogretilen inceleme notu ornegi , calistirilmamistir

arayuz          Genel islevin ikinci parametresi zorunlu hale gelmis; onceki
                imzayla cagiran kod artik derlenmiyor. Varsayilan deger
                verilirse sozlesme korunur.
gerceklestirim  Dongu, liste bos oldugunda son elemani okuyor; bos girdi
                icin bir erken donus gerekiyor.
test            Testin tek iddiasi cagrinin hata firlatmadigi; donen degeri
                dogrulayan bir iddia yok.
belge           Islevin anlattigi davranis degismis, aciklama satiri eski
                davranisi tarif ediyor.
bicim           Girinti bu dosyada iki ayri genislikte kullanilmis.
```

Bu blok bir örnektir ve çalıştırılmaz; bu dersin sayıları yalnız ölçüm bloğundan gelir.
Notların ortak bir yanı var: **beşi de değişikliğin bir yerini gösteriyor ve ne yapılırsa
kapanacağını söylüyor.** Hiçbiri kişiden söz etmiyor. Bu, kurs boyunca korunan sınırdır —
inceleme yazanı değil, gönderilen değişikliği okur.

İkinci ortak yanları, hiçbirinin ötekinin yerine geçememesidir. Arayüz notu imzaya bakmadan
yazılamaz; biçim notunu yazan göz döngü sınırını aramıyordur. Aynı dosyanın aynı satır
aralığında duran iki kusur, ayrı eksenlerde olduğu için ayrı okumalar gerektirir. Ölçümün
tablosu bu bağımsızlığın sayısal karşılığıdır.

Bilgi yayma ve tasarım hizalama da aynı bağımlılığı taşır. Bir değişikliği yalnız biçim
ekseninden okuyan kişi o kodun ikinci sahibi olmaz; girintiyi öğrenir, davranışı öğrenmez.
Aynı biçimde, tasarım hizalaması yalnız arayüz ve gerçekleştirim eksenlerinden görülebilir.
Eksen seçimi bu yüzden incelemenin üç işini birden belirler.

#### Yazılmamış Olanın Kusuru

Beş eksenin dışında altıncı bir kusur sınıfı vardır ve kurgunun en önemli parçası budur:
**eksik gereksinim (unwritten requirement)**. Bu, değişikliğin içindeki yanlış bir satır
değildir; **olması gerekip de hiç yazılmamış** olandır.

Bir arayüz kusuru için imzaya bakılır, bir test kusuru için iddiaya bakılır. Yazılmamış bir
gereksinim için bakılacak bir yer yoktur, çünkü o gereksinim değişikliğin içinde bir metin
olarak bulunmaz. İnceleme **gönderilene** bakar; gönderilmemiş olanın yokluğunu göremez. Bu
bir dikkat sorunu da değildir: eksen listesinde o sınıf yoktur.

#### Ölçümün Kurgusu

Ölçüm bir değişiklik ve içine serpilmiş **24 kusur** üzerine kurulur. Her kusur altı sınıftan
birine aittir. Kâhin kurgunun kendisidir: kusurları biz yerleştirdiğimiz için hangisinin
hangi öbekte ve hangi sınıfta olduğu bilinir. Dört yapılandırma aynı değişikliğe bakar ve her
biri için **bulunan** ile **kaçan** birlikte yazılır.

- **IE1** — Değişiklik 600 satırdır, yani 12 öbektir; dikkat de 12 öbektir. Değişikliğin
  tamamı okunur ve bu ders boyunca okunmamış öbek yoktur.
- **IE2** — 24 kusur altı sınıfa kurgu tarafından dağıtılır; sınıf listesi ve dağılım kursun
  sabitidir ve hiçbir derste değiştirilmez.
- **IE3** — Bir inceleyen yalnız kendi eksenlerindeki kusuru görür. Eksen dışındaki bir kusur,
  satırın üzerinden geçilmiş olsa bile bulunmaz.
- **IE4** — Birden çok inceleyenin bulgusu birleşimdir: aynı kusuru iki kişi bulursa bir kez
  sayılır. Yapılandırmalar arasındaki fark bu yüzden **kişi sayısı değil, kapsanan eksen
  kümesidir.**
- **IE5** — Aynı eksene bakan iki inceleyen aynı kümeyi bulur. Kurgu, ikinci kişinin birinciyi
  tamamladığı bir bulma payı içermez; bu kasıtlı bir yalınlaştırmadır ve ölçümün sonucunu
  şuraya bağlar: eksen çeşitliliği.
- **IE6** — Altıncı sınıf hiçbir eksenin arama listesinde değildir. Bu bir eksiklik değil,
  tanımdır.
- **IE7** — Ölçümde tur, bekleme ve geri bildirim yazımı yoktur; bunlar sonraki konuların
  değişkenleridir. Burada tek bir turun tek bir okuması sayılır.
- **IE8** — 24 kusurluk bir kümede ölçülebilen en küçük fark **1/24**, yani **0,042**'dir.
  Bundan küçük bir fark bu kümeyle savunulamaz.

#### Ölçüm

```python
"""Kod incelemenin amaci: bakan kisi sayisi mi, bakilan eksen sayisi mi.

Bolum 1 - degisiklik ve kusurlarin sinif dagilimi.
Bolum 2 - dort yapilandirma: bulunan, kacan, hicbir eksenin aramadigi kacan.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"      # hicbir eksende aranmaz
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12                          # bir turda gercekten okunan obek
OBEK = 50                            # satir


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    """Bir inceleyen: yalniz kendi ekseninde ve yalniz okudugu obekte gorur."""
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


TAM = set(EKSENLER)
ATAMALAR = {
    "tek inceleyen, tüm eksenler": [TAM],
    "üç inceleyen, aynı eksen": [{"gerceklestirim"}] * 3,
    "üç inceleyen, ayrı eksen": [{"arayuz"}, {"gerceklestirim"},
                                 {"test", "belge"}],
    "beş inceleyen, beş eksen": [{e} for e in EKSENLER],
}

d = degisiklik(600)
dagilim = {s: sum(1 for k in d["kusurlar"] if k["sinif"] == s) for s in SINIFLAR}
print(f"değişiklik {d['satir']} satır, {d['obek']} öbek, "
      f"kusur {len(d['kusurlar'])}, dikkat {DIKKAT} öbek")
print("sınıf dağılımı: " + ", ".join(f"{s} {n}" for s, n in dagilim.items()))
print()
print(f"{'atama':<28s} {'eksen':>5s} {'inceleyen':>9s} {'bulunan':>7s} "
      f"{'kaçan':>5s} {'yazılmayan kaçan':>16s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    eksen = len(set().union(*atama))
    print(f"{ad:<28s} {eksen:5d} {len(atama):9d} {len(b):7d} "
          f"{len(kacan):5d} {yaz:16d}")
```

```
değişiklik 600 satır, 12 öbek, kusur 24, dikkat 12 öbek
sınıf dağılımı: arayuz 3, gerceklestirim 6, test 3, belge 3, bicim 7, eksik gereksinim 2

atama                        eksen inceleyen bulunan kaçan yazılmayan kaçan
tek inceleyen, tüm eksenler      5         1      22     2                2
üç inceleyen, aynı eksen         1         3       6    18                2
üç inceleyen, ayrı eksen         4         3      15     9                2
beş inceleyen, beş eksen         5         5      22     2                2
```

#### Sayı İnceleyen Sayısını İzlemiyor

Tablonun iki sütunu yan yana duruyor ve **bulunan** sütunu ikisinden yalnız birini izliyor.

**İnceleyen sayısı 1, 3, 3, 5**; bulunan kusur **22, 6, 15, 22**. Aralarında hiçbir düzenli
ilişki yok: bir kişi 22 buluyor, üç kişi 6 buluyor, beş kişi yine 22 buluyor.

**Eksen sayısı 5, 1, 4, 5**; bulunan kusur **22, 6, 15, 22**. Bu sütun bulunanı satır satır
açıklıyor. Beş eksen 22 veriyor, dört eksen 15, tek eksen 6. Kursun ölçü ekseni buradan
çıkar: **bir incelemenin sayısı bakan kişi sayısı değil, bakılan eksen sayısıdır.**

İkinci ve dördüncü satır bunu tek başına söylüyor. **Üç inceleyen aynı eksende 6** kusur
buluyor; üçü de gerçekleştirime bakıyor ve gerçekleştirim sınıfında 6 kusur var. İkinci ve
üçüncü kişi birinciye tek bir kusur eklemiyor, çünkü aynı şeyi arıyorlar. Buna karşılık **tek
inceleyen beş eksene bakınca 22** buluyor ve **beş inceleyen beş eksene dağılınca yine 22**.
Beş kişiyle bir kişi arasında **0** fark var. İkinci iddia budur: **inceleyen eklemek kusur
bulmaz; eksen eklemek bulur.**

Üçüncü satır aradaki ara değeri veriyor. Üç inceleyen dört ekseni kapsıyor — biri arayüze,
biri gerçekleştirime, biri hem teste hem belgeye bakıyor — ve **15** kusur çıkıyor. Kaçan 9
kusurun **7**'si biçim sınıfındandır; o eksene kimse bakmıyor. Bu, kişi eklemenin değil eksen
eklemenin işe yaradığının en somut kanıtıdır: aynı üç kişi, ekseni dağıtınca 6 yerine 15
buluyor. Fark **9** kusurdur ve kümenin çözünürlüğünün yirmi katından fazladır.

#### Dağılımın Kendisi Bir Sonuç

Çıktının ikinci satırı ölçümden önce gelen bir bilgidir ama kendi başına okunmayı hak eder:
**biçim 7, gerçekleştirim 6, arayüz 3, test 3, belge 3, eksik gereksinim 2.**

En kalabalık sınıf biçimdir ve 24 kusurun **7**'sini, yani **0,292**'sini tutar. Bir
incelemede en çok not düşülen şeyin neden çoğu zaman biçim olduğunu bu sayı açıklıyor: biçim
kusuru hem sayıca fazladır hem de görülmesi en az bilgi ister. Ardından **gerçekleştirim**
gelir, **6** kusurla ve bu sınıf tam tersidir — görülmesi kodun ne yaptığını anlamayı
gerektirir.

Kalan üç eksen — arayüz, test, belge — **3**'er kusur taşır ve toplamları **9**'dur. Üçü
birden biçim ile gerçekleştirimin toplamından azdır; buna karşılık üçü de ayrı bir okuma
isteyen sınıflardır ve hiçbiri ötekinin yan ürünü olarak bulunmaz.

Dağılımın pratik sonucu ilerideki derslerin konusudur. Bir inceleme dikkatini kalabalık ama
ucuz sınıfa harcarsa, pahalı sınıflara kalan pay küçülür; toplam bulunan sayısı bunu
göstermez, ancak sınıf başına ayrıştırma gösterir. Bu kursta her ölçümde **bulunan ve kaçan**
birlikte yazılmasının ve kaçanların sınıfının ayrıca sayılmasının nedeni budur.

#### Dördünde de Kaçan İki Kusur

Son sütun dört satırda da aynı değeri veriyor: **2**.

Bu iki kusur eksik gereksinim sınıfındandır ve yapılandırma ne olursa olsun kaçıyor. Tek
inceleyen beş eksene baksa da kaçıyor, beş inceleyen beş eksene dağılsa da kaçıyor. Kaçan
sayısı **2**'ye kadar iniyor ve orada duruyor — çünkü kalan iki kusur için bakılacak bir yer
üretilmemiş.

Buradan **dördüncü okuma** çıkar: **hiçbir eksen yazılmayanı görmez.** Eksen eklemek bulunanı
22'ye kadar çıkarır; 24'e çıkarmaz. İncelemeye daha çok kişi koymak, daha çok eksen dağıtmak
ya da aynı değişikliği ikinci kez okutmak bu iki kusuru bulmaz. Bunlar ancak inceleme
dışındaki bir yerde — gereksinimin yazıldığı yerde — yakalanır.

İki kusurun yakalanabileceği yer bellidir ve incelemenin öncesindedir: gereksinimin
yazıldığı, kabul ölçütünün belirlendiği ve değişikliğin kapsamının kararlaştırıldığı yer.
Oraya konan tek bir cümle, incelemenin hiçbir eksenle bulamadığı bir kusuru ortadan
kaldırabilir. Bu yüzden bu kursun sayıları bir incelemenin ne kadar iyi olduğunu değil,
**neyi hiç göremeyeceğini** de söylüyor.

Bu, incelemenin bir kusuru değil, sınırının tanımıdır. Bir incelemenin "hiçbir şey bulmadım"
demesi, değişikliğin doğru olduğu anlamına gelmez; **gönderilenin içinde, bakılan eksenlerde
bir şey bulunmadığı** anlamına gelir. Bu cümlenin üç koşulu vardır ve üçü de tabloda ayrı
sütun olarak durur.

#### Özet

- İncelemenin üç işi vardır — hata bulma, bilgi yayma, tasarım hizalama — ve üçünü birden
  belirleyen şey kimin **hangi eksene** baktığıdır.
- Bir inceleyen iki sınırla çalışır: **ekseni** yalnız aradığı sınıfı görmesini, **dikkati**
  bir turda okuduğu öbek sayısını sınırlar. Bu derste değişiklik dikkat kadardır, bu yüzden
  kaçan her kusurun nedeni tek başına eksendir.
- Aynı değişiklikte üç inceleyen aynı eksende **6**, üç inceleyen ayrı eksende **15**, tek
  inceleyen beş eksende **22** kusur bulur; beş inceleyen beş eksende yine **22** bulur.
  **İnceleyen eklemek kusur bulmaz, eksen eklemek bulur.**
- İki **eksik gereksinim** kusuru dört yapılandırmanın **dördünde de** kaçar; eksen listesinde
  o sınıf yoktur ve inceleme gönderilmemiş olanın yokluğunu göremez.
- Sınıf dağılımı eşit değildir: biçim **7**, gerçekleştirim **6**, arayüz, test ve belge
  **3**'er kusur taşır. En kalabalık sınıf, görülmesi en az bilgi isteyen sınıftır.
- Bulunan sayı en iyi durumda **22/24**'te durur; kalan **2** kusur incelemenin değil,
  gereksinimin yazıldığı yerin sorunudur.

#### Sonraki Adım

Tablonun tek eksenli satırı 6 kusur veriyordu ve o eksen gerçekleştirimdi. Beş eksenin her
biri kendi payını taşıyor ve paylar birbirinden ayrı: bir eksenin bulduğu kusuru başka bir
eksen bulmuyor. Sonraki ders bu ayrılığı ilk eksende, **arayüz** ekseninde ölçer: genel bir
arayüzün sözleşmesini bozan bir değişikliği inceleme nasıl fark eder, o bulguyu kaç eksen
görebilir ve arayüze bakan inceleyenin yerine başka bir eksene bakan biri konursa kaç kusur
kaybedilir.

### Arayüz Anlamı

Source: https://academia.sh/tr/kurslar/kod-inceleme/arayuz-anlami

Beş eksenin bulduğu kümeler ayrıktır ve ikili kesişimlerin toplamı 0'dır; arayüz ekseni kapatıldığında bulunan 22'den 19'a iner ve arayüzsüz on inceleyen, beş eksene bakan tek inceleyenden 3 kusur az bulur.

Önceki ders beş eksenli bir okumanın 24 kusurun **22**'sini bulduğunu, tek eksenli bir
okumanın **6**'sını bulduğunu gösterdi. Aradaki fark eksen sayısındandı; ama tablo bir şeyi
varsaymıştı ve doğrulamamıştı: eksenlerin **payları birbirinden ayrı**. Beş eksenin toplamı
22 çıkıyorsa, aynı kusuru iki eksenin birden saymadığı kabul edilmiş demektir.

Bu ders o kabulü ölçer ve ölçümü ilk eksende, **arayüz** ekseninde yapar. Sorusu şudur: bir
arayüz kusuru gerçekten yalnız arayüze bakan gözle mi bulunur, yoksa yeterince çok kişi
yeterince dikkatli okursa başka bir eksenden de görünür mü.

#### Genel Arayüzün Sözleşmesi

Bir kod parçasının **genel arayüzü**, dışarıdan çağrılabilen adların ve onların
davranışlarının kümesidir: işlev imzaları, tip alanları, dönüş değerleri, hata biçimleri ve
adların kendisi. Bu kümeye **arayüz sözleşmesi (interface contract)** denir, çünkü çağıran
taraf ona güvenerek kod yazar.

Sözleşmenin bozulması bir derleme hatası olmak zorunda değildir. Sürümleme stratejileri ve
kırıcı olan ile olmayan değişikliğin sınıflandırması Web API Tasarımı kursunun Hata, Sürüm ve
Belge konusunda kuruldu; burada tekrarlanmıyor. Bu dersin ölçtüğü tek şey **incelemede nasıl
fark edildiğidir**: hangi eksene bakan göz bu izi görür, hangisi görmez.

#### Beş Bozma Biçimi ve İncelemedeki İzi

**Zorunlu parametre eklemek.** İz imzanın kendisindedir ve değişikliğin içinde okunur. Çağıran
kod derlenmez; kusur birleştirmeden sonra derleme aşamasında da yakalanır. İncelemenin buradaki
katkısı bulmak değil, **erken** bulmaktır.

**Parametrenin anlamını değiştirmek.** İmza aynı kalır — aynı ad, aynı tür — ama beklenen değer
başkadır; bir süre alanının birimi saniyeden milisaniyeye geçmiştir. Değişiklikte görünen tek
şey gövdedeki bir çarpandır, imzada iz yoktur.

**Dönüş değerinin davranışını değiştirmek.** Boş liste yerine boş değer dönmek, hata yerine
varsayılan dönmek, sıralı yerine sırasız dönmek. İz gövdededir; çağıran taraf derlenir ve
sessizce yanlış çalışır.

**Atılan hata sınıfını değiştirmek.** Yakalama blokları artık eşleşmez; hata yakalanmadan
yukarı çıkar ve çağıran taraf bunu derleme sırasında öğrenmez.

**Bir adı kaldırmak ya da yeniden adlandırmak.** En görünür biçimdir ve değişikliğin içinde
doğrudan okunur; kaldırılan adı kimin kullandığı ise değişikliğin dışındadır.

Ortadaki üç biçimin ortak yanı dersin çıkış noktasıdır: **derleyici sessizdir, testler
geçer, geriye tek savunma olarak inceleme kalır** — çünkü testler de aynı değişiklikte yeni
davranışa göre güncellenmiştir.

#### İzin Değişikliğin İçinde, Sonucunun Dışında

Arayüz kusurunun incelemedeki ayırt edici yanı şudur: **izi küçüktür, sonucu değişikliğin
dışındadır.** Gönderilen değişiklikte görünen şey tek bir satırdır — bir imza. O satırın
kırdığı kod ise değişikliğin içinde değildir; başka dosyalarda, başka depolarda ya da henüz
yazılmamış çağrılardadır.

Bu, arayüz ekseninin neden ayrı bir okuma gerektirdiğini açıklıyor. Gerçekleştirime bakan göz
işlevin gövdesini okur ve gövde doğrudur; teste bakan göz testleri okur ve testler geçer,
çünkü testler de yeni imzayla birlikte güncellenmiştir. İzi görmek için imzanın **eski
hâliyle** karşılaştırılması gerekir ve bunu yapan tek okuma arayüz ekseninden yapılandır.

```text
# ogretilen inceleme notu ornegi , calistirilmamistir

konu     genel islevin imzasi
onceki   ayristir(metin)
sonraki  ayristir(metin, kip)

not      Ikinci parametre varsayilansiz eklenmis; onceki imzayla yapilan
         cagri artik gecerli degil. Bu, cagiran koda dokunmadan
         yayimlanamayacak bir degisiklik. Iki yol var: kip parametresine
         onceki davranisi veren bir varsayilan vermek, ya da onceki
         imzayi koruyup yeni davranisi ayri bir adla sunmak.
```

Not değişikliğin bir yerini gösteriyor, kırılan koşulu adlandırıyor ve iki kapanış yolu
öneriyor. Bu blok bir örnektir ve çalıştırılmaz; dersin sayıları yalnız ölçüm bloğundan
gelir.

#### İncelemenin Elindeki Üç Kaynak

Arayüz ekseninde çalışan bir okuma üç kaynağa bakabilir ve üçünün kapsamı farklıdır.

**Değişikliğin kendisi** eklenen ve silinen satırlardır. Sözleşmenin yeni hâli buradadır,
önceki hâli de silinen satırlarda durur; bu iki hâlin karşılaştırılması arayüz ekseninin asıl
işidir.

**Değişikliğin başlığı ve açıklaması** yazanın niyetini taşır. "Kip parametresi eklendi"
cümlesiyle "kip parametresi zorunlu olarak eklendi" cümlesi arasındaki fark, incelemenin
hangi soruyu soracağını belirler. Bu kaynak eksikse okuma imzayı kendi başına yorumlamak
zorunda kalır.

**Deponun geri kalanı** çağıran kodu içerir ama değişikliğin parçası değildir. Arayüz
kusurunun sonucu buradadır ve inceleme bu kaynağa bakmak zorunda değildir; bakması ayrı bir
karardır ve ayrı bir okuma isteği doğurur.

Ölçüm bu üç kaynağı ayrı ayrı modellemez; arayüz ekseni açıksa kusur bulunur, kapalıysa
bulunmaz. Modelin bu yalınlığı ölçülen şeyi tek bir değişkende tutmak içindir: **hangi eksene
bakıldığı.**

#### Ölçümün Varsayımları

- **IE9** — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, dikkat 12 öbek. Değişikliğin
  tamamı okunur; bu derste de okunmamış öbek yoktur.
- **IE10** — Bir kusur tek bir sınıfa aittir. Aynı satırda iki sınıftan kusur bulunabilir ama
  bunlar iki ayrı kusurdur ve ayrı sayılır.
- **IE11** — İki eksenin **kesişimi**, ikisinin de bulduğu kusur numaralarının kümesidir.
  Sınıflar birbirini dışladığı için bu kesişimin boş çıkması beklenir; ölçüm bunu varsaymaz,
  sayar.
- **IE12** — "Yalnız bu eksende" sütunu, o eksenin bulduğu ve öteki dört eksenin hiçbirinin
  bulamadığı kusur sayısıdır.
- **IE13** — Arayüzsüz kurullarda hiçbir inceleyen arayüz ekseni taşımaz; kalan dört eksen
  serbestçe dağıtılır ve kişi sayısı artırılabilir.
- **IE14** — "On inceleyen, arayüzsüz" kurulunda dört eksenin her birine ikişer kişi ve
  ayrıca dördünü birden taşıyan iki kişi düşer; toplam on okuma yapılır.
- **IE15** — Ölçüm hâlâ tek turludur. Arayüz kusurunun sonradan, çağıran kod kırıldığında
  bulunması bu tablonun dışındadır ve inceleme bulgusu sayılmaz.

#### Ölçüm

```python
"""Arayuz ekseni: bir eksenin buldugunu baska eksen buluyor mu.

Bolum 1 - bes tek eksenli okuma; kesisim ve yalniz kendi ekseninde gorunen.
Bolum 2 - arayuz ekseni olan ve olmayan yapilandirmalar.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


TAM = set(EKSENLER)
d = degisiklik(600)
tekil = {e: incele(d, {e}) for e in EKSENLER}

print(f"{'eksen':<15s} {'bulunan':>7s} {'öteki dört eksende de':>21s} "
      f"{'yalnız bu eksende':>17s}")
for e in EKSENLER:
    oteki = set().union(*(tekil[o] for o in EKSENLER if o != e))
    print(f"{e:<15s} {len(tekil[e]):7d} {len(tekil[e] & oteki):21d} "
          f"{len(tekil[e] - oteki):17d}")
birlesim = set().union(*tekil.values())
kesisim = sum(len(tekil[a] & tekil[b])
              for a in EKSENLER for b in EKSENLER if a < b)
print(f"beş tekil okumanın birleşimi {len(birlesim)}, "
      f"ikili kesişimlerin toplamı {kesisim}")

print()
DORT = TAM - {"arayuz"}
KURULLAR = {
    "tek inceleyen, beş eksen": [TAM],
    "tek inceleyen, arayüzsüz": [DORT],
    "üç inceleyen, arayüz dahil": [{"arayuz"}, {"gerceklestirim"},
                                   {"test", "belge"}],
    "üç inceleyen, arayüz yerine": [{"gerceklestirim"}, {"gerceklestirim"},
                                    {"test", "belge"}],
    "on inceleyen, arayüzsüz": [{e} for e in sorted(DORT)] * 2 + [DORT] * 2,
}
print(f"{'kurul':<28s} {'inceleyen':>9s} {'bulunan':>7s} {'kaçan':>5s} "
      f"{'arayüz kaçan':>12s} {'yazılmayan kaçan':>16s}")
for ad, atama in KURULLAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    ar = sum(1 for k in kacan if k["sinif"] == "arayuz")
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    print(f"{ad:<28s} {len(atama):9d} {len(b):7d} {len(kacan):5d} "
          f"{ar:12d} {yaz:16d}")
```

```
eksen           bulunan öteki dört eksende de yalnız bu eksende
arayuz                3                     0                 3
gerceklestirim        6                     0                 6
test                  3                     0                 3
belge                 3                     0                 3
bicim                 7                     0                 7
beş tekil okumanın birleşimi 22, ikili kesişimlerin toplamı 0

kurul                        inceleyen bulunan kaçan arayüz kaçan yazılmayan kaçan
tek inceleyen, beş eksen             1      22     2            0                2
tek inceleyen, arayüzsüz             1      19     5            3                2
üç inceleyen, arayüz dahil           3      15     9            0                2
üç inceleyen, arayüz yerine          3      12    12            3                2
on inceleyen, arayüzsüz             10      19     5            3                2
```

#### Paylar Ayrık

Üst tablonun orta sütunu beş satırda da **0** veriyor ve ikili kesişimlerin toplamı da
**0**'dır. Beş eksenin hiçbiri ötekinin bulduğu tek bir kusuru bile bulmuyor.

Sağdaki sütun bunun aynadaki görüntüsü: her eksenin bulduğu kusurların **tamamı** yalnız o
eksende görünüyor — arayüzde **3**, gerçekleştirimde **6**, testte **3**, belgede **3**,
biçimde **7**. Toplamları **22** ve bu, beş tekil okumanın birleşimine eşit. Yani bir eksenin
katkısı, hangi eksenlerin zaten açık olduğundan bağımsızdır.

Ayrıklık, iki kusurun aynı dosyada ya da aynı satır aralığında bulunamayacağı anlamına
gelmiyor; **sınıfların** ayrı olduğu anlamına geliyor. Aynı işlevin aynı satırında hem bir
imza kusuru hem bir biçim kusuru durabilir ve kurgu bunları iki ayrı kusur olarak sayar. Aynı
metni okuyan iki göz, aradıkları şey ayrı olduğu için ayrı şeyler bulur.

Bunun pratik karşılığı kesindir: **bir eksen kapatıldığında kaybedilen kusur sayısı, o
eksenin sınıfındaki kusur sayısıdır.** Kapanan ekseni telafi eden bir kalıntı yoktur. Arayüz
ekseni kapatılırsa üç kusur gider; başka eksenlere ne kadar okuma eklenirse eklensin o üçü
geri getirmez. Alt tablo bu cümleyi sınıyor.

#### Arayüz Ekseni Kapatılınca

Alt tablonun ilk iki satırı ölçümün çekirdeği. Aynı tek inceleyen, aynı değişiklik, tek fark
arayüz ekseninin açık olup olmaması: bulunan **22**'den **19**'a iniyor, kaçan **2**'den
**5**'e çıkıyor ve fark tam olarak **3** arayüz kusuru. Kayıp, sınıfın büyüklüğü kadar.

Üçüncü ve dördüncü satır aynı ölçümü üç kişilik bir kurulda tekrarlıyor. Arayüz ekseni açıkken
üç inceleyen **15** buluyor; arayüze bakan kişinin yerine ikinci bir gerçekleştirim okuması
konduğunda **12**'ye iniyor. Kişi sayısı değişmedi, okuma sayısı değişmedi, hatta ikinci
gerçekleştirim okuması fazladan bir emek. Sonuç **3** kusur eksik. Aynı eksene ikinci kez
bakmanın getirisi **0**'dır ve bu ölçümde bedeli görünür hâle geliyor.

Son satır dersin en keskin sonucu. **On inceleyen** arayüz ekseni olmadan çalışıyor: dört
eksenin her birine ikişer kişi, ayrıca dördünü birden okuyan iki kişi daha. Bulunan **19**.
Beş eksene bakan **tek** inceleyen **22** buluyor. On kişilik bir kurul, tek kişilik bir
kuruldan **3** kusur az buluyor — ve fark, on kişinin hiçbirinin bakmadığı tek eksenden
geliyor.

Dördüncü satırın yapılandırması uydurma değildir; bir incelemede kusur kaçtığında verilen ilk
karar çoğu zaman **bir inceleyen daha eklemektir**. Eklenen kişiye hangi eksene bakacağı
söylenmezse, en tanıdık eksene bakar — gerçekleştirime. Tablo o kararın sayısal sonucunu
veriyor: kurul büyüdü, okuma sayısı arttı, bulunan sayı **15**'ten **12**'ye indi. Sayının
düşmesinin nedeni yeni kişinin bir şeyi bozması değil, yerine geçtiği okumanın **başka bir
eksende** olmasıdır.

Aradaki fark **3/24**, yani **0,125**'tir; kümenin çözünürlüğü **1/24 = 0,042** olduğuna göre
bu farkın üç katıdır ve ölçüm bandının içindedir. Sayının küçüklüğü aldatıcı olabilir: kaçan
üç kusurun her biri, değişikliğin dışındaki kodu kıran bir sözleşme bozulmasıdır ve
incelemenin bulamadığı yerde ancak çağıran taraf kırıldığında görünür.

Ekseni açmanın ucuz bir yolu vardır ve tabloda görünmez: arayüz ekseni, değişikliğin tamamını
yeniden okumadan da açılabilir. Genel bildirimlerin geçtiği satırlar değişikliğin küçük bir
parçasıdır ve önce onlara bakan bir okuma, arayüz sınıfının üç kusurunu ötekilerden önce
görür. Eksen açmak her zaman kurula bir kişi eklemek değildir; bazen yalnız okuma sırasını
değiştirmektir. Kurgu bu ayrımı ölçmez — eksen ya açıktır ya kapalıdır — ama tablonun
söylediği ikisi için de aynıdır: **kapalı bir ekseni telafi eden bir kişi sayısı yoktur.**

#### Sözleşmenin Yazılmamış Yanı

Arayüz ekseni sözleşmenin **yazılmış** hâlini karşılaştırır. İmza, dönüş türü ve hata sınıfı
metindir ve metin okunabilir. Sözleşmenin bir de yazılmamış yanı vardır: çağıran tarafın
güvendiği ama hiçbir yerde belirtilmemiş davranışlar — çağrının yinelenmesinin güvenli olup
olmadığı, dönen listenin sırasının kararlı olup olmadığı, aynı girdiye aynı yanıtın verilip
verilmeyeceği.

Bu davranışlar bozulduğunda arayüz ekseni bir iz bulamaz, çünkü karşılaştırılacak bir önceki
metin yoktur. Kurgudaki karşılığı doğrudandır: böyle bir kusur arayüz sınıfına değil, altıncı
sınıfa — **eksik gereksinim** sınıfına — düşer ve arayüz ekseni açık olsa bile kaçmaya devam
eder. Alt tablonun son sütununun beş satırda da **2** vermesinin nedeni budur.

Ayrım tek bir soruya iner: **bozulan şey bir yerde yazılı mı?** Yazılıysa arayüz ekseninin
işidir ve eksen açıldığında bulunur. Yazılı değilse hiçbir eksenin işi değildir ve incelemenin
dışında, sözleşmenin yazıldığı yerde kapatılır.

#### Özet

- Genel arayüz, dışarıdan çağrılabilen adların ve davranışlarının kümesidir; sözleşmesi beş
  ayrı biçimde bozulabilir ve bunların üçü çağıran kodu kırmadan yanlış çalıştırır.
- Arayüz kusurunun izi değişikliğin içinde tek bir satırdır, sonucu ise değişikliğin
  dışındadır; bu yüzden imzanın önceki hâliyle karşılaştırılmasını gerektirir.
- Beş eksenin bulduğu kümeler ayrıktır: ikili kesişimlerin toplamı **0**, her eksenin
  bulduğunun tamamı yalnız o eksende görünür ve beşinin birleşimi **22**'dir.
- Bir eksen kapatıldığında kaybedilen kusur, o sınıfın büyüklüğü kadardır: arayüz ekseni
  kapatılınca bulunan **22**'den **19**'a iner, kaçan **2**'den **5**'e çıkar.
- Arayüze bakan kişinin yerine ikinci bir gerçekleştirim okuması konduğunda üç kişilik kurul
  **15** yerine **12** buluyor; arayüzsüz **on inceleyen** ise **19** ile beş eksene bakan
  tek inceleyenin **22**'sinin altında kalıyor.
- Sözleşmenin yazılmamış yanı bozulduğunda arayüz ekseninin karşılaştıracağı metin yoktur; bu
  kusur altıncı sınıfa düşer ve eksen açık olsa bile kaçar.

#### Sonraki Adım

Tabloda en büyük tekil payı **gerçekleştirim** ekseni taşıyor: **6** kusur, 24'ün **0,250**'si.
Arayüz ekseninin bulgusu imzanın karşılaştırılmasıyla çıkıyordu; gerçekleştirim ekseninin
bulgusu için karşılaştırılacak bir önceki hâl yoktur — kodun ne yapması gerektiği ile ne
yaptığı arasındaki farka bakılır. Sonraki ders bu ekseni ölçer: eksenler tek tek açıldığında
bulunan sayı hangi eğriyle büyür, gerçekleştirim ekseninin kendi payı bu eğrinin neresinde
durur ve tek başına en çok bulan eksen olması onu ne kadar yeterli kılar.

### Gerçekleştirim Anlamı

Source: https://academia.sh/tr/kurslar/kod-inceleme/gerceklestirim-anlami

Bir eksenin marjinal katkısı hangi eksenlerin zaten açık olduğundan bağımsızdır: gerçekleştirim iki ayrı sırada da 6 kusur ekler ve aynı eksene bir, üç ya da on iki kişi bakması 6 sayısını değiştirmez.

Önceki ders beş eksenin bulduğu kümelerin ayrık olduğunu ölçtü: ikili kesişimlerin toplamı
**0** ve her eksenin bulduğu yalnız o eksende görünüyor. Bundan bir sonuç doğrudan çıkar ama
henüz sınanmadı — eğer paylar ayrıksa, bir eksenin katkısı **hangi eksenlerin zaten açık
olduğundan bağımsız** olmalıdır.

Bu ders o sonucu sınar ve sınamayı en büyük tekil payın sahibi olan eksende, **gerçekleştirim**
ekseninde yapar. Ölçüm iki soru sorar: eksenler farklı sıralarla açıldığında eğri değişir mi
ve aynı eksene daha çok kişi bakması o eksenin payını büyütür mü.

#### Gerçekleştirim Ekseni Ne Sorar

**Gerçekleştirim (implementation)** ekseni, kodun **ne yapması gerektiği** ile **ne yaptığı**
arasındaki farkı arar. Arayüz ekseninden ayrılan yanı buradadır: arayüzde karşılaştırılan iki
metin vardı — imzanın önceki ve sonraki hâli. Gerçekleştirimde karşılaştırmanın bir tarafı
metin değildir. Bir tarafta gövdenin yaptığı iş durur, öteki tarafta okuyanın o gövdenin
yapması gerektiğini düşündüğü iş.

Eksen üç alt soruya ayrılır.

**Doğruluk.** Gövde, adının ve açıklamasının söylediği işi yapıyor mu. Bu soru en çok
görünen kusuru üretir çünkü kodun kendisi delildir: yanlış karşılaştırma yönü, ters çevrilmiş
koşul, yanlış değişkenin döndürülmesi.

**Kenar durum (edge case).** Gövde, alışılmış girdinin dışında da doğru mu. Boş koleksiyon,
tek elemanlı koleksiyon, sınır değerin kendisi, sıfıra bölme, taşma, eşzamanlı erişim. Kenar
durum kavramı Yazılım Kalitesi ve Test müfredatının test derslerinde kuruldu; burada onun
inceleme tarafı ölçülüyor.

**Karmaşıklık.** Gövdenin dallanma sayısı, iç içe geçme derinliği ve tek bir yerde topladığı
sorumluluk. Adlandırma, işlev uzunluğu ve karmaşıklık ölçütlerinin kendisi Temiz Kod kursunda
kuruldu ve burada tekrarlanmıyor. Bu derste bunlar bir **kural listesi** değildir; bir
**inceleme bulgusudur** — incelemenin gördüğü, not düştüğü ve kapanmasını istediği şeydir.
Aradaki fark önemlidir: kural listesi değişikliğe uygulanır, bulgu ise değişikliğin belirli
bir yerini gösterir.

```text
# ogretilen inceleme notu ornegi , calistirilmamistir

dogruluk      Toplam hesaplanirken son eleman disarida kaliyor; ust sinir
              dahil olmali. Ayni girdi icin beklenen deger 15, donen 10.

kenar durum   Liste bos oldugunda ilk eleman okunuyor. Bos girdi icin bir
              erken donus ya da bos degerin acikca ele alinmasi gerekiyor.

karmasiklik   Bu govdede dort ic ice kosul var ve ucuncusu ilk ikisinin
              disinda hicbir durumda calismiyor. Kosul ayri bir yardimci
              islevle disari alinirsa dallanma ikiye iner.
```

Üç notun ortak biçimi şudur: **nerede, ne, hangi koşulda.** Üçü de değişikliğin bir yerini
gösteriyor ve kapanma koşulunu adlandırıyor. Bu blok bir örnektir ve çalıştırılmaz; dersin
sayıları yalnız ölçüm bloğundan gelir.

#### Doğruluğun Kâhini Nerede

Arayüz ekseninin karşılaştıracağı iki metin vardı; gerçekleştirim ekseninin bir tarafı
yoktur. Okuyan, kodun **ne yapması gerektiğini** bir yerden çıkarmak zorundadır ve o yer
değişikliğin içinde olmayabilir.

Üç kaynak kullanılabilir. **Değişikliğin açıklaması** niyeti tarif eder; kısa yazıldığında
okuyan niyeti gövdeden çıkarmaya çalışır ve bu döngüseldir — gövdenin doğru olup olmadığı,
yine gövdeye bakılarak karara bağlanamaz. **Testler** beklenen davranışı örnekle verir; ama
testler aynı değişiklikte yazıldıysa gövdeyle aynı yanlış anlayışı paylaşabilirler. **Belge**
davranışı sözle verir ve değişiklikle birlikte güncellenmemişse eski davranışı anlatır.

Üç kaynağın da kusurlu olabileceği açık ve bu bir rastlantı değil: aynı değişiklikte üçü de
aynı elden çıkar. Gerçekleştirim ekseninin pahalı olmasının nedeni budur — okuyan, kodun ne
yapması gerektiğine dair bağımsız bir yargıya sahip olmak zorundadır.

Bunun ölçümdeki karşılığı yoktur ve olmaması bilinçlidir. Kurgu her ekseni eşit maliyette
sayar: eksen açıksa sınıfı bulunur. Gerçek bir incelemede gerçekleştirim ekseni kusur başına
en pahalı eksendir ve biçim ekseni en ucuzu. Tablo bulunan kusuru sayar, harcanan dikkati
saymaz; **iki sayının ayrı olduğu bu kursun son dersine kadar açık tutulur.**

#### Katkı Sıraya Bağlı mı

Bir eksenin **marjinal katkısı**, o eksen açıldığında bulunan kusur sayısının ne kadar
arttığıdır. Paylar ayrıksa bu artış her zaman sınıfın büyüklüğü kadar olmalıdır ve açılma
sırası hiçbir şey değiştirmemelidir.

Bunun sınanması gerekir, çünkü sezgi tersini söyler. Bir incelemede eksenler gerçekten sırayla
açılır: okuma bir yerden başlar ve ilerledikçe okuyanın bakışı değişir. Sezgi, ilk açılan
eksenin "kolay" kusurları toplayacağını ve sonrakilere daha az iş kalacağını söyler. Ölçüm bu
sezgiyi iki ayrı sırayla sınar: biri gerçekleştirimden başlar, öteki biçimden.

#### Ölçümün Varsayımları

- **IE16** — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, dikkat 12 öbek. Okunmamış
  öbek yoktur.
- **IE17** — Eğri, tek bir inceleyenin eksen kümesinin adım adım büyütülmesidir. Her adımda
  aynı değişiklik yeniden okunur; okuma bütçesi adım sayısıyla tükenmez.
- **IE18** — Marjinal katkı, o adımdaki kümülatif bulunan sayısından bir önceki adımınkinin
  çıkarılmasıdır.
- **IE19** — İki sıra aynı beş ekseni içerir ve yalnız açılma düzenleri farklıdır; sıra B,
  sıra A'nın tersidir.
- **IE20** — İkinci bölümde aynı eksene bakan inceleyenler birbirinin aynıdır; kurgu, ikinci
  bir okumanın birincinin gözünden kaçanı yakalaması gibi bir pay içermez. Bu yalınlaştırma
  bilerek yapılır ve ölçümün sonucunu tek bir değişkene bağlar.
- **IE21** — "Okuma" sütunu yapılan inceleme sayısıdır; aynı kişinin iki kez okuması ile iki
  kişinin birer kez okuması bu kurguda ayırt edilmez.
- **IE22** — Oran, bulunanın 24'e bölümüdür. Kümenin çözünürlüğü **1/24 = 0,042**'dir.

#### Ölçüm

```python
"""Gerceklestirim ekseni: eksen ekleme egrisi ve ayni eksene kisi ekleme.

Bolum 1 - eksenler iki ayri sirayla acilinca kumulatif bulunan ve marjinal.
Bolum 2 - gerceklestirim ekseni acik, kapali ve cok okumayla.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def egri(d, sira):
    """Eksenler tek tek acilir; her adimda kumulatif ve marjinal."""
    acik, satirlar, onceki = set(), [], 0
    for e in sira:
        acik.add(e)
        n = len(incele(d, acik))
        satirlar.append((e, n, n - onceki))
        onceki = n
    return satirlar


TAM = set(EKSENLER)
d = degisiklik(600)
A = egri(d, ("gerceklestirim", "arayuz", "test", "belge", "bicim"))
B = egri(d, ("bicim", "belge", "test", "arayuz", "gerceklestirim"))

print(f"{'adım':>4s} {'sıra A':<15s} {'toplam':>6s} {'marjinal':>8s}  "
      f"{'sıra B':<15s} {'toplam':>6s} {'marjinal':>8s}")
for i, (a, b) in enumerate(zip(A, B), start=1):
    print(f"{i:4d} {a[0]:<15s} {a[1]:6d} {a[2]:8d}  "
          f"{b[0]:<15s} {b[1]:6d} {b[2]:8d}")

print()
DORT = TAM - {"gerceklestirim"}
KURULLAR = {
    "bir inceleyen, gerçekleştirim": [{"gerceklestirim"}],
    "üç inceleyen, gerçekleştirim": [{"gerceklestirim"}] * 3,
    "on iki inceleyen, gerçekleştirim": [{"gerceklestirim"}] * 12,
    "bir inceleyen, dört eksen": [DORT],
    "bir inceleyen, beş eksen": [TAM],
}
print(f"{'kurul':<33s} {'okuma':>5s} {'bulunan':>7s} {'kaçan':>5s} "
      f"{'gerçekleştirim kaçan':>20s} {'oran':>5s}")
for ad, atama in KURULLAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    gk = sum(1 for k in kacan if k["sinif"] == "gerceklestirim")
    print(f"{ad:<33s} {len(atama):5d} {len(b):7d} {len(kacan):5d} "
          f"{gk:20d} {len(b) / 24:5.3f}")
```

```
adım sıra A          toplam marjinal  sıra B          toplam marjinal
   1 gerceklestirim       6        6  bicim                7        7
   2 arayuz               9        3  belge               10        3
   3 test                12        3  test                13        3
   4 belge               15        3  arayuz              16        3
   5 bicim               22        7  gerceklestirim      22        6

kurul                             okuma bulunan kaçan gerçekleştirim kaçan  oran
bir inceleyen, gerçekleştirim         1       6    18                    0 0.250
üç inceleyen, gerçekleştirim          3       6    18                    0 0.250
on iki inceleyen, gerçekleştirim     12       6    18                    0 0.250
bir inceleyen, dört eksen             1      16     8                    6 0.667
bir inceleyen, beş eksen              1      22     2                    0 0.917
```

#### Eğri Sıradan Bağımsız

Üst tablonun iki yarısı aynı beş ekseni açıyor, biri gerçekleştirimden biri biçimden
başlayarak ve iki eğri de **22**'de bitiyor.

Marjinal sütunlar ölçümün asıl sonucu. Gerçekleştirim, sıra A'da **ilk** açılan eksen ve
katkısı **6**; sıra B'de **son** açılan eksen ve katkısı yine **6**. Biçim, B'de ilk sırada
**7** ekliyor, A'da son sırada yine **7**. Arayüz, test ve belge her iki sırada da **3**
ekliyor.

Bir eksenin katkısı, ondan önce kaç eksenin açıldığına bakmıyor. "Kolay kusurlar önce
toplanır, sonraya az iş kalır" sezgisi bu kurguda yanlış çıkıyor ve nedeni önceki derste
ölçülmüştü: paylar ayrık olduğu için tüketilecek ortak bir havuz yok. Her eksen kendi
sınıfını getiriyor ve o sınıfı başka hiçbir eksen zaten toplamış olamıyor.

Bağımsızlığın sınırı da bellidir. Bu derste dikkat tükenmiyor, çünkü değişiklik dikkat
kadar. Okuma sırasının önem kazandığı tek durum, okumanın bitmeden kesildiği durumdur: o
zaman hangi eksenin sonraya bırakıldığı doğrudan **hiç bakılmayan eksen** hâline gelir. Bu
konunun ölçümlerinde böyle bir kesilme yoktur.

Bunun doğrudan bir kullanımı var. Bir kurulun bulacağı kusur sayısı, kimin önce baktığına ya
da okumanın hangi dosyadan başladığına bakmadan, yalnız **açık eksenlerin sınıf
büyüklüklerinin toplamı** olarak önceden hesaplanabilir. Sıra bir plan değişkeni değildir;
**kapsam** olan tek değişkendir.

#### Aynı Eksene Kişi Eklemek

Alt tablonun ilk üç satırı tek bir sayıyı üç kez veriyor: **6**.

Bir inceleyen gerçekleştirime bakıyor ve **6** buluyor. Üç inceleyen aynı eksene bakıyor,
yine **6**. On iki inceleyen aynı eksene bakıyor, yine **6**. Okuma sayısı bire karşı on iki
oranında arttı ve bulunan kusur **0** arttı. Oran üç satırda da **0,250**'de duruyor.

Bu, kursun ikinci iddiasının en sert biçimidir: **inceleyen eklemek kusur bulmaz.** Buradaki
"bulmaz" mecaz değil, ölçülen sayıdır — on bir fazladan okumanın getirisi sıfırdır. Kurgu
bunu bir yalınlaştırmayla elde ediyor: aynı eksene bakan ikinci okuma birincinin gördüğünü
görür. Gerçek bir incelemede ikinci okumanın küçük bir ek payı olabilir, ama bu payın
büyüklüğü hiçbir zaman **yeni bir eksen açmanın** payı kadar olmaz, çünkü ikinci okuma
tanımı gereği aynı sınıfın içinde arar.

Bu, ikinci okumanın hiçbir işe yaramadığı anlamına gelmiyor; **bulma dışında** bir işe
yaradığı anlamına geliyor. İlk dersin üç işi burada ayrışır: aynı eksene bakan ikinci okuma
kusur bulmaz ama **bilgi yayar** — o kodun ikinci bir okuru olur ve sonraki değişikliklerde
gerçekleştirim ekseninde bakabilecek kişi sayısı artar. Yeni katılan birinin deneyimli birinin
baktığı eksende okuma yapması da aynı sınıfa girer; bu bir öğrenme kararıdır.

Ayrım şurada keskinleşir: **ikinci okuma bir bulma kararıysa ölçülebilir ve getirisi 0'dır;
bir yayma kararıysa bu tabloda ölçülmez.** İkisi birbirinin yerine geçtiğinde sonuç yanlış
olur. Bir kusur kaçtıktan sonra verilen "bir kişi daha baksın" kararı, sayının söylediğine
göre bulma tarafında karşılıksızdır. Karşılığı olan karar, bakılmayan bir ekseni açmaktır.

Son iki satır aynı ölçümün öteki ucunu veriyor. Gerçekleştirim ekseni kapatıldığında, kalan
dört eksene bakan tek bir inceleyen **16** kusur buluyor ve kaçan **8**'in **6**'sı
gerçekleştirim sınıfından. Eksen geri açıldığında bulunan **22**'ye çıkıyor: oran
**0,667**'den **0,917**'ye. Tek bir ekseni açmanın getirisi **6** kusur; on bir fazladan
okumanın getirisi **0**.

#### Üç Alt Sorunun Ayrı Ağırlığı

Ölçüm gerçekleştirim sınıfını tek bir sayı olarak veriyor — **6** — ve içindeki üç alt soruyu
ayırmıyor. Bu bir kurgu kararıdır; ama ayrımın pratikte bir sonucu var ve tablonun dışında
kalıyor.

**Doğruluk** kusurunun bir kanıtı vardır: yanlış sonucu üreten bir girdi gösterilebilir.
Bulgu tartışmaya kapalıdır ve kapanması tek bir düzeltmeyle olur.

**Kenar durum** kusurunun kanıtı da bir girdidir, ama o girdinin gerçekten oluşup oluşmadığı
tartışılabilir. Bulgu bu yüzden bazen bir düzeltmeyle değil, bir kararla kapanır: o durumun
kapsam dışı olduğunun yazılı hâle getirilmesiyle.

**Karmaşıklık** kusurunun gösterilebilir bir girdisi yoktur. Bulgu bugünkü bir yanlışı değil,
sonraki değişikliklerin maliyetini işaret eder ve bu yüzden kapanması için ortak bir ölçüt
gerekir. Ölçütün kendisi Temiz Kod kursunun konusudur; incelemede kalan iş, bulguyu
değişikliğin belirli bir yerine bağlamak ve neyin kapanmış sayılacağını yazmaktır.

Üçü de aynı sınıfta sayılır çünkü üçü de aynı eksenin okumasıyla bulunur. Kaç turda
kapandıkları ise ayrı bir değişkendir ve bu konunun ölçümlerine girmez.

#### Özet

- Gerçekleştirim ekseni kodun ne yapması gerektiği ile ne yaptığı arasındaki farkı arar ve üç
  alt soruya ayrılır: doğruluk, kenar durum, karmaşıklık.
- Karmaşıklık burada bir kural listesi değil, bir **inceleme bulgusudur**: değişikliğin
  belirli bir yerini gösterir ve kapanma koşulunu adlandırır.
- Bir eksenin marjinal katkısı açılma sırasından bağımsızdır: gerçekleştirim iki sırada da
  **6**, biçim iki sırada da **7**, kalan üç eksen **3**'er kusur ekler ve iki eğri de
  **22**'de biter.
- Bir kurulun bulacağı sayı, açık eksenlerin sınıf büyüklüklerinin toplamıdır; okuma sırası
  bir plan değişkeni değildir.
- Aynı eksene bir, üç ve on iki okuma **6** kusur bulur; oran **0,250**'de sabit kalır. On
  bir fazladan okumanın getirisi **0**, tek bir yeni eksenin getirisi **6** kusurdur.
- Aynı eksendeki ikinci okumanın karşılığı bulmada değil bilgi yaymadadır; ikisi birbirinin
  yerine konduğunda "bir kişi daha baksın" kararı bulma tarafında karşılıksız kalır.

#### Sonraki Adım

Buraya kadar iki eksen ölçüldü ve ikisinde de kaçan kusurun nedeni aynıydı: o eksene kimse
bakmıyordu. Ama kaçmanın ikinci bir nedeni daha olabilir — kusurun bulunduğu metnin hiç
okunmamış olması. Bu derste böyle bir kaçış yoktu, çünkü değişiklik dikkat kadardı. Sonraki
ders **test** ekseninde bu ikisini birbirinden ayırır: testin kendisinin taşıdığı kusurlar
okunmuş öbeklerin içinde mi duruyor, aynı öbeği başka eksenlerden okuyan inceleyenler o
kusurun üzerinden kaç kez geçiyor ve geçtikleri hâlde neden görmüyorlar.

### Testlerin İncelenmesi

Source: https://academia.sh/tr/kurslar/kod-inceleme/testlerin-incelenmesi

Üç test kusurunun üçü de okunmuş öbeklerde duruyor ve o öbeklerde başka eksenlerden bulgu veren inceleyenler var; okunmamış öbekte kaçan kusur sayısı beş eksenin beşinde de 0 ve test ekseni kapatılınca bulunan 22'den 19'a iniyor.

Önceki ders bir kusurun kaçmasının bu kurguda tek bir nedeni olduğunu varsaymıştı: o eksene
kimsenin bakmaması. Ama kaçmanın ikinci bir nedeni daha olabilir — kusurun bulunduğu metnin
hiç okunmamış olması. İki neden aynı sonucu verir ve tabloda aynı sütunda görünür; oysa
ikisine verilecek karşılık aynı değildir.

Bu ders o ayrımı ölçer ve ölçümü **test** ekseninde yapar. Test ekseninin seçilmesi rastgele
değil: testler değişikliğin gövdesiyle aynı dosyalarda ya da onlara komşu dosyalarda durur,
yani başka eksenlere bakan inceleyenlerin gözünün önünden geçer. Sorusu şudur: bir kusur,
okunmuş bir metnin içinde, o metni okuyan birden çok kişinin gözü önünde kaçabilir mi.

#### Testin Kendisi de İncelenir

Test seviyeleri, test piramidi, kapsam ölçütleri ve test yazma teknikleri Yazılım Kalitesi ve
Test müfredatında kuruldu ve burada tekrarlanmıyor. Bu dersin konusu testin nasıl yazılacağı
değil, **incelemede testin kendisine bakıldığında ne bulunduğudur.**

Ayrım şurada durur. Bir değişikliğin testleri iki ayrı rolde bulunur. Birinci rolde test bir
**delildir**: gövdenin doğru olduğunu gösterir ve gerçekleştirim eksenine bakan okuma ona
dayanır. İkinci rolde test bir **inceleme nesnesidir**: kendisi de yazılmış koddur ve kendi
kusurlarını taşır.

İkinci rol atlandığında ilk rol çöker. Gövdenin doğruluğuna testlerin geçmesine bakarak karar
veren bir okuma, testlerin ne doğruladığını denetlemediyse hiçbir şeye bakmamış olur. Test
ekseni tam olarak bu denetimdir.

#### Testin Taşıdığı Üç Kusur

**Kapsam.** Değişikliğin getirdiği yeni yol test edilmemiştir. Testler vardır, geçerler ve
sayıları da artmış olabilir; ama değişen davranışın kendisine dokunan bir test yoktur. Bu
kusurun incelemede görünen izi, değişen gövdenin bir dalına karşılık gelen bir iddianın
bulunmamasıdır.

**Anlamlılık.** Test yeni yolu çalıştırır ama bir şey doğrulamaz. Yalnız çağrının hata
fırlatmadığını sınayan bir test, gövde ne dönerse dönsün geçer. Aynı sınıfa, sonucu kendi
hesaplayan testler de girer: beklenen değeri gövdenin kullandığı ifadeyle üreten bir iddia,
gövde yanlış olsa da doğrulanır.

**Kırılganlık.** Test, davranışa değil gerçekleştirimin iç ayrıntısına bağlanmıştır: çağrı
sırasına, iç bir yapının alan adına, kayıt satırının tam metnine. Böyle bir test davranış
değişmeden kırılır ve kırıldığında düzeltilmesi gereken şey gövde değil testtir.

Üçünün incelemedeki görünürlüğü aynı değildir. Kapsam kusuru sayılabilir bir eksikliktir ve
gövdenin dalları ile testlerin durumları yan yana konduğunda ortaya çıkar. Anlamlılık kusuru
testin metnini okumayı gerektirir ve test **sayısına** bakan bir okumadan kaçar, çünkü hiçbir
şey doğrulamayan bir test de bir testtir ve sayıya girer. Kırılganlık kusuru üçünün en
zorudur: test bugün geçer ve kusurun bedeli sonraki bir değişiklikte, kendisiyle ilgisi
olmayan bir işi durdurarak ödenir.

```text
# ogretilen inceleme notu ornegi , calistirilmamistir

kapsam        Degisiklik iki yeni dal getiriyor; testler yalnizca ilk dali
              cagiriyor. Ikinci dal icin bir durum eklenmesi gerekiyor.

anlamlilik    Testin tek iddiasi cagrinin hata firlatmadigi. Gövde herhangi
              bir deger dondurse de bu test geciyor; donen degerin
              dogrulanmasi gerekiyor.

kirilganlik   Test, kayit satirinin tam metnini karsilastiriyor. Kayit
              bicimi degistiginde davranis ayni kalsa da test kirilacak;
              karsilastirma sonuca baglanabilir.
```

Üç not da testin bir yerini gösteriyor ve neyin eklenmesiyle kapanacağını söylüyor. Bu blok
bir örnektir ve çalıştırılmaz; dersin sayıları yalnız ölçüm bloğundan gelir.

#### Test Değişiklikle Aynı Elden Çıkar

Test ekseninin ayrı bir okuma gerektirmesinin yapısal bir nedeni var ve bu neden önceki dersin
sorusuna bağlanıyor: gerçekleştirim eksenine bakan okuma, gövdenin ne yapması gerektiğini
bir yerden çıkarmak zorundaydı ve kullanılabilecek kaynaklardan biri testlerdi.

Sorun şu ki testler aynı değişikliğin parçasıdır. Gövde ile test aynı anda, aynı anlayışla
yazılır. Gövdenin dayandığı bir yanlış anlama varsa, test de aynı yanlış anlamayı kaydeder ve
gövdeyi doğrular. Bu durumda testin geçmesi bir delil değil, bir yankıdır.

Bunun incelemedeki sonucu doğrudandır: **testin doğruluğu, gövdenin doğruluğundan bağımsız
olarak sınanmalıdır.** Test ekseni bunu yapan tek okumadır ve bakacağı şey testin geçip
geçmediği değil, testin **ne iddia ettiğidir**. Bir iddianın gövdeyle aynı ifadeyi
tekrarlaması, gövdenin dallarından birini hiç çağırmaması ya da hiçbir sonucu
karşılaştırmaması, testin çalıştırılmasıyla değil okunmasıyla görülür.

Ölçüm bu bağımlılığı modellemez — test sınıfındaki kusurlar, gerçekleştirim sınıfındakilerden
bağımsız kusurlardır. Modelin yalınlığı burada ölçümün lehinedir: bağımlılık eklenseydi test
ekseninin kapatılmasının bedeli tabloda görünenden büyük çıkardı.

#### Okunmuş Metnin İçinde Kaçmak

Kurguda bir kusurun bulunması iki koşula bağlıdır: kusurun sınıfı inceleyenin ekseninde
olacak ve kusurun bulunduğu öbek inceleyenin okuduğu öbekler arasında olacak. İki koşuldan
biri sağlanmazsa kusur kaçar.

Bu konunun ölçeğinde ikinci koşul her zaman sağlanır: değişiklik 12 öbek, dikkat de 12 öbek.
Dolayısıyla bu derste **hiçbir kusur okunmadığı için kaçmaz.** Ölçüm bunu varsaymak yerine
sayar ve kaçanları ikiye ayırır — okunmuş öbekte kaçanlar ve okunmamış öbekte kaçanlar.

İkinci sütunun sıfır çıkması, birinci sütunun tamamının **eksen kaçışı** olduğunu gösterir.
Bu, dersin sorusuna doğrudan yanıttır: kaçan kusur, kimsenin bakmadığı bir yerde değil,
herkesin okuduğu bir yerde duruyordur.

#### Ölçümün Varsayımları

- **IE23** — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, dikkat 12 öbek.
- **IE24** — Bir öbek 50 satırdır ve okuma birimi öbektir; bir öbeği okuyan inceleyen, o
  öbeğin tamamını görmüş sayılır.
- **IE25** — "Aynı öbekteki öteki sınıf" sütunu, o öbekte bulunan ve test dışındaki eksen
  sınıflarından olan kusurların sınıf adlarıdır.
- **IE26** — "O öbekte bulgu veren başka eksen" sayısı, o öbekte kendi sınıfından bir kusur
  bulunan test dışı eksen sayısıdır. Bu eksene bakan bir inceleyen o öbekte bir not düşmüş
  demektir; öbeği okuduğu kurguca kesindir.
- **IE27** — Okunmuş öbekte kaçan kusur, öbeği okunan ama sınıfı inceleyenin ekseninde
  olmayan kusurdur. Okunmamış öbekte kaçan, öbeği hiç okunmayan kusurdur.
- **IE28** — İkinci bölümdeki her satır tek eksenli tek bir okumadır; kaçan sütunları o tek
  okumaya göredir.
- **IE29** — Testin geçmesi ya da kalması ölçümde yoktur; ölçülen şey testin **incelemede**
  bulunan kusurudur, çalıştırıldığında verdiği sonuç değil.
- **IE30** — Öbek düzeyinde çözünürlük **1/12 = 0,083**, kusur düzeyinde **1/24 = 0,042**.

#### Ölçüm

```python
"""Testlerin incelenmesi: okunmus obekte kacan kusur.

Bolum 1 - test kusurlarinin durdugu obekler ve ayni obekteki oteki siniflar.
Bolum 2 - her tek eksenli okuma icin kacanin okunmus ve okunmamis ayrimi.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


TAM = set(EKSENLER)
d = degisiklik(600)
test_kusurlari = [k for k in d["kusurlar"] if k["sinif"] == "test"]

print(f"{'kusur':>5s} {'öbek':>4s} {'aynı öbekteki öteki sınıf':<28s} "
      f"{'o öbekte bulgu veren başka eksen':>32s}")
for k in test_kusurlari:
    komsu = sorted({o["sinif"] for o in d["kusurlar"]
                    if o["obek"] == k["obek"] and o["sinif"] in EKSENLER
                    and o["sinif"] != "test"})
    print(f"{k['no']:5d} {k['obek']:4d} {', '.join(komsu):<28s} "
          f"{len(komsu):32d}")
dolu = {k["obek"] for k in d["kusurlar"]}
cok = sum(1 for o in range(d["obek"])
          if len({k["sinif"] for k in d["kusurlar"] if k["obek"] == o}) > 1)
print(f"{d['obek']} öbeğin {len(dolu)}'inde en az bir kusur var; "
      f"{cok} öbekte birden çok sınıftan kusur var")

print()
print(f"{'eksen':<15s} {'okunan öbek':>11s} {'bulunan':>7s} "
      f"{'okunmuş öbekte kaçan':>20s} {'okunmamış öbekte kaçan':>22s}")
for e in EKSENLER:
    b = incele(d, {e})
    okunan = set(range(min(DIKKAT, d["obek"])))
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    ok = sum(1 for k in kacan if k["obek"] in okunan)
    yok = sum(1 for k in kacan if k["obek"] not in okunan)
    print(f"{e:<15s} {len(okunan):11d} {len(b):7d} {ok:20d} {yok:22d}")

print()
DORT = TAM - {"test"}
for ad, eksenler in (("beş eksen", TAM), ("testsiz dört eksen", DORT)):
    b = incele(d, eksenler)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    tk = sum(1 for k in kacan if k["sinif"] == "test")
    print(f"{ad:<20s} bulunan {len(b):2d}  kaçan {len(kacan):2d}  "
          f"test kaçan {tk}  yazılmayan kaçan "
          f"{sum(1 for k in kacan if k['sinif'] == YAZILMAYAN)}")
```

```
kusur öbek aynı öbekteki öteki sınıf    o öbekte bulgu veren başka eksen
    3    9 gerceklestirim                                              1
    7    1 arayuz, bicim                                               2
   19    7 arayuz                                                      1
12 öbeğin 11'inde en az bir kusur var; 7 öbekte birden çok sınıftan kusur var

eksen           okunan öbek bulunan okunmuş öbekte kaçan okunmamış öbekte kaçan
arayuz                   12       3                   21                      0
gerceklestirim           12       6                   18                      0
test                     12       3                   21                      0
belge                    12       3                   21                      0
bicim                    12       7                   17                      0

beş eksen            bulunan 22  kaçan  2  test kaçan 0  yazılmayan kaçan 2
testsiz dört eksen   bulunan 19  kaçan  5  test kaçan 3  yazılmayan kaçan 2
```

#### Aynı Öbek, Ayrı Eksen

Üst tablo üç test kusurunu tek tek gösteriyor ve üçü de yalnız başına durmuyor.

**3 numaralı kusur** dokuzuncu öbekte ve aynı öbekte bir gerçekleştirim kusuru var.
**7 numaralı kusur** birinci öbekte ve orada hem arayüz hem biçim kusuru var. **19 numaralı
kusur** yedinci öbekte ve yanında bir arayüz kusuru duruyor.

Sağdaki sütun bunun anlamını veriyor: **1, 2, 1.** Bu sayılar, o öbekte kendi sınıfından bir
kusur **bulmuş** eksenlerin sayısıdır. Yani birinci öbekte iki ayrı inceleyen not düşmüştür;
ikisi de o elli satırı okumuştur; ve ikisi de aynı elli satırın içindeki test kusurunu
görmemiştir. Aynı şey dokuzuncu ve yedinci öbek için birer kez geçerlidir.

Üç kusur üç ayrı öbekte duruyor; öbek düzeyinde bu **3/12**, yani **0,250**'dir. Test
kusurlarının bulunduğu öbekler değişikliğin dörtte birine denk geliyor ve bu öbeklerin
hiçbiri okunmamış değil. Öbek düzeyinde ölçülebilen en küçük fark **1/12 = 0,083** olduğuna
göre bu pay ölçüm bandının rahatça içindedir.

Alt satır kurgunun yoğunluğunu veriyor: **12 öbeğin 11'inde** en az bir kusur var ve
**7 öbekte** birden çok sınıftan kusur var. Değişiklik dar bir yere sıkışmış değil; sınıflar
birbirine karışmış hâlde duruyor. Bir inceleyenin okuduğu her öbekte, kendi bulduğunun
yanında bulmadığı bir şey olma olasılığı yüksek.

#### Kaçmanın Tek Nedeni

Orta tablo bu dersin ayrımını sayıya çeviriyor. Beş satırın hepsinde **okunan öbek 12** ve
**okunmamış öbekte kaçan 0**.

Sıfır sütunu şunu söylüyor: bu ölçekte hiçbir kusur, metni okunmadığı için kaçmıyor. Kaçan
kusurların tamamı — arayüzde **21**, gerçekleştirimde **18**, testte **21**, belgede
**21**, biçimde **17** — okunmuş öbeklerin içinde duruyor. Her birinin tek bir nedeni var:
inceleyenin ekseninde o sınıf yok.

Bu, incelemenin en aldatıcı yanını adlandırıyor. Bir inceleyen değişikliğin **tamamını**
okuduğunu söyleyebilir ve doğru söylüyordur; okuma gerçekten yapılmıştır. Ama "tamamını
okudum" cümlesi "tamamına baktım" anlamına gelmez. Okuma bir kapsama, bakma bir eksene
aittir ve tablo ikisinin ayrı olduğunu gösteriyor.

Bunun incelemenin kaydına dokunan bir karşılığı var. Bir inceleme "bir şey bulamadım" diyerek
kapandığında geriye kalan bilgi eksiktir: hangi eksenlerde bakıldığı yazılı değildir. Aynı
değişikliğe sonradan bakan biri, kapanmış incelemenin hangi sınıfları kapsadığını bilemez ve
tabloya göre bu bilgi, bulunan kusur listesi kadar belirleyicidir.

Kaydın taşıması gereken şey bu yüzden yalnız bulgu listesi değil, **bakılan eksen
listesidir**. "Arayüz ve gerçekleştirim eksenlerinde okundu, test ve belge eksenlerinde
okunmadı" biçiminde bir not bulunan sayısını değiştirmez; kaçanların **hangi sınıflarda**
olduğunu önceden söyler. Bu not değişiklik hakkındadır ve incelemenin kapsamını kaydeder,
bakan kişinin başarısını değil.

Alt iki satır kaybın büyüklüğünü veriyor. Beş eksene bakan okuma **22** buluyor, test ekseni
kapatıldığında **19**. Kaçan **2**'den **5**'e çıkıyor ve fark tam olarak **3** test kusuru.
Test ekseninin payı, önceki derste ölçülen kurala uygun biçimde sınıfının büyüklüğü kadar.

Bu üç kusurun kaçmasının pratikteki karşılığı, ötekilerden bir bakıma daha ağırdır. Kaçan bir
test kusuru yalnız kendisi kalmaz; testin **delil** rolünü de bozar. Kapsamı eksik bir test
takımı, gerçekleştirim ekseninde çalışan sonraki okumalara yanlış bir güvence verir — testler
geçiyordur, ama geçtikleri şey değişen davranış değildir.

#### Özet

- Test bir değişiklikte iki rol taşır: gövdenin doğruluğunun **delili** ve kendisi de
  incelenen bir **nesne**. İkinci rol atlandığında birincisi dayanaksız kalır.
- Testin taşıdığı kusurlar üç türdür: **kapsam** (yeni yol test edilmemiş), **anlamlılık**
  (iddia bir şey doğrulamıyor), **kırılganlık** (test iç ayrıntıya bağlanmış).
- Üç test kusuru 9, 1 ve 7 numaralı öbeklerde duruyor ve o öbeklerde sırasıyla **1, 2, 1**
  başka eksen bulgu vermiş; o öbekleri okuyan inceleyenler test kusurunun üzerinden geçmiş.
- Beş eksenin beşinde de **okunmamış öbekte kaçan 0**'dır: bu ölçekte kaçan her kusurun tek
  nedeni bakılmayan eksendir. "Tamamını okudum" cümlesi "tamamına baktım" anlamına gelmez.
- Test ekseni kapatıldığında bulunan **22**'den **19**'a iner, kaçan **2**'den **5**'e çıkar;
  kaçan üç kusur ayrıca testin delil rolünü zayıflatır.
- Test gövdeyle aynı anda ve aynı anlayışla yazıldığı için testin geçmesi bağımsız bir delil
  değildir; test ekseni testin ne iddia ettiğine bakar, geçip geçmediğine değil.

#### Sonraki Adım

Buraya kadar üç eksen ölçüldü ve üçünün de nesnesi koddu: imza, gövde, test. Dördüncü eksenin
nesnesi kodun dışındadır — değişikliğin **belgeye** yansıması. Bu eksen kapatıldığında da
kaybın sınıf büyüklüğü kadar olması beklenir; ama belge ekseninin ayrı bir yanı var. Yazılmış
bir belgenin yanlış olması ile bir davranışın hiç belgelenmemiş olması aynı şey değildir ve
ikisi kurguda ayrı sınıflara düşer. Sonraki ders beş ekseni tek tek kapatarak kaybı ölçer ve
belge ekseninin bulabildiği ile bulamadığını ayırır.

### Belgelendirme İncelemesi

Source: https://academia.sh/tr/kurslar/kod-inceleme/belgelendirme-incelemesi

Beş eksen tek tek kapatıldığında kayıp her zaman kapatılan sınıfın büyüklüğü kadar: 3, 6, 3, 3 ve 7 kusur; belge ekseni kapatılınca bulunan 22'den 19'a iner ve aynı öbekte duran iki eksik gereksinim kusuru eksen açık olsa da kaçmayı sürdürür.

Önceki üç ders üç ekseni ölçtü ve üçünün de nesnesi koddu: imza, gövde, test. Dördüncü eksenin
nesnesi kodun dışındadır. Değişiklik bir davranışı değiştirdiğinde o davranışı **anlatan**
metin de değişmelidir; değişmezse geriye, kodun söylediğiyle çelişen bir metin kalır.

Bu ders o ekseni ölçer ve ölçümü bir adım genişletir: beş eksen tek tek kapatılır ve her
kapanışın kaybı yan yana konur. Ardından belge ekseninin kendine özgü sınırı ölçülür —
yazılmış bir belgenin yanlış olması ile bir davranışın hiç yazılmamış olması arasındaki fark.

#### Değişikliğin Belgeye Yansıması

Belge ekseninin baktığı metin türleri ayrıdır ve hepsi aynı değişiklikte bulunmaz. Gövdenin
yanındaki açıklama satırları, genel arayüzün referans metni, deponun tanıtım dosyası ve kurulum
yönergesi, örnek kod parçaları — her biri bir davranışa dayanır ve o davranış değiştiğinde
geçersiz olur.

Doküman türlerinin ayrımı, okur tanımı ve yazım disiplini Teknik Yazarlık ve Dokümantasyon
kursunun konusudur ve burada tekrarlanmıyor. Bu dersin ölçtüğü tek şey **incelemede belgeye
bakılıp bakılmadığı ve bakılmadığında ne kaçtığıdır.**

Belge ekseninin ayırt edici yanı, bulgusunun bir çelişkiyle bulunmasıdır. Öteki eksenler tek
bir metne bakar: arayüz imzaya, gerçekleştirim gövdeye, test iddiaya. Belge ekseni **iki
metni** karşılaştırır — kodun yaptığı iş ile metnin anlattığı iş. Bu yüzden belge kusuru
yalnız belge dosyasına bakarak bulunamaz; belgeyi doğru okumak, kodu da okumuş olmayı
gerektirir.

Bu karşılaştırma zorunluluğu belge eksenini pahalı gösterir, oysa ucuzlatılabilir. Kodun
yaptığı iş zaten arayüz ve gerçekleştirim eksenlerinde okunmuştur; belge ekseni o okumanın
üstüne ikinci metni koyar. İki ekseni aynı okumada birlikte taşımak, üçüncü derste ölçülen
toplanabilirliğin pratik karşılığıdır — eksenler birbirinin payını yemez ve bir arada
yürütülebilir.

#### Belge Ekseninin Üç Bulgusu

**Eskimiş metin.** Davranış değişmiş, onu anlatan cümle değişmemiştir. Metin dilbilgisi
olarak kusursuzdur ve bir zamanlar doğruydu; bugün yanlıştır. Bu, üçü içinde en sık kaçanıdır,
çünkü metnin kendisi değişikliğin içinde **görünmez** — değişmediği için değişiklikte yer
almaz.

**Eksik metin.** Değişiklik yeni bir genel ad ya da yeni bir yapılandırma seçeneği getirmiş,
ama onu anlatan bir metin eklenmemiştir. Bu bulgunun izi değişikliğin içindedir: eklenen ad
görünür, karşılığında eklenen bir açıklama görünmez.

**Çelişen metin.** Aynı davranış iki ayrı yerde anlatılmış ve biri güncellenmiştir. Okur
hangisine bakarsa ona inanır; iki metnin çeliştiğini yalnız ikisini birden okuyan görür.

```text
# ogretilen inceleme notu ornegi , calistirilmamistir

eskimis     Islevin aciklama satiri "bos liste doner" diyor; govde artik
            bos deger donduruyor. Aciklamanin yeni davranisa gore
            guncellenmesi gerekiyor.

eksik       Yeni yapilandirma secenegi eklenmis, kurulum yonergesinde
            karsiligi yok. Secenegin varsayilan degeriyle birlikte
            yonergeye eklenmesi gerekiyor.

celisen     Tanitim dosyasindaki ornek eski cagri bicimini kullaniyor,
            referans metni yeni bicimi anlatiyor. Iki metinden biri
            otekine gore guncellenmeli.
```

Bu blok bir örnektir ve çalıştırılmaz; dersin sayıları yalnız ölçüm bloğundan gelir.

#### Belge Ekseni Neden Kapanır

Beş eksen içinde en sık kapananı belgedir. Nedenleri kurgunun dışındadır ama tablonun nasıl
okunacağını değiştirir.

**Belge en sona bırakılır.** Değişikliğin gövdesi ve testleri hazırdır, belge "birleştirmeden
sonra" yazılacaktır. İnceleme bu durumda ekseni kapatmış olmaz, ertelemiş olur; ölçüm
açısından ikisi aynıdır, çünkü o turda belge kusuru bulunmaz.

**Belge bulgusu engelleyici sayılmaz.** Bir gerçekleştirim bulgusu birleştirmeyi durdurur, bir
belge bulgusu çoğu zaman durdurmaz: bulgu yazılır ve değişiklik yine de birleşir. Tablo bu
ayrımı içermez — bulunan kusur bulunmuştur, kapanıp kapanmadığı sonraki konuların
değişkenidir.

**Belge değişikliğin kapsamı dışında durur.** Gövdenin yanındaki açıklama satırı değişikliğin
içindedir; tanıtım dosyası, kurulum yönergesi ya da referans metni başka bir yerde, hatta
başka bir depoda olabilir. Kapsam dışındaki metin incelemeye hiç gelmez ve eksen açık olsa da
bulgu üretilemez.

Üçü de yönetilebilir kararlardır ve tablonun verdiği sayı bu kararların fiyatıdır: belge
ekseninin kapanması, o turda **3** kusurun kaçması demektir. Kullanışlı olan sayının
büyüklüğü değil, kaçanların **hangi sınıfta** olduğunun önceden bilinmesidir.

#### Ölçümün Varsayımları

- **IE31** — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, dikkat 12 öbek. Okunmamış
  öbek yoktur; kaçan her kusurun nedeni bakılmayan eksendir.
- **IE32** — Birinci bölümde her satır tek bir inceleyenin okumasıdır ve satırlar arasındaki
  tek fark, kapatılan eksendir. İlk satırda hiçbir eksen kapatılmaz.
- **IE33** — "Kayıp" sütunu, beş eksen açıkken bulunan sayıdan o satırda bulunanın
  çıkarılmasıdır.
- **IE34** — Kaçanın sınıf dökümü, o satırda bulunamayan kusurların sınıflara göre sayımıdır
  ve azalan sırada yazılır.
- **IE35** — Belge kusuru, değişiklikte **yazılmış** bir metnin kodla çelişmesidir. Kurgu bu
  metnin nerede durduğunu değil, hangi öbeğe düştüğünü tutar.
- **IE36** — Eksik gereksinim kusuru, hiç yazılmamış olanın kusurudur ve bir öbeğe düşmüş
  olması onu görünür yapmaz; öbek yalnız kusurun ait olduğu yeri işaretler.
- **IE37** — Belge ekseni açıldığında yalnız belge sınıfı bulunur; altıncı sınıf hiçbir
  eksenin arama listesinde değildir ve bu ölçümde de değişmez.
- **IE38** — Çözünürlük kusur düzeyinde **1/24 = 0,042**, öbek düzeyinde **1/12 = 0,083**.

#### Ölçüm

```python
"""Belgelendirme incelemesi: bir eksen kapatilinca ne kaciyor.

Bolum 1 - bes eksen tek tek kapatilir; bulunan, kacan ve kacanin sinif dokumu.
Bolum 2 - yazilmis belgenin kusuru ile hic yazilmamis gereksinim ayrimi.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


TAM = set(EKSENLER)
d = degisiklik(600)

print(f"{'kapatılan eksen':<16s} {'açık':>4s} {'bulunan':>7s} {'kaçan':>5s} "
      f"{'kayıp':>5s} {'kaçanın sınıf dökümü':<36s}")
tam = incele(d, TAM)
for e in ("-",) + EKSENLER:
    acik = TAM if e == "-" else TAM - {e}
    b = incele(d, acik)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    dokum = {}
    for k in kacan:
        dokum[k["sinif"]] = dokum.get(k["sinif"], 0) + 1
    metin = ", ".join(f"{s} {n}" for s, n in
                      sorted(dokum.items(), key=lambda x: -x[1]))
    print(f"{e:<16s} {len(acik):4d} {len(b):7d} {len(kacan):5d} "
          f"{len(tam) - len(b):5d} {metin:<36s}")

print()
belge = [k for k in d["kusurlar"] if k["sinif"] == "belge"]
yazilmayan = [k for k in d["kusurlar"] if k["sinif"] == YAZILMAYAN]
print(f"{'sınıf':<18s} {'kusur':>5s} {'öbek':<12s} {'belge ekseni bulur mu':>21s}")
print(f"{'belge':<18s} {len(belge):5d} "
      f"{str(sorted(k['obek'] for k in belge)):<12s} {'evet':>21s}")
print(f"{YAZILMAYAN:<18s} {len(yazilmayan):5d} "
      f"{str(sorted(k['obek'] for k in yazilmayan)):<12s} {'hayır':>21s}")
for ad, acik in (("belge ekseni açık", TAM), ("belge ekseni kapalı",
                                              TAM - {"belge"})):
    b = incele(d, acik)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    print(f"{ad:<20s} belge kaçan "
          f"{sum(1 for k in kacan if k['sinif'] == 'belge')}, "
          f"yazılmayan kaçan "
          f"{sum(1 for k in kacan if k['sinif'] == YAZILMAYAN)}")
```

```
kapatılan eksen  açık bulunan kaçan kayıp kaçanın sınıf dökümü                
-                   5      22     2     0 eksik gereksinim 2                  
arayuz              4      19     5     3 arayuz 3, eksik gereksinim 2        
gerceklestirim      4      16     8     6 gerceklestirim 6, eksik gereksinim 2
test                4      19     5     3 test 3, eksik gereksinim 2          
belge               4      19     5     3 belge 3, eksik gereksinim 2         
bicim               4      15     9     7 bicim 7, eksik gereksinim 2         

sınıf              kusur öbek         belge ekseni bulur mu
belge                  3 [2, 2, 3]                     evet
eksik gereksinim       2 [2, 10]                      hayır
belge ekseni açık    belge kaçan 0, yazılmayan kaçan 2
belge ekseni kapalı  belge kaçan 3, yazılmayan kaçan 2
```

#### Beş Eksen Tek Tek Kapatılınca

Üst tablo bu konunun kapanış tablosudur: aynı değişiklik, aynı tek inceleyen, tek fark
kapatılan eksen.

**Kayıp** sütunu beş satırda da tek bir kuralı doğruluyor: **3, 6, 3, 3, 7.** Bu sayılar sınıf
dağılımının kendisidir. Bir eksen kapatıldığında kaybedilen kusur sayısı, o eksenin sınıfındaki
kusur sayısına eşittir — ne eksik ne fazla. Üçüncü dersin sıra bağımsızlığı ölçümü bunu ileri
yönde göstermişti; bu tablo geri yönde gösteriyor.

Kaybın büyüklüğü eksenden eksene üç kat değişiyor. En pahalı kapanış **biçim** ekseninindir:
**7** kusur, bulunan **15**'e iner. Ardından **gerçekleştirim** gelir: **6** kusur, bulunan
**16**. Arayüz, test ve belge eksenlerinin her biri **3** kusura mal olur ve üçünde de bulunan
**19**'da durur.

Belge ekseni bu tabloda en ucuz kapanışlardan biri görünüyor ve bu görüntü dersin uyarısıdır.
Tablo **kaç kusur kaçtığını** sayıyor; **kaçan kusurun bedelinin ne zaman ödendiğini**
saymıyor. Bir gerçekleştirim kusuru çalıştırıldığında ödenir, bir kez. Bir belge kusuru her
okunduğunda ödenir ve okuyan her kişi aynı yanlış bilgiyi alır. İki sayı aynı sütunda
toplanıyor ama iki ayrı zamanda ödeniyor. Bu ayrım kurgunun dışındadır ve tablodan
çıkarılamaz; tablo yalnız bulunan ve kaçan sayısını verir.

Tablonun bir satırı ilk dersin tablosuyla birebir örtüşüyor. Biçim ekseni kapatıldığında
bulunan **15**'tir; ilk derste "üç inceleyen, ayrı eksen" yapılandırması da **15** bulmuştu
ve o kurulun kapsadığı eksenler arayüz, gerçekleştirim, test ve belgeydi — yani biçim
dışındaki dört eksen. İki ayrı ölçüm, iki ayrı yoldan aynı sayıya varıyor. Bu bir rastlantı
değil, toplanabilirliğin sonucudur: aynı eksen kümesi kaç kişiye dağıtılırsa dağıtılsın aynı
kümeyi bulur.

Tablonun pratik kullanımı bir fiyat listesidir. Bir eksenin kapanması çoğu zaman açıkça
verilmiş bir karar değildir; kimsenin o eksene atanmamış olmasıyla ya da o eksenin bulgusunun
engelleyici sayılmamasıyla kendiliğinden olur. Tablo o kararın karşılığını önceden veriyor ve
karşılıklar eşit değil: biçim ekseninin kapanması **7**, gerçekleştirimin **6**, ötekilerin
**3**'er kusura mal oluyor. "Bir eksen daha açalım" ile "bir kişi daha ekleyelim" arasındaki
seçim de aynı ölçümün içinde: ikinci kararın getirisi üçüncü derste **0** ölçülmüştü,
birincisinin getirisi burada **3 ile 7** arasında.

Sağdaki döküm sütunu her satırda aynı iki kelimeyi taşıyor: **eksik gereksinim 2.** Altı
satırın altısında da orada duruyor, hiçbir eksen onu kaldırmıyor.

#### Yazılmış Belge ve Yazılmamış Gereksinim

Alt tablo bu iki sınıfı yan yana koyuyor ve aradaki farkın nerede olmadığını gösteriyor.

**Belge** sınıfının üç kusuru **2, 2 ve 3** numaralı öbeklerde. **Eksik gereksinim** sınıfının
iki kusuru **2 ve 10** numaralı öbeklerde. İki sınıfın kusurları **aynı öbekte** buluşuyor:
ikinci öbekte hem iki belge kusuru hem bir eksik gereksinim kusuru var. Aynı elli satır, aynı
okuma, aynı inceleyen.

Belge ekseni açıldığında **belge kaçan 0** oluyor; ikinci öbekteki iki belge kusuru bulunuyor.
Aynı öbekteki eksik gereksinim kusuru bulunmuyor ve **yazılmayan kaçan 2** olarak kalıyor.
Belge ekseni kapatıldığında belge kaçan **3**'e çıkıyor, yazılmayan kaçan yine **2**.

Fark bu yüzden **yer** farkı değildir. İki kusur aynı öbekte duruyor ve okuma ikisinin de
üzerinden geçiyor. Fark, **bakılacak bir metnin olup olmamasıdır.** Belge kusurunda ortada
yazılmış bir cümle vardır ve o cümle kodla karşılaştırılabilir; eksik gereksinim kusurunda
karşılaştırılacak bir cümle hiç yazılmamıştır.

Bu, belge ekseninin en çok karıştırılan yanıdır. Belge ekseni açık olduğunda bir incelemenin
"belgeye de bakıldı" demesi doğrudur, ama bakılan şey **yazılmış olandır**. Yazılmamış bir
gereksinim, belge ekseninin de dışındadır — çünkü belge ekseni de sonuçta iki metni
karşılaştırır ve iki metinden biri yoksa karşılaştırma yapılamaz. Beş eksenin beşi de aynı
tanımın içinde kalır: **inceleme yazılana bakar.**

Buradan belge ekseninin sınır durumu çıkar. Bir davranış hiç belgelenmemişse bu bir belge
kusuru mudur, yoksa eksik gereksinim midir? Ayrım, metnin **beklenip beklenmediğine** bakar.
Değişiklik yeni bir genel ad getirmişse o adın belgelenmesi beklenir ve eksikliği belge
sınıfına düşer — ikinci bulgu türü tam olarak budur ve belge ekseni onu bulur. Buna karşılık
değişikliğin hiç ele almadığı bir durum, belge ekseninin bekleyeceği bir metin üretmez ve
altıncı sınıfta kalır.

Sınırın pratik karşılığı tek cümledir: **belge ekseni, değişikliğin getirdiğinin
belgelenmesini sorar; getirmediğinin ne olduğunu sormaz.** İkinci soruyu soran şey inceleme
değil, değişikliğin kapsamını belirleyen karardır.

#### Özet

- Belge ekseni tek bir metne değil **iki metne** bakar: kodun yaptığı iş ile metnin anlattığı
  iş. Bulgusu bir çelişkidir ve yalnız belgeyi okuyarak bulunamaz.
- Üç bulgu türü vardır: **eskimiş metin** (değişmediği için değişiklikte görünmez), **eksik
  metin** (eklenen adın karşılığı yok), **çelişen metin** (iki yerde iki ayrı davranış).
- Bir eksen kapatıldığında kayıp, o eksenin sınıf büyüklüğüne eşittir: **3, 6, 3, 3, 7**. En
  pahalı kapanış biçim ekseninindir ve bulunanı **15**'e indirir.
- Belge ekseni kapatıldığında bulunan **22**'den **19**'a iner. Tablo kaçan kusuru sayar,
  bedelin ne zaman ödendiğini saymaz: bir belge kusuru her okunduğunda yeniden ödenir.
- Belge kusurları **2, 2, 3**, eksik gereksinim kusurları **2 ve 10** numaralı öbeklerde;
  ikinci öbekte ikisi birden var. Belge ekseni açıkken belge kaçan **0**, yazılmayan kaçan
  yine **2**'dir.
- Fark yer farkı değil metin farkıdır: belge kusurunda karşılaştırılacak bir cümle vardır,
  eksik gereksinimde yoktur.

#### Sonraki Adım

Tablonun en pahalı satırı biçim ekseninindir: kapatıldığında **7** kusur kaçar ve bulunan
**15**'e iner. Bu, beş eksenin en kalabalık sınıfıdır ve aynı zamanda görülmesi en az bilgi
isteyen sınıftır. İki özelliğin bir arada bulunması onu ayrı bir soruya açıyor: bu eksen bir
insanın okumasını gerektiriyor mu. Sonraki ders biçim ekseninin bir araca devredilmesini
ölçer — bulunan toplam nasıl değişir, insanın bulgusunun sınıf dağılımı ne olur ve aynı
sonucu vermek için kaç inceleyen gerekir.

### Kod Biçimi ve Otomasyon

Source: https://academia.sh/tr/kurslar/kod-inceleme/kod-bicimi-ve-otomasyon

Biçim ekseni bir araca devredildiğinde insanın bulgusu 22'den 15'e, bulgunun biçim payı 0,318'den 0,000'a iner; toplam beş eksen zaten kapsanmışsa değişmez, üç inceleyenlik bir kurulda 15'ten 22'ye çıkar.

Önceki dersin tablosunda en pahalı kapanış biçim ekseninindi: kapatıldığında **7** kusur
kaçıyor ve bulunan **15**'e iniyordu. Aynı eksen, ilk dersin sınıf dağılımında da en kalabalık
sınıftı ve orada bir not düşülmüştü — bu sınıfın görülmesi en az bilgi isteyen sınıf olduğu.

İki özelliğin bir arada bulunması bu ekseni ötekilerden ayırıyor ve bir soru açıyor: **bu
eksen bir insanın okumasını gerektiriyor mu.** Ders o soruyu ölçer. Biçim ekseni bir araca
devredilir ve üç şey sayılır: toplam bulunanın ne olduğu, insanın kendi bulgusunun ne kadar
küçüldüğü ve o bulgunun hangi sınıflardan oluştuğu.

#### Biçim Ekseni Ne Arar

Biçim ekseni kodun **görünüşüne** bakar: girinti genişliği ve tutarlılığı, satır uzunluğu,
boşluk yerleşimi, ayraçların konumu, içe aktarma sırası, adların büyük ve küçük harf düzeni,
sondaki boşluklar, dosya sonu satırı.

Bu listede olmayan bir şey var ve ayrım kursun içinde durur: **adın seçimi** biçim ekseninin
işi değildir. Bir adın anlamlı olup olmadığı bir yargıdır ve gerçekleştirim ekseninde okunur;
o adın hangi harf düzeniyle yazıldığı bir kuraldır ve biçim ekseninde okunur. Adlandırmanın
kendisi Temiz Kod kursunun konusudur ve burada tekrarlanmıyor.

Ayrımın ölçüme giren yanı tek cümleyle kurulur: **biçim kusurunun doğruluğunu belirleyen şey
bir yargı değil, yazılabilir bir kuraldır.** Yazılabilen kural uygulanabilir, uygulanabilen
kural da devredilebilir. Öteki dört eksenin hiçbiri bu özelliği taşımaz: bir imzanın
sözleşmeyi bozup bozmadığı, bir gövdenin doğru olup olmadığı, bir iddianın anlamlı olup
olmadığı ve bir metnin kodla çelişip çelişmediği kural değil yargı gerektirir.

#### Kararın Kendisi ve Kararın Uygulanması

Biçim tartışması iki ayrı iştir ve karıştırılmaları en çok tur harcayan durumdur.

**Birinci iş kararın kendisidir:** hangi girinti genişliği, hangi satır uzunluğu, hangi
sıralama. Bu bir kez verilir ve bir metne yazılır. Karar tek başına doğru ya da yanlış
değildir; değeri tutarlılığındadır.

**İkinci iş kararın uygulanmasıdır:** her değişiklikte kuralın gerçekten uygulanıp
uygulanmadığına bakmak. Bu iş her değişiklikte yeniden yapılır ve hiçbir yargı içermez;
kuralın metni ile kodun metni karşılaştırılır.

Devredilen şey ikinci iştir. Bir **biçimlendirici**, kuralı koda uygular; bir **otomatik
denetleyici**, uygulanmadığı yerleri bildirir. İkisi de bir araç sınıfıdır ve kararı vermez —
kendilerine verilmiş kuralı yürütürler. Bu araçların hatta nasıl bağlandığı Sürekli Tümleştirme
ve Teslimat kursunun, ön yüz projelerinde nasıl kurulduğu Frontend Kalitesi kursunun konusudur
ve burada tekrarlanmıyor. Bu dersin ölçtüğü tek şey **devretme sonrasında incelemede ne
kaldığıdır.**

Ayrımın atlanması pratikte tek bir belirti verir: aynı biçim konusu değişiklikten değişikliğe
yeniden tartışılır. Tartışılan şey görünüşte kodun bir satırıdır, gerçekte ise hiç yazılmamış
bir karardır. Kural bir metne yazılana kadar her inceleme o kararı yeniden vermek zorunda
kalır ve verilen karar hiçbir yerde birikmez.

Kuralın yazılması bu yüzden aracın kurulmasından önce gelir ve ondan bağımsızdır. Yazılı bir
kural, araç olmadan da tartışmayı bitirir: bulgu artık bir tercih değil, bir metne yapılan
atıftır. Araç bunun üstüne yalnız yürütmeyi ekler. Sıranın tersi işlemez — kuralı olmayan bir
depoya araç kurmak kararı araca aldırmak olur ve tartışma kodun satırından aracın ayarına
taşınıp orada sürer.

```text
# ogretilen inceleme notu ornegi , calistirilmamistir

devredilmeden once
  bicim   Girinti bu dosyada iki ayri genislikte kullanilmis.
  bicim   Satir uzunlugu dort yerde sinirin uzerinde.
  bicim   Ice aktarma sirasi dosyanin geri kalanindan farkli.

devredildikten sonra
  (bicim ekseninde inceleme notu yok; kural araca yazilmis durumda)
  arayuz  Genel islevin ikinci parametresi zorunlu hale gelmis.
  test    Testin tek iddiasi cagrinin hata firlatmadigi.
```

Bu blok bir örnektir ve çalıştırılmaz; dersin sayıları yalnız ölçüm bloğundan gelir.

#### Aracın İki Farkı

Ölçüme giren araç iki noktada inceleyenden ayrılır.

**Tek eksenlidir.** Yalnız biçim sınıfına bakar ve öteki dört sınıftan hiçbir şey bulmaz.
Kural yazılabilen tek eksen odur; yargı gerektiren eksenlerde aracın bir karşılığı yoktur.

**Dikkati yoktur.** İnceleyen bir turda sınırlı sayıda öbek okur; araç değişikliğin tamamını
okur ve bu sınır ona uygulanmaz. Bu dersin ölçeğinde iki sınır çakışıyor — değişiklik 12
öbek, dikkat de 12 öbek — bu yüzden fark sayıya yansımıyor. Farkın koşulu buna rağmen bellidir
ve bu konunun dışındadır.

#### Ölçümün Varsayımları

- **IE39** — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, dikkat 12 öbek. Sınıf listesi
  ve dağılım değişmez.
- **IE40** — Araç yalnız biçim sınıfındaki kusurları bulur ve hepsini bulur; öbek sınırı ona
  uygulanmaz.
- **IE41** — Araç yanlış bulgu üretmez. Kurgu, aracın kural dışı bir şeyi kusur saymasını
  içermez; ölçüm bu yüzden aracın lehinedir ve bu açıkça yazılır.
- **IE42** — "Araçsız" sütunda insan beş eksenin tamamını taşıyabilir; "araçlı" sütunda hiçbir
  inceleyen biçim ekseni taşımaz.
- **IE43** — İnceleyen sayısı iki rejimde de aynı tutulur; devretme kurula kişi eklemez ve
  kuruldan kişi çıkarmaz.
- **IE44** — Araç bir okuma sayılmaz ve inceleyen sütununa girmez; bulgusu ayrı bir sütunda
  durur.
- **IE45** — Devretmenin bedeli — kuralın yazılması, aracın kurulması, hattın bağlanması —
  ölçümde yoktur. Ölçülen tek şey bulunan ve kaçan kusurdur.
- **IE46** — Oran, insanın bulgusundaki biçim kusurunun insanın toplam bulgusuna bölümüdür.
  Çözünürlük kusur düzeyinde **1/24 = 0,042**.

#### Ölçüm

```python
"""Kod bicimi ve otomasyon: bicim ekseni araca devredilince ne degisir.

Bolum 1 - ayni kurullar aracsiz ve aracli; insanin buldugu ve toplam bulunan.
Bolum 2 - insanin bulgusunun sinif dagilimi iki rejimde.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def bicimlendirici(d):
    """Arac sinifi: yalniz bicim ekseninde bakar, dikkat siniri yoktur."""
    return {k["no"] for k in d["kusurlar"] if k["sinif"] == "bicim"}


TAM = set(EKSENLER)
INSAN = TAM - {"bicim"}
d = degisiklik(600)
arac = bicimlendirici(d)

KURULLAR = {
    "tek inceleyen": ([TAM], [INSAN]),
    "üç inceleyen, ayrı eksen": ([{"arayuz"}, {"gerceklestirim"},
                                  {"test", "belge"}],
                                 [{"arayuz"}, {"gerceklestirim"},
                                  {"test", "belge"}]),
    "üç inceleyen, aynı eksen": ([{"gerceklestirim"}] * 3,
                                 [{"gerceklestirim"}] * 3),
    "beş inceleyen, beş eksen": ([{e} for e in EKSENLER],
                                 [{e} for e in sorted(INSAN)] + [INSAN]),
}
print(f"{'kurul':<26s} {'araçsız bulunan':>15s} {'araçlı: insan':>13s} "
      f"{'araç':>4s} {'toplam':>6s} {'kaçan':>5s}")
for ad, (a, b) in KURULLAR.items():
    yalin = kurul(d, a)
    insan = kurul(d, b)
    toplam = insan | arac
    kacan = [k for k in d["kusurlar"] if k["no"] not in toplam]
    print(f"{ad:<26s} {len(yalin):15d} {len(insan):13d} {len(arac):4d} "
          f"{len(toplam):6d} {len(kacan):5d}")

print()
print(f"{'rejim':<22s} {'insanın bulgusu':>15s} "
      f"{'biçim payı':>10s} {'oran':>5s}")
for ad, eksenler in (("biçim insanda", TAM), ("biçim araçta", INSAN)):
    b = incele(d, eksenler)
    bicim = sum(1 for k in d["kusurlar"]
                if k["no"] in b and k["sinif"] == "bicim")
    print(f"{ad:<22s} {len(b):15d} {bicim:10d} {bicim / len(b):5.3f}")
kalan = sorted({k["sinif"] for k in d["kusurlar"]
                if k["no"] in incele(d, INSAN)})
print("biçim araçtayken insanın bulgusunun sınıfları: " + ", ".join(kalan))
toplam = incele(d, INSAN) | arac
kacan = [k for k in d["kusurlar"] if k["no"] not in toplam]
print(f"insan artı araç: bulunan {len(toplam)}, kaçan {len(kacan)}, "
      f"hiçbir eksenin aramadığı "
      f"{sum(1 for k in kacan if k['sinif'] == YAZILMAYAN)}")
```

```
kurul                      araçsız bulunan araçlı: insan araç toplam kaçan
tek inceleyen                           22            15    7     22     2
üç inceleyen, ayrı eksen                15            15    7     22     2
üç inceleyen, aynı eksen                 6             6    7     13    11
beş inceleyen, beş eksen                22            15    7     22     2

rejim                  insanın bulgusu biçim payı  oran
biçim insanda                       22          7 0.318
biçim araçta                        15          0 0.000
biçim araçtayken insanın bulgusunun sınıfları: arayuz, belge, gerceklestirim, test
insan artı araç: bulunan 22, kaçan 2, hiçbir eksenin aramadığı 2
```

#### Araç Toplamı Ne Zaman Değiştirir

Üst tablonun ilk ve son satırı aynı şeyi söylüyor: **22 ve 22.** Beş eksenin tamamı zaten
insanlar tarafından kapsanıyorsa aracın toplam bulunana katkısı **0**'dır. Araç, kimsenin
bakmadığı bir yere bakmıyor.

İkinci satır tersini gösteriyor. Üç inceleyen dört ekseni kapsıyordu — arayüz, gerçekleştirim,
test, belge — ve araçsız **15** buluyordu. Biçim ekseni araca verilince toplam **22**'ye
çıkıyor. Kurula kimse eklenmedi, kimse çıkarılmadı; kapsanmayan tek eksen kapsandı ve karşılığı
**7** kusur oldu. **Üç kişilik bir kurul, beş kişilik bir kurulun sayısına eşitlendi.**

Üçüncü satır aynı kuralı en dar kurulda tekrarlıyor. Üç inceleyen aynı eksene bakıyordu ve
**6** buluyordu; araç **13**'e çıkarıyor. Kaçan hâlâ **11** ve bunun **9**'u insanların
bakmadığı üç eksenden geliyor. Araç bir ekseni kapatıyor, ötekileri kapatmıyor.

Örüntü tek cümlede toplanıyor: **aracın katkısı, insanların kapsamadığı eksen kadardır.**
Bu, kursun ikinci iddiasının araç tarafındaki karşılığıdır. Araç da kişi gibi davranıyor —
sayıyı büyüten şey onun varlığı değil, kapsadığı eksenin daha önce kapsanmamış olması.

Aracın katkısının **ne zaman** gerçekleştiği tabloda görünmüyor ama incelemeyi değiştiriyor.
Araç, değişiklik gönderildiği anda çalışır ve bulduğu yedi kusur inceleme başlamadan kapanmış
olur. İnceleyen o yedi kusuru hiç görmez: inceleme metninde yer almazlar, bir not yazılmaz,
bir yanıt beklenmez. Toplam aynı kalan satırlarda bile incelemenin **konusu** küçülür ve
küçülen kısım tam olarak yargı gerektirmeyen kısımdır.

Son sütun dört satırda da altıncı sınıfı taşıyor. Araçlı en iyi durumda kaçan **2**'dir ve
ikisi de eksik gereksinim sınıfındandır. **Otomasyon bulunanın tavanını 22'den yukarı
çıkarmıyor.** Araç yazılana bakar, tıpkı inceleme gibi; yazılmamış olanı o da göremez.

#### Dikkat Nereye Kayıyor

Alt tablo aynı devretmeye insanın tarafından bakıyor ve buradaki sayılar toplamın sabit
kaldığı satırlarda bile değişiyor.

Biçim insandayken tek inceleyenin bulgusu **22** kusur ve bunun **7**'si biçim sınıfından;
oran **0,318**. Biçim araçtayken insanın bulgusu **15**'e iniyor ve biçim payı **0**;
oran **0,000**. İnsanın bulgusunun sınıfları geriye dört tane kalıyor: arayüz, belge,
gerçekleştirim, test.

Değişen şey toplam değil, **incelemenin içeriğidir.** Devretmeden önce bir incelemenin
bulgularının yaklaşık üçte biri kural kusurudur; sonra sıfırı. Geriye kalan her bulgu yargı
gerektiren bir eksendendir. İnceleme metninde tartışılan şey de aynı oranda değişir: kuralın
uygulanması artık tartışma konusu değildir, çünkü kararı veren metin bir kez yazılmıştır ve
uygulaması yürütülmektedir.

Burada dürüst bir sınır var ve yazılması gerekiyor. Bu ölçekte serbest kalan okumanın sayısal
bir getirisi **yoktur**: değişiklik 12 öbek, dikkat de 12 öbek, yani insanın okuması zaten
tükenmiyordu. Biçim ekseninden boşalan dikkat başka bir eksene aktarılsa da tabloda bir sayı
değişmez, çünkü öteki eksenler zaten eksiksiz okunuyordu.

Serbest kalan dikkatin karşılığının görünmesi için tek bir koşul gerekir: **okunacak şeyin
dikkatten büyük olması.** Bu kurguda öyle bir durum henüz kurulmadı ve bu konunun değişkeni
değil.

#### Aracın Lehine Kurulmuş İki Varsayım

Ölçüm aracı iki noktada gerçekte olabileceğinden güçlü tutuyor ve ikisi de sonucun
okunmasını etkiliyor.

**Araç biçim sınıfının tamamını buluyor.** Bir biçimlendirici yalnız kendisine yazılmış
kuralları uygular; kural kümesinin dışında kalan bir biçim kusuru — deponun geri kalanından
farklı bir dosya düzeni, tutarsız bir kısaltma biçimi — araca görünmez ve insanda kalır.
Ölçümde böyle bir artık yoktur; olsaydı "biçim payı 0,000" satırı sıfırdan büyük çıkardı.

**Araç yanlış bulgu üretmiyor.** Kural kümesi ile deponun geri kalanı uyuşmadığında araç,
kusur olmayan yerleri de bildirir. Bu bulgular incelemeye girmez ama zaman harcatır ve kuralın
yeniden yazılmasını gerektirir. Ölçüm bu maliyeti içermiyor.

İki varsayım da bilerek kondu. Amaç, aracın **en iyi durumunda bile** toplamın **22**'de
kaldığını göstermektir: tavanı belirleyen şey aracın niteliği değil, eksen listesinin
kendisidir.

#### Özet

- Biçim ekseni kodun görünüşüne bakar ve öteki dört eksenden bir noktada ayrılır: doğruluğunu
  belirleyen şey bir yargı değil, **yazılabilir bir kuraldır**. Adın seçimi bu eksende değil,
  adın harf düzeni bu eksendedir.
- Biçim tartışması iki iştir: **kararın kendisi** bir kez verilir ve bir metne yazılır,
  **kararın uygulanması** her değişiklikte yinelenir. Araca devredilen ikincisidir.
- Aracın toplam bulunana katkısı, insanların kapsamadığı eksen kadardır: beş eksen zaten
  kapsanıyorsa **0**, üç inceleyenlik bir kurulda **15**'ten **22**'ye, aynı eksene bakan
  üç inceleyende **6**'dan **13**'e.
- Otomasyon tavanı yükseltmez: araçlı en iyi durumda kaçan **2**'dir ve ikisi de eksik
  gereksinim sınıfındandır. Araç da yazılana bakar.
- Devretme, toplam sabit kalan durumlarda bile incelemenin içeriğini değiştirir: insanın
  bulgusu **22**'den **15**'e, biçim payı **0,318**'den **0,000**'a iner ve geriye yalnız
  yargı gerektiren dört eksen kalır.
- Bu ölçekte serbest kalan dikkatin sayısal getirisi **0**'dır, çünkü değişiklik dikkatten
  büyük değildir.

#### Sonraki Adım

Bu konunun altı dersi tek bir değişkeni oynattı: **bakılan eksen.** Eksen sayısını artırmak
bulunanı **6**'dan **15**'e, oradan **22**'ye çıkardı; eksen kapatmak sınıf büyüklüğü kadar
kusur kaybettirdi; kişi eklemek hiçbir şey değiştirmedi. Bütün bu ölçümlerin ortak bir sessiz
kabulü vardı ve son ders onu açıkça söyledi: **değişiklik her zaman dikkat kadardı**, yani
okunacak şey okunabiliyordu.

Sonraki konu o kabulü kaldırır. Bakılan eksen sabit tutulur ve bu kez **bakılacak şey** büyür.
Soru şudur: eksen çeşitliliğinin kazandırdığı kusurlar, değişiklik okunabilir olmaktan
çıktığında yerinde kalır mı, yoksa bulunan oran eksenlerden bağımsız olarak mı çöker.

## İnceleme Kültürü

İncelenebilir değişikliğin sınırları, kişi değil değişiklik üzerine konuşan geri bildirim dili, tasarım tartışmasını karara bağlama, ve bekleme süresi ile tur sayısının okunması.

### Değişiklik Boyutu

Source: https://academia.sh/tr/kurslar/kod-inceleme/degisiklik-boyutu

Dikkat 12 öbekte sabittir; aynı 24 kusur 100 satırda 22, 900 satırda 18, 2400 satırda 2 kez bulunur ve 2400 satırın 36 öbeği hiç okunmaz.

Önceki ders biçim eksenini araca devretti ve dikkatin başka bir eksene kaydığını ölçtü.
Konu boyunca kurulan örüntü buydu: eksen sayısını artırmak bulunan kusur sayısını artırdı.
Bir inceleyici beş eksene baktığında beş inceleyicinin bulduğunu buluyordu; sayıyı büyüten
şey bakan kişi değil, bakılan eksendi.

Bu dersin sorusu ters yönden geliyor. Eksen sayısı sabit kalsın ve **bakılacak şey büyüsün**.
Aynı inceleyici, aynı beş eksen, aynı kusurlar — yalnız değişiklik 100 satır yerine 2400
satır olsun. Eksen çeşitliliği hiç bozulmadığı hâlde bulunan sayısı ne olur?

#### Dikkat Bir Bütçedir

Ortak kurgunun inceleyicisi iki sınırla çalışıyor. Birincisi **ekseni**: yalnız baktığı
eksenlerdeki kusuru görür. İkincisi **dikkati**: bir inceleme turunda gerçekten okuduğu
**öbek** sayısı sınırlıdır. Öbek 50 satırdır, dikkat 12 öbektir. Bu, bir oturuşta gerçekten
okunan yaklaşık 600 satır demektir.

Dikkatin bir bütçe olması, kurgunun en önemli varsayımıdır ve gözlemle uyumludur. İnceleyen
bir değişikliği baştan sona aynı yoğunlukta okumaz; ilk öbekler dikkatli okunur, sonrakiler
giderek daha hızlı taranır ve bir yerden sonra okuma yerini onaya bırakır. Kurgu bu
azalmayı sertleştirip ikili hâle getiriyor: ilk 12 öbek okunur, gerisi okunmaz. Sertleştirme
sayıyı abartmaz, çünkü gerçekte okunmayı bırakan öbekler de tamamen kör değildir — ama
örüntüyü görünür kılar.

Buradan çıkan ilk sonuç aritmetiktir. Değişiklik 600 satırın altındaysa öbeklerin hepsi
okunur ve dikkat sınırı hiç devreye girmez; sınırlayan tek şey eksen listesidir. Değişiklik
600 satırı aştığındaysa **artan her öbek okunmayanlar kümesine gider.** Dikkat büyümez;
değişiklik büyür.

#### Aynı Kusur, Dört Boyut

Ölçümü anlamlı kılan kısıt şudur: dört boyutta da **aynı 24 kusur** vardır. Kurgu kusur
sayısını değişiklik boyutuyla birlikte büyütmez. Bu kasıtlıdır. Kusur sayısı da büyüseydi
oranın düşmesi şaşırtıcı olmazdı; sabit tutulduğunda düşüşün tek kaynağı kalır — okunmayan
öbek.

Sınıf dağılımı da dört boyutta aynıdır: arayüz 3, gerçekleştirim 6, test 3, belge 3, biçim 7
ve **eksik gereksinim 2**. Altıncı sınıf hiçbir eksenin aramadığı sınıftır: yazılmamış
olanın kusuru. İnceleme gönderilen değişikliğin içine bakar; gönderilmemiş olanın yokluğunu
göremez. Bu ders o iki kusuru **kaçan** sütununda ayrıca gösterir, çünkü boyut ne olursa
olsun kaçmaya devam ederler ve düşüşün nedeni onlar değildir.

Değişen tek şey satır sayısıdır. Satır sayısı öbek sayısını belirler, öbek sayısı da
kusurların dağıldığı alanı. Kusurlar bu alana serpilir; dikkat sabit kaldığı için serpilme
alanı büyüdükçe kusurların giderek artan bir bölümü okunmayan öbeklere düşer.

Ölçümün varsayımları:

- **IK1** — Dört boyut da aynı ortak kurgudan üretilir: 24 kusur, aynı sınıf dağılımı, aynı
  kâhin. Kusurları biz yerleştirdiğimiz için hangisinin hangi öbekte olduğu bilinir.
- **IK2** — Değişen tek şey satır sayısıdır. Eksen ataması sabittir: tek inceleyici, beş
  eksenin hepsi. Dikkat sabittir: 12 öbek.
- **IK3** — Okuma öbeğin başından başlar ve dikkat dolunca durur. Okunmayan öbekteki kusur,
  sınıfı hangi eksende olursa olsun görülmez.
- **IK4** — İkinci ölçümde `incele` bir başlangıç öbeği alır; bu, dikkat sınırının nereye
  yerleştiğini değiştirmektir, dikkati büyütmek değildir. Her pencerede yine 12 öbek okunur.
- **IK5** — Bölme kusurları yeniden dağıtmaz. Aynı 2400 satır, aynı 48 öbek, aynı 24 kusur;
  yalnız okuma dört ayrı pencerede yapılır.
- **IK6** — Kümenin çözünürlüğü 24 kusurda **1/24**, yani **0,042**'dir; öbek düzeyinde
  **1/12**. Bundan küçük bir fark bu kümeyle savunulamaz.

#### Ölçüm

```python
"""Degisiklik boyutu: ayni 24 kusur, dort olcek, sabit dikkat.

Bolum 1 - olcek buyudukce okunan obek sabit kalir, bulunan oran duser.
Bolum 2 - ayni 2400 satir dort pencerede okundugunda ne degisir.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12          # bir turda gerçekten okunan öbek sayısı
OBEK = 50            # satır
OLCEKLER = (100, 300, 900, 2400)


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, bas=0, dikkat=DIKKAT):
    """Inceleyici bas obeginden baslar ve dikkati kadar obek okur."""
    okunan = set(range(bas, min(bas + dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


TAM = set(EKSENLER)
d0 = degisiklik(600)
dagilim = {s: sum(1 for k in d0["kusurlar"] if k["sinif"] == s) for s in SINIFLAR}
print("sınıf dağılımı: " + ", ".join(f"{s} {n}" for s, n in dagilim.items()))
print()
print(f"{'satır':>6s} {'öbek':>5s} {'okunan':>7s} {'okunmayan':>10s} "
      f"{'bulunan':>8s} {'kaçan':>6s} {'yazılmayan kaçan':>17s} {'oran':>6s}")
for satir in OLCEKLER:
    d = degisiklik(satir)
    b = incele(d, TAM)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    print(f"{satir:6d} {d['obek']:5d} {min(DIKKAT, d['obek']):7d} "
          f"{max(0, d['obek'] - DIKKAT):10d} {len(b):8d} {len(kacan):6d} "
          f"{yaz:17d} {len(b) / len(d['kusurlar']):6.3f}")

print()
buyuk = degisiklik(2400)
toplam = set()
print(f"{'parça':>6s} {'öbek aralığı':>13s} {'bulunan':>8s}")
for i, bas in enumerate(range(0, buyuk["obek"], DIKKAT)):
    b = incele(buyuk, TAM, bas)
    toplam |= b
    print(f"{i + 1:6d} {f'{bas}-{bas + DIKKAT - 1}':>13s} {len(b):8d}")
kacan = [k for k in buyuk["kusurlar"] if k["no"] not in toplam]
print(f"dört pencere toplamı: bulunan {len(toplam)}, kaçan {len(kacan)}, "
      f"oran {len(toplam) / 24:.3f}")
print("kaçan sınıfları: " + ", ".join(sorted({k["sinif"] for k in kacan})))
```

```
sınıf dağılımı: arayuz 3, gerceklestirim 6, test 3, belge 3, bicim 7, eksik gereksinim 2

 satır  öbek  okunan  okunmayan  bulunan  kaçan  yazılmayan kaçan   oran
   100     2       2          0       22      2                 2  0.917
   300     6       6          0       22      2                 2  0.917
   900    18      12          6       18      6                 2  0.750
  2400    48      12         36        2     22                 2  0.083

 parça  öbek aralığı  bulunan
     1          0-11        2
     2         12-23       12
     3         24-35        2
     4         36-47        6
dört pencere toplamı: bulunan 22, kaçan 2, oran 0.917
kaçan sınıfları: eksik gereksinim
```

#### Oranın Çöktüğü Yer

Üst tablonun ilk iki satırı sıkıcıdır ve sıkıcı olması gerekir. 100 satırda 2 öbek, 300
satırda 6 öbek vardır; ikisi de dikkatin altındadır, ikisinde de okunmayan öbek **0**'dır.
Bulunan **22**, kaçan **2** ve kaçan ikisinin ikisi de **eksik gereksinim**. Yani değişiklik
dikkatin altında kaldığı sürece boyutun hiçbir etkisi yoktur; kaçan tek şey zaten hiçbir
eksenin aramadığı sınıftır.

Üçüncü satırda sınır devreye giriyor. 900 satır 18 öbektir, 12'si okunur, **6 öbek okunmaz**.
Bulunan **18**'e iner, oran **0,750** olur. Kaçan **6**'nın **2**'si eksik gereksinim,
kalan **4**'ü ise okunabilir olduğu hâlde okunmamış kusurdur. Bunlar sınıfları itibarıyla
inceleyicinin baktığı eksenlerdedir — gerçekleştirim ve biçim. İnceleyicinin listesinde
vardır, kâhinde vardır, yalnız gözünün önünde değildir.

Dördüncü satır çöküştür. 2400 satır **48 öbektir** ve dikkat hâlâ 12'dir; **36 öbek hiç
okunmaz.** Bulunan **2**'ye düşer, oran **0,083** olur. Kusur sayısı değişmedi, sınıf
dağılımı değişmedi, inceleyicinin eksen listesi değişmedi. Yalnız değişiklik büyüdü.

Kaçan sütunundaki sınıf listesi de bu satırda genişliyor. 900 satırda kaçanlar iki eksene
dağılmıştı; 2400 satırda kaçan 22 kusur **altı sınıfın altısına** birden yayılıyor. Bir
eksenin kapatılmasıyla oluşan kayıp o eksenle sınırlıdır ve nereye baktığı bilinir;
okunmayan öbeğin ürettiği kayıp ise **eksenden bağımsızdır** ve nereye düştüğü bilinmez.
İki kayıp aynı değildir: birincisi bir karardır, ikincisi bir kazadır.

İki satır arasındaki farkı bir cümlede toplamak mümkün: **oran, okunan öbeğin toplam öbeğe
oranını izler.** 900 satırda 12/18 okunur ve oran 0,750'ye düşer; 2400 satırda 12/48 okunur
ve oran 0,083'e düşer. İkincisinin 12/48 = 0,250'nin de altına inmesinin nedeni kusurların
öbeklere düzgün dağılmamasıdır: ilk 12 öbekte yalnız 3 kusur vardır ve biri eksik gereksinim
sınıfındadır. Büyük değişiklikte inceleyicinin nerede durduğu bir kumar hâline gelir.

Farkların ölçüm bandının içinde olup olmadığına da bakmak gerekir. 22'den 18'e iniş
**4/24 = 0,167**'lik bir farktır; kümenin çözünürlüğü 0,042 olduğuna göre bu fark dört
basamak yukarıdadır ve savunulabilir. 18'den 2'ye iniş **16/24 = 0,667**'dir ve tartışma
gerektirmez. Buna karşılık 100 ile 300 satır arasındaki fark **0**'dır — kümenin
söyleyebileceği hiçbir şey yoktur ve olmadığını söylemek de bir sonuçtur.

#### Büyük Değişikliğin Nereden Geldiği

Sayılar bir sınır gösteriyor, ama sınırın neden aşıldığını göstermiyor. 2400 satırlık bir
değişikliği kimse tek oturuşta yazmaz; o boyut **birikir**. Birikmenin üç yaygın kaynağı
vardır ve üçü de akışla ilgilidir, yazımla değil.

Birincisi **dalın ömrüdür**. Dallanma ve İşbirliği kursunda kurulan ayrım burada sayıya
dönüşür: kısa ömürlü dal küçük değişiklik üretir, uzun ömürlü dal her gün biraz daha büyür
ve incelemeye geldiğinde tek bir amaç değil, bir haftanın toplamıdır. İkincisi **karışan
sınıflardır**: yeniden adlandırma, dosya taşıma ve biçim düzeltmesi davranış değişikliğiyle
aynı değişiklikte gelir. Üçüncüsü **üretilen dosyalardır**: bağımlılık kilit dosyası,
derlenmiş çıktı ya da yeniden üretilebilen tablo değişikliğe girdiğinde satır sayısını
büyütür, ama içinde inceleyicinin karar verebileceği hiçbir şey yoktur.

Üçünün ortak sonucu aynıdır ve ölçümdeki dördüncü satırdır: dikkat aynı kalır, öbek sayısı
büyür. Üçünün de çaresi inceleme sırasında değil, incelemeden **önce** verilir — dalın
ömrünü kısaltmak, sınıfları ayırmak, üretilen dosyayı incelemenin dışına almak. İnceleme
masasına 48 öbek geldiğinde yapılabilecek tek şey kalmıştır: geri göndermek.

#### Bölmek Satırı Azaltmaz, Okunan Öbeği Artırır

Alt tablo aynı 2400 satırı dört pencerede okuyor. Değişiklik bölünmedi, kusurlar yeniden
serpilmedi, dikkat büyütülmedi — yalnız okuma dört kez, her seferinde 12 öbeklik başka bir
pencereden yapıldı. Sonuç: **2 + 12 + 2 + 6 = 22** bulunan, **2** kaçan, oran **0,917**.

Bu, 100 satırlık değişiklikle **aynı** orandır. Bulunan sayısını belirleyen şey değişikliğin
satır sayısı değil, **okunan öbek sayısıdır.** 2400 satır dört pencerede okunduğunda 48
öbeğin 48'i okunur ve okunmayan kalmaz. Kaçan **2** kusur yine eksik gereksinim sınıfındadır
ve bölmek onlara dokunmaz: hiçbir pencere yazılmamış olanı göstermez.

Pencerelerin arasındaki dengesizlik de öğreticidir. İlk pencere yalnız **2**, ikincisi
**12** kusur veriyor. Tek geçişte okunan pencere, kusur bakımından en fakir penceredir.
Değişikliği bir turda okuyan inceleyici bunu bilemez; hangi öbeklerin yoğun olduğunu ancak
hepsini okuduktan sonra öğrenir.

Bölmenin bedeli sayıda görünmez ama gerçektir: dört pencere dört ayrı okuma demektir. Bu
bedel bu konunun son dersinde bekleme süresi ve inceleme turu sayısı olarak ödenecek. Burada
kaydedilmesi gereken şey bedelin **var** olduğu ve **öngörülebilir** olduğudur — 22 kusuru
bulmanın karşılığı, okumayı dörde bölmektir.

#### İncelenebilir Değişikliğin Sınırı

Ölçüm pratik bir sınır veriyor: bir değişiklik, inceleyicinin dikkati kadar öbeğe sığdığında
incelenebilirdir. Kurgunun sayılarıyla bu yaklaşık 600 satırdır. Sayının kendisi kurgunun
varsayımıdır ve ekipten ekibe değişir; değişmeyen şey **bir sınırın olduğu ve aşıldığında
oranın sessizce düştüğüdür.**

Sessizlik burada anahtar sözcüktür. Okunmayan öbek geri bildirim üretmez. 2400 satırlık bir
değişikliğin incelemesi de onaylanır, o da kapanır ve dışarıdan bakan biri iki incelemeyi
birbirinden ayıramaz. **Onay, okunduğunun kanıtı değildir.** Ölçümdeki 22 kaçan kusur da
onaylanmış bir incelemenin ardından koda girmiştir.

Sınırı korumanın yolu değişikliği bölmektir, ama bölme keyfi olamaz. Her parçanın kendi
başına anlaşılır ve kendi başına doğru olması gerekir; yoksa inceleyen parçayı okur, ne
yaptığını anlamaz ve bir sonraki parçayı bekler — bu da okumayı ertelemenin başka bir
adıdır. Uygulanabilir bölme ölçütleri şunlardır: **tek amaç** (bir parça tek bir şey
yapar), **kendi başına doğruluk** (parça tek başına birleştirilse sistem bozulmaz) ve
**taşınan ile taşınmayanın ayrılması** (yeniden adlandırma, dosya taşıma ve biçim düzeltmesi
davranış değişikliğiyle aynı değişikliğe konmaz).

Son ölçüt en çok kazandıranıdır. Biçim düzeltmesi 300 satır büyütüyorsa, o 300 satır 6 öbek
demektir ve dikkatin 6 öbeği davranış değişikliğinden çalınmıştır. Önceki ders biçim eksenini
araca devretmişti; bu ders aynı devrin ikinci kazancını gösteriyor — devredilen eksen yalnız
tartışmayı değil, **öbeği** de incelemenin dışına çıkarır.

Bölünemeyen değişiklikler de vardır. Tek bir arayüzün adı değişiyorsa ve o ad iki bin satırda
geçiyorsa, parçalara ayırmak her parçayı kendi başına bozuk bırakır — birinci ölçüt ile
ikinci ölçüt çakışır. Böyle bir durumda yapılabilecek şey bölmek değil, **okuma sırasını
bildirmektir**: değişikliğin hangi öbeklerinin karar gerektirdiği, hangilerinin aynı düzenin
tekrarı olduğu yazan tarafından açıkça yazılır. Alt tablo bunun neden işe yaradığını
gösteriyor — dört pencerenin ikisi 2, biri 12, biri 6 kusur veriyor. Okunacak öbekler
işaretlenmiş olsaydı inceleyicinin ilk 12 öbeği okuması bir kumar olmaktan çıkardı.

Bu bildirim bir hesap verme aracı değildir ve öyle kullanılmamalıdır. Ölçtüğü şey kişinin
dikkati değil, **değişikliğin okunabilirliğidir**: aynı 48 öbek, sırası bildirilmiş hâlde
başka bir sonuç veriyor. Sıradaki iki ders bu ayrımı sürdürecek — ölçülen şey her seferinde
değişikliğin ve sürecin bir özelliğidir.

#### Özet

- Dikkat bir bütçedir: bir inceleme turunda okunan öbek sayısı sabittir (kurguda 12 öbek,
  600 satır). Değişiklik bundan büyükse artan her öbek okunmayanlar kümesine gider.
- Aynı 24 kusur, aynı eksen listesi: 100 ve 300 satırda **22** bulunur (**0,917**), 900
  satırda **18** (**0,750**), 2400 satırda **2** (**0,083**). Kusur sayısı değişmedi,
  yalnız değişiklik büyüdü.
- 2400 satır **48 öbektir** ve **36 öbek hiç okunmaz**; okunan 12 öbek kusur bakımından en
  fakir penceredir, bu yüzden oran 12/48'in bile altına iner.
- Aynı 2400 satır dört pencerede okunduğunda bulunan **22**'ye, oran **0,917**'ye çıkar.
  Belirleyici olan satır sayısı değil, **okunan öbek sayısıdır.**
- Kaçan **2** kusur her boyutta ve her pencerede aynı kalır: **eksik gereksinim**. Boyutu
  küçültmek de bölmek de yazılmamış olanı göstermez.
- Onay okunduğunun kanıtı değildir; okunmayan öbek geri bildirim üretmez ve iki inceleme
  dışarıdan aynı görünür.

#### Sonraki Adım

Değişiklik incelenebilir boyutta olduğunda inceleyen 22 kusuru buluyor. Ama bulunan bir kusur,
düzeltilmiş bir kusur değildir: aradaki mesafeyi bir **inceleme notu** kapatır ve notun ne
dediği, kusurun kaç inceleme turunda kapandığını belirler. Sonraki ders aynı 22 bulguyu üç ayrı
yazımla ölçüyor — ne değişeceği ve neden değişeceği yazılı olan not, yalnız ne görüldüğünü
söyleyen not ve kapanma ölçütü taşımayan istek aynı kusuru kaç inceleme turunda kapatır ve
hangi not biçimi değişikliği açık kusurla birlikte kapanmaya zorlar.

### Geri Bildirim Dili

Source: https://academia.sh/tr/kurslar/kod-inceleme/geri-bildirim-dili

Aynı 22 bulgu eyleme dönük yazıldığında 2 inceleme turunda kapanır, kapanma ölçütü yazılmadığında 4 turda; üçüncü turda birleştirilen değişiklikte ölçütsüz yazım 22 notun 22'sini açık bırakır.

Önceki ders incelenebilir değişikliğin sınırını ölçtü: dikkat 12 öbekte sabit kaldığı için
aynı 24 kusur 100 satırda 22 kez, 2400 satırda 2 kez bulunuyordu. Değişiklik okunabilir
boyuttayken inceleyen bulabileceğinin neredeyse hepsini buluyor.

Ama bulunan bir kusur, düzeltilmiş bir kusur değildir. Aradaki mesafeyi tek bir şey kapatır:
**inceleme notu**. Bu dersin sorusu notun kibarlığı değil, işlevidir — aynı bulgu iki ayrı
biçimde yazıldığında kusurun koddan çıkması kaç **inceleme turu** sürer ve hangi yazım
kusuru kodda bırakır.

#### Notun Öznesi

Bu kursun sınırı burada en somut hâlini alır: **inceleme notunun öznesi değişikliktir.**
Kural bir görgü kuralı değil, bir işlerlik kuralıdır ve gerekçesi ölçülebilir.

Sınama mekaniktir. Notun cümlesine bakılır ve tek bir soru sorulur: **öznesi ne?** Özne bir
kod öğesiyse — bir işlev, bir parametre, bir koşul, bir test, bir belge satırı — not
yerindedir. Özne bir rolse not yeniden yazılır ve öznesi, notun aslında konuştuğu kod
öğesiyle değiştirilir. İçerik kaybolmaz; yalnız cümle, düzeltilebilir olan şeyi işaret
etmeye başlar.

Gerekçe şudur: bir notun **kapanma ölçütü** kodda bulunur. "Şu koşul boş girdide sıfıra
bölüyor" biçiminde bir not, o koşul değiştiğinde kapanır ve kapandığı herkesçe görülür.
Öznesi rol olan bir cümlenin böyle bir ölçütü yoktur — neyin değişmesiyle kapanacağı yazılı
değildir, bu yüzden kapanamaz ve inceleme turlarını dolaşır. Ölçüm bu dolaşmanın bedelini
sayacak.

Aynı sınır ölçümün kendisine de uygulanır. Bu derste sayılan şey kimin kaç not yazdığı değil,
**notun hangi biçimde yazıldığında kaç inceleme turu sürdüğüdür.** Ölçülen özne yine
değişikliktir.

#### Notun Üç Yazımı

Aynı bulgu üç biçimde yazılabilir ve üçü de değişiklik hakkındadır. Fark, notun okurun eline
ne verdiğidir.

```text
# ogretilen ornek not , calistirilmamistir , olcum degildir

gözlem
  ortalama() boş liste geldiğinde beklenmedik davranıyor.

ölçütsüz istek
  Boş liste durumu daha sağlam ele alınmalı.

eyleme dönük
  ortalama() boş liste aldığında toplamı uzunluğa bölüyor ve sıfıra bölme
  hatası veriyor. Bu durumda 0.0 dönmesi ya da tanımlı bir hata yükseltilmesi
  gerekiyor. Hangisi seçilirse test dosyasına o durumun karşılığı eklenmeli;
  not, o test geçtiğinde kapanır.
```

**Gözlem**, ne görüldüğünü söyler ve orada durur. Doğrudur, yerini gösterir, ama ne
isteneceğini yazmaz; yazanın bir soru sorması ve inceleyenin yanıtlaması gerekir. Bu bir
alışveriştir ve bir inceleme turu tutar.

**Ölçütsüz istek** bir değişiklik ister ama isteğin ne zaman karşılandığını söylemez. "Daha
sağlam" bir ölçüt değildir: yazan bir düzeltme gönderir, inceleyen düşündüğü şeyin bu
olmadığını görür, not yeniden açılır. Bu iki alışveriştir.

**Eyleme dönük** not üç şeyi birden taşır: **ne görüldü**, **ne değişmeli**, **ne olunca
kapanır.** Üçüncüsü en çok atlanan ve en çok kazandıranıdır. Kapanma ölçütü not içinde
yazıldığında, düzeltmenin doğru olup olmadığı tartışma gerektirmez.

```text
# ogretilen ornek not , calistirilmamistir , olcum degildir

gözlem
  Yeni parametre imzanın ortasına eklenmiş.

eyleme dönük
  esik parametresi imzanın ortasına eklendiği için konuma göre çağıran kod
  sessizce kayıyor. Parametre imzanın sonuna alınmalı ve varsayılan değer
  verilmeli; böylece eski çağrılar değişmeden çalışır. Not, imza sonda ve
  varsayılanlı olduğunda kapanır.
```

İkinci örnek eyleme dönüklüğün bir üslup değil bir bilgi meselesi olduğunu gösteriyor.
Eyleme dönük not daha uzundur çünkü **daha fazla şey söyler**: gözlemin taşımadığı iki
bilgi, istenen değişiklik ve kapanma ölçütü, orada yazılıdır. Kısalık burada bir erdem
değildir; eksik bilgi sonraki inceleme turunda geri gelir.

#### Soru Biçimindeki Not

Notların bir bölümü soru biçiminde yazılır ve bu biçim tek başına iyi ya da kötü değildir.
Belirleyici olan, sorunun **durumu adlandırıp adlandırmadığıdır**.

Durumu adlandıran bir soru eyleme dönüktür: hangi girdiyle, hangi kod öğesinde, hangi
sonucun beklendiği yazılıysa yazan soruyu ya bir düzeltmeyle ya da tek cümlelik bir
gerekçeyle kapatabilir. Durumu adlandırmayan bir soru ise gözlemle aynı sınıftadır — bir
alışveriş ekler, çünkü önce hangi durumdan söz edildiğinin belirlenmesi gerekir.

Soru biçiminin gerçek işlevi başka bir yerdedir: notun kendisi yanlış bir varsayıma
dayanıyor olabilir. Böyle bir not soru biçiminde yazıldığında varsayım tek bir yanıtla
düzelir ve bu bir alışveriş tutar; aynı varsayım kesin bir istek biçiminde yazıldığında ise
önce yanlış bir düzeltme gönderilir ve iki alışveriş tutar. Ölçüm bunu doğrudan gösteriyor: ölçütsüz istek rejiminin
fazladan iki turu, yanlış anlaşılmanın ancak düzeltme geldikten sonra fark edilmesinden
geliyor. Bilinmeyen bir şey varsa, bilinmediğini yazmak turdan tasarruf ettirir.

Ölçümün varsayımları:

- **IK7** — Yapılandırma sabittir: tek inceleyici, beş eksenin hepsi, 600 satır, dikkat 12
  öbek. Bulunan 22, kaçan 2 ve kaçan ikisi de **eksik gereksinim** sınıfındadır. Not yazımı
  bu sayıları değiştirmez; ölçülen şey bulunanın kapanmasıdır.
- **IK8** — Bulunan her kusur için bir not yazılır. Notun yazımı, kusurun koddan çıkması
  için gereken alışveriş sayısını belirler: eyleme dönük **2**, gözlem **3**, ölçütsüz
  istek **4**.
- **IK9** — Bir inceleme turu, o anda açık olan bütün notların bir alışverişini birden
  tüketir. Notlar sırayla değil toplu ele alınır; bu yüzden inceleme turu sayısını en yavaş
  not belirler.
- **IK10** — Bir inceleme turunun beklemeye eklediği süre **6 birimdir** ve yazımdan
  bağımsızdır. **Not-turu**, bir notun açık kaldığı her inceleme turu için bir birim
  sayılır; toplam yükün sayımıdır.
- **IK11** — Karışık rejimde her notun yazımı `uretec` ile seçilir; hiçbir kural
  uygulanmadığında notların ne dağılımla yazıldığının bir örneğidir.
- **IK12** — İkinci ölçümde değişiklik üçüncü inceleme turunda birleştirilir. O anda açık
  kalan notların kusurları kodda kalır ve hiç bulunmayan 2 kusura eklenir.

#### Ölçüm

```python
"""Geri bildirim dili: ayni 22 bulgu, dort not yazimi.

Bolum 1 - her yazim kac inceleme turunda kapanir, bekleme ve tasinan not-turu.
Bolum 2 - degisiklik ucuncu turda birlestirilirse hangi notlar acik kalir.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50
TUR_BEKLEME = 6      # bir inceleme turunun beklemeye ekledigi birim
# Bir notun kapanmasi icin gereken alisveris sayisi.
YAZIMLAR = {"eyleme dönük": 2, "gözlem": 3, "ölçütsüz istek": 4}


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def dongu(gereken, kapak=6, tur_basina_bekleme=TUR_BEKLEME):
    """Her inceleme turu acik notlarin bir alisverisini tuketir."""
    acik, tur, bekleme, not_turu = list(gereken), 0, 0, 0
    while acik and tur < kapak:
        tur += 1
        bekleme += tur_basina_bekleme
        not_turu += len(acik)
        acik = [g - 1 for g in acik if g > 1]
    return tur, bekleme, not_turu, len(acik)


TAM = set(EKSENLER)
d = degisiklik(600)
bulunan = sorted(incele(d, TAM))
kacan = [k for k in d["kusurlar"] if k["no"] not in set(bulunan)]
r = uretec(TOHUM)
karisik = [list(YAZIMLAR)[r(3)] for _ in bulunan]
REJIMLER = {ad: [ad] * len(bulunan) for ad in YAZIMLAR}
REJIMLER["karışık"] = karisik

print(f"bulunan {len(bulunan)}, kaçan {len(kacan)}, bunun yazılmayan sınıfı "
      f"{sum(1 for k in kacan if k['sinif'] == YAZILMAYAN)}")
print("karışık rejimin dağılımı: " +
      ", ".join(f"{a} {karisik.count(a)}" for a in YAZIMLAR))
print()
print(f"{'not yazımı':<16s} {'tur':>4s} {'bekleme':>8s} {'not-turu':>9s} "
      f"{'kapanmayan':>11s} {'kodda kalan':>12s}")
for ad, notlar in REJIMLER.items():
    tur, bekleme, nt, acik = dongu(YAZIMLAR[n] for n in notlar)
    print(f"{ad:<16s} {tur:4d} {bekleme:8d} {nt:9d} {acik:11d} "
          f"{acik + len(kacan):12d}")

print()
print("değişiklik üçüncü inceleme turunda birleştirilirse")
print(f"{'not yazımı':<16s} {'tur':>4s} {'bekleme':>8s} {'kapanan':>8s} "
      f"{'kapanmayan':>11s} {'kodda kalan':>12s}")
for ad, notlar in REJIMLER.items():
    tur, bekleme, nt, acik = dongu((YAZIMLAR[n] for n in notlar), kapak=3)
    print(f"{ad:<16s} {tur:4d} {bekleme:8d} {len(notlar) - acik:8d} "
          f"{acik:11d} {acik + len(kacan):12d}")
```

```
bulunan 22, kaçan 2, bunun yazılmayan sınıfı 2
karışık rejimin dağılımı: eyleme dönük 2, gözlem 11, ölçütsüz istek 9

not yazımı        tur  bekleme  not-turu  kapanmayan  kodda kalan
eyleme dönük        2       12        44           0            2
gözlem              3       18        66           0            2
ölçütsüz istek      4       24        88           0            2
karışık             4       24        73           0            2

değişiklik üçüncü inceleme turunda birleştirilirse
not yazımı        tur  bekleme  kapanan  kapanmayan  kodda kalan
eyleme dönük        2       12       22           0            2
gözlem              3       18       22           0            2
ölçütsüz istek      3       18        0          22           24
karışık             3       18       13           9           11
```

#### Turun Nereden Geldiği

Üst tablonun ilk sütunları aynı 22 bulgunun bedelini veriyor. Eyleme dönük yazımda süreç
**2 inceleme turu** ve **12 birim bekleme** ile kapanıyor. Gözlem yazımında **3 tur / 18
birim**, ölçütsüz istekte **4 tur / 24 birim**. Bulunan hiç değişmedi: her rejimde 22 bulgu,
2 kaçan, kaçanların ikisi de eksik gereksinim. **Not yazımı bulunanı değiştirmez; bulunanın
ne zaman koddan çıktığını değiştirir.**

Kapanmayı geciktiren şeyin ne olduğu sayının içinde yazılı. Gözlem yazımı bir alışveriş
ekliyor çünkü eksik olan bilgi — ne isteniyor — sonraki inceleme turunda sorulup
yanıtlanıyor. Ölçütsüz istek iki alışveriş ekliyor çünkü eksik olan bilgi ancak yanlış bir
düzeltme geldikten sonra ortaya çıkıyor. **Her eksik bilgi, kendisini bir inceleme turunda
geri ister.**

Not-turu sütunu yükü daha iyi gösteriyor: **44**, **66**, **88**. Ölçütsüz yazım eyleme
dönük yazımın tam iki katı yük üretiyor ve bunun tamamı aynı 22 bulgunun taşınmasıdır.
Kodda hiçbir fark yok; fark yalnız notların ne söylediğinde.

Karışık rejim ise inceleme turu sayısının nasıl belirlendiğini açığa çıkarıyor. Dağılım
**2 eyleme dönük, 11 gözlem, 9 ölçütsüz istek**; toplam yük **73** not-turu, yani ortalama
üç rejimin arasında. Buna karşılık inceleme turu sayısı **4** — yani en yavaş rejimin
sayısı. **Toplu ele alınan notlarda inceleme turu sayısını ortalama değil, en yavaş not
belirler.** Yirmi iki notun on üçü kusursuz yazılsa bile, kalan dokuzu süreci dört tura
taşır.

#### Kapanmadan Kapanan İnceleme

Alt tablo gerçek bir kısıt ekliyor: değişiklik sonsuza kadar açık kalmaz. Üçüncü inceleme
turunda birleştirildiğinde her rejim aynı beklemeyi ödüyor ama farklı şeyler teslim ediyor.

Eyleme dönük yazım zaten ikinci turda bitmişti; sınır ona dokunmuyor. Gözlem yazımı tam
üçüncü turda kapanıyor. Ölçütsüz istek rejiminde ise **kapanan 0**, **kapanmayan 22** ve
kodda kalan kusur **24** — yani hepsi. Bu, tablonun en sert satırıdır: inceleme 24 kusurun
22'sini **buldu** ve **hiçbirini** teslim etmedi. Bulunan sayısıyla ölçülen bir süreç bu
incelemeyi başarılı sayardı.

Karışık rejim daha gerçekçi bir sonuç veriyor: **13 kapanan, 9 kapanmayan**, kodda kalan
**11**. On birin **2**'si hiçbir eksenin aramadığı sınıftır — eksik gereksinim, incelemenin
görebileceği bir şey değildi. Kalan **9**'u ise görüldü, yazıldı ve yazımı yüzünden
kapanamadı. İki kayıp arasındaki fark önemlidir: birincisi incelemenin sınırıdır, ikincisi
incelemenin **kendi ürettiği** kayıptır ve tamamen ortadan kaldırılabilir.

Kümenin çözünürlüğü 24 kusurda **1/24 = 0,042**'dir. 9 kusurluk fark bunun yirmi katıdır ve
tartışmasız ölçüm bandının içindedir. 22'den 13'e inen kapanan sayısı da öyle.

Alt tablonun bekleme sütunu ayrıca dikkat çekicidir: gözlem, ölçütsüz istek ve karışık
rejimlerin üçü de **18** birim harcıyor. Sınıra dayanan üç süreç aynı süreyi tüketiyor;
farklılaşan tek şey o sürenin sonunda kaç kusurun gerçekten koddan çıktığı — sırasıyla 22,
0 ve 13. **Yalnız beklemeye bakan bir okuma bu üç rejimi ayırt edemez.**

#### Notu Eyleme Dönük Kılan Alışkanlıklar

Ölçümden çıkan dört alışkanlık doğrudan uygulanabilir ve dördü de notun içine bir bilgi
ekler.

**Kapanma ölçütünü yaz.** Not, hangi gözlemlenebilir durumda kapanacağını söylemeli: bir
testin geçmesi, bir imzanın belirli hâle gelmesi, bir belge satırının eklenmesi. Ölçütsüz
istek rejiminin fazladan iki turu buradan geliyor.

**İsteği gözlemden ayır.** Gözlem yerini gösterir, istek yönü verir. İkisi aynı notta
bulunmadığında eksik olan, sonraki inceleme turunda sorulur.

**Bağlayıcı olmayanı işaretle.** Her not bir engel değildir; kimi not bir öneridir ve
düzeltilmeden de birleştirilebilir. Bunu notun kendisinde belirtmek, bağlayıcı olmayan
notların inceleme turu sayısına katılmasını önler — karışık rejimin dört tura çıkmasının
nedeni tam olarak birkaç notun yavaşlığıydı.

**Aynı bulguyu bir kez yaz.** Bir düzenin on yerde tekrarlandığı bir değişiklikte her
tekrara ayrı not yazmak not sayısını büyütür ama bilgiyi büyütmez; on notun onu aynı
alışverişi bekler. Düzeni bir kez yazıp kapsamını belirtmek — hangi dosyalarda, hangi
öğelerde — aynı kapanma ölçütünü tek notla verir.

Dört alışkanlığın ortak yanı, hepsinin notu **daha bilgili** kılmasıdır. Ölçümde yavaşlığın
tek kaynağı vardı: notta olmayan bilginin sonraki inceleme turunda istenmesi. Nezaket bu
tablonun hiçbir sütununda görünmez; görünen şey, bilginin nerede durduğudur.

#### Özet

- İnceleme notunun öznesi değişikliktir; sınama mekaniktir — özne bir kod öğesi değilse not,
  konuştuğu kod öğesi özne olacak biçimde yeniden yazılır.
- Gerekçe ölçülebilir: notun **kapanma ölçütü** kodda bulunur. Ölçütü olmayan not neyle
  kapanacağını söylemez ve inceleme turlarını dolaşır.
- Aynı 22 bulgu eyleme dönük yazıldığında **2 tur / 12 bekleme / 44 not-turu**, gözlem
  yazıldığında **3 / 18 / 66**, ölçütsüz istek yazıldığında **4 / 24 / 88** tutar. Bulunan
  ve kaçan hiç değişmez: 22 ve 2, kaçanların ikisi de **eksik gereksinim**.
- Notlar toplu ele alındığı için inceleme turu sayısını ortalama değil **en yavaş not**
  belirler: karışık rejimde 22 notun 13'ü hızlı yazılmış olsa da süreç 4 tur sürer.
- Değişiklik üçüncü inceleme turunda birleştirildiğinde ölçütsüz yazım **0** not kapatır ve
  **24** kusur kodda kalır; karışık yazım **13** kapatır, kodda **11** kalır — bunun 2'si
  hiç bulunamayan sınıftır, **9**'u ise bulunup kapanamayandır.

#### Sonraki Adım

Ölçüm bir şeyi varsayıyordu: yeterince alışveriş yapıldığında not kapanır. Bu her zaman
doğru değildir. Kimi notta eksik olan bilgi değil, **anlaşmadır** — yazan ile inceleyen aynı
kod öğesi hakkında farklı bir tasarım savunur ve alışveriş sayısını artırmak tarafları
yaklaştırmaz. Sonraki ders böyle bir bulgunun kaç inceleme turu taşındığını ve dört ayrı
karara bağlama kuralının beklemeye, kapanan nota ve kodda kalan kusura ne yaptığını ölçüyor.

### Anlaşmazlık Çözümü

Source: https://academia.sh/tr/kurslar/kod-inceleme/anlasmazlik-cozumu

Yirmi iki bulgunun altısı tasarım anlaşmazlığına döndüğünde kural yokluğu 6 inceleme turu ve 36 birim bekleme üretip 8 kusuru kodda bırakır; ölçüte bağlama 3 tur ve 18 birimle kodda yalnız 2 bırakır.

Önceki ders inceleme notunun yazımını ölçtü ve tek bir kaynak buldu: notta olmayan bilgi,
sonraki inceleme turunda geri isteniyordu. Eyleme dönük yazım 2 inceleme turunda kapanıyor,
kapanma ölçütü olmayan yazım 4 turda. Ölçümün varsayımı şuydu — yeterince alışveriş
yapıldığında not kapanır.

Bu varsayım her notta doğru değildir. Kimi bulguda eksik olan bilgi değil, **karardır**:
aynı kod öğesi hakkında iki tasarım savunulur, ikisi de çalışır, ikisinin de testi geçer.
Böyle bir notta alışveriş sayısını artırmak kapanmaya yaklaştırmaz; aynı iki gerekçe her
inceleme turunda yeniden yazılır. Bu dersin sorusu şudur: kararsız kalan bir bulgu kaç
inceleme turu taşınır ve onu karara bağlayan kural beklemeye ne ekler.

#### Anlaşmazlık ile Eksik Bilgi Ayrımı

İki not birbirine benzer görünür ama farklı davranır ve ayrım mekanik olarak yapılabilir.
Sınama tek sorudur: **notu kapatacak bilgi taraflardan birinde var mı?**

Varsa not eksik bilgi notudur. Yazan boş girdi durumunda ne olması gerektiğini biliyordur ya
da inceleyen imzanın neden bozulduğunu biliyordur; bilgi bir alışverişle karşıya geçer ve not
kapanır. Önceki dersin bütün ölçümü bu sınıftaydı.

Yoksa not bir **tasarım anlaşmazlığıdır**. Eksik olan şey kimsenin sahip olmadığı bir
bilgidir: hangi tasarımın daha iyi olduğu, mevcut ölçütlerle belirlenemiyordur. Böyle bir
notta alışveriş bilgi taşımaz, yalnız gerekçeleri tekrarlar. Ölçüm bu tekrarın maliyetini
sayacak.

Anlaşmazlığın hangi eksenlerde çıktığı da rastgele değildir. Biçim ekseni bir araca
devredildiğinde tartışma kalmaz; testin bir durumu kapsayıp kapsamadığı ya da belgede bir
satırın bulunup bulunmadığı gözlemle çözülür. Anlaşmazlık asıl olarak **arayüz** ve
**gerçekleştirim** eksenlerinde çıkar, çünkü bu iki eksende birden çok savunulabilir çözüm
vardır. Ölçüm anlaşmazlıkları yalnız bu iki sınıftan seçiyor.

Kurumsal karar alma düzenleri, yetki dağılımı ve ekip yapısı bu dersin konusu değildir;
onlar **Süreç, Ekip ve Teslimat** kursunda kuruldu. Burada ölçülen şey incelemenin kendi
sayılarıdır: inceleme turu, bekleme ve kodda kalan kusur.

#### Dört Karara Bağlama Kuralı

Ölçüm aynı 22 bulguyu dört kuralla işletiyor. Kurallar birbirinin yerine geçer; ekip
bunlardan birini önceden seçer ve anlaşmazlık çıktığında uygular.

**Kural yok.** Anlaşmazlık her inceleme turunda yeniden tartışılır. Tartışmanın bir bitiş
düzeneği olmadığı için değişikliğin açık kalabildiği en çok inceleme turu dolar ve
anlaşmazlıklar açık kalır.

**Ölçüte bağlama.** Tartışma yazılı bir ölçüte götürülür: arayüz sözleşmesindeki bir kural,
ölçülmüş bir sayı, bir testin geçip geçmemesi. Ölçüt tarafların tercihinden bağımsızdır ve
karar ondan çıkar.

**Sahibin kararı.** Kod sahipliği tanımlıysa, ölçütle çözülemeyen anlaşmazlıkta kararı sahip
verir. Karar tek alışverişte gelir ama sahip incelemenin içinde değildir; sürece dahil
edilmesi ek bekleme yükler.

**Ayrı iş öğesine ayırma.** Anlaşmazlık bu değişiklikten çıkarılır ve kendi iş öğesine
taşınır. Değişiklik hemen kapanır; tasarım tartışması sürer ve kusur bu değişiklikte
düzeltilmez.

```text
# ogretilen ornek not , calistirilmamistir , olcum degildir

anlaşmazlık
  Aynı işlev için iki tasarım savunuluyor: seçenekleri tek bir sözlük
  parametresinde toplamak ya da ayrı adlandırılmış parametreler bırakmak.
  İki yazım da çalışıyor ve iki yazımın da testi geçiyor.

ölçüte bağlanmış hâli
  Karar ölçütü, arayüz sözleşmesindeki geriye dönük uyumluluk kuralıdır:
  yeni seçenek eklendiğinde eski çağrılar değişmeden çalışmalıdır. Sözlük
  parametresi bu kuralı sağlıyor, ayrı parametreler her eklemede imzayı
  değiştiriyor. Not, sözlük parametresi seçilip belgeye yazıldığında kapanır.
```

Örnek, ölçüte bağlamanın ne yaptığını gösteriyor: tartışmayı bitiren şey tarafların ikna
olması değil, **kararı verecek yerin değişmesidir.** Karar artık nottan değil, sözleşmeden
çıkıyor ve not önceki dersin sınamasından geçen bir kapanma ölçütü kazanıyor.

Ölçümün varsayımları:

- **IK13** — Yapılandırma sabittir: tek inceleyici, beş eksen, 600 satır, dikkat 12 öbek.
  Bulunan 22, kaçan 2 ve kaçanların ikisi de **eksik gereksinim** sınıfındadır. Karara
  bağlama kuralı bu sayıları değiştirmez.
- **IK14** — Anlaşmazlık yalnız **arayüz** ve **gerçekleştirim** sınıflarındaki bulgularda
  çıkabilir. Bu sınıflarda bulunan 9 notun hangilerinin anlaşmazlığa döndüğü `uretec` ile
  seçilir.
- **IK15** — Anlaşmazlık olmayan not eyleme dönük yazılmıştır ve **2** alışverişte kapanır.
  Önceki dersin en iyi rejimi bu derste taban kabul edilir.
- **IK16** — Kural yokken anlaşmazlık hiç kapanmaz: her inceleme turunda yeniden tartışılır.
  Ölçüte bağlama ve sahibin kararı **3** alışverişte kapatır; ayrı iş öğesine ayırma **2**
  alışverişte kapatır ama kusuru koddan çıkarmaz.
- **IK17** — Bir inceleme turu beklemeye **6 birim** ekler. Sahibin kararı ayrıca **6 birim**
  sahip beklemesi ekler: sahip incelemenin dışındadır ve sıraya girmesi gerekir.
- **IK18** — Bir değişiklik en çok **6 inceleme turu** açık kalabilir. Bu sınırda hâlâ açık
  olan notların kusurları kodda kalır.
- **IK19** — Kümenin çözünürlüğü 24 kusurda **1/24 = 0,042**'dir; bekleme birim başına
  ölçülür ve bir inceleme turundan küçük fark bu kümeyle savunulamaz.

#### Ölçüm

```python
"""Anlasmazlik cozumu: ayni 22 bulgu, dort karara baglama kurali.

Bolum 1 - anlasmazlik hangi bulgularda cikiyor.
Bolum 2 - her kural kac inceleme turu, ne kadar bekleme ve kodda ne birakiyor.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50
TUR_BEKLEME = 6      # bir inceleme turunun beklemeye ekledigi birim
KAPAK = 6            # bir degisikligin acik kalabildigi en cok inceleme turu
TARTISILIR = ("arayuz", "gerceklestirim")   # anlasmazlik cikabilen siniflar
EYLEME_DONUK = 2     # anlasmazlik olmayan notun kapanma alisverisi
# alisveris None ise anlasmazlik her turda yeniden tartisilir ve kapanmaz.
KURALLAR = {
    "kural yok": {"alisveris": None, "sahip": 0, "erteler": False},
    "ölçüte bağlama": {"alisveris": 3, "sahip": 0, "erteler": False},
    "sahibin kararı": {"alisveris": 3, "sahip": TUR_BEKLEME, "erteler": False},
    "ayrı iş öğesi": {"alisveris": 2, "sahip": 0, "erteler": True},
}


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def dongu(gereken, kapak=KAPAK, tur_basina_bekleme=TUR_BEKLEME):
    """Her inceleme turu acik notlarin bir alisverisini tuketir."""
    acik, tur, bekleme, not_turu = list(gereken), 0, 0, 0
    while acik and tur < kapak:
        tur += 1
        bekleme += tur_basina_bekleme
        not_turu += len(acik)
        acik = [g - 1 for g in acik if g > 1]
    return tur, bekleme, not_turu, len(acik)


TAM = set(EKSENLER)
d = degisiklik(600)
bulunan = [k for k in d["kusurlar"] if k["no"] in incele(d, TAM)]
kacan = [k for k in d["kusurlar"] if k not in bulunan]
r = uretec(TOHUM)
for k in bulunan:
    k["anlasmazlik"] = k["sinif"] in TARTISILIR and r(2) == 0
anl = [k for k in bulunan if k["anlasmazlik"]]

print(f"bulunan {len(bulunan)}, kaçan {len(kacan)}, bunun yazılmayan sınıfı "
      f"{sum(1 for k in kacan if k['sinif'] == YAZILMAYAN)}")
print(f"tartışılır sınıfta bulunan "
      f"{sum(1 for k in bulunan if k['sinif'] in TARTISILIR)}"
      f", anlaşmazlığa dönen {len(anl)}")
print("anlaşmazlık sınıfları: " +
      ", ".join(f"{s} {sum(1 for k in anl if k['sinif'] == s)}"
                for s in TARTISILIR))
print()
print(f"{'kural':<16s} {'tur':>4s} {'bekleme':>8s} {'not-turu':>9s} "
      f"{'anlaşmazlık not-turu':>21s} {'kapanan':>8s} {'ertelenen':>10s} "
      f"{'kodda kalan':>12s}")
for ad, kural in KURALLAR.items():
    gereken = [kural["alisveris"] or KAPAK + 1 if k["anlasmazlik"]
               else EYLEME_DONUK for k in bulunan]
    tur, bekleme, nt, acik = dongu(gereken)
    anl_nt = sum(min(g, tur) for g, k in zip(gereken, bulunan)
                 if k["anlasmazlik"])
    ertelenen = len(anl) if kural["erteler"] else 0
    kapanan = len(bulunan) - acik - ertelenen
    print(f"{ad:<16s} {tur:4d} {bekleme + kural['sahip']:8d} {nt:9d} "
          f"{anl_nt:21d} {kapanan:8d} {ertelenen:10d} "
          f"{acik + ertelenen + len(kacan):12d}")
```

```
bulunan 22, kaçan 2, bunun yazılmayan sınıfı 2
tartışılır sınıfta bulunan 9, anlaşmazlığa dönen 6
anlaşmazlık sınıfları: arayuz 1, gerceklestirim 5

kural             tur  bekleme  not-turu  anlaşmazlık not-turu  kapanan  ertelenen  kodda kalan
kural yok           6       36        68                    36       16          0            8
ölçüte bağlama      3       18        50                    18       22          0            2
sahibin kararı      3       24        50                    18       22          0            2
ayrı iş öğesi       2       12        44                    12       16          6            8
```

#### Kararsız Bulgunun Taşıdığı

Yirmi iki bulgunun **9**'u tartışılır sınıftadır ve bunların **6**'sı anlaşmazlığa dönüyor:
arayüzde 1, gerçekleştirimde 5. Kalan 16 not eksik bilgi notudur ve önceki dersin taban
rejiminde, 2 alışverişte kapanır.

Kural yokken tablo çöküyor. Süreç **6 inceleme turuna** ve **36 birim beklemeye** çıkıyor;
sonunda **16** not kapanıyor, **6** anlaşmazlık açık kalıyor ve kodda kalan kusur **8**
oluyor. Sekizin **2**'si hiçbir eksenin aramadığı sınıftır — eksik gereksinim, incelemenin
göremeyeceği kusur. Kalan **6**'sı görüldü, yazıldı, tartışıldı ve **karara
bağlanmadığı için** kodda kaldı.

Anlaşmazlık not-turu sütunu maliyetin nereden geldiğini tek sayıda veriyor: **36**. Altı
anlaşmazlığın her biri altı inceleme turu boyunca açık kaldı; 6 × 6 = 36. Toplam yükün
**68**'inin 36'sı, yani yarıdan fazlası, hiçbir şey üretmeyen tekrardır. Eksik bilgi
notlarının hepsi ikinci turda kapanmıştı; üçüncü turdan altıncı tura kadar geçen dört tur
yalnız altı anlaşmazlık için harcandı.

Buradaki sayı çifti tanıdıktır. Ortak kurgunun en kötü eksen yapılandırması da **6 inceleme
turu / 36 bekleme** üretiyordu. İki farklı neden, aynı fatura: orada dar bir eksen listesi
yüzünden kusurlar ilk turda görülemiyordu, burada görülen kusurlar karara bağlanamıyor. Her
iki durumda da inceleme turu sayısını uzatan şey, **ilk turda kapanmayan işin miktarıdır.**

Bu eşleşme ölçütlerin okunmasıyla ilgili bir uyarı da veriyor. Dışarıdan bakıldığında iki
süreç aynı iki sayıyı gösteriyor; sayıların hangisinin eksen darlığından, hangisinin karara
bağlanmamış tartışmadan geldiği tablonun kendisinde yazılı değildir. Aynı fatura, iki ayrı
düzeltme gerektirir.

#### Karara Bağlamanın İki Yolu

Ölçüte bağlama en dengeli satırdır: **3 inceleme turu**, **18 birim bekleme**, **22 kapanan**
ve kodda kalan **2**. İkisi de eksik gereksinim, yani incelemenin ulaşamayacağı sınıf. Bu
kural, incelemenin bulabildiği her şeyi teslim eden tek kuraldır.

Bedeli kural yokluğuna göre negatiftir: 36 birimden 18 birime iner. Karara bağlama kuralı
beklemeyi **artırmıyor**, azaltıyor. Ölçümün en pratik sonucu budur — anlaşmazlık çözümü bir
ek süreç değil, sürecin en pahalı kalemini ortadan kaldıran şeydir.

Sahibin kararı aynı sonucu veriyor: **22 kapanan**, kodda kalan **2**. Aradaki fark bekleme
sütununda: **24** birim, ölçüte bağlamadan **6** birim fazla. Fark tam olarak bir inceleme
turudur ve nedeni yapısaldır — sahip incelemenin içinde değildir, dahil edilmesi gerekir. Bu
kural ölçütün olmadığı ya da ölçütlerin çeliştiği anlaşmazlıklar için ayrılırsa fazladan 6
birim yalnız gereken yerde ödenir.

#### Hangi Ölçüt Bağlar

Ölçüte bağlamanın işe yaraması ölçütün bir niteliğine dayanır: **tarafların tercihinden
bağımsız olması ve önceden yazılmış olması.** İki koşuldan biri eksikse tartışma ölçüt
tartışmasına dönüşür ve tablodaki 18 birim geri gelmez.

Bağlayan ölçütler bellidir. **Arayüz sözleşmesi** geriye dönük uyumluluk sorularını kapatır;
sözleşmenin ne söylediği tartışma sırasında değil, önceden yazılmıştır. **Ölçülmüş bir sayı**
başarım anlaşmazlıklarını kapatır: iki tasarımın hangisinin daha hızlı olduğu bir tercih
değil, bir ölçüm sonucudur. **Bir testin geçip geçmemesi** davranış anlaşmazlıklarını
kapatır. **Belgede yazılı bir kural** — adlandırma düzeni, katman sınırı, bağımlılık yönü —
yapısal anlaşmazlıkları kapatır.

Bağlamayan ölçütler de bellidir ve hepsinin ortak yanı, tartışma anında üretilmiş olmalarıdır:
kişisel alışkanlık, "daha temiz" ya da "daha okunur" gibi ölçülemeyen sıfatlar ve başka bir
yerde şöyle yapıldığı gözlemi. Temiz kod ilkeleri **Temiz Kod** kursunda kuruldu ve orada bir
kural listesidir; bir anlaşmazlığı kapatabilmeleri için o listenin ekipte yazılı ve
bağlayıcı olması gerekir. Yazılı değilse ölçüt değil, ikinci bir tercihtir.

Buradan pratik bir sonuç çıkar: ölçüt tartışma sırasında değil, **tartışmadan önce** yazılır.
Ölçümdeki 36 birimlik fatura, ölçütün eksikliğinin faturasıdır — ve o eksiklik incelemenin
içinde giderilemez.

#### Erteleme Bir Karardır

Ayrı iş öğesine ayırma tablonun en hızlı satırıdır: **2 inceleme turu**, **12 birim
bekleme**, toplam yük **44** not-turu. Bu sayılar tesadüf değildir; anlaşmazlıkların
tartışılmadığı bir süreç, önceki dersin eyleme dönük rejimiyle aynı sayıları verir.

Ödenen bedel sağdaki iki sütunda: **6 ertelenen** ve kodda kalan **8** kusur. Ertelenen
notlar kaybolmuş değildir, kendi iş öğelerinde durur; ama o değişiklik birleştiğinde kod, 6
kusuru üzerinde taşır. Kodda kalan sayısı bakımından erteleme ile kural yokluğu **aynı
sonucu** veriyor: ikisinde de 8. Fark, ertelemenin bunu **24 birim daha az beklemeyle** ve
bir kayıt bırakarak yapmasıdır.

Bu yüzden erteleme bir kaçış değil, bir karardır — ama ancak kaydı gerçekten tutulduğunda.
İş öğesi açılmadan yapılan erteleme, ölçümde kural yokluğuyla aynı yere düşer: 6 kusur kodda,
kaydı hiçbir yerde. Ertelemenin sınırı da buradan çıkar: anlaşmazlığın kendisi ertelenebilir,
ama anlaşmazlığın altındaki kusur bir hataysa ertelenemez. Tasarımın hangi biçimde
yazılacağı bekleyebilir; boş girdide sıfıra bölünmesi bekleyemez.

#### Özet

- Tasarım anlaşmazlığı eksik bilgi notundan mekanik olarak ayrılır: notu kapatacak bilgi
  taraflardan birinde varsa not eksik bilgi notudur, yoksa anlaşmazlıktır.
- Anlaşmazlık **arayüz** ve **gerçekleştirim** eksenlerinde çıkar; ölçümde tartışılır
  sınıftaki 9 bulgunun **6**'sı anlaşmazlığa dönüyor.
- Kural yokken süreç **6 inceleme turu / 36 birim bekleme** tutar, **16** not kapanır ve
  kodda **8** kusur kalır. Toplam yükün **68** not-turunun **36**'sı yalnız altı
  anlaşmazlığın tekrarıdır.
- Ölçüte bağlama **3 tur / 18 birim** ile **22** notun hepsini kapatır; kodda kalan **2**,
  hiçbir eksenin aramadığı **eksik gereksinim** sınıfıdır. Sahibin kararı aynı sonucu verir
  ama sahip incelemenin dışında olduğu için **24** birim tutar.
- Ayrı iş öğesine ayırma en hızlı satırdır (**2 tur / 12 birim**) ama kodda **8** kusur
  bırakır — kural yokluğuyla aynı sayı, çok daha az beklemeyle ve bir kayıtla.

#### Sonraki Adım

Üç ders üç ayrı nedenle aynı iki sayıyı üretti: inceleme turu ve bekleme. Değişiklik boyutu
okunan öbeği belirledi, not yazımı kapanma hızını, karara bağlama kuralı ise kapanıp
kapanmayacağını. Sonraki ders bu iki sayıyı doğrudan ölçüt olarak alıyor: eksen atamasının
kendisi inceleme turu ve bekleme üzerinde ne yapıyor, inceleme kuyruğunun sağlığı nasıl
okunur ve bu ölçütlerin neden kişi başına raporlanmadığı.

### İnceleme Ölçütleri

Source: https://academia.sh/tr/kurslar/kod-inceleme/inceleme-olcutleri

Üç inceleyici aynı eksende 6 inceleme turu, 36 birim bekleme ve 3 kalan kusur üretir; tek inceleyici beş eksende 2 tur, 12 birim ve 0 kalan verir ve aynı fark inceleme kuyruğunda 2'ye karşı 15 turluk açık kalmaya dönüşür.

Üç ders aynı iki sayıya çıktı. Değişiklik boyutu okunan öbeği belirledi ve bulunanı; not
yazımı bulunanın kapanma hızını; karara bağlama kuralı kapanıp kapanmayacağını. Üçünde de
sonuç bir **inceleme turu** sayısı ve bir **bekleme** miktarıydı.

Bu ders o iki sayıyı doğrudan ölçüt olarak alıyor ve üçüncü bir ölçüt ekliyor: incelemenin
tek bir değişikliğe değil, **inceleme kuyruğuna** yaptığı. Sorulan şey şudur — bu üç sayı
neyi ölçer, hangi kararı destekler ve tek başına okunduğunda neyi gizler.

#### Üç Ölçüt

**Bekleme süresi**, bir değişikliğin incelemeye girdiği andan kapandığı ana kadar geçen
süredir. Ortak kurguda her inceleme turu beklemeye 6 birim ekler; bekleme, inceleme turu
sayısının doğrudan bir işlevidir.

**İnceleme turu sayısı**, değişikliğin kapanmadan önce kaç kez gidip geldiğidir. Kaynağı
tek bir şeydir ve önceki üç ders bunu üç ayrı yoldan gösterdi: **ilk turda kapanmayan iş**.
İlk turda görülemeyen kusur, yazılmayan kapanma ölçütü ve karara bağlanmayan tartışma aynı
yere çıkar.

**İnceleme kuyruğu sağlığı**, tek bir değişikliğin değil, aynı anda açık olan bütün
değişikliklerin ölçütüdür. Ekibin inceleme kapasitesi sınırlıdır: aynı anda ancak belirli
sayıda değişiklik incelenebilir. Her değişiklik daha çok inceleme turu tuttukça kapasite
daha uzun süre bağlanır ve arkadan gelen değişiklikler bekler. Kuyruk sağlığı bu birikmenin
olup olmadığını gösterir.

#### Ölçütler Neden Kişi Başına Raporlanmaz

Bu üç ölçüt **sürecin** ölçütleridir ve kişi başına raporlanmaz; çünkü tablonun her satırını
üreten şey kişilerin çabası değil **eksen atamasıdır** — üç inceleyicinin 6 inceleme turu
üretmesi, üçünün de işini eksiksiz yapmasına rağmen olur.

Ölçümün ikinci satırı bunun kanıtıdır. Orada üç inceleyici vardır, üçü de bakmakla yükümlü
oldukları eksende her kusuru bulur ve sonuç 24 kusurun 6'sıdır. Kişi başına bir sayı
çıkarılsaydı üç inceleyici de düşük görünürdü; oysa değiştirilmesi gereken tek şey, üçünün
aynı eksene bakmasıdır. Ölçüt yanlış özneye bağlandığında düzeltme de yanlış yere gider.

Bir ikinci gerekçe önceki dersten çıkıyor. Not yazımı değiştiğinde bulunan kusur sayısı hiç
değişmiyordu — 22 sabit kalıyordu. Yani not sayısı ile bulunan kusur sayısı birbirinden
bağımsızdır. Kişi başına not sayısı raporlanan bir düzende artan şey not sayısı olur,
bulunan kusur sayısı olmaz.

Ölçümün varsayımları:

- **IK20** — Ortak kurgu değişmez: 600 satır, 12 öbek, 24 kusur, sınıf dağılımı sabit.
  Değişen tek şey **eksen atamasıdır**.
- **IK21** — Dört atama ölçülür: tek inceleyici tüm eksenlerde; üç inceleyici aynı eksende;
  üç inceleyici ayrı eksenlerde; beş inceleyici beş eksende. Her inceleyicinin dikkati
  **12 öbektir**.
- **IK22** — Her inceleme turunda bulunan kusurlar düzeltilir; kalan kusur sonraki tura
  kalır ve her turda bulunanın yarısı kadarı temizlenir. Bir değişiklik en çok **6 inceleme
  turu** açık kalabilir.
- **IK23** — Bir inceleme turu beklemeye **6 birim** ekler ve bu atamadan bağımsızdır.
- **IK24** — İnceleme kuyruğunda her turda **bir** değişiklik gelir; toplam **12**
  değişiklik girer. Ekibin kapasitesi **3 eşzamanlı** incelemedir.
- **IK25** — Kuyruktaki bütün değişiklikler aynı atamayla incelenir; bu yüzden hepsi aynı
  inceleme turu sayısını tutar.
- **IK26** — Kuyruk ölçümü 60 tur boyunca izlenir; bu süre dört atamanın dördünde de bütün
  değişikliklerin kapanmasına yeter.
- **IK27** — Kümenin çözünürlüğü 24 kusurda **1/24 = 0,042**'dir; bekleme ve inceleme turu
  birim başına sayılır.

#### Ölçüm

```python
"""Inceleme olcutleri: bulunan, inceleme turu, bekleme ve kuyruk sagligi.

Bolum 1 - dort eksen atamasinin bulundugu ve kacirdigi.
Bolum 2 - ayni atamalarin inceleme turu, bekleme ve kalan kusuru.
Bolum 3 - ayni turlarin inceleme kuyruguna yaptigi.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT = 12
OBEK = 50
KAPASITE = 3         # ayni anda incelenebilen degisiklik sayisi
GELEN = 12           # olcum boyunca kuyruga giren degisiklik


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=6):
    """Her tur bulunanlari duzeltir; kalan kusur sonraki tura kalir."""
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


def kuyruk(tur, gelen=GELEN, kapasite=KAPASITE, sure=60):
    """Her turda bir degisiklik gelir; ayni anda en cok kapasite kadari incelenir."""
    sira, calisan, biten, anlik = [], {}, [], 0
    for t in range(1, sure + 1):
        if t <= gelen:
            sira.append(t)
        for no in [n for n, b in calisan.items() if b == t]:
            biten.append((no, t))
            del calisan[no]
        while sira and len(calisan) < kapasite:
            calisan[sira.pop(0)] = t + tur
        if t == gelen:
            anlik = len(sira) + len(calisan)
    return anlik, max(b - g for g, b in biten), max(b for _, b in biten)


TAM = set(EKSENLER)
ATAMALAR = {
    "tek inceleyici, tüm eksenler": [TAM],
    "üç inceleyici, aynı eksen": [{"gerceklestirim"}] * 3,
    "üç inceleyici, ayrı eksen": [{"arayuz"}, {"gerceklestirim"},
                                  {"test", "belge"}],
    "beş inceleyici, beş eksen": [{e} for e in EKSENLER],
}
d = degisiklik(600)

print(f"{'atama':<30s} {'inceleyici':>10s} {'bulunan':>8s} {'kaçan':>6s} "
      f"{'yazılmayan kaçan':>17s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    print(f"{ad:<30s} {len(atama):10d} {len(b):8d} {len(kacan):6d} {yaz:17d}")

print()
print(f"{'atama':<30s} {'tur':>4s} {'bekleme':>8s} {'kalan kusur':>12s}")
for ad, atama in ATAMALAR.items():
    tur, bekleme, kalan = tur_dongusu(kurul(d, atama), len(d["kusurlar"]))
    print(f"{ad:<30s} {tur:4d} {bekleme:8d} {kalan:12d}")

print()
print(f"inceleme kuyruğu: her turda bir değişiklik gelir, {GELEN} değişiklik, "
      f"kapasite {KAPASITE}")
print(f"{'atama':<30s} {'tur':>4s} {'12. turda açık':>15s} "
      f"{'en uzun açık kalma':>19s} {'son kapanış':>12s}")
for ad, atama in ATAMALAR.items():
    tur = tur_dongusu(kurul(d, atama), len(d["kusurlar"]))[0]
    anlik, en_uzun, son = kuyruk(tur)
    print(f"{ad:<30s} {tur:4d} {anlik:15d} {en_uzun:19d} {son:12d}")
```

```
atama                          inceleyici  bulunan  kaçan  yazılmayan kaçan
tek inceleyici, tüm eksenler            1       22      2                 2
üç inceleyici, aynı eksen               3        6     18                 2
üç inceleyici, ayrı eksen               3       15      9                 2
beş inceleyici, beş eksen               5       22      2                 2

atama                           tur  bekleme  kalan kusur
tek inceleyici, tüm eksenler      2       12            0
üç inceleyici, aynı eksen         6       36            3
üç inceleyici, ayrı eksen         3       18            0
beş inceleyici, beş eksen         2       12            0

inceleme kuyruğu: her turda bir değişiklik gelir, 12 değişiklik, kapasite 3
atama                           tur  12. turda açık  en uzun açık kalma  son kapanış
tek inceleyici, tüm eksenler      2               2                   2           14
üç inceleyici, aynı eksen         6               9                  15           27
üç inceleyici, ayrı eksen         3               3                   3           15
beş inceleyici, beş eksen         2               2                   2           14
```

#### Turu Uzatan Şey

İlk iki tablo yan yana okunduğunda konunun sonucu çıkıyor. Üç inceleyici aynı eksende
çalıştığında **6** kusur bulunuyor, süreç **6 inceleme turu** ve **36 birim bekleme** tutuyor
ve sonunda **3 kusur** hâlâ kalıyor. Tek inceleyici beş eksene baktığında **22** kusur
bulunuyor, süreç **2 inceleme turu** ve **12 birim** tutuyor, kalan **0**.

Karşılaştırma önemlidir çünkü ikinci satırda **üç kat daha çok inceleyici** vardır. Üç kişi
altı kat bekleme üretiyor ve sonunda üç kusur teslim edemiyor; bir kişi bunu üçte bir
beklemeyle ve eksiksiz yapıyor. **İnceleme kuyruğunu uzatan şey inceleyici sayısı değil, ilk
turda görülemeyendir.**

Bağ doğrudan aritmetiktir. İlk turda bulunan azsa geriye çok kusur kalır; kalan kusurlar
sonraki turlarda ancak bulunanın yarısı hızıyla temizlenir; bu yüzden az bulmak, hem daha
çok inceleme turu hem de sınırda kalan kusur demektir. Üç inceleyici ayrı eksenlere
dağıldığında **15** bulunuyor ve süreç **3 tur / 18 birim** ile kapanıyor: aynı üç kişi,
yalnız eksen dağılımı değişti.

Kaçan sütununun en sağı bütün satırlarda **2**'dir. Dört yapılandırmanın dördü de iki
**eksik gereksinim** kusurunu kaçırıyor. Bu sayı ne inceleyici ekleyerek ne eksen ekleyerek
düşüyor — hiçbir eksen yazılmayanı aramaz. Ölçütlerin okunmasında bu satır bir taban görevi
görür: 24 kusurun 2'si incelemenin erişemeyeceği yerdedir ve bir sürecin hedefi 22'dir.
Tabanı bilmeyen bir okuma her incelemeyi eksik bulur ve ulaşılamayacak bir sayıyı hedef
olarak koyar; ölçütün üst sınırı, ölçtüğü sürecin sınırıdır.

#### Kuyruğun Sağlığı

Üçüncü tablo aynı farkın tek bir değişikliğin dışında ne yaptığını gösteriyor. Ekip aynı
ekiptir, kapasite **3 eşzamanlı** incelemedir, her turda bir değişiklik gelir.

İnceleme turu sayısı **2** olduğunda kuyruk sağlıklıdır: on ikinci turda yalnız **2**
değişiklik açıktır, en uzun açık kalma **2 turdur** ve son değişiklik **14.** turda kapanır.
İnceleme turu sayısı **3** olduğunda sistem tam sınırdadır — kapasite 3, hizmet süresi 3 —
ve açık sayısı **3**'te durur.

İnceleme turu sayısı **6** olduğunda kuyruk bozulur. On ikinci turda **9** değişiklik
açıktır; en uzun açık kalma **2 turdan 15 tura** çıkar; son değişiklik **27.** turda kapanır.
Tek bir değişiklikte fark 2'ye karşı 6 iken, kuyrukta **2'ye karşı 15**'tir. Kapasite
tükendiğinde gecikme yalnız eklenmez, **birikir**.

Kuyruk sağlığının sade bir kuralı buradan çıkıyor: **inceleme turu sayısı kapasiteyi
aştığında kuyruk büyür.** Bu, incelemeye ayrılan kişi sayısıyla değil, bir incelemenin kaç
turda kapandığıyla ilgilidir — ve önceki üç ders o sayının nereden geldiğini tek tek
gösterdi.

Birikmenin aritmetiği de sadedir. Kapasite 3 ve hizmet süresi 6 iken sistem turda ancak
**0,5** değişiklik kapatabilir, oysa turda **1** değişiklik geliyor. Üstelik ilk kapanış
7. turdan önce olamaz; on ikinci turda gelen 12 değişikliğin yalnız **3**'ü kapanmıştır ve
**9**'u açıktır. Girişin durması bu birikimi hemen silmez: en son gelen değişikliğin sırası
21. turda gelir ve **27.** turda kapanır. **Kuyruk, bozulduğu hızda düzelmez.**

#### Üç Ölçütün Tek Başına Gizledikleri

Hiçbir ölçüt tek başına okunmaz, çünkü her biri iki ayrı nedenle aynı değeri alabilir.

**Kısa bekleme** iyi bir işaret olabilir ya da hiç okunmamış bir değişikliğin işareti
olabilir. Değişiklik boyutu dersinde 2400 satırlık bir inceleme de tek turda onaylanıyordu;
bulunan kusur **2**'ydi. Bekleme tek başına okunduğunda bu inceleme örnek görünür.

**Az inceleme turu** ya ilk turda çok bulunmasından gelir ya da hiçbir şeyin bulunmamasından.
İkisini ayıran şey ikinci tablonun son sütunudur: kalan kusur. Anlaşmazlık dersinde erteleme
kuralı **2 tur / 12 birim** veriyordu — tablonun en iyi satırıyla aynı — ama kodda **8** kusur
bırakıyordu.

**Sağlıklı kuyruk** ya hızlı kapanan incelemelerden gelir ya da kuyruğa hiç girmeyen
değişikliklerden. Üçünün ortak çaresi aynıdır: ölçütler **bulunan ve kaçan kusurla birlikte**
okunur. Bu konunun bütün tabloları bu yüzden iki tarafı da taşıdı.

#### Hangi Ölçüt Hangi Kararı Destekler

Bir ölçütün değeri, desteklediği karar kadardır. Üç ölçüt üç ayrı karara bakar ve
birbirinin yerine geçmez.

**İnceleme turu sayısı** eksen dağılımı kararını destekler. İkinci tablo bunu doğrudan
veriyor: aynı üç kişi aynı eksende 6 tur, ayrı eksenlerde 3 tur üretiyor. Tur sayısı
yükseldiğinde sorulacak soru "kim yavaş" değil, **hangi eksene bakılmıyor** olmalıdır.

**Bekleme süresi** değişiklik boyutu kararını destekler. Bekleme, inceleme turu sayısının
altı katıdır ve inceleme turu sayısını belirleyen şey ilk turda bulunandır; ilk turda
bulunanı en çok düşüren şey de okunmayan öbektir. Beklemenin uzaması, çoğu zaman incelemeye
gönderilen değişikliğin dikkate sığmadığının işaretidir.

**Kuyruk sağlığı** kapasite kararını destekler. Üçüncü tablo, hizmet süresinin kapasiteyi
aştığı anda birikmenin başladığını gösteriyor. Buradaki karar iki yönlüdür: ya inceleme turu
sayısı düşürülür ya da eşzamanlı inceleme kapasitesi artırılır. İkisinin maliyeti aynı
değildir — birincisi eksen dağılımıyla ve değişiklik boyutuyla ödenir, ikincisi başka işten
alınan zamanla.

Üçü birlikte okunduğunda tablo tek bir cümleye iner: **bulunanı artıran her düzeltme,
beklemeyi ve kuyruğu da düzeltir.** Ölçümde bunun tersi bir satır yoktur; en çok bulan iki
yapılandırma aynı zamanda en az bekleyen ve kuyruğu en sağlıklı olanlardır.

#### Özet

- Üç ölçüt sürecin ölçütleridir: bekleme süresi, inceleme turu sayısı ve inceleme kuyruğu
  sağlığı. Kişi başına raporlanmazlar, çünkü değerlerini üreten şey eksen atamasıdır —
  üç inceleyicinin 6 inceleme turu üretmesi, üçünün de işini eksiksiz yapmasına rağmen olur.
- Üç inceleyici aynı eksende **6** kusur bulur, **6 tur / 36 birim** tutar ve **3 kusur**
  kalır; tek inceleyici beş eksende **22** bulur, **2 tur / 12 birim** tutar, **0** kalır.
  Üç kat inceleyici, üç kat bekleme.
- İnceleme kuyruğunu uzatan şey inceleyici sayısı değil, **ilk turda görülemeyendir**: az
  bulunan, hem daha çok inceleme turu hem de sınırda kalan kusur üretir.
- Kapasitesi 3 olan bir kuyrukta inceleme turu sayısı 2 iken en uzun açık kalma **2 tur**,
  6 iken **15 turdur**; on ikinci turda açık değişiklik **2**'den **9**'a çıkar. Kapasite
  aşıldığında gecikme birikir.
- Dört yapılandırmanın dördü de **2** eksik gereksinim kusurunu kaçırır; bu, ölçütlerin
  okunduğu tabandır — incelemenin ulaşabileceği en çok kusur 24'ün 22'sidir.
- Hiçbir ölçüt tek başına okunmaz: kısa bekleme, az inceleme turu ve sağlıklı kuyruk hem en
  iyi hem en kötü durumda aynı değeri alabilir; ayıran şey bulunan ve kaçan kusurdur.

#### Sonraki Adım

Bu konuda inceleme hep **tek bir değişikliğin** çevresindeydi: bir değişiklik gelir,
okunur, notlar yazılır, kapanır. Üçüncü tablo o çemberin dışına ilk adımı attı ve
değişikliklerin birbirini beklediğini gösterdi. Peki değişikliğin kendisi bir başlangıç
değil, daha uzun bir zincirin **içindeki bir öğeyse**? Sonraki konu incelemeyi bu zincirin
bir durağı olarak ele alıyor: öğenin incelemeye gelmeden önce ve kapandıktan sonra nerede
durduğu ve incelemenin toplam sürede hangi payı tuttuğu.

## Ekip Akışı

İş öğesi yaşam döngüsü, dışarıdan katkının beklentilerini yazma, kod sahipliği ve zorunlu inceleyiciler, depo platformunun sınıf düzeyindeki yetenekleri, ve sürüm notu ile etiketin okura anlamı.

### İş Takibi ve Panolar

Source: https://academia.sh/tr/kurslar/kod-inceleme/is-takibi-ve-panolar

İş öğesinin durumları arasında geçen bekleme incelemenin dışında 19 birimdir; inceleme atamaya göre 12 ile 36 arasında değişir ve zincirin payının 0,387'sinden 0,655'ine çıkar, kalan üç kusur öğeyi panoya geri koyunca toplam 31'den 105'e gider.

Buraya kadar inceleme tek bir değişikliğin çevresinde ölçüldü: kaç eksene bakıldı, kaç öbek
okundu, kaç tur döndü. Değişiklik bu ölçümlerde tek başına duruyordu — bir yerden gelmiyor,
bir yere gitmiyordu. Oysa bir ekipte değişiklik yalnız bir değişiklik değildir; **bir akışın
içindeki bir öğedir.** Önce bir öneri olarak doğar, bir sıraya girer, biri onu üstlenir,
yazılır, incelenir, tümleşir ve kapanır.

Bu zincirde inceleme yalnız bir halkadır. Bu dersin sorusu şudur: **halkanın kendisi ne kadar
sürüyor ve zincirin tamamında payı ne?** İnceleme turunu kısaltmanın değerini bilmek için
önce turun neyin içinde durduğunu bilmek gerekir. Zincirin geri kalanı incelemeden uzunsa,
inceleme turunu yarıya indirmek toplamda az şey değiştirir.

#### İş Öğesi ve Durumları

**İş öğesi (work item)**, bir ekibin izlediği en küçük iş birimidir: bir hata kaydı, bir
istek, bir görev. Öğenin tek bir kimliği, tek bir sahibi ve her an tek bir **durumu** vardır.
**Pano (board)**, bu öğelerin durumlarına göre dizildiği yüzeydir; her sütun bir durumdur ve
öğe soldan sağa ilerler.

Pano bir kayıt aracı değil, bir **görünürlük** aracıdır. Aynı bilgi bir listede de durabilir;
panonun eklediği şey, hangi durumda kaç öğe biriktiğinin bakışta okunmasıdır. Bir sütunun
şişmesi, o durumdan çıkışın girişten yavaş olduğunu söyler.

```text
# örnek pano dökümü — çalıştırılmamıştır

öneri        sırada        yazılıyor     incelemede    tümleşti
─────────    ──────────    ──────────    ──────────    ──────────
#412         #398          #377          #361          #350
#411         #395          #374          #359
             #391                        #356
             #388                        #352
                                         #349
```

Durum kümesinin kendisi bir tasarım kararıdır ve tek ölçütü vardır: **bir durum, çıkışı
başkasının eylemine bağlı olduğunda anlamlıdır.** `incelemede` bir durumdur çünkü öğe orada
yazanın değil inceleyenin eylemini bekler. Çıkışı hep aynı kişinin elinde olan bir sütun ise
durum değil, o kişinin özel listesidir; panoda yer kaplar ve hiçbir bekleme bildirmez. Aynı
ölçüt sütun sayısını da sınırlar: her yeni durum ancak yeni bir devir noktası varsa eklenir.

Bu dökümde `incelemede` sütunu beş öğe taşıyor, `yazılıyor` iki. Sayının kendisi bir kusur
değildir; kusur, sütunun **boşalma hızının** dolma hızından düşük olmasıdır. Beş öğe orada
biriktiyse **inceleme kuyruğu (review queue)** uzuyor demektir ve kuyruğun uzaması öğelerin
her birine bekleme yazar.

#### Bekleme Durumda Değil Geçişte Durur

Panonun kolay yanılttığı nokta budur. Bir öğe `incelemede` sütununda dururken geçen zamanın
tamamı inceleme değildir; bir bölümü **inceleyenin öğeye bakmasını beklemektir.** Ölçülecek
şey öğenin bir sütunda durduğu süre değil, bir sütundan diğerine **geçmesi için geçen
süredir.**

Bu ayrım ölçümü tanımlar. Zincirde beş geçiş vardır ve bunların dördü incelemenin dışındadır:
öneri sıraya girer, sıradan biri onu üstlenir, yazım biter ve öğe incelemeye çıkar, inceleme
biter ve öğe kapanır. Beşinci geçiş — `incelemede` durumundan `tümleşti` durumuna — incelemenin
kendisidir ve **sabit değildir**: kaç tur döndüğüne bağlıdır.

**Bekleme süresi (wait time)** burada birimsiz sayılır. Saat ya da gün değil, karşılaştırılabilir
bir birimdir; amaç mutlak süreyi değil, halkaların birbirine oranını okumaktır. Bu ölçütler
**sürecin** ölçütleridir: bir öğenin ne kadar beklediği, o öğeye bakan kişinin değil, zincirin
biçiminin sonucudur.

#### Sütun Uzunluğu ile Bekleme Aynı Şey Değildir

Panonun `incelemede` sütununda duran beş öğe bir **birikimdir**; geçişte ölçülen bekleme ise
bir **hızdır**. İkisi aynı sayıyı vermez. Beş öğelik bir sütun, çıkış hızı birim başına beş
öğeyse tek birimlik bekleme demektir; çıkış hızı birim başına bir öğeyse beş birimlik bekleme
demektir. Sütuna bakan biri iki durumu ayırt edemez, çünkü pano birikimi gösterir ve hızı
göstermez.

Bunun doğrudan sonucu şudur: **sütunu kısaltmak beklemeyi kısaltmaz.** Beş öğeden ikisini
başka bir sütuna taşımak birikimi düşürür ve panoyu rahatlatır; geçişin ne kadar sürdüğüne
dokunmaz. Beklemeyi kısaltan tek şey geçişin kendisini hızlandırmaktır ve inceleme halkasında
bunun anlamı tur sayısını düşürmektir.

Bir ayrım daha gerekiyor. Bir iş öğesi birden çok değişiklik taşıyabilir; o zaman inceleme
halkası öğe başına birden çok kez yürür ve zincirin toplamı buna göre büyür. Bu ölçüm öğe
başına **tek** değişiklik sayar ve sayıları o varsayımla verir. Öğe üç değişikliğe bölünmüşse
inceleme dışı geçişler bir kez, inceleme halkası üç kez ödenir — payı da o oranda büyür. Bu,
öğeleri bölmenin bedava olmadığını söyler: bölme incelemeyi kolaylaştırır ama zincirdeki
inceleme payını yükseltir.

#### İncelemenin Zincirdeki Yeri

İnceleme halkasının uzunluğunu ne belirler? Kursun beşinci okuması bunu söylüyordu: **turu ve
beklemeyi uzatan şey ilk turda görülemeyendir.** Bir turda bulunanlar düzeltilir; bulunmayanlar
sonraki tura kalır ve her tur zincire bir bekleme daha yazar. Eksen çeşitliliği düşükse ilk tur
az bulur, tur sayısı artar, halka uzar.

Dolayısıyla zincirin toplamı iki kaynaktan beslenir. Biri **sabit** kısımdır — öneri, sıra,
yazım ve kapanış geçişleri; bunlar incelemenin nasıl yapıldığından bağımsızdır. Diğeri
**değişken** kısımdır ve doğrudan eksen atamasının sonucudur. Ölçüm bu ikisini ayrı sayar ve
oranlarını verir.

Bir kusur daha vardır: turlar bittiğinde **kalan kusur**. Kalan kusur inceleme bitmiş, öğe
kapanmış demek değildir; kapanan öğe daha sonra o kusur yüzünden **yeniden açılır** ve zincire
ikinci kez girer. Bu ikinci geçiş öneriyle başlamaz — öğe zaten önerilmiştir — ama sıradan
itibaren her şeyi tekrarlar.

Ölçümün varsayımları:

- **EA1** — Ortak tanımın 600 satırlık değişikliği ve 24 kusuru olduğu gibi kullanılır; sınıf
  dağılımı ve kâhin kursun sabitidir.
- **EA2** — İnceleme dışı dört geçişin beklemesi sabittir ve atamadan bağımsızdır: sırasıyla
  **5**, **9**, **2** ve **3** birim. Bu değerler zincirin biçimini temsil eder, bir ekibin
  ölçümü değildir.
- **EA3** — İnceleme halkasının beklemesi ortak tanımın tur döngüsünden gelir: her tur
  **6 birim** yazar ve tur sayısı ilk turda bulunan kusur sayısının sonucudur.
- **EA4** — Bulunan kusur o turda düzeltilmiş sayılır; kalan kusur sonraki tura taşınır. Altı
  tur üst sınırdır ve bu sınıra dayanan atamada kusur kalır.
- **EA5** — Kalan kusur öğeyi kapandıktan sonra **bir kez** yeniden açar. İkinci geçiş
  `sırada` durumundan başlar; öneri geçişi tekrarlanmaz.
- **EA6** — Ölçüt öğe başına raporlanır, kişi başına değil. Zincirdeki hiçbir sayı bir rolün
  başarımı olarak okunamaz; hepsi zincirin biçiminin sonucudur.
- **EA7** — Kümenin çözünürlüğü 24 kusurda **1/24**'tür; bekleme birimi tur başına **6** olduğu
  için zincirde ölçülebilen en küçük fark **6** birimdir.

#### Ölçüm

```python
"""Is ogesi zinciri: durumlar arasi bekleme ve incelemenin payi.

Bolum 1 - dort atamada bulunan, kacan ve inceleme beklemesi.
Bolum 2 - zincirin toplami, incelemenin payi ve yeniden acilma bedeli.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT, OBEK = 12, 50
# Incelemenin disinda kalan gecisler: pano uzerinde okunan bekleme.
DIS = (("öneri", "sırada", 5), ("sırada", "yazılıyor", 9),
       ("yazılıyor", "incelemede", 2), ("tümleşti", "kapandı", 3))


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=6):
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


TAM = set(EKSENLER)
ATAMALAR = {
    "tek inceleyici, tüm eksenler": [TAM],
    "üç inceleyici, aynı eksen": [{"gerceklestirim"}] * 3,
    "üç inceleyici, ayrı eksen": [{"arayuz"}, {"gerceklestirim"}, {"test", "belge"}],
    "beş inceleyici, beş eksen": [{e} for e in EKSENLER],
}
DIS_TOPLAM = sum(b for _, _, b in DIS)
d = degisiklik(600)

print(f"iş öğesi 1 | değişiklik {d['satir']} satır, {d['obek']} öbek, "
      f"kusur {len(d['kusurlar'])} | inceleme dışı bekleme {DIS_TOPLAM}")
print("inceleme dışı geçişler: "
      + ", ".join(f"{a}→{b} {n}" for a, b, n in DIS))
print()
print(f"{'atama':<30s} {'bulunan':>7s} {'kaçan':>5s} {'yazılmayan':>10s} "
      f"{'tur':>3s} {'inceleme':>8s} {'kalan':>5s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    print(f"{ad:<30s} {len(b):7d} {len(kacan):5d} {yaz:10d} "
          f"{tur:3d} {bekleme:8d} {kalan:5d}")

print()
print(f"{'atama':<30s} {'zincir':>6s} {'inceleme payı':>13s} "
      f"{'yeniden açılma':>14s} {'toplam':>6s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    zincir = DIS_TOPLAM + bekleme
    # Kalan kusur öğeyi panoya geri koyar: sırada durumundan başlayan ikinci tur.
    yeniden = 0 if kalan == 0 else zincir - DIS[0][2]
    print(f"{ad:<30s} {zincir:6d} {bekleme / zincir:13.3f} "
          f"{yeniden:14d} {zincir + yeniden:6d}")
```

```
iş öğesi 1 | değişiklik 600 satır, 12 öbek, kusur 24 | inceleme dışı bekleme 19
inceleme dışı geçişler: öneri→sırada 5, sırada→yazılıyor 9, yazılıyor→incelemede 2, tümleşti→kapandı 3

atama                          bulunan kaçan yazılmayan tur inceleme kalan
tek inceleyici, tüm eksenler        22     2          2   2       12     0
üç inceleyici, aynı eksen            6    18          2   6       36     3
üç inceleyici, ayrı eksen           15     9          2   3       18     0
beş inceleyici, beş eksen           22     2          2   2       12     0

atama                          zincir inceleme payı yeniden açılma toplam
tek inceleyici, tüm eksenler       31         0.387              0     31
üç inceleyici, aynı eksen          55         0.655             50    105
üç inceleyici, ayrı eksen          37         0.486              0     37
beş inceleyici, beş eksen          31         0.387              0     31
```

#### Zincirin Okunması

İnceleme dışı bekleme **19** birimdir ve dört satırın dördünde de aynıdır. Değişen tek şey
inceleme halkasıdır ve o **12** ile **36** arasında gidiyor. Zincirin toplamı böylece **31**
ile **55** arasında oynuyor: en kötü atama, en iyisinden **%77** daha uzun bir zincir üretiyor.

İncelemenin payı sağdaki sütunda. En iyi atamada zincirin **0,387**'si inceleme; yani öğenin
beklemesinin yaklaşık üçte ikisi incelemenin dışında geçiyor. En kötü atamada pay **0,655**'e
çıkıyor — inceleme artık zincirin yarısından fazlası. Bu iki sayının arasındaki fark bir
sonuç veriyor: **inceleme sabit maliyetli bir halka değil, zincirin en oynak halkasıdır.**

Buradan pratik bir sıralama çıkar. `sırada→yazılıyor` geçişi **9** birimle inceleme dışı en
uzun halkadır ve iyi atamada tek başına inceleme halkasının dörtte üçü kadardır. Zincirin en
iyi durumunda kısaltılacak yer inceleme değil, sıradır. Ama kötü atamada inceleme **36**
birimdir ve sıranın dört katıdır; orada sırayı kısaltmanın toplama katkısı küçük kalır.
**Hangi halkanın kısaltılacağı, atamanın hangisi olduğuna bağlıdır** ve bunu panodaki sütun
uzunluğu değil, geçiş beklemesi söyler.

Soldaki tablo aynı satırlarda bulunan ve kaçan sayısını da veriyor ve ikisi birlikte okunmalı.
`üç inceleyici, aynı eksen` satırı **6** bulup **18** kaçırıyor; zincirin en uzun olduğu satır,
aynı zamanda en az bulan satır. `tek inceleyici, tüm eksenler` **22** bulup **2** kaçırıyor ve
zincirin en kısası. Yani uzun zincir daha iyi bir inceleme satın almıyor — **uzunluğun kaynağı
zaten bulunamayanlardır.**

Kaçanların içinde her satırda **2** tane **eksik gereksinim** kusuru var ve bu sayı dört
satırda da değişmiyor. Zincirin biçimi, atamanın çeşitliliği, tur sayısı — hiçbiri o iki
kusuru bulmuyor. İş takibi bu sınıfın çaresi değildir; öğe panoda ne kadar iyi izlenirse
izlensin, gönderilmemiş olanın yokluğu incelemeye görünmez.

#### Yeniden Açılma

İkinci tablonun son iki sütunu zincirin gerçek maliyetini veriyor. `üç inceleyici, aynı eksen`
atamasında altı tur sonunda **3** kusur hâlâ duruyor. Öğe kapanmıştır; kusurlar kapanmamıştır.
Kalan kusur eninde sonunda bir yerde ortaya çıkar ve öğe **yeniden açılır**.

Yeniden açılma zincire **50** birim ekliyor: öneri dışındaki her geçiş bir kez daha yürüyor.
Toplam **55**'ten **105**'e çıkıyor. Aynı değişiklik, en iyi atamada **31** birimde kapanıyor;
buradaki fark **74** birim, yani üç kat fazlası.

Bu sayının okunma biçimi önemlidir. Yeniden açılma bir gecikme değil, **ertelenmiş bir
beklemedir**: zincirin ilk geçişinde ödenmeyen bekleme, ikinci geçişte faiziyle ödenir. Panoya
bakan biri ilk geçişte hiçbir sorun görmez — öğe kapanmıştır, sütun boşalmıştır, sayılar
temizdir. Sorun panoda, öğe geri döndüğünde belirir ve o an artık ilk incelemenin ölçümüyle
ilişkilendirilmez.

Bu yüzden bir panonun okunabilmesi için kapanan öğe sayısı tek başına yetmez. **Yeniden açılan
öğe sayısı ayrı bir sütun ya da ayrı bir sayım olarak durmalıdır;** yoksa zincirin en pahalı
davranışı hiçbir yerde görünmez. Kapanış sayısı, ilk geçişte kapanan ile ikinci geçişte
kapananı ayırmadığı sürece iki farklı süreci aynı sayıyla raporlar.

#### Özet

- **İş öğesi** bir akıştaki en küçük iş birimidir; **pano** öğeleri durumlarına göre dizer ve
  bekleme durumların içinde değil, durumlar arasındaki **geçişlerde** birikir.
- Zincirin inceleme dışı beklemesi **19** birimle sabittir; inceleme halkası atamaya göre
  **12** ile **36** arasında değişir ve zincirin toplamını **31**'den **55**'e taşır.
- İncelemenin zincirdeki payı **0,387** ile **0,655** arasındadır; inceleme sabit maliyetli bir
  halka değil, zincirin en oynak halkasıdır ve hangi halkanın kısaltılacağı atamaya bağlıdır.
- Uzun zincir daha iyi bir inceleme satın almaz: **36** birimlik halka **6** kusur bulup **18**
  kaçırır, **12** birimlik halka **22** bulup **2** kaçırır.
- Altı tur sonunda kalan **3** kusur öğeyi yeniden açar ve zincire **50** birim daha ekler;
  toplam **105**'e çıkar. Kapanış sayısı bu ikinci geçişi ayrı saymadıkça gizler.
- Dört atamanın dördünde de **2** **eksik gereksinim** kusuru kaçar; iş takibi bu sınıfı
  bulmaz.

#### Sonraki Adım

Bu ölçümde öğeyi yazanın ne göndereceğini bildiği varsayıldı: zincire giren değişiklik, ekibin
beklentilerini karşılamaya çalışılarak yazılmış bir değişiklikti. Peki yazan o beklentileri
nereden biliyor? Ekibin içindeki biri onları turlarda öğrenmiştir; dışarıdan gelen biri
öğrenmemiştir. Yazılmamış bir beklenti, incelemenin ilk turunda bir bulgu olarak geri döner ve
her bulgu bir tur daha yazar. Sonraki ders bu beklentilerin yazılı hâlini ölçer: **katkı
rehberi** hangi sınıfları incelemeden önce kapatır, kapattığı her sınıf kaç tur eksiltir ve
hiçbir eksenin aramadığı sınıfa dokunabilen tek düzenek gerçekten rehber midir?

### Katkı Rehberleri

Source: https://academia.sh/tr/kurslar/kod-inceleme/katki-rehberleri

Yazılı beklenti incelemeden önce çalışır: dar bir incelemede rehberin kapsamı büyüdükçe tur 6'dan 5, 4, 3 ve 2'ye iner, geniş incelemede tur 2'de sabit kalır ve gereksinim beyanı isteyen rehber kaçan 24'lük kümede ilk kez 0'a düşürür.

Önceki ders iş öğesinin zincirini ölçtü ve inceleme halkasının uzunluğunun tur sayısından
geldiğini gösterdi. Turu uzatan şey ilk turda görülemeyendir; peki bir bulgunun ilk turda
görülmesi gerekmeyen bir türü var mı? Var: **yazan zaten biliyorsa hiç bulgu olmaz.**

Bir ekibin içinde çalışan biri beklentilerin çoğunu daha önceki turlarda öğrenmiştir. Dışarıdan
gelen biri öğrenmemiştir ve aynı beklentiyi kendi turlarında yeniden öğrenir. **Katkı rehberi
(contribution guide)**, bu öğrenmeyi turdan önceye taşıyan yazılı metindir. Bu dersin sorusu
rehberde ne yazacağı değil — **yazılı her beklentinin kaç tur eksilttiğidir** ve rehberin hiç
dokunamadığı bir yer olup olmadığıdır.

#### Beklenti Nerede Öğrenilir

Bir beklenti üç yerden öğrenilebilir. **Rehberden**: yazan değişikliği göndermeden önce okur ve
uyar. **Turdan**: inceleyen bulguyu yazar, yazan düzeltir, değişiklik yeniden gönderilir.
**Hiçbir yerden**: beklenti kimsenin aklına gelmez ve değişiklik öyle tümleşir.

Üçünün maliyeti aynı değildir. Rehberden öğrenilen beklenti sıfır tur harcar; bulgu hiç
doğmadığı için inceleme kuyruğuna hiç girmez. Turdan öğrenilen beklenti en az bir tur harcar ve
her tur zincire bekleme yazar. Hiç öğrenilmeyen beklenti tur harcamaz ama kusur olarak kalır.

Rehberin ölçülebilir etkisi bu yüzden **tur sayısında** aranır, bulunan kusur sayısında değil.
Rehber incelemenin gözünü açmaz; incelemeye gelen kusuru azaltır. Bu ayrım kursun ikinci
iddiasının aynadaki görüntüsüdür: eksen eklemek **bulunanı** büyütür, rehber **gireni** küçültür.

Üçüncü yolun — hiç öğrenilmeyen beklentinin — bu ölçümde bir karşılığı vardır ve o **eksik
gereksinim** sınıfıdır. Kimsenin yazmadığı, kimsenin sormadığı beklenti hiçbir eksende görünmez
ve hiçbir turda konuşulmaz. Rehberin en ilginç sorusu da buradadır: yazılı bir metin, hiç
konuşulmayan bir sınıfa dokunabilir mi?

#### Rehberde Ne Yazılı Olabilir

Rehber bir üslup metni değil, bir **kabul koşulu listesidir**. Her maddesi, karşılanmadığında
bir inceleme turu doğuracak bir beklentiyi adlandırır. İyi yazılmış bir madde, yazanın
göndermeden önce kendi başına doğrulayabileceği bir şey söyler.

```text
# örnek katkı rehberi parçası — çalıştırılmamıştır

## Göndermeden önce
- Biçim: depo kökündeki biçim ayarı uygulanmış olmalı; elle biçim
  düzeltmesi ayrı bir değişiklik olarak gönderilir.
- Test: değiştirilen her genel davranış için en az bir doğrulayan
  test bulunmalı; yalnız çağrıyı tekrarlayan test sayılmaz.
- Belge: genel arayüz değiştiyse ilgili belge aynı değişiklikte
  güncellenir.
- Gereksinim beyanı: değişikliğin karşıladığı gereksinim, iş öğesi
  numarasıyla ve tek cümleyle açıklama alanına yazılır; karşılanmayan
  gereksinim varsa o da yazılır.

## İnceleme
- Bir değişiklik tek bir gereksinimi karşılar.
- Açıklama alanı boş gönderilen değişiklik incelemeye alınmaz.
```

Maddelerin yazımı ölçülebilirliği belirler. "Testler anlamlı olmalı" bir madde değildir; yazan
onu göndermeden önce denetleyemez ve inceleyen ondan bir bulgu türetemez. "Değiştirilen her
genel davranış için en az bir doğrulayan test bulunmalı" ise denetlenebilir bir koşuldur: bakış
açısı değişse de yanıtı evet ya da hayırdır. Aynı fark ikinci bölümde de görünür — "açıklama
alanı boş gönderilen değişiklik incelemeye alınmaz" bir kapıdır ve uygulanabilir; "açıklamalar
yeterli olmalı" bir dilektir.

Dört maddenin ilk üçü kolay tanınır: biçim, test ve belge, incelemenin baktığı beşin üçüdür.
Dördüncü madde başkadır ve ölçümün asıl sorusu odur. **Gereksinim beyanı**, yazandan
değişikliğin ne yapması gerektiğini yazmasını ister. İnceleme yazılana bakar; rehber, yazanı
**gereksinimin kendisini yazmaya** zorlayarak incelemenin bakabileceği yüzeyi genişletir.

Ölçümün varsayımları:

- **EA8** — Ortak tanımın 600 satırlık değişikliği ve 24 kusuru olduğu gibi kullanılır; sınıf
  dağılımı ve kâhin kursun sabitidir. `degisiklik` değiştirilmez.
- **EA9** — Rehber incelemeden **önce** çalışır: kapsamındaki sınıfların kusurları yazan
  tarafından gönderilmeden giderilir ve incelemeye hiç girmez. Rehber bir eksen değildir; kusur
  bulmaz, kusurun doğmasını engeller.
- **EA10** — Rehberin kapsamı bir sınıf listesidir. Dört kapsam denenir ve her biri bir
  öncekinin üstüne bir sınıf ekler; beşincisi **eksik gereksinim** sınıfını ekler.
- **EA11** — Kapsamdaki her sınıfın **bütün** kusurları giderilir. Bu bir üst sınırdır; kısmen
  uyulan bir rehberin etkisi bu sayıların altında kalır.
- **EA12** — İnceleme iki atamayla yürütülür: beş eksene bakan tek inceleyen ve aynı eksene
  bakan üç inceleyen. Dikkat **12 öbekte** sabittir ve 600 satır 12 öbektir; okunmayan öbek
  yoktur.
- **EA13** — Tur döngüsü ortak tanımdan gelir ve tur başına **6 birim** bekleme yazar. Turun
  girdisi artık 24 değil, rehberden geçen kusur sayısıdır.
- **EA14** — Kümenin çözünürlüğü 24 kusurda **1/24**'tür; tur ölçeğinde ölçülebilen en küçük
  fark **1 tur**, yani **6 birim** beklemedir.

#### Ölçüm

```python
"""Katki rehberi: yazili beklentinin kapattigi inceleme turu.

Rehber incelemeden once calisir: kapsamindaki siniflarin kusurlarini
yazan gondermeden giderir. Degisiklik ve sinif listesi degismez.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT, OBEK = 12, 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def rehberden_gecen(d, kapsam):
    """Rehberin kapsamindaki sinif gonderilmeden once giderilir."""
    return [k for k in d["kusurlar"] if k["sinif"] not in kapsam]


def incele(kusurlar, obek, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, obek)))
    return {k["no"] for k in kusurlar
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(kusurlar, obek, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(kusurlar, obek, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=6):
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


TAM = set(EKSENLER)
REHBERLER = {
    "rehber yok": set(),
    "biçim yazılı": {"bicim"},
    "biçim, test": {"bicim", "test"},
    "biçim, test, belge": {"bicim", "test", "belge"},
    "üçü + gereksinim beyanı": {"bicim", "test", "belge", YAZILMAYAN},
}
ATAMALAR = {"tek inceleyici, tüm eksenler": [TAM],
            "üç inceleyici, aynı eksen": [{"gerceklestirim"}] * 3}
d = degisiklik(600)
dagilim = {s: sum(1 for k in d["kusurlar"] if k["sinif"] == s) for s in SINIFLAR}
print("sınıf dağılımı: " + ", ".join(f"{s} {n}" for s, n in dagilim.items()))

for atama_adi, atama in ATAMALAR.items():
    print()
    print(atama_adi)
    print(f"{'rehber kapsamı':<25s} {'giderilen':>9s} {'giren':>5s} "
          f"{'bulunan':>7s} {'kaçan':>5s} {'yazılmayan':>10s} {'tur':>3s} "
          f"{'bekleme':>7s} {'kalan':>5s}")
    for ad, kapsam in REHBERLER.items():
        giren = rehberden_gecen(d, kapsam)
        b = kurul(giren, d["obek"], atama)
        kacan = [k for k in giren if k["no"] not in b]
        yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
        tur, bekleme, kalan = tur_dongusu(b, len(giren))
        print(f"{ad:<25s} {24 - len(giren):9d} {len(giren):5d} {len(b):7d} "
              f"{len(kacan):5d} {yaz:10d} {tur:3d} {bekleme:7d} {kalan:5d}")
```

```
sınıf dağılımı: arayuz 3, gerceklestirim 6, test 3, belge 3, bicim 7, eksik gereksinim 2

tek inceleyici, tüm eksenler
rehber kapsamı            giderilen giren bulunan kaçan yazılmayan tur bekleme kalan
rehber yok                        0    24      22     2          2   2      12     0
biçim yazılı                      7    17      15     2          2   2      12     0
biçim, test                      10    14      12     2          2   2      12     0
biçim, test, belge               13    11       9     2          2   2      12     0
üçü + gereksinim beyanı          15     9       9     0          0   1       6     0

üç inceleyici, aynı eksen
rehber kapsamı            giderilen giren bulunan kaçan yazılmayan tur bekleme kalan
rehber yok                        0    24       6    18          2   6      36     3
biçim yazılı                      7    17       6    11          2   5      30     0
biçim, test                      10    14       6     8          2   4      24     0
biçim, test, belge               13    11       6     5          2   3      18     0
üçü + gereksinim beyanı          15     9       6     3          0   2      12     0
```

#### Turların Okunması

İki tablo aynı rehberleri iki ayrı inceleme altında ölçüyor ve sonuçları taban tabana zıt.

**Dar incelemede** — üç inceleyen aynı eksene bakıyor — rehber her sınıf eklendiğinde bir tur
eksiltiyor: **6, 5, 4, 3, 2**. Bekleme **36**'dan **12**'ye iniyor; üçte ikisi kalkıyor. Bulunan
sütunu ise beş satırın beşinde de **6**'da duruyor. Rehber bir tek kusur daha buldurmadı; yalnız
turların yiyeceği kusuru azalttı ve döngüyü erken bitirdi.

**Geniş incelemede** — tek inceleyen beş eksene birden bakıyor — ilk dört satır **2 tur / 12
bekleme** ile aynı. Kapsam üç sınıfa çıksa bile tur sayısı kımıldamıyor. Nedeni tablonun
solunda: bu incelemede kaçan zaten **2**'de sabit ve döngü ikinci turda bitiyor; kısaltacak tur
yok. Rehber burada turu değil, **turun içindeki işi** azaltıyor — giren **24**'ten **11**'e,
bulunan **22**'den **9**'a iniyor.

Geniş incelemenin beşinci satırı bu sabitliği kırıyor: tur **1**'e, bekleme **6**'ya iniyor.
Kursta bir turda kapanan tek yapılandırma budur. Nedeni tabloda okunuyor — kaçan **0**. Döngü
ikinci tura ancak kalan kusur varsa geçer; kalan yoksa ilk tur onaydır ve iş biter.

Buradan iki cümlelik bir sonuç çıkar. **Katkı rehberi, incelemenin dar olduğu yerde tur satın
alır; geniş olduğu yerde iş azaltır.** İki kazanç da gerçektir ama aynı şey değildir ve aynı
sayıya bakılarak görülmez: birincisi bekleme sütununda, ikincisi giren sütununda okunur.

İlk satırdaki **6 tur / 36 bekleme / 3 kalan** ile ikinci satırdaki **5 tur / 30 bekleme /
0 kalan** arasındaki fark ayrıca dikkate değer. Tek bir sınıfın rehbere yazılması yalnız bir tur
eksiltmedi; **kalan kusuru da sıfırladı.** Döngü altı tur sınırına dayanmadan bittiği için
kapanmamış kusur kalmadı. Önceki dersin ölçtüğü **50** birimlik yeniden açılma bedeli bu satırda
ortadan kalkıyor.

#### Rehberin Yazılmayana Uzanması

Beşinci satır kursun boyunca ilk kez başka bir şey gösteriyor. **Eksik gereksinim** sınıfı
şimdiye kadar her yapılandırmada **2** kaçanla duruyordu; burada **0**. Kaçan toplamı da geniş
incelemede **0**'a iniyor — 24 kusurluk kümede kaçanın sıfırlandığı tek satır budur.

Bunun nedeni bir eksenin nihayet o sınıfa bakması değildir. Eksen listesi değişmedi; hiçbir
inceleyen yeni bir yere bakmıyor. Değişen şey, **kusurun sınıfının değişmesidir.** Gereksinim
beyanı istendiğinde yazan, değişikliğin ne yapması gerektiğini metne yazar; yazılmamış olan
yazılmış olur ve artık incelemenin bakabildiği bir yüzeyde durur.

Bu, kursun dördüncü okumasının tek gerçek karşı örneğidir ve okumayı çürütmez, sınırını
belirler. **Hiçbir eksen yazılmayanı görmez** doğrudur; çare ekseni değiştirmek değil,
**yazılmayanı yazdırmaktır.** İnceleme sürecinin dışında duran bir düzenek — bir rehber
maddesi — incelemenin göremediği sınıfı incelemenin görebileceği sınıfa çevirir.

Ölçünün çözünürlüğüne dikkat: iki kusur, 24'lük kümede **2/24**'tür. Bu, kümenin en küçük
biriminin iki katıdır ve savunulabilir. Bir kusurluk bir fark bu kümeyle savunulamazdı.

#### Rehberin Okunduğu An

Ölçüm bir üst sınırı veriyor. **EA11** kapsamdaki her sınıfın bütün kusurlarının giderildiğini
varsayıyor; gerçekte uyulma oranı bunun altındadır ve tablodaki kazançlar aynı oranda küçülür.
Biçim kusurlarının yarısı giderilseydi giderilen **7** değil **3** ya da **4** olurdu, dar
incelemede tur **5** yerine **6**'da kalabilirdi. Rehberin değeri metnin içeriğinden çok
**kaçının uyulduğuna** bağlıdır.

Uyulma oranını belirleyen şey rehberin nerede okunduğudur. Depo kökünde duran ve bir kez okunan
bir metin, gönderme anından uzaktır; o an geldiğinde madde hatırlanmaz. Aynı maddenin
gönderme yüzeyinde bir denetim listesi olarak karşıya çıkması, metni her gönderimde yeniden
okutur. İkisi aynı cümleyi taşır ve aynı sonucu vermez.

İkinci belirleyici, maddenin doğrulanabilirliğidir. Yazanın kendi başına denetleyemediği bir
madde atlanır; atlanan madde yalnız kendi kazancını kaybettirmez, listenin tamamının okunma
alışkanlığını da zayıflatır. Bu yüzden rehberi uzatmak ters yönde çalışabilir: kırk maddelik bir
listede uyulan madde oranı, dört maddelik bir listedekinden düşüktür.

Ölçüm bunun için bir eşik verir. Bir maddenin tabloda görünen en küçük etkisi **1 tur**, yani
**6 birim** beklemedir. Hiçbir kapsamda tur ya da giren sayısını değiştirmeyen bir madde,
rehberde yer kaplar ve ölçülebilir bir karşılığı yoktur.

#### Rehberin Kapatamadığı

Beşinci satır dar incelemede de kaçanı **3**'e indiriyor ama sıfırlamıyor. Kalan üç kusur
`gerceklestirim` dışındaki eksenlerde duruyor ve rehberin kapsamına girmiyor: **arayuz** sınıfı
her iki tabloda da hiçbir rehber maddesiyle kapatılmadı.

Bunun bir nedeni var. Rehber, yazanın **kendi başına doğrulayabileceği** beklentileri yazabilir.
Biçim ayarının uygulanıp uygulanmadığı, testin var olup olmadığı, belgenin güncellenip
güncellenmediği — üçü de gönderilmeden önce tek başına denetlenebilir. Bir arayüz kararının
doğru olup olmadığı ise ancak başka biri tarafından değerlendirilebilir; rehbere yazılabilecek
hâli yoktur, çünkü kabul koşulu değil **yargı** gerektirir.

Sınır bu yüzden keskindir: **rehber, denetlenebilir beklentileri kapatır; yargı gerektiren
eksenler incelemede kalır.** Rehberi şişirmek bu sınırı aşmaz, yalnız okunmaz bir metin üretir
ve okunmayan madde hiçbir tur eksiltmez — tabloda görünmeyen bu satırın değeri her zaman
**0 tur**'dur.

#### Özet

- **Katkı rehberi** beklentiyi turdan önceye taşır: kapsamındaki sınıfın kusurları incelemeye
  hiç girmez. Rehber bir eksen değildir; bulunanı büyütmez, gireni küçültür.
- Dar incelemede rehber kapsamı büyüdükçe tur **6, 5, 4, 3, 2** olarak iner ve bekleme
  **36**'dan **12**'ye düşer; bulunan beş satırın beşinde de **6**'da kalır.
- Geniş incelemede tur ilk dört satırda **2**'de sabittir; rehber orada tur değil iş azaltır —
  giren **24**'ten **11**'e, bulunan **22**'den **9**'a iner.
- Tek bir sınıfın yazılması dar incelemede kalan kusuru **3**'ten **0**'a indirir ve önceki
  dersin **50** birimlik yeniden açılma bedelini ortadan kaldırır.
- **Gereksinim beyanı** isteyen rehber, **eksik gereksinim** kaçanını **2**'den **0**'a
  düşürür; sınıf incelemenin görebileceği yüzeye taşındığı için, yeni bir eksen eklendiği için
  değil.
- Rehber yalnız yazanın tek başına doğrulayabileceği beklentileri kapatır; **arayuz** gibi yargı
  gerektiren eksenler her kapsamda incelemede kalır.

#### Sonraki Adım

Rehber kimin neyi yapacağını değil, **neyin karşılanacağını** yazar. Değişiklik gönderildikten
sonra bir soru daha doğar: **kim bakacak?** Kimi depoda bu soru serbesttir, kimi depoda dosya
yoluna bağlı bir kural yanıtlar — bir dizinin sahibi vardır ve o dizine dokunan her değişiklik
sahibinin onayını bekler. Sonraki ders bu kuralı ölçer: **kod sahipliği** ve **zorunlu
inceleyen**, eksen çeşitliliğini artırır mı yoksa daraltır mı? Zorunlu inceleyen sayısını
üçe çıkarmak bulunanı büyütür mü — yoksa kursun ikinci iddiası burada tersinden mi görünür?

### Sahiplik ve Onay Kuralları

Source: https://academia.sh/tr/kurslar/kod-inceleme/sahiplik-ve-onay-kurallari

Zorunlu inceleyen sayısını bire, ikiye ve üçe çıkarmak bulunanı 6'da, turu 6'da ve beklemeyi 36'da sabit bırakır; tek serbest onay aynı değişiklikte 22 bulur ve kursun ikinci iddiası burada tersinden görünür — sahiplik bir kişi seçimi değil, bir eksen seçimidir.

Önceki ders katkı rehberini ölçtü: yazılı beklenti incelemeye giren kusuru azaltıyor ve dar
incelemede tur satın alıyordu. Rehber neyin karşılanacağını yazar. Değişiklik gönderildikten
sonra ise başka bir soru doğar ve rehber onu yanıtlamaz: **kim bakacak?**

Kimi depoda bu soru serbesttir; kimi depoda dosya yoluna bağlı bir kural yanıtlar. Bir dizinin
**sahibi** vardır ve o dizine dokunan her değişiklik sahibinin onayını bekler. Bu dersin sorusu
kuralın adil olup olmadığı değil — **kuralın kaç eksen açtığı** ve açtığı eksen sayısının bulunan
kusura ne yaptığıdır.

#### Kod Sahipliği Bir Yol Kuralıdır

**Kod sahipliği (code ownership)**, deponun bölümlerini rollere bağlayan bir eşlemedir. Kural
metni yolları ve rolleri listeler; bir değişiklik gönderildiğinde dokunduğu yollara bakılır ve
karşılık gelen roller **zorunlu inceleyen (required reviewer)** olarak eklenir.

```text
# örnek sahiplik kuralı — çalıştırılmamıştır

# yol öneki            zorunlu inceleyen rolü
/                      bakım
/cekirdek/             çekirdek-sahibi
/cekirdek/protokol/    protokol-sahibi
/belge/                belge-sahibi
```

Üç özellik hemen görünür. Kural **yola** bakar, değişikliğin içeriğine değil: `/cekirdek/`
altındaki bir yazım düzeltmesi de çekirdek sahibini çağırır. Kural **en özgül eşleşmeyi**
uygular: `/cekirdek/protokol/` altındaki bir değişiklik protokol sahibini çağırır. Ve kural bir
**kapıdır**: sahip onaylamadan değişiklik tümleşmez.

Kuralın yola bakması iki yönlü çalışır. Bir yandan otomatiktir ve unutulmaz: kimse "buna kimin
bakması gerekir" diye düşünmez, eşleme kendiliğinden yürür. Öte yandan kural **yolu bilir,
değişikliği bilmez.** Aynı dosyaya dokunan iki değişiklikten biri bir arayüz kararı taşıyor,
diğeri bir günlük satırı ekliyor olabilir; kural ikisine de aynı sahibi çağırır. Ölçüm bu ikinci
yönü doğrudan sınar: sahibin bakışı değişiklikten bağımsız olduğu için, kuralın açtığı eksen
kümesi de değişiklikten bağımsızdır.

Kuralın karşıladığı ihtiyaç açıktır. Deponun her bölümünü herkes bilmez; bir bölümün geçmişini,
gerekçelerini ve tuzaklarını en iyi bilen rol, oraya dokunan değişikliği en iyi değerlendirendir.
Ekip yapısı ile kod yapısı arasındaki bu ilişki **Süreç, Ekip ve Teslimat** kursunda kurumsal
tarafıyla tartışıldı; burada tekrarlanmaz. Bu derste ölçülen tek şey incelemenin kendi
sayılarıdır.

#### Onay Kuralı Kaç Onay ve Kimden

Sahiplik eşlemesi kimin çağrılacağını söyler; **onay kuralı** kaç onay gerektiğini söyler. İki
ayar birbirinden bağımsızdır ve dört bileşim üretir: sahiplik yok ve tek onay; sahiplik var ve
tek sahip onayı; sahiplik var ve birden çok sahip onayı; sahiplik var ama sahip onayının yanına
serbest bir onay da eklenmiş.

Bu ayarların hepsi **kişi sayısıyla** ifade edilir ve kursun ölçüsü kişi sayısı değildir. Bir
zorunlu inceleyen bir eksen taşır; iki zorunlu inceleyen iki eksen taşımak zorunda değildir.
Sahiplik kuralı yola göre yazıldığı için, aynı yolun sahipleri çoğu zaman **aynı bakış açısını**
taşır: bölümün gerçekleştirimini bilirler. Onay sayısını artırmak bu durumda kişi ekler, eksen
eklemez.

Kuralın üçüncü bir ayarı daha vardır ve ölçümün dışında kalır: **yazanın kendi onayı sayılır
mı?** Sahip kendi bölümüne yazdığında, kural onu hem yazan hem zorunlu inceleyen olarak
gösterir. Onay bu durumda bir bakış eklemez — değişikliğe zaten bakan tek bakış, onu yazan
bakıştır. Ölçünün diliyle: kendi onayı **sıfır eksen** ekler. Kuralın bunu dışlaması, tabloda
bir satır değiştirmez ama tablonun geçerliliğini korur; dışlanmadığında bütün satırlar birinci
sütundaki onay sayısını olduğundan yüksek gösterir.

Ölçüm tam bu noktayı sınar. Kursun ikinci iddiası **inceleyen eklemek kusur bulmaz; eksen
eklemek bulur** diyordu. Sahiplik kuralı, inceleyen ekleyip eksen eklemeyen bir düzeneğin en
temiz örneğidir; iddia burada **tersinden** görünür.

Ölçümün varsayımları:

- **EA15** — Ortak tanımın 600 satırlık değişikliği ve 24 kusuru olduğu gibi kullanılır; sınıf
  dağılımı ve kâhin kursun sabitidir.
- **EA16** — Sahibin baktığı eksen **gerçekleştirimdir**. Sahiplik yola göre atandığı ve yolun
  sahibi bölümün gerçekleştirimini bilen rol olduğu için varsayılan bakış budur.
- **EA17** — Aynı yolun birden çok sahibi **aynı ekseni** taşır. Bu bir kişilik iddiası değil,
  kuralın sonucudur: kural yolu seçer, yol bakışı seçer.
- **EA18** — Serbest onay, eksen ataması kısıtlanmamış bir incelemedir ve beş eksenin hepsine
  bakar. Kuralın açtığı eksen sayısı, atamadaki eksenlerin birleşimidir.
- **EA19** — Dikkat **12 öbekte** sabittir ve 600 satır 12 öbektir; okunmayan öbek yoktur. Bu
  ölçümde tek değişen şey eksen atamasıdır.
- **EA20** — Tur döngüsü ortak tanımdan gelir ve tur başına **6 birim** bekleme yazar. Onay
  sayısı turu doğrudan değiştirmez; turu ilk turda bulunan kusur sayısı belirler.
- **EA21** — Kümenin çözünürlüğü 24 kusurda **1/24**'tür; eksen ölçeğinde ölçülebilen en küçük
  fark bir eksendir ve eksenler eşit büyüklükte değildir.

#### Ölçüm

```python
"""Kod sahipligi ve zorunlu inceleyen: onay kuralinin eksen cesitliligi.

Bolum 1 - alti onay kurali; zorunlu inceleyen sayisi ile bakilan eksen sayisi.
Bolum 2 - hicbir sahibin bakmadigi eksenlerde duran kusur.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT, OBEK = 12, 50


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=6):
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


TAM = set(EKSENLER)
SAHIP = {"gerceklestirim"}          # sahibin baktığı tek eksen
KURALLAR = {
    "sahiplik yok, bir onay": [TAM],
    "tek zorunlu inceleyen": [SAHIP],
    "iki zorunlu inceleyen": [SAHIP] * 2,
    "üç zorunlu inceleyen": [SAHIP] * 3,
    "zorunlu inceleyen + serbest onay": [SAHIP, TAM],
    "üç sahip, ayrı eksen": [{"arayuz"}, SAHIP, {"test", "belge"}],
}
d = degisiklik(600)
dagilim = {s: sum(1 for k in d["kusurlar"] if k["sinif"] == s) for s in SINIFLAR}
print("sınıf dağılımı: " + ", ".join(f"{s} {n}" for s, n in dagilim.items()))
print()
print(f"{'onay kuralı':<33s} {'onay':>4s} {'eksen':>5s} {'bulunan':>7s} "
      f"{'kaçan':>5s} {'yazılmayan':>10s} {'tur':>3s} {'bekleme':>7s} "
      f"{'kalan':>5s}")
for ad, atama in KURALLAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    eksen = set().union(*atama)
    print(f"{ad:<33s} {len(atama):4d} {len(eksen):5d} {len(b):7d} "
          f"{len(kacan):5d} {yaz:10d} {tur:3d} {bekleme:7d} {kalan:5d}")

print()
print(f"{'onay kuralı':<33s} {'bakılmayan eksen':>16s} {'orada duran kusur':>17s}")
for ad, atama in KURALLAR.items():
    eksen = set().union(*atama)
    bos = [e for e in EKSENLER if e not in eksen]
    duran = sum(1 for k in d["kusurlar"] if k["sinif"] in bos)
    print(f"{ad:<33s} {len(bos):16d} {duran:17d}")
```

```
sınıf dağılımı: arayuz 3, gerceklestirim 6, test 3, belge 3, bicim 7, eksik gereksinim 2

onay kuralı                       onay eksen bulunan kaçan yazılmayan tur bekleme kalan
sahiplik yok, bir onay               1     5      22     2          2   2      12     0
tek zorunlu inceleyen                1     1       6    18          2   6      36     3
iki zorunlu inceleyen                2     1       6    18          2   6      36     3
üç zorunlu inceleyen                 3     1       6    18          2   6      36     3
zorunlu inceleyen + serbest onay     2     5      22     2          2   2      12     0
üç sahip, ayrı eksen                 3     4      15     9          2   3      18     0

onay kuralı                       bakılmayan eksen orada duran kusur
sahiplik yok, bir onay                           0                 0
tek zorunlu inceleyen                            4                16
iki zorunlu inceleyen                            4                16
üç zorunlu inceleyen                             4                16
zorunlu inceleyen + serbest onay                 0                 0
üç sahip, ayrı eksen                             1                 7
```

#### İkinci İddia Tersinden

Tablonun ikinci, üçüncü ve dördüncü satırları aynıdır. Onay sayısı **1**, **2**, **3** olarak
artıyor; bulunan **6**'da, kaçan **18**'de, tur **6**'da, bekleme **36**'da ve kalan **3**'te
duruyor. Üç kat onay, bir tek kusur daha buldurmuyor.

Kursun ikinci iddiası düz yönde "eksen eklemek bulur" diyordu. Burada iddia tersinden okunuyor:
**eksen eklemeden inceleyen eklemek hiçbir şey bulmaz.** Sahiplik kuralının kişi eklemesi
bedelsiz de değildir — üç kişinin onayını beklemek gerçek bir bekleme üretir; ölçümde tur
sayısına yansımasa da öğe üç ayrı imzayı sırayla toplar.

Birinci satır karşılaştırmayı veriyor. Sahiplik kuralı olmayan, tek onaylı ama eksen kısıtı
bulunmayan bir inceleme **22** buluyor, **2** kaçırıyor, **2 tur / 12 bekleme** ile kapanıyor.
Üç zorunlu sahibin bulduğunun **üç katından fazlasını**, üçte bir beklemeyle. Onay sayısı bire
düşüyor ve sonuç iyileşiyor; çünkü değişen şey sayı değil, **eksen sayısıdır**: **1**'den
**5**'e.

Beşinci satır kuralı kurtaran bileşimi gösteriyor. Zorunlu sahip duruyor, yanına eksen kısıtı
olmayan bir onay ekleniyor: bulunan **22**, kaçan **2**, tur **2**, bekleme **12**. Sahiplik
kuralının değeri korunuyor — bölümü bilen rol yine bakıyor — ve eksen boşluğu kapanıyor. Kural
şu hâle geliyor: **zorunlu inceleyen bir eksen garantisidir, bir kapsama garantisi değildir.**

Beşinci satırın onay sayısı **2**'dir ve ikinci satırın **1**'inden fazladır; buna rağmen tur
**6**'dan **2**'ye, bekleme **36**'dan **12**'ye iniyor. Onay eklemek bu kez zinciri kısalttı —
çünkü eklenen onay yeni bir eksen getirdi. Aynı işlemin iki yönde çalışması, kişi sayısının
ölçüde neden yer almadığını gösteriyor: onay sayısı tek başına ne iyi ne kötü bir işarettir,
yanına eksen sütunu konmadan okunamaz.

Altıncı satır aynı sonucu başka yoldan üretiyor. Üç sahip, üç ayrı bölümün sahibi olduğu için üç
ayrı eksene bakıyor: bulunan **15**, tur **3**, bekleme **18**. Üç onay yine üç onaydır ama
eksen **1** yerine **4**'tür ve sayı buna göre değişiyor. **Sahiplik kuralının kalitesi, kaç
sahip çağırdığında değil, çağırdığı sahiplerin kaç ayrı ekseni temsil ettiğinde saklıdır.**

#### Sahipliğin Boşluğu

İkinci tablo aynı satırları başka bir sorudan okuyor: kuralın hiç kapsamadığı eksenlerde kaç
kusur duruyor?

Tek eksenli sahiplik kurallarında **4** eksen açıkta ve orada **16** kusur duruyor. Bunlar
kaçanların bir alt kümesi değildir — kaçan **18**'in **16**'sı buradan gelir, kalan ikisi
**eksik gereksinim** sınıfıdır. Yani dar sahiplikte kaçanların neredeyse tamamı **kimsenin
sorumlu olmadığı** eksenlerde duruyor.

Bu sayının okunma biçimi önemlidir. **16** kusur, bakılıp da görülmemiş kusur değildir; hiç
bakılmamış eksenlerdeki kusurdur. Aradaki fark sürecin nereye dokunacağını belirler: bakılıp
görülmeyen kusur için dikkat ya da değişiklik boyutu tartışılır; hiç bakılmayan eksen için
**kuralın kendisi** değiştirilir. İki soruna aynı çözümü uygulamak ikisini de çözmez.

Üç ayrı eksene bakan altıncı satırda açık eksen **1**'e, orada duran kusur **7**'ye iniyor.
Açıkta kalan tek eksen **biçim** ve orada **7** kusur var — kümedeki en kalabalık sınıf. Bu,
sahiplik kuralına biçim ekseni için bir sahip eklemenin en büyük tek kazancı vereceğini
söylemez; kalabalık sınıf, en ucuza kapatılabilen sınıftır ve kapatılması için insan gerekmez.
O tartışma **inceleme ekseni** konusunun kendi dersine aittir.

Son sütunun sabitliği yine altını çiziyor: altı kuralın altısında da **2** **eksik gereksinim**
kusuru kaçıyor. Sahiplik kuralı ne kadar geniş yazılırsa yazılsın, kimse yazılmamış olanın
sahibi olamaz.

#### Kapının Ölçülmeyen Yanı

Ölçüm bir şeyi kasten dışarıda bırakıyor ve bu sınır yazılmalı: **zorunlu inceleyenin
erişilebilirliği.** Tur döngüsü her tura sabit bir bekleme yazar ve o beklemenin kaç kişiden
toplandığına bakmaz. Gerçekte bir kapı, kuyruğu tek bir role bağlar; o rol meşgulse öğe
`incelemede` sütununda durur ve zincirin en oynak halkası daha da uzar.

Bu etki tabloda görünmüyor, ama tablonun okunmasını değiştiriyor. İkinci, üçüncü ve dördüncü
satırlar bulunan bakımından birbirinin aynısıdır; **bekleme bakımından değildir.** Üç imzayı
sırayla toplayan bir kural, aynı sonucu bir imzayla üreten kuraldan daha uzun sürer ve ölçüm bu
farkı kaydetmez. Yani tablodaki **36** birim, üç zorunlu inceleyenli kural için bir **alt
sınırdır.**

İkinci ölçülmeyen yan, kuralın kapsamının dosya sayısına göre büyümesidir. Geniş bir yol öneki
her değişikliği aynı role bağlar; o rol kuyruğun tamamının kapısı hâline gelir. Ölçümde
görünmez, çünkü ölçüm tek bir iş öğesine bakar. Zincirde görünür, çünkü aynı rolün kuyruğunda
bekleyen öğe sayısı `sırada` sütununu şişirir.

Üçüncü yan kuralın **yokluğunda** ortaya çıkar. Sahiplik kuralı olmayan bir depoda birinci satır
elde edilir — **22** bulunan — ama yalnız o değişikliğe bakan biri gerçekten çıkarsa. Kural,
eksen çeşitliliğini garanti etmez; bir bakışın var olacağını garanti eder. Ölçüm var olan bakışı
sayar, var olmayanı değil.

#### Özet

- **Kod sahipliği** dosya yolunu bir role bağlayan bir eşlemedir; eşleşen roller **zorunlu
  inceleyen** olur ve onayları bir kapı gibi çalışır.
- Zorunlu inceleyen sayısını **1**'den **3**'e çıkarmak bulunanı **6**'da, turu **6**'da ve
  beklemeyi **36**'da sabit bırakır: eksen eklemeden inceleyen eklemek hiçbir şey bulmaz.
- Eksen kısıtı olmayan **tek** onay aynı değişiklikte **22** bulur ve **2 tur / 12 bekleme** ile
  kapanır; fark kişi sayısından değil, eksen sayısının **1**'den **5**'e çıkmasından gelir.
- Zorunlu sahibin yanına serbest bir onay eklemek her ikisini de verir: bulunan **22**, açık
  eksen **0**. Sahiplik bir eksen garantisidir, kapsama garantisi değildir.
- Dar sahiplikte **4** eksen açıkta kalır ve orada **16** kusur durur; bunlar bakılıp görülmemiş
  değil, hiç bakılmamış kusurlardır ve çareleri kuralın kendisidir.
- Altı kuralın altısında da **2** **eksik gereksinim** kusuru kaçar; yazılmamış olanın sahibi
  atanamaz.

#### Sonraki Adım

Buraya kadar akışın kuralları metinle kuruldu: rehber bir metin, sahiplik bir eşleme metniydi.
Bu kuralların yürüdüğü bir yüzey de var — iş öğesinin kaydedildiği, kuyruğun görüldüğü,
tartışmanın değişikliğe iliştiği, tümleşen işin yayımlandığı ve yayımlananın tüketilebildiği
yetenekler. Sonraki ders bu yetenekleri **sınıf düzeyinde** ele alır ve her birine tek bir soru
sorar: **hangi geçişin beklemesini kısaltıyor?** Yanıtı olmayan yetenek, zincirde bir yeri
olmayan yetenektir; ve hiçbirinin bulunan kusur sayısına dokunup dokunmadığı da aynı ölçümde
görünecek.

### Depo Platformu Yetenekleri

Source: https://academia.sh/tr/kurslar/kod-inceleme/depo-platformu-yetenekleri

Beş yetenek zinciri 45 birimden 21'e indirir ama bulunan 15, kaçan 9 ve yazılmayan kaçan 2 her satırda değişmeden kalır; tek tek kazançlar 2 ile 7 arasındadır ve yalnız tartışmanın kazancı tur sayısıyla büyür — 4, 6, 12.

Önceki iki ders akışın kurallarını metinle kurdu: katkı rehberi bir metin, sahiplik bir eşleme
metniydi. Kuralların yürüdüğü bir yüzey de var — iş öğesinin kaydedildiği, kuyruğun görüldüğü,
tartışmanın değişikliğe iliştiği, tümleşen işin yayımlandığı ve yayımlananın tüketilebildiği
yetenekler.

Bu yetenekler ürün olarak değil **sınıf** olarak ele alınır: sorun izleme, pano, tartışma, sürüm
yayımı, paket kaydı. Hangi barındırma yüzeyinde durdukları bu dersin konusu değildir ve beş yıl
sonra da aynı sınıflar var olacaktır. Bu dersin sorusu tek: **her yetenek zincirin hangi
geçişinin beklemesini kısaltıyor ve kısalttığı miktar ne?**

#### Beş Yetenek Sınıfı

**Sorun izleme**, bir önerinin kaydedildiği yerdir. Öneri bir kayda dönüşmediğinde bir yerde
sözlü olarak durur ve sıraya girmesi birinin onu hatırlamasına bağlıdır. Kayıt, öneriyi
zincirin ilk geçişine bağlar.

**Pano**, iş öğelerinin durumlarına göre dizildiği yüzeydir. Önceki derste ölçüldüğü gibi
birikimi gösterir, hızı göstermez; katkısı sıradaki öğenin **üstlenilmesini** hızlandırmasıdır.
Kimse sırada ne olduğunu görmüyorsa, sıradan bir şey alınması birinin sormasına bağlıdır.

**Tartışma**, bir bulgunun ve karşı görüşün değişikliğe **iliştiği** yerdir. Bulgu değişikliğin
dışında bir yazışmada durursa, sonraki tur onu yeniden kurmak zorunda kalır: hangi satır, hangi
gerekçe, hangi karşı öneri. İlişik tartışma bu yeniden kurmayı ortadan kaldırır.

**Sürüm yayımı**, tümleşen işin bir noktaya bağlanıp dışarıya bildirildiği yetenektir. **Paket
kaydı**, yayımlanan işin bir bağımlılık olarak **çekilebildiği** yerdir. İkisi ayrı geçişlere
dokunur ve ikisi de incelemenin sonrasındadır.

Beşinin ortak yanı, her birinin bir **kayıt** tutmasıdır. Kaydın alanları yeteneğin zincirde ne
yapabileceğini belirler.

```text
# örnek iş öğesi kaydı — çalıştırılmamıştır

kimlik      : #377
durum       : incelemede
sınıf       : arayuz
gereksinim  : dış çağrıda zaman aşımı süresi ayarlanabilmeli
bağlı öneri : #361
değişiklik  : ödeme-zaman-asimi
tartışma    : 4 not, 2'si bir satıra iliştirilmiş
sürüm       : —
```

`durum` alanı öğenin panodaki sütununu, `değişiklik` alanı hangi değişikliğin bu öğeyi
karşıladığını, `tartışma` alanı bulguların nereye iliştiğini, `sürüm` alanı ise işin
yayımlanıp yayımlanmadığını söyler. Alanlardan biri boşsa zincirin o halkası ölçülemez: `sürüm`
alanı hiç doldurulmayan bir depoda `tümleşti→kapandı` geçişinin süresi bilinmez.

#### Yeteneklerin Birbirine Bağlanması

Yeteneklerin tek başına değil, **birbirine bağlı** olması ölçümü mümkün kılıyor. Zincirin
beklemesi geçişlerde ölçülür ve bir geçişin ölçülebilmesi için iki ucun aynı kimliğe bağlı olması
gerekir: öneri hangi iş öğesine, iş öğesi hangi değişikliğe, değişiklik hangi tartışmaya, tümleşen
iş hangi sürüme.

Bağ koptuğunda kayıp yalnız izlenebilirlik değildir. Bir bulgunun değişiklikten kopmuş bir
yazışmada durması, o bulgunun bir sonraki turda yeniden kurulmasını gerektirir ve ölçümde
tartışmanın kazancı tam olarak budur — **6**'dan **4**'e inen tur süresi, kopmuş bağın
tamir maliyetidir.

Aynı mantık zincirin sonunda da işler. Bir sürüm notunun hangi iş öğelerini kapsadığı, sürüm ile
öğeler arasındaki bağdan çıkar. Bağ yoksa not elle yazılır ve elle yazılan not, kimsenin
doğrulayamadığı bir listedir. Bu ders bağın **beklemeye** etkisini ölçüyor; notun **okura**
etkisi sonraki dersin konusudur.

#### Her Yetenek Bir Geçişe Dokunur

Ölçümün tasarımı tek bir kurala dayanıyor: **bir yetenek yalnız bir geçişe dokunur.** Bir
yeteneğin birden çok yere iyi geldiği söylenirse ölçüm anlamını yitirir; hangi kazancın nereden
geldiği ayrılamaz. Eşleme şudur: sorun izleme `öneri→sırada`, pano `sırada→yazılıyor`, sürüm
yayımı `tümleşti→kapandı`, paket kaydı `kapandı→tüketilebilir`. Tartışma bunların hiçbirine
dokunmaz; **turun süresine** dokunur.

Son geçiş bu derste ekleniyor. Önceki dersin zinciri iş öğesinin kapanışında bitiyordu; paket
kaydı bir adım ötesine, işin bir başkası tarafından **tüketilebilir** hâle gelmesine dokunur. Bu
adım iş öğesinin durumu değildir ve panoda görünmez, ama zincirin okurunun beklediği yer orasıdır.

#### Turun Sayısı ile Turun Süresi

Tartışmanın ayrı durması bir ayrımı zorunlu kılıyor. **İnceleme turunun sayısı** ile **bir turun
süresi** aynı şey değildir. Tur sayısını belirleyen şey ilk turda bulunandır ve bu, kursun
başından beri eksen atamasının sonucudur. Bir turun süresini belirleyen ise bulgunun bir turdan
diğerine ne kadar bütün taşındığıdır.

Bu ayrımın pratik sonucu şudur: **hiçbir platform yeteneği tur sayısını düşürmez.** Tur sayısı
incelemenin gördüğüyle belirlenir ve bir yüzey görmeyi değiştirmez. Yetenekler beklemeye dokunur
ve tartışma da beklemeye dokunur — yalnız çarpanı farklıdır, çünkü tur başına yazılan beklemeyi
değiştirir ve tur sayısıyla çarpılır.

Ölçümün varsayımları:

- **EA22** — Ortak tanımın 600 satırlık değişikliği ve 24 kusuru olduğu gibi kullanılır; sınıf
  dağılımı ve kâhin kursun sabitidir.
- **EA23** — Zincir önceki dersin geçişleridir, sonuna `kapandı→tüketilebilir` **8** birim
  eklenmiştir. Diğer dört geçiş **5**, **9**, **2** ve **3** birimdir.
- **EA24** — Her yetenek **tek bir geçişin** beklemesini yeni bir değere indirir: sorun izleme
  **1**, pano **4**, sürüm yayımı **1**, paket kaydı **1**. Değerler yeteneğin var olduğu ve
  kullanıldığı durumu temsil eder.
- **EA25** — Tartışma tek geçişe değil, **tur başına beklemeye** dokunur ve onu **6**'dan
  **4**'e indirir. Gerekçesi, ilişik tartışmanın turlar arasında yeniden kurulmayı ortadan
  kaldırmasıdır.
- **EA26** — Ana ölçümün ataması `üç inceleyici, ayrı eksen` atamasıdır. İkinci ölçüm tartışmayı dört
  atamada ayrı ayrı sınar; başka hiçbir şey değişmez.
- **EA27** — Yetenekler bulunan kusura dokunmaz. Bir yüzey ne eksen ekler ne dikkat büyütür; bu
  varsayım ölçümün sonucuyla birlikte sınanır ve tabloda doğrulanır.
- **EA28** — Kümenin çözünürlüğü 24 kusurda **1/24**'tür; zincirde ölçülebilen en küçük fark
  **1 birim** beklemedir.

#### Ölçüm

```python
"""Depo platformu yetenekleri: her yetenegin dokundugu tek gecis.

Bolum 1 - bes yetenek tek tek ve birlikte; bulunan ve kacan degismiyor mu.
Bolum 2 - tur suresini kisaltan yetenegin dort atamadaki kazanci.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT, OBEK = 12, 50
# Zincir: is ogesinin gecisleri ve sonuncusu tuketiciye uzanan adim.
ZINCIR = {"öneri→sırada": 5, "sırada→yazılıyor": 9, "yazılıyor→incelemede": 2,
          "tümleşti→kapandı": 3, "kapandı→tüketilebilir": 8}
TUR_BEKLEME = 6
# Her yetenek tek bir gecise dokunur; tartisma turun suresine dokunur.
YETENEKLER = {
    "sorun izleme": ("öneri→sırada", 1),
    "pano": ("sırada→yazılıyor", 4),
    "tartışma": ("tur süresi", 4),
    "sürüm yayımı": ("tümleşti→kapandı", 1),
    "paket kaydı": ("kapandı→tüketilebilir", 1),
}


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=TUR_BEKLEME):
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


def zincir_toplami(d, atama, acik):
    """Acik yeteneklerin ayarlariyla zincirin toplam beklemesi."""
    gecis = dict(ZINCIR)
    tur_suresi = TUR_BEKLEME
    for ad in acik:
        yer, deger = YETENEKLER[ad]
        if yer == "tur süresi":
            tur_suresi = deger
        else:
            gecis[yer] = deger
    b = kurul(d, atama)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]), tur_suresi)
    return sum(gecis.values()) + bekleme, tur, bekleme, b, kalan


TAM = set(EKSENLER)
ATAMALAR = {
    "tek inceleyici, tüm eksenler": [TAM],
    "üç inceleyici, aynı eksen": [{"gerceklestirim"}] * 3,
    "üç inceleyici, ayrı eksen": [{"arayuz"}, {"gerceklestirim"}, {"test", "belge"}],
    "beş inceleyici, beş eksen": [{e} for e in EKSENLER],
}
d = degisiklik(600)
ANA = ATAMALAR["üç inceleyici, ayrı eksen"]
taban, t0, b0, bul0, _ = zincir_toplami(d, ANA, [])
print(f"atama: üç inceleyici, ayrı eksen | zincir {taban} | tur {t0} | "
      f"inceleme {b0} | bulunan {len(bul0)} | kaçan {24 - len(bul0)}")
print()
print(f"{'yetenek':<16s} {'dokunduğu geçiş':<23s} {'tur':>3s} "
      f"{'zincir':>6s} {'kısalan':>7s} {'bulunan':>7s} {'kaçan':>5s} "
      f"{'yazılmayan':>10s}")
for ad in YETENEKLER:
    z, tur, _, b, _ = zincir_toplami(d, ANA, [ad])
    yaz = sum(1 for k in d["kusurlar"]
              if k["no"] not in b and k["sinif"] == YAZILMAYAN)
    print(f"{ad:<16s} {YETENEKLER[ad][0]:<23s} {tur:3d} {z:6d} "
          f"{taban - z:7d} {len(b):7d} {24 - len(b):5d} {yaz:10d}")
z, tur, _, b, _ = zincir_toplami(d, ANA, list(YETENEKLER))
yaz = sum(1 for k in d["kusurlar"]
          if k["no"] not in b and k["sinif"] == YAZILMAYAN)
print(f"{'beşi birlikte':<16s} {'—':<23s} {tur:3d} {z:6d} {taban - z:7d} "
      f"{len(b):7d} {24 - len(b):5d} {yaz:10d}")

print()
print(f"{'atama':<30s} {'tur':>3s} {'tartışmasız':>11s} {'tartışmalı':>10s} "
      f"{'kısalan':>7s}")
for ad, atama in ATAMALAR.items():
    yok, tur, _, _, _ = zincir_toplami(d, atama, [])
    var, _, _, _, _ = zincir_toplami(d, atama, ["tartışma"])
    print(f"{ad:<30s} {tur:3d} {yok:11d} {var:10d} {yok - var:7d}")
```

```
atama: üç inceleyici, ayrı eksen | zincir 45 | tur 3 | inceleme 18 | bulunan 15 | kaçan 9

yetenek          dokunduğu geçiş         tur zincir kısalan bulunan kaçan yazılmayan
sorun izleme     öneri→sırada              3     41       4      15     9          2
pano             sırada→yazılıyor          3     40       5      15     9          2
tartışma         tur süresi                3     39       6      15     9          2
sürüm yayımı     tümleşti→kapandı          3     43       2      15     9          2
paket kaydı      kapandı→tüketilebilir     3     38       7      15     9          2
beşi birlikte    —                         3     21      24      15     9          2

atama                          tur tartışmasız tartışmalı kısalan
tek inceleyici, tüm eksenler     2          39         35       4
üç inceleyici, aynı eksen        6          63         51      12
üç inceleyici, ayrı eksen        3          45         39       6
beş inceleyici, beş eksen        2          39         35       4
```

#### Kısalanın Okunması

Zincirin tabanı **45** birim. Tek tek açıldığında yeteneklerin kazancı **2** ile **7** arasında
değişiyor ve sıralama şöyle: paket kaydı **7**, tartışma **6**, pano **5**, sorun izleme **4**,
sürüm yayımı **2**.

Sıralamayı belirleyen şey yeteneğin önemi değil, dokunduğu geçişin **başlangıçtaki uzunluğudur.**
Paket kaydı en çok kısaltıyor çünkü `kapandı→tüketilebilir` en uzun geçişti — **8** birim. Sürüm
yayımı en az kısaltıyor çünkü dokunduğu geçiş zaten **3** birimdi ve orada kısaltılacak yer yok.
Bu, bir yeteneğin değerinin **zincirdeki yerine bağlı** olduğunu söyler: aynı yetenek başka bir
zincirde başka bir sıraya oturur.

Beşi birlikte açıldığında zincir **45**'ten **21**'e iniyor; kazanç **24** birim, yani zincirin
**%53**'ü. Tek tek kazançların toplamı da **24**'tür ve bu bir tesadüf değil — her yetenek ayrı
bir geçişe dokunduğu için kazançlar birbirine karışmıyor ve toplanabiliyor. Aynı geçişe dokunan
iki yetenek olsaydı toplam, tek tek kazançların toplamından küçük olurdu.

`tur` sütunu altı satırın altısında da **3**. Hiçbir yetenek turu düşürmüyor. Zincirin toplamı
yarıya inerken tur sayısı hiç kımıldamıyor; **beklemeyi kısaltmak ile turu kısaltmak ayrı
işlerdir** ve bu yüzeyler yalnız birincisini yapar.

#### Tartışmanın Ayrıcalığı

İkinci tablo tartışmayı dört atamada ayrı ayrı sınıyor ve tek tabloda görünmeyen bir şey
gösteriyor: tartışmanın kazancı **sabit değil.** İki turluk atamalarda **4** birim, üç turlukta
**6**, altı turlukta **12**.

Nedeni tanımında. Tartışma tur başına beklemeyi **6**'dan **4**'e indiriyor; kazanç tur başına
**2** birim ve tur sayısıyla çarpılıyor. Diğer dört yetenek zincirin **sabit** kısmına dokunuyor
ve kazançları atamadan bağımsız — hangi atama olursa olsun paket kaydı **7** birim kısaltır.

Buradan bir sıralama kuralı çıkar. **İncelemenin iyi olduğu bir zincirde tartışmanın kazancı en
küçük yeteneklerden biridir; incelemenin kötü olduğu bir zincirde en büyüğüdür.** Altı turluk
satırda tartışma **12** birim kısaltıyor ve bu, paket kaydının **7**'sinden fazla. Yani bir
yeteneğin sırası, ekibin incelemesinin ne durumda olduğuna bağlı olarak değişir ve sabit bir
öncelik listesi yazılamaz.

Aynı satır bir uyarı da taşıyor. Altı turluk atamanın zinciri tartışmayla birlikte **51** birim;
tartışmasız iki turluk atamanın **39**'undan hâlâ uzun. **Hiçbir yetenek kötü bir eksen
atamasını kapatmaz.** Yüzey, incelemenin görmediğini görmesini sağlamaz.

#### Dokunulmayan Sütunlar

Tablonun sağ üç sütunu altı satırda da aynı: bulunan **15**, kaçan **9**, yazılmayan kaçan
**2**. **EA27** bunu varsaymıştı ve ölçüm doğruluyor.

Bu sabitlik dersin asıl bulgusudur. Beş yetenek zincirin yarısını kesiyor ve **bir tek kusur
daha buldurmuyor.** Kusur bulmanın kaynağı kursun başından beri aynı: bakılan eksen sayısı ve
okunan öbek sayısı. Bir yüzey ne eksen ekler ne dikkat büyütür; iş öğesinin bir yerden bir yere
geçmesini hızlandırır.

Yazılmayan kaçan sütunu bunu en sert biçimde söylüyor. **Eksik gereksinim** sınıfı, sorun izleme
yeteneği açıkken de **2** kaçıyor — hem de öneriyi kaydeden yetenek tam olarak budur. Kayıt,
öneriyi zincire sokar; kaydedilmemiş gereksinimi kaydetmez. Bir önceki dersin ölçtüğü
**gereksinim beyanı**, o sınıfa dokunabilen düzenekti ve o bir yüzey değil, bir **rehber
maddesiydi**.

Bu ayrım bir seçim kuralı verir: bir yetenek zincirde bir geçişi kısaltıyorsa değerlidir ve
kısalttığı miktar ölçülebilir. Bulunan kusuru artırma iddiası taşıyan bir yetenek varsa, o iddia
ancak eksen sayısını ya da okunan öbek sayısını değiştirerek doğru olabilir; bu tablodaki hiçbir
yetenek bunu yapmıyor.

#### Özet

- Beş yetenek sınıf düzeyinde ele alınır — sorun izleme, pano, tartışma, sürüm yayımı, paket
  kaydı — ve her biri zincirde **tek bir geçişe** dokunur.
- Zincir **45** birimden, beşi birlikte açıldığında **21**'e iner; kazanç **24** birim ve tek tek
  kazançların toplamına eşittir, çünkü geçişler örtüşmez.
- Tek tek kazançlar **2** ile **7** arasındadır ve sıralamayı geçişin başlangıçtaki uzunluğu
  belirler: paket kaydı **7**, sürüm yayımı **2**.
- Altı satırın altısında da tur **3**'te kalır; hiçbir yetenek tur sayısını düşürmez. Yalnız
  tartışma turun **süresine** dokunur ve kazancı tur sayısıyla büyür: **4**, **6**, **12**.
- Bulunan **15**, kaçan **9** ve yazılmayan kaçan **2** her satırda değişmez: yetenekler
  beklemeyi kısaltır, kusur buldurmaz.
- Altı turluk atamanın tartışmalı zinciri **51** birimdir ve iki turluk atamanın tartışmasız
  **39**'undan uzundur; hiçbir yetenek kötü bir eksen atamasını kapatmaz.

#### Sonraki Adım

Zincirin sonunda bir geçiş kaldı ve ölçümde yalnız bir sayıyla göründü: tümleşen iş bir noktaya
bağlanıp dışarıya bildiriliyor. O bildirimin kendisi bir metindir ve bir okuru vardır — bu
kursun boyunca hiç görünmeyen biri. Sonraki ders o metni ölçer: **sürüm notu** okura ne söylüyor?
Değişikliklerin listesi ile değişikliklerin **anlamının** listesi arasındaki fark kaç soruya
yanıt veriyor ve okurun sorduğu sorulardan kaçı hiçbir not biçiminde yanıt bulamıyor?

### Sürüm Yayımlama Düzeni

Source: https://academia.sh/tr/kurslar/kod-inceleme/surum-yayimlama-duzeni

Yirmi dört iş öğesi ve altı okur sorusu 144 karar eder: ham değişiklik listesi 22'sini yanıtlar (0,153), sınıflanmış liste 44'ünü, anlam listesi 88'ini, etiket ve dağıtım varlığıyla birlikte 132'sini (0,917); yanıtsız kalan 12 kararın 12'si de eksik gereksinim sınıfındandır.

Önceki ders zincirin sonundaki geçişi bir sayıyla gördü: tümleşen iş bir noktaya bağlanıp
dışarıya bildiriliyordu. O bildirimin kendisi bir metindir ve bir okuru vardır — kursun boyunca
hiç görünmeyen biri. İnceleme yazanı ve inceleyeni tanır; **sürüm notunun okuru ise ne
değişikliği görmüştür ne tartışmayı.**

Bu dersin sorusu notun nasıl üretildiği değil. Soru şudur: **not okura ne söylüyor?**
Değişikliklerin listesi ile değişikliklerin **anlamının** listesi arasındaki fark kaç soruya
yanıt veriyor ve okurun sorduğu sorulardan kaçı hiçbir biçimde yanıt bulamıyor?

#### Okur Neyi Sorar

Sürüm notunu okuyan kişi sürümü merak etmez; **kendi durumunu** merak eder. Altı soru sorar ve
her sorunun yanıtı notta ancak belirli bir alan yazılmışsa bulunur.

`değişti mi` sorusunun yanıtı **başlıktadır** — bir şeyin değiştiğini söyleyen en az alan budur.
`hangi alan` sorusu **sınıf** ister: değişiklik nereye dokundu. `beni etkiler mi` sorusu **etki**
ister; `ne yapmalıyım` sorusu **eylem** ister. `hangi noktadan sonra` sorusunun yanıtı bir
**sınırdır** ve onu etiket verir. `nasıl edinirim` sorusunun yanıtı bir **varlıktır** ve onu
dağıtım varlığı verir.

Etiketin nasıl konduğu ve neyi işaretlediği **Sürüm Kontrolüne Giriş** kursunda kuruldu;
sürümün hangi hattan geçerek yayımlandığı **Sürekli Tümleştirme ve Teslimat** kursunun konusudur.
İkisi de burada tekrarlanmaz. Bu derste etiket ve **dağıtım varlığı (release asset)** yalnız
birer **alan** olarak sayılır: okurun iki sorusunu yanıtlayan iki alan.

#### İki Liste

Aynı sürüm iki biçimde yazılabilir ve ikisi aynı bilgiden üretilir.

```text
# örnek sürüm notu — iki biçim, çalıştırılmamıştır

## değişiklik listesi
- #377 ödeme çağrısında zaman aşımı ayarı
- #381 yeniden deneme sayacı düzeltmesi
- #388 günlük biçimi güncellendi

## anlam listesi
### Dış çağrı yapan uygulamalar
- Zaman aşımı süresi artık ayarlanabilir; varsayılan değişmedi.
  Yapılacak: ayar verilmezse davranış aynıdır, işlem gerekmez.
- Yeniden deneme sayısı üç yerine iki. Yapılacak: üç deneme
  bekleyen çağrı yolları gözden geçirilmeli.
### İç değişiklikler
- Günlük biçimi ve biçim düzeltmeleri; okur tarafında etkisi yok.
```

Fark uzunlukta değil. Birinci liste **ne yapıldığını** söylüyor, ikincisi **okura ne olduğunu**.
Birinci listede üç satır da aynı ağırlıkta duruyor; ikincisinde okuru ilgilendirmeyen değişiklik
tek bir satıra toplanmış ve okurun gerçekten bakması gereken iki madde ayrılmış. Ölçüm bu iki
farkı ayrı ayrı sayar: **yanıtlanan soru** ve **taranan satır**.

Ölçümün varsayımları:

- **EA29** — Sürümün iş öğeleri ortak tanımın kümesinden alınır: **24** öğe ve sınıf dağılımı
  kursun sabit dağılımıdır. `degisiklik` ve sınıf listesi değiştirilmez.
- **EA30** — **Eksik gereksinim** sınıfındaki öğe birleştirilmemiştir; hiçbir not biçimine
  giremez. Nota giren öğe sayısı bu yüzden **22**'dir.
- **EA31** — Okurun altı sorusu vardır ve her sorunun yanıtı tek bir alanda durur. Alan yazılıysa
  soru yanıtlanır, yazılmamışsa yanıtsız kalır; yanlış yanıt bu ölçümde yoktur.
- **EA32** — Dört not biçimi denenir ve her biri bir öncekinin alanlarını kapsar: başlık;
  başlık ve sınıf; anlam listesi; anlam listesine etiket ve dağıtım varlığının eklenmiş hâli.
- **EA33** — Okura dönük sınıflar **arayüz**, **gerçekleştirim** ve **belgedir**; test ve biçim
  öğeleri okurun durumunu değiştirmez. Sınıf alanı yazılmamışsa okur ayrım yapamaz ve nota giren
  bütün satırları tarar.
- **EA34** — Kümenin çözünürlüğü 24 öğede **1/24**, karar ölçeğinde **1/144**'tür; bir öğenin
  bir sorusu bu ölçümde ölçülebilen en küçük birimdir.

#### Ölçüm

```python
"""Surum notu: degisiklik listesi ile anlam listesi arasindaki fark.

Bolum 1 - dort not bicimi ve okurun alti sorusu.
Bolum 2 - okurun taradigi satir ile isine yarayan satir.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
OBEK = 50
# Okurun sorusu -> yanıtı taşıyan alan.
SORULAR = {"değişti mi": "başlık", "hangi alan": "sınıf",
           "beni etkiler mi": "etki", "ne yapmalıyım": "eylem",
           "hangi noktadan sonra": "sınır", "nasıl edinirim": "varlık"}
BICIMLER = {
    "ham değişiklik listesi": ("başlık",),
    "sınıflanmış liste": ("başlık", "sınıf"),
    "anlam listesi": ("başlık", "sınıf", "etki", "eylem"),
    "anlam + etiket + varlık": ("başlık", "sınıf", "etki", "eylem",
                                "sınır", "varlık"),
}
# Okura donuk sinif: surum notunun okuru bunlari arar.
DISARI = {"arayuz", "gerceklestirim", "belge"}


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


d = degisiklik(600)
# Sürümün iş öğeleri: sınıf dağılımı kursun sabit dağılımıdır.
OGELER = [{"no": k["no"], "sinif": k["sinif"]} for k in d["kusurlar"]]
# Yazılmayan sınıf birleştirilmemiştir; hiçbir not biçimine giremez.
NOTTA = [o for o in OGELER if o["sinif"] != YAZILMAYAN]
dagilim = {s: sum(1 for o in OGELER if o["sinif"] == s) for s in SINIFLAR}
print("sürüm: " + ", ".join(f"{s} {n}" for s, n in dagilim.items()))
print(f"iş öğesi {len(OGELER)} | nota giren {len(NOTTA)} | okur sorusu "
      f"{len(SORULAR)} | karar {len(OGELER) * len(SORULAR)}")
print()
print(f"{'not biçimi':<24s} {'alan':>4s} {'yanıtlanan':>10s} {'yanıtsız':>8s} "
      f"{'oran':>6s} {'yazılmayandan':>13s}")
toplam = len(OGELER) * len(SORULAR)
for ad, alanlar in BICIMLER.items():
    yanit = sum(1 for o in NOTTA for s in SORULAR if SORULAR[s] in alanlar)
    yazsiz = (len(OGELER) - len(NOTTA)) * len(SORULAR)
    print(f"{ad:<24s} {len(alanlar):4d} {yanit:10d} {toplam - yanit:8d} "
          f"{yanit / toplam:6.3f} {yazsiz:13d}")

print()
print(f"{'not biçimi':<24s} {'taranan satır':>13s} {'işe yarayan':>11s} "
      f"{'oran':>6s}")
for ad, alanlar in BICIMLER.items():
    # Sınıf alanı yoksa okur bütün satırları tarar; varsa dış gruba iner.
    taranan = (len(NOTTA) if "sınıf" not in alanlar
               else sum(1 for o in NOTTA if o["sinif"] in DISARI))
    yarayan = sum(1 for o in NOTTA if o["sinif"] in DISARI)
    print(f"{ad:<24s} {taranan:13d} {yarayan:11d} {yarayan / taranan:6.3f}")
```

```
sürüm: arayuz 3, gerceklestirim 6, test 3, belge 3, bicim 7, eksik gereksinim 2
iş öğesi 24 | nota giren 22 | okur sorusu 6 | karar 144

not biçimi               alan yanıtlanan yanıtsız   oran yazılmayandan
ham değişiklik listesi      1         22      122  0.153            12
sınıflanmış liste           2         44      100  0.306            12
anlam listesi               4         88       56  0.611            12
anlam + etiket + varlık     6        132       12  0.917            12

not biçimi               taranan satır işe yarayan   oran
ham değişiklik listesi              22          12  0.545
sınıflanmış liste                   12          12  1.000
anlam listesi                       12          12  1.000
anlam + etiket + varlık             12          12  1.000
```

#### Farkın Okunması

Yüz kırk dört kararın ham değişiklik listesinde **22**'si yanıtlanıyor — oran **0,153**. Liste
eksiksizdir, hiçbir iş öğesi atlanmamıştır ve okurun altı sorusundan beşine yanıt vermez.
Eksiksizlik ile yanıtlayıcılık aynı şey değildir.

Sınıf alanının eklenmesi yanıtlananı **44**'e çıkarıyor, anlam listesi **88**'e. Asıl sıçrama
üçüncü satırdadır: **etki** ve **eylem** alanları tek başlarına **44** karar taşıyor, yani
kümenin yaklaşık üçte biri. Bu iki alanın ortak yanı, ikisinin de değişiklikten **türetilemez**
olmasıdır. Başlık ve sınıf birleştirilen işten çıkarılabilir; etki ve eylem ancak biri
yazarsa vardır.

Dördüncü satırda oran **0,917**'ye çıkıyor. Bu sayı kursta tanıdıktır: 100 satırlık değişiklikte
bulunan kusurun oranı da **0,917**'ydi. Tesadüf değil — her ikisinde de dışarıda kalan tam olarak
**2/24**'tür ve o iki öğe aynı sınıftandır.

Alttaki tablo ikinci farkı veriyor. Ham listede okur **22** satır tarıyor ve **12**'si işine
yarıyor: oran **0,545**. Okurun yarıya yakını boşa okuma. Sınıf alanı eklendiğinde taranan
**12**'ye iniyor ve oran **1,000** oluyor. Dikkat çekici olan, bu kazancın **ikinci** satırda
sağlanmasıdır: gruplama, etki ve eylem yazılmadan da okurun taramasını yarıya indiriyor.
**En ucuz iyileştirme, notu yeniden yazmak değil, sınıflamaktır.**

#### Özet

- Sürüm notunun okuru ne değişikliği ne tartışmayı görmüştür; altı sorusu vardır ve her sorunun
  yanıtı notta yazılmış tek bir alanda durur.
- Yüz kırk dört kararın ham değişiklik listesi **22**'sini yanıtlar (**0,153**), sınıflanmış
  liste **44**'ünü, anlam listesi **88**'ini, etiket ve dağıtım varlığıyla birlikte **132**'sini
  (**0,917**).
- **Etki** ve **eylem** alanları tek başlarına **44** karar taşır ve ikisi de birleştirilen işten
  türetilemez; ancak biri yazarsa vardır.
- Okur ham listede **22** satır tarayıp **12**'sini kullanır (**0,545**); sınıf alanı taramayı
  **12**'ye indirir ve oranı **1,000** yapar — bu kazanç etki ve eylem yazılmadan elde edilir.
- Yanıtsız kalan **12** kararın **12**'si de **eksik gereksinim** sınıfındandır; birleştirilmemiş
  iş hiçbir not biçiminde görünmez.

#### Kurs Kapanışı

Kurs tek bir ölçüyle yürüdü: bir incelemenin sayısı **bakan kişi sayısı değil, bakılan eksen
sayısı ve okunan öbek sayısıdır.** On beş ders bu ölçüyü ayrı yerlere uyguladı.

| ders | ölçülen | bulunan ya da kaçan |
|---|---|---|
| Kod İncelemenin Amacı | eksen çeşitliliğinin bulduğu | üç inceleyen aynı eksende 6, ayrı eksende 15, tek inceleyen beş eksende 22, beş inceleyen yine 22; dördünde de 2 eksik gereksinim kaçar |
| Arayüz Anlamı | bir ekseni kapatmanın bedeli | beş eksenin kümeleri ayrık, ikili kesişimlerin toplamı 0; arayüz kapatılınca bulunan 22'den 19'a iner ve arayüzsüz on inceleyen 19'da kalır |
| Gerçekleştirim Anlamı | bir eksenin marjinal katkısı | gerçekleştirim iki sırada da 6, biçim 7, kalan üçü 3'er ekler; aynı eksene 1, 3 ve 12 okuma 6'da kalır, oran 0,250 |
| Testlerin İncelenmesi | testin kendisinin taşıdığı kusur | üç test kusuru 9, 1 ve 7 numaralı öbeklerde ve o öbeklerde 1, 2, 1 başka eksen bulgu vermiş; okunmamış öbekte kaçan beş eksende de 0, test ekseni kapatılınca bulunan 22'den 19'a iner |
| Belgelendirme İncelemesi | belge ekseni kapatıldığında kaçan | beş eksenin tek tek kapanış bedeli 3, 6, 3, 3 ve 7; belge kapatılınca bulunan 22'den 19'a iner, belge ekseni açıkken belge kaçan 0 ve yazılmayan kaçan yine 2 |
| Kod Biçimi ve Otomasyon | biçim ekseni araca devredilince dikkatin kayması | insanın bulgusu 22'den 15'e, biçim payı 0,318'den 0,000'a iner; aracın katkısı kapsanmayan eksen kadardır — beş eksen kapsanıyorsa 0, üç inceleyende 15'ten 22'ye ve araçlı en iyi durumda kaçan yine 2 |
| Değişiklik Boyutu | sabit dikkat karşısında boyut | 100 ve 300 satırda 22 (0,917), 900'de 18 (0,750), 2400'de 2 (0,083); 48 öbeğin 36'sı hiç okunmaz |
| Geri Bildirim Dili | aynı bulgunun yazımının ürettiği tur | eyleme dönük 2 tur / 12 bekleme / 44 not-turu, gözlem 3 / 18 / 66, ölçütsüz 4 / 24 / 88; bulunan 22 ve kaçan 2 değişmez |
| Anlaşmazlık Çözümü | kararsız bulgunun taşındığı tur | kural yokluğu 6 tur / 36 bekleme ve kodda 8 kusur; ölçüte bağlama 3 tur / 18 birim ve kodda yalnız 2 |
| İnceleme Ölçütleri | bekleme, tur ve kuyruk sağlığı | üç inceleyen aynı eksende 6 tur / 36 bekleme / 3 kalan, tek inceleyen beş eksende 2 / 12 / 0; kuyrukta en uzun açık kalma 2 tura karşı 15 tur |
| İş Takibi ve Panolar | zincir beklemesi ve incelemenin payı | inceleme dışı 19 sabit, halka 12 ile 36 arası, pay 0,387 ile 0,655; kalan 3 kusur zinciri 55'ten 105'e taşır |
| Katkı Rehberleri | yazılı beklentinin kapattığı tur | dar incelemede tur 6, 5, 4, 3, 2 ve bekleme 36'dan 12'ye; gereksinim beyanı eksik gereksinim kaçanını 2'den 0'a indirir |
| Sahiplik ve Onay Kuralları | zorunlu inceleyenin eksen çeşitliliğine etkisi | onay 1'den 3'e çıkarken bulunan 6, tur 6, bekleme 36 sabit; eksen kısıtsız tek onay 22 bulur, dar sahiplikte 4 eksen açık ve orada 16 kusur |
| Depo Platformu Yetenekleri | her yeteneğin kısalttığı geçiş | zincir 45'ten 21'e, kazanç 24; bulunan 15, kaçan 9 ve yazılmayan 2 her satırda sabit; tartışmanın kazancı 4, 6, 12 |
| Sürüm Yayımlama Düzeni | notun okura yanıtladığı soru | 144 kararın 22'si (0,153), 44'ü, 88'i ve 132'si (0,917); yanıtsız kalan 12'nin 12'si eksik gereksinim |

Tablodan üç okuma çıkar. **Birincisi:** sayıyı büyüten şey kişi değil eksendir ve bu her konuda
yeniden doğrulandı — aynı eksene bakan üçüncü kişi 0, yeni bir eksen 3 ile 7 arası kusur ekler.
**İkincisi:** turu ve beklemeyi belirleyen şey ilk turda görülemeyendir; rehber, sahiplik kuralı
ve platform yetenekleri beklemeye dokunur, bulunana dokunmaz. **Üçüncüsü:** on beş satırın
hepsinde aynı iki kusur kaçar. Eksen eklemek, boyut küçültmek, tur kısaltmak, kural yazmak, yüzey
açmak — hiçbiri onlara ulaşmaz. Onlara ulaşan tek düzenek, yazanın gereksinimi **yazmasını**
isteyen rehber maddesiydi ve o bir inceleme aracı değildi.

Üçüncü okuma kursun sınırını çiziyor. **İnceleme yazılana bakar.** Gönderilen değişikliğin
içindeki her şeyi — arayüzü, gerçekleştirimi, testi, belgeyi, biçimi — yeterince çok eksenle ve
yeterince küçük bir boyutla görmek mümkündür. Gönderilmemiş olanın yokluğu ise incelemenin
konusu değildir; onu ancak **yazmak** kapatır.

Sonraki kurs — Teknik Yazarlık ve Dokümantasyon — tam bu işi ele alır: doküman türlerinin
birbirinden ayrılması, öğretici ile referansın ayrı yapıları, deponun kendi belgeleri, arayüz
referansının düzeni ve sürüm notlarının okura anlamıyla yazılması. Bu dersin son ölçümü oraya
bir sayı bırakıyor: notun altı sorudan kaçını yanıtladığı, notu kimin yazdığına değil,
**hangi alanların yazıldığına** bağlıydı. Ayrım baştan konmalıdır: **inceleme yazılana bakar;
yazılmayanı yazmak ayrı bir iştir.** Bu kursun bıraktığı ölçü, orada yazılan her belgenin kaç
soruyu yanıtladığını saymakta kullanılacak birimdir.

