---
title: 'Kod Yardımcıları'
source: 'https://academia.sh/tr/kurslar/model-apileri/kod-yardimcilari'
course: "Model API'leri ile Uygulama Geliştirme"
language: tr
updated: '2026-08-17T18:06:36+00:00'
license: 'CC BY-SA 4.0'
---

# Kod Yardımcıları

Kurgu bir kod tabanı üzerinde tamamlama, açıklama ve dönüştürme kullanımlarının kabul oranıyla ölçülmesi: bağlamsız çağrı yirmi dört görevin yalnız yedisini kabule götürüyor ve çöküş tamamlama (1/8) ile dönüştürmede (2/8); ayakta kalan tek sınıf açıklama (4/8). Açık dosya bağlamı 10/24 veriyor ama aynı kurulumun iki koşum farkı 2/24 olduğu için kazanç dar. Bütün kod tabanı 18/24'e çıkarıyor, bedeli 1104 belirteçten 4224 belirtece; bin belirteç başına kabul 6,34'ten 4,26'ya düşüyor. Koşumdan bağımsız beklenen kabul sütununda dönüştürme, bütün kod tabanıyla bile (0,4675) hiç bağlamsız açıklamanın (0,6450) altında kalıyor.

Bu kursun buraya kadarki dersleri çağrıyı hep bir ürünün içinde ele aldı: bir abone kısa bir
destek talebi yazıyor, bir istemci onu bir model uç noktasına gönderiyor, ve ölçülen şey o hattın
belirteci, yeniden denemesi, önbellek isabeti ve kesinti payı oluyordu. Aynı çağrının bir yerde
daha yapıldığı hiç sayılmadı: **geliştiricinin kendi masasında**, henüz hiçbir aboneye ulaşmamış
bir kodun üzerinde.

Oradaki ölçü farklıdır. Yanıtı okuyan bir abone değil, kodu yazan kişidir; ve o kişi yanıtı ya
olduğu gibi kullanıma alır ya da atıp kendi yazar. Bu dersin ölçütü budur: **kabul**. Ders kurgu
bir kod tabanı kurar, üç kullanım sınıfını aynı görev kümesinde ölçer ve **düzeneksiz çağrının
hangi sınıfta çöktüğünü** sayar.

- **YG1.** Kod tabanı **kurgudur**: ölçüm ağının kendi yardımcı betikleri. Hiçbir gerçek depo,
  paket, çerçeve ya da ürün değildir. **Beş modül, 53 satır.**
- **YG2.** Kod yardımcısı bir **benzeticidir**; gerçek bir yardımcı, düzenleyici ya da eklenti
  çağrılmaz. Tohum **20260218**, `random` kullanılmaz.
- **YG3.** Ölçüt **kabuldür**: geliştirici öneriyi kullanıma alıyorsa kabul, yeniden yazıyorsa
  ret. Önerinin gerçekten doğru olup olmadığı ayrı bir sorudur ve bu derste sorulmaz.
- **YG4.** Üç kullanım sınıfı: **tamamlama** (eksik bir gövdeyi yazmak), **açıklama** (var olan
  bir parçanın ne yaptığını söylemek), **dönüştürme** (var olan bir parçayı başka bir biçime
  çevirmek). Sınıf başına sekiz kurgu görev, toplam **yirmi dört**.
- **YG5.** Taban kabul olasılığı sınıfa göre farklıdır: açıklama **0,72**, tamamlama **0,34**,
  dönüştürme **0,18**. Gerekçe yapısaldır: açıklamanın girdisi istemin **içindedir**; tamamlama
  ile dönüştürme kod tabanının **geri kalanına** uymak zorundadır.
- **YG6.** Bağlam örtüşmesi kabulü yükseltir, **ilgisiz dosya düşürür**, görev zorluğu düşürür.
  Üçü tek bir puanda toplanır ve puan sıfır ile bir arasına kırpılır.
- **YG7.** Bedel belirteçtir: taban **40**, bağlamdaki dosya başına **26**, dönüştürmeye **18**
  ek. Gecikme sınıfı üç kurulumda da aynıdır: **tek çağrı**, görev başına bir tane.
- **YG8.** Koşumdan bağımsız ölçü **beklenen kabuldür** (puanların ortalaması); sayılan kabul iki
  koşumda ayrı basılır (tohum **20260218** ve **20260219**).

## Kurgu Kod Tabanı

Ölçüm ağının saha ekibi, sayaç okumalarını rapora çeviren bir avuç yardımcı betik taşıyor. Bu
betikler bir ürün değil, bir ekibin kendi işini gördüğü kısa dosyalardır ve **kurgudur**. Beş
modül bir sözlükte tutulur; böylece hem tek blokta gösterilebilir hem de bağlam seçimi
**dosya adıyla** yapılabilir.

```python
# KURGU KOD TABANI -- gercek bir depo, paket ya da urun degildir. Olcum aginin
# kendi yardimci betikleri: bes modul. Tohum 20260218.
KOD = {
    "okuma.py": """
def ayristir(satir):
    p = satir.split(";")
    if len(p) != 4:
        return None
    if not p[3].lstrip("-").isdigit():
        return None
    return {"abone": p[0], "bolge": p[1], "donem": p[2], "endeks": int(p[3])}

def tuketim(onceki, simdiki):
    fark = simdiki - onceki
    if fark < 0:
        fark = fark + 100000
    return fark
""",
    "tarife.py": """
BASAMAK = ((10, 4), (25, 7), (40, 11))
USTU = 16

def bedel(m3):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    return top + kalan * USTU
""",
    "denetim.py": """
GECERLI_BOLGE = ("dogu", "bati", "kuzey", "guney", "merkez")

def gecerli(kayit):
    if kayit is None:
        return False
    if kayit["endeks"] < 0:
        return False
    return kayit["bolge"] in GECERLI_BOLGE

def ayikla(kayitlar):
    return [k for k in kayitlar if gecerli(k)]
""",
    "ozet.py": """
def bolge_toplam(kayitlar, tuketimler):
    top = {}
    for k, t in zip(kayitlar, tuketimler):
        top[k["bolge"]] = top.get(k["bolge"], 0) + t
    return top

def bolge_sayi(kayitlar):
    say = {}
    for k in kayitlar:
        say[k["bolge"]] = say.get(k["bolge"], 0) + 1
    return say
""",
    "bicim.py": """
def satir(bolge, m3, tutar):
    return bolge.ljust(8) + str(m3).rjust(7) + str(tutar).rjust(9)

def rapor(baslik, satirlar):
    return "\\n".join([baslik] + satirlar)
""",
}


def yukle(kod):
    ad = {}
    for dosya, kaynak in kod.items():
        alan = {}
        exec(kaynak, alan)
        ad[dosya] = alan
    return ad


AD = yukle(KOD)
BOY = {d: len(k.strip().split("\n")) for d, k in KOD.items()}
print("modul       satir")
for d in KOD:
    print(f"  {d:<10}{BOY[d]:>4}")
print(f"  {'toplam':<10}{sum(BOY.values()):>4}")

OKUMA = [                                   # KURGU sayac okumalari
    "A017;dogu;2026-01;41250", "A017;dogu;2026-02;41312",
    "B204;bati;2026-02;99800", "B204;bati;2026-03;300",
    "C088;kuzey;2026-02;7130", "C088;kuzey;2026-03;7166",
    "D311;disari;2026-03;5000", "E402;guney;2026-03;bozuk",
]
kayitlar = [AD["okuma.py"]["ayristir"](s) for s in OKUMA]
temiz = AD["denetim.py"]["ayikla"](kayitlar)
print("\nokunan", len(kayitlar), "gecerli", len(temiz))

esler = [(temiz[i], temiz[i + 1]) for i in range(0, len(temiz) - 1, 2)]
tuk = [AD["okuma.py"]["tuketim"](a["endeks"], b["endeks"]) for a, b in esler]
sonraki = [b for _, b in esler]
toplam = AD["ozet.py"]["bolge_toplam"](sonraki, tuk)
satirlar = [AD["bicim.py"]["satir"](b, m, AD["tarife.py"]["bedel"](m))
            for b, m in sorted(toplam.items())]
print(AD["bicim.py"]["rapor"]("bolge        m3    tutar", satirlar))
```

```
modul       satir
  okuma.py    13
  tarife.py   13
  denetim.py  11
  ozet.py     11
  bicim.py     5
  toplam      53

okunan 8 gecerli 6
bolge        m3    tutar
bati        500     7670
dogu         62      662
kuzey        36      266
```

Beş modül birbirine bağlıdır ve tek bir hat kurar: `okuma.py` satırı kayda çevirir, `denetim.py`
geçersizleri atar, `ozet.py` bölgeye toplar, `tarife.py` basamaklı bedeli hesaplar, `bicim.py`
hizalı satırı yazar. Sekiz okumanın ikisi elenmiştir: biri tanınmayan bir bölge taşıyor, birinin
endeksi sayı değil. Batı bölgesinin 500 metreküpü de bir kural sonucudur; sayaç 99800'den 300'e
dönmüştür ve `tuketim` bu dönüşü telafi eder.

**53 satırın tamamı bir istemin içine sığar.** Kod tabanının küçük tutulması kasıtlıdır: burada
"bağlamı büyütmek" gerçekten bir seçenektir ve bedeli sayılabilir. Büyük bir depoda bu seçenek
zaten yoktur, ama ölçünün yönü aynıdır.

## Üç Kullanım Sınıfı ve Kabul

Yirmi dört kurgu görev üç sınıfa bölünür. **Tamamlama** bir gövdeyi yazmayı ister: bölge sayımı
alan yeni bir işlev, eksik bir dal, bir kenar durumu. **Açıklama** var olan bir parçanın ne
yaptığını sorar: `tuketim` niçin 100000 ekliyor, `BASAMAK` demeti neyi kodluyor. **Dönüştürme**
var olan bir parçayı başka bir biçime çevirir: sözlük yerine demet döndürmek, döngüyü kavramaya
çevirmek, iki modülü ortak bir imzada birleştirmek.

Bu üç sınıfın kabul oranı aynı olmaz ve nedeni benzeticiye taban olasılık olarak yazılmıştır.
Açıklamanın **girdisi istemin içindedir**: açıklanacak parça zaten gönderilmiştir, dışarıdan bir
şey bilmek gerekmez. Tamamlama ile dönüştürme ise kod tabanının **görülmeyen kısmına** uymak
zorundadır — hangi anahtar adları kullanılıyor, hangi işlev neyi döndürüyor, hangi geçersizlik
kuralı nerede uygulanıyor.

```python
# YARDIMCI BENZETICISI -- KURGUDUR. Gercek bir kod yardimcisi cagrilmaz.
# Kabul, gorev sinifi ile baglam ortusmesinden hesaplanir; random kullanilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


SINIF = ("tamamlama", "aciklama", "donusturme")
DOSYA = ("okuma.py", "tarife.py", "denetim.py", "ozet.py", "bicim.py")
GEREKEN = {                                 # gorev numarasi -> gereken dosyalar
    0: ("okuma.py",),
    1: ("tarife.py",),
    2: ("denetim.py", "okuma.py"),
    3: ("ozet.py", "denetim.py"),
    4: ("bicim.py", "ozet.py"),
    5: ("tarife.py", "okuma.py"),
    6: ("ozet.py", "okuma.py", "tarife.py"),
    7: ("denetim.py", "bicim.py"),
}
GOREV = [                                   # 24 KURGU gorev: 3 sinif x 8
    {"ad": s + "-" + str(i + 1), "sinif": s, "gereken": GEREKEN[i], "zorluk": 0.05 * (i % 4)}
    for s in SINIF
    for i in range(8)
]
TABAN = {"tamamlama": 0.34, "aciklama": 0.72, "donusturme": 0.18}


def yardimci(gorev, baglam, tohum=TOHUM):
    r = uretec(tohum ^ izno(gorev["ad"] + "|" + ",".join(sorted(baglam))))
    ortu = sum(1 for d in gorev["gereken"] if d in baglam) / len(gorev["gereken"])
    ilgisiz = sum(1 for d in baglam if d not in gorev["gereken"]) / len(DOSYA)
    puan = TABAN[gorev["sinif"]] + 0.55 * ortu - 0.30 * ilgisiz - gorev["zorluk"]
    puan = min(max(puan, 0.0), 1.0)
    kabul = r() < puan
    belirtec = 40 + 26 * len(baglam) + (18 if gorev["sinif"] == "donusturme" else 0)
    return {"kabul": kabul, "puan": puan, "belirtec": belirtec}


KURULUM = (("yok", ()), ("acik dosya", ("okuma.py",)), ("butun kod tabani", DOSYA))


def olc(baglam, sinif, tohum=TOHUM):
    g = [x for x in GOREV if x["sinif"] == sinif]
    s = [yardimci(x, baglam, tohum) for x in g]
    return (sum(x["kabul"] for x in s), sum(x["puan"] for x in s) / len(s),
            sum(x["belirtec"] for x in s))


print("gorev sayisi", len(GOREV), " ornek:",
      ", ".join(g["ad"] + " -> " + "+".join(g["gereken"]) for g in GOREV[:2]))
print("\nbaglam            sinif       beklenen  kabul A  kabul B")
for ad, b in KURULUM:
    for s in SINIF:
        ka, p, _ = olc(b, s)
        kb, _, _ = olc(b, s, TOHUM + 1)
        print(f"{ad:<18}{s:<12}{p:>8.4f}{ka:>7}/8{kb:>7}/8")

print("\nbaglam            toplam A  toplam B  belirtec  kabul/1000 belirtec")
for ad, b in KURULUM:
    ta = sum(olc(b, s)[0] for s in SINIF)
    tb = sum(olc(b, s, TOHUM + 1)[0] for s in SINIF)
    bel = sum(olc(b, s)[2] for s in SINIF)
    print(f"{ad:<18}{ta:>7}/24{tb:>8}/24{bel:>10}{1000 * ta / bel:>17.2f}")
```

```
gorev sayisi 24  ornek: tamamlama-1 -> okuma.py, tamamlama-2 -> tarife.py

baglam            sinif       beklenen  kabul A  kabul B
yok               tamamlama     0.2650      1/8      1/8
yok               aciklama      0.6450      4/8      6/8
yok               donusturme    0.1050      2/8      0/8
acik dosya        tamamlama     0.3954      3/8      1/8
acik dosya        aciklama      0.7417      5/8      6/8
acik dosya        donusturme    0.2429      2/8      1/8
butun kod tabani  tamamlama     0.6275      6/8      7/8
butun kod tabani  aciklama      0.9813      8/8      8/8
butun kod tabani  donusturme    0.4675      4/8      5/8

baglam            toplam A  toplam B  belirtec  kabul/1000 belirtec
yok                     7/24       7/24      1104             6.34
acik dosya             10/24       8/24      1728             5.79
butun kod tabani       18/24      20/24      4224             4.26
```

## Düzeneksiz Çağrının Çöktüğü Yer

İlk üç satır çıplak çağrının tablosudur: bağlam yok, yalnız görev tarifi gönderiliyor. Yirmi dört
görevin **yedisi** kabul ediliyor ve ikinci koşumda da **yedisi**. Toplam sabit görünse de dağılım
sabit değildir, ve asıl bilgi dağılımdadır.

Çöküş iki sınıftadır. **Tamamlama 1/8**, iki koşumda da aynı; beklenen kabul **0,2650**.
**Dönüştürme 2/8** ve ikinci koşumda **0/8**; beklenen kabul **0,1050**, tablonun en düşük
sayısı. Ayakta kalan tek sınıf **açıklamadır**: 4/8 ve 6/8, beklenen kabul **0,6450**. Bir
geliştirici bağlamsız bir yardımcıya "bu işlev ne yapıyor" diye sorabilir ve yanıtın yarısından
fazlasını kullanabilir; aynı yardımcıdan "bu işlevi tamamla" istediğinde sekiz denemenin yedisini
atacaktır.

Neden yapısaldır ve sayı onu doğrular. Açıklama görevinde bilinmesi gereken her şey isteme
konulmuştur. Tamamlama görevinde ise yazılacak gövdenin döndüreceği sözlüğün anahtarları,
çağıracağı işlevin adı ve uyacağı geçersizlik kuralı **başka dosyalardadır**. Yardımcı onları
göremediği için makul ama uymayan bir kod üretir; makul kod da reddedilen koddur.

Sınıf içinde de dağılım vardır ve tek sayı onu gizler. Her sınıfın sekiz görevi dört ayrı zorluk
kademesine dağılır ve zorluk kabul puanından doğrudan düşülür; sınıfın ortalaması, en kolay
görevle en zor görevin arasında bir yerdedir. İki koşum farkı ise ayrı bir şeyi ölçer: aynı görev,
aynı bağlam ve aynı puan, iki tohumda iki ayrı karara varabilir. Bu yüzden tabloda sayılan kabulün
yanına **beklenen kabul** sütunu konulmuştur; sayılan kabul koşuma bağlıdır, beklenen kabul
kurulumun kendisine.

## Bağlamın Kattığı ve Ödettiği

İkinci kurulum bir geliştiricinin en kolay yaptığı şeydir: o an açık olan dosyayı da göndermek.
Burada bu dosya `okuma.py`, ve her görev için aynı. Toplam **7/24'ten 10/24'e** çıkıyor, kazanç
**3/24**. Aynı kurulumun iki koşum farkı ise **2/24** (10'a karşı 8). Kazanç, farkın ancak bir
buçuk katıdır; üstelik tamamlama sütununda yön **tersine dönüyor** (3/8 ve 1/8). Sabit tek bir
dosya bir düzenek değildir; görevle ilgisi olduğunda yardım eder, olmadığında ilgisiz bağlam
olarak sayılır.

Üçüncü kurulum belirsiz değildir. Bütün kod tabanı gönderildiğinde toplam **18/24** ve ikinci
koşumda **20/24**; tabana göre kazanç **11/24**, iki koşum farkının beş katından fazla. Üç sınıf
da yükseliyor: tamamlama 1/8'den 6/8'e, açıklama 4/8'den 8/8'e, dönüştürme 2/8'den 4/8'e.

Bedel sütunu bu kazancın fiyatını yazıyor. Çağrı sayısı üç kurulumda da **24**'tür ve gecikme
sınıfı **tek çağrı** olarak aynı kalır; değişen yalnız belirteçtir: **1104'ten 4224'e**, yaklaşık
**3,8 kat**. Bin belirteç başına kabul ise **6,34'ten 5,79'a, oradan 4,26'ya** düşüyor. Düzenek
işi iyileştirdi ve **birim başına verimi düşürdü**; ikisi aynı anda doğrudur ve ikisi de yazılmak
zorundadır.

Son olarak koşumdan bağımsız sütun bir sıralamayı sabitliyor. Dönüştürme, **bütün kod tabanı**
verildiğinde bile **0,4675**'te kalıyor; açıklama **hiç bağlam olmadan 0,6450**. Bağlam eklemek
sınıfların yerini değiştirmiyor, hepsini birlikte yukarı taşıyor. Bir kod yardımcısını "iyi" ya da
"kötü" diye tek sayıyla anmak bu yüzden yanıltıcıdır: sayı görev sınıfına göre değişir ve en çok
bağlam alan zor sınıf, en az bağlam alan kolay sınıfın gerisinde kalabilir.

## Özet

- Kurgu kod tabanı beş modül ve 53 satırdır; okuma, denetim, özet, tarife ve biçim tek bir rapor
  hattı kurar ve tamamı bir istemin içine sığar.
- Ölçüt kabuldür ve üç kullanım sınıfına göre ayrı sayılır; sınıflar arası fark yapısaldır,
  çünkü açıklamanın girdisi istemin içinde, tamamlama ile dönüştürmenin girdisi dışarıdadır.
- Bağlamsız çağrı 7/24 kabul veriyor; çöküş tamamlama (1/8) ile dönüştürmede (2/8), ayakta kalan
  tek sınıf açıklama (4/8, beklenen 0,6450).
- Tek bir sabit dosya eklemek 10/24 veriyor ama aynı kurulumun iki koşum farkı 2/24'tür ve
  tamamlama sütununda yön tersine döner: sabit bağlam bir düzenek değildir.
- Bütün kod tabanı 18/24'e çıkarıyor; bedel 1104 belirteçten 4224 belirtece, bin belirteç başına
  kabul 6,34'ten 4,26'ya iniyor. Çağrı sayısı ve gecikme sınıfı değişmiyor.
- Bağlam sınıfların sırasını değiştirmiyor: tam bağlamlı dönüştürme (0,4675) bağlamsız
  açıklamanın (0,6450) altında kalır.

## Sonraki Adım

Bu derste bağlam üç kez **sabit** verildi: hiç, hep aynı dosya, ya da hepsi. Üçü de bir seçim
değildir. Gerçek bir masada bağlam her görev için yeniden kurulur ve iki soru sorulur: hangi
dosyalar ve kaç tane. Yukarıdaki tablo bu soruların ikisini de yanıtsız bırakıyor; yalnız uçları
gösteriyor. Sonraki ders arayı doldurur: dosya sayısı bir bir artarken belirteç nasıl büyüyor,
kabul nerede tepe yapıyor, ve **görevle ilgisi olmayan bir dosya** kabule ne yapıyor. Orada
ölçülecek olan bağlamın **boyu** değil, **seçimidir**.
