---
title: 'Gösterge Tablosu Tasarımı'
source: 'https://academia.sh/tr/kurslar/gorsellestirme-ve-raporlama/gosterge-tablosu-tasarimi'
course: 'Görselleştirme, Raporlama ve Ölçekli Analiz'
language: tr
updated: '2026-08-17T18:08:49+00:00'
license: 'CC BY-SA 4.0'
---

# Gösterge Tablosu Tasarımı

Aynı on iki ölçüt üç düzende kodlanır ve her düzende kaçının bir bakışta geri okunduğu sayılır: eklenme sırasına dizilmiş düzende 1, her ölçüte bir gösterim verildiğinde 2, karara göre bölünmüş düzende 9 ölçüt geri okunur. Desteklenen karar sayısı sırasıyla 0, 0 ve 3'tür; bakış bütçesi on ikiye çıkarıldığında ilk iki düzen 2 ve 6 ölçüt geri okutur ama yine hiçbir kararı desteklemez. Uzunluk kanalında ayrı ayrı yüzde 1,50 ve yüzde 3,08 hatayla geri okunan iki oranın arasındaki 1,861'lik fark yüzde 34,3 hatayla 2,500 okunur.

Sekiz derste tek bir gösterim doğru kuruldu: değer bir kanala kodlandı, okuyucu onu geri okudu,
aradaki hata sayıldı. Bir rapor tek bir gösterimden oluşmuyor. Karar verecek kişi bir bakışta
birden çok sayıyla karşılaşıyor; her sayı doğru kodlanmış olabilir ve sayfa yine de hiçbir kararı
desteklemeyebilir.

Bu dersin ölçüsü iki sayıdır: **bir bakışta geri okunabilen ölçüt sayısı** ve **desteklenen karar
sayısı**. Buradaki gösterge tablosu bir işletim aracı değildir. DevOps ve Gözlemlenebilirlik
kursunun gösterge tablosu dersi nöbetçinin ekranını ele almış, "panel bir soruya yanıt veriyor mu"
diye denetlemişti; uyarı kuralı ve eşik tasarımı orada kuruldu ve **burada tekrarlanmaz**. Soru
burada başkadır: sayı kanalından geri okunabiliyor mu ve onu karara çevirecek bir dayanağı var mı.

- **RP1.** Küme K03'ten devralınır ve **kurgudur**: 3.199 satırlık okuma tablosu, 1.329 abone, üç
  dönem, beş bölge, tarife basamakları 10/25/40 m³. Tohum koda yazılıdır.
- **RP2.** Rapor da **kurgudur**: on iki ölçüt ve üç karar, ölçüm ağını yürüten birimin dönem sonu
  raporundan gelir.
- **RP3.** Bir bakış **beş göz duraktır**. Bu bir karardır; aynı denetim üç, beş, sekiz ve on iki
  bütçesiyle yeniden koşturulur.
- **RP4.** Okuma çözünürlüğü çözücüde yazılıdır: metin çubuğu **tam hücre** sayılır (20 hücre),
  renk basamağı ancak basamağın **orta değerine** çözülür (5 basamak), çıplak sayı iki ondalıkla
  basılır. Kanal büyüklüğü, etiket işareti taşır.
- **RP5.** Hata eşiği **yüzde 5**'tir; gerekçesi raporun en küçük karşılaştırmasının bu büyüklükte
  olmasıdır. Ölçek tavanı da bir karardır ve ölçüt tanımıyla birlikte yazılır.
- **RP6.** Bir ölçüt üç koşul birden sağlanırsa **geri okunmuş** sayılır: bakış bütçesinin içinde
  olmak, hatası eşiğin altında kalmak, bir dayanağı olmak.

## Ölçüt, Kanal ve Dayanak

On iki ölçütün tamamı kurgu kümeden hesaplanır. Üçü K05'ten gelir: doğu ortalaması 24,674 m³,
kuzeyle farkı 4,463 m³, hiç okuması olmayan 69 abone.

```python
# rapor.py — MODELDIR. K03'un kurgu kumesi ayni tohumla uretilir; uzerine kurgu
# bir donem sonu raporu kurulur. Her olcut bir kanala kodlanir, okuyucu geri okur.
import math

TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF
BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26),
         ("bati", 0.14, 14), ("merkez", 0.18, 23)]


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 ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


ABONE, ELENEN = [], []
for i in range(HAM):
    r = uretec(TOHUM + i)
    b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])]
    ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05])
    ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17])
    (ELENEN if r() < 0.046 else ABONE).append(
        {"abone_no": 10001 + i, "bolge": b[0], "taban": b[2]})
GECERLI = {k["abone_no"] for k in ABONE}
OKUMA = {}
for k in ABONE + ELENEN:
    r = uretec(TOHUM + 7000 + k["abone_no"])
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        t = 0.0 if r() < 0.038 else math.floor(
            k["taban"] * math.exp((r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100
            + 0.5) / 100
        if k["abone_no"] in GECERLI:
            OKUMA.setdefault(k["abone_no"], {})[d + 1] = t
        r()


def okumalar(donem, bolge=None):
    return [OKUMA[k["abone_no"]][donem] for k in ABONE
            if (bolge is None or k["bolge"] == bolge)
            and donem in OKUMA.get(k["abone_no"], {})]


def eksik_oran(donem, bolge=None):
    kume = [k for k in ABONE if bolge is None or k["bolge"] == bolge]
    return sum(1 for k in kume if donem not in OKUMA.get(k["abone_no"], {})) / len(kume)


d2, d3 = okumalar(2), okumalar(3)
sirali = sorted(d3)
tum = {b[0]: sum((okumalar(d, b[0]) for d in (1, 2, 3)), []) for b in BOLGE}
ort = {b: sum(v) / len(v) for b, v in tum.items()}
eksik = {b[0]: eksik_oran(3, b[0]) for b in BOLGE}
en_eksik = max(eksik, key=lambda b: eksik[b])

# (kod, ad, deger, birim, olcek tavani). Tavan bir karardir; kanal ona gore kodlar.
OLCUT = [
    ("O1", "donem 3 toplam tuketim", sum(d3), "m3", 20000.0),
    ("O2", "abone basina ortalama", sum(d3) / len(d3), "m3", 40.0),
    ("O3", "ortanca tuketim",
     (sirali[418] + sirali[419]) / 2, "m3", 40.0),
    ("O4", "eksik okuma orani", eksik_oran(3) * 100, "%", 50.0),
    ("O5", "sifir okuma sayisi", sum(1 for v in d3 if v == 0.0), "adet", 50.0),
    ("O6", "40 m3 ustu abone orani", sum(1 for v in d3 if v > 40) / len(d3) * 100, "%", 5.0),
    ("O7", "en yuksek bolge ortalamasi", max(ort.values()), "m3", 40.0),
    ("O8", "dogu-kuzey ortalama farki", ort["dogu"] - ort["kuzey"], "m3", 10.0),
    ("O9", "donem 2-3 degisim orani",
     (sum(d3) / len(d3) - sum(d2) / len(d2)) / (sum(d2) / len(d2)) * 100, "%", 20.0),
    ("O10", "10-25 basamagindaki abone orani",
     sum(1 for v in d3 if 10 <= v < 25) / len(d3) * 100, "%", 100.0),
    ("O11", "hic okumasi olmayan abone",
     sum(1 for k in ABONE if not OKUMA.get(k["abone_no"])), "adet", 100.0),
    ("O12", "en yuksek eksik okuma orani (" + en_eksik + ")", eksik[en_eksik] * 100, "%", 50.0),
]
AD = {o[0]: o[1] for o in OLCUT}
DEG = {o[0]: o[2] for o in OLCUT}
BIRIM = {o[0]: o[3] for o in OLCUT}
TAVAN = {o[0]: o[4] for o in OLCUT}

print(f"kurgu kume (tohum {TOHUM}): {len(ABONE)} abone, "
      f"{sum(len(v) for v in OKUMA.values())} okuma, {len(BOLGE)} bolge")
print(f"rapor donem 3 uzerine kurulur: {len(d3)} okuma\n")
for k, ad, d, br, tv in OLCUT:
    print(f"  {k:<4} {ad:<38} {d:>10.3f} {br}")
```

```
kurgu kume (tohum 20260218): 1329 abone, 3199 okuma, 5 bolge
rapor donem 3 uzerine kurulur: 838 okuma

  O1   donem 3 toplam tuketim                  15353.190 m3
  O2   abone basina ortalama                      18.321 m3
  O3   ortanca tuketim                            17.845 m3
  O4   eksik okuma orani                          36.945 %
  O5   sifir okuma sayisi                         28.000 adet
  O6   40 m3 ustu abone orani                      0.955 %
  O7   en yuksek bolge ortalamasi                 24.674 m3
  O8   dogu-kuzey ortalama farki                   4.463 m3
  O9   donem 2-3 degisim orani                    -6.910 %
  O10  10-25 basamagindaki abone orani            74.105 %
  O11  hic okumasi olmayan abone                  69.000 adet
  O12  en yuksek eksik okuma orani (bati)         38.806 %
```

## Aynı Sayının Üç Kanalı

Eşiğin gerekçesi de bu listeden çıkar: raporun taşıdığı en küçük karşılaştırma, küme geneli eksik
okuma oranı ile en yüksek bölgenin oranı arasındadır.

```python

# Her kanal bir kodlayici ve bir cozucu ciftidir; okuma cozunurlugu cozucude yazilidir.
HUCRE, BASAMAK, ESIK = 20, 5, 0.05


def kodla(kanal, x, tavan):
    if kanal == "sayi":
        return round(abs(x), 2)
    if kanal == "uzunluk":
        return max(0, min(HUCRE, int(abs(x) / tavan * HUCRE + 0.5)))
    return max(0, min(BASAMAK - 1, int(abs(x) / tavan * BASAMAK)))


def coz(kanal, kod, tavan):
    if kanal == "sayi":
        return kod
    if kanal == "uzunluk":
        return kod * tavan / HUCRE
    return (kod + 0.5) * tavan / BASAMAK


def hata(kanal, k):
    x, tavan = DEG[k], TAVAN[k]
    return abs(coz(kanal, kodla(kanal, x, tavan), tavan) - abs(x)) / abs(x)


en_kucuk = (DEG["O12"] - DEG["O4"]) / DEG["O4"]
print(f"raporun tasidigi en kucuk karsilastirma: kume geneli eksik okuma orani "
      f"{DEG['O4']:.3f} ile\n{AD['O12']} {DEG['O12']:.3f} arasinda yuzde "
      f"{en_kucuk * 100:.1f}. Geri okuma hatasi esigi bu yuzden yuzde {ESIK * 100:.0f}.\n")
print(f"{'olcut':<6}{'kaynaktaki sayi':>16}  {'kanal':<9}{'kodlanan':>9}"
      f"{'geri okunan':>13}{'hata %':>9}")
for k in ("O9", "O12"):
    for kanal in ("sayi", "uzunluk", "renk"):
        print(f"{k:<6}{DEG[k]:>16.3f}  {kanal:<9}{kodla(kanal, DEG[k], TAVAN[k]):>9}"
              f"{coz(kanal, kodla(kanal, DEG[k], TAVAN[k]), TAVAN[k]):>13.3f}"
              f"{hata(kanal, k) * 100:>9.2f}")
```

```
raporun tasidigi en kucuk karsilastirma: kume geneli eksik okuma orani 36.945 ile
en yuksek eksik okuma orani (bati) 38.806 arasinda yuzde 5.0. Geri okuma hatasi esigi bu yuzden yuzde 5.

olcut  kaynaktaki sayi  kanal     kodlanan  geri okunan   hata %
O9              -6.910  sayi          6.91        6.910     0.00
O9              -6.910  uzunluk          7        7.000     1.31
O9              -6.910  renk             1        6.000    13.17
O12             38.806  sayi         38.81       38.810     0.01
O12             38.806  uzunluk         16       40.000     3.08
O12             38.806  renk             3       35.000     9.81
```

Çıplak sayının hatası sıfıra yakındır ve bu onu en iyi kanal yapmaz: hatasız okunan 38,81'in iyi
mi kötü mü olduğu kaynağın kendisinden okunamaz. Renk basamağı ise beş kovaya böldüğü için iki
ölçütte de eşiği aşıyor.

## Üç Düzen, İki Sayı

Birinci düzen ölçütlerin eklenme sırasını korur ve hepsini çıplak sayı basar. İkincisi her ölçüte
bir gösterim ve bir dayanak verir, sırayı değiştirmez. Üçüncüsü kararlara göre bölümlere ayırır.

```python

# RP3: bir bakis bes gozduraktir; asagida dort butce icin ayni denetim kosar.
BUTCE = 5
KARAR = [("ek okuma turu hangi bolgeye", ("O4", "O12", "O8")),
         ("tarife basamagi siniri gozden gecirilsin mi", ("O3", "O6", "O10")),
         ("donem 3 toplamasi yenilensin mi", ("O5", "O9", "O11"))]
SIRA = ["O1", "O2", "O9", "O4", "O5", "O3", "O6", "O7", "O8", "O10", "O11", "O12"]
CESIT = {"O1": "uzunluk", "O2": "renk", "O9": "renk", "O4": "renk", "O5": "uzunluk",
         "O3": "uzunluk", "O6": "renk", "O7": "uzunluk", "O8": "sayi", "O10": "renk",
         "O11": "uzunluk", "O12": "renk"}
DUZEN = {
    "eklenme sirasi": [[(k, "sayi", k in ("O8", "O9")) for k in SIRA]],
    "her olcute bir gosterim": [[(k, CESIT[k], True) for k in SIRA]],
    "karara gore bolunmus": [[(k, "sayi" if k == "O8" else "uzunluk", True) for k in kk]
                             for _, kk in KARAR],
}


def denetle(bolumler, butce=BUTCE):
    """Bir olcut ancak uc kosul birden saglanirsa geri okunmus sayilir:
    bakis butcesinin icinde olmak, hatasi esigin altinda kalmak, dayanagi olmak."""
    okunan = [k for b in bolumler for k, kanal, dayanak in b[:butce]
              if dayanak and hata(kanal, k) <= ESIK]
    return okunan, [ad for ad, kk in KARAR if all(k in okunan for k in kk)]


print(f"{len(OLCUT)} olcut, {len(KARAR)} karar, hata esigi yuzde {ESIK * 100:.0f}. "
      f"Son dort sutun: geri okunan olcut / desteklenen karar.\n")
print(f"{'duzen':<24}{'gosterilen':>11}{'bakis':>7}"
      + "".join(f"{'butce ' + str(b):>10}" for b in (3, 5, 8, 12)))
for ad, bol in DUZEN.items():
    print(f"{ad:<24}{sum(len(b) for b in bol):>11}{len(bol):>7}" + "".join(
        f"{'/'.join(str(len(x)) for x in denetle(bol, b)):>10}" for b in (3, 5, 8, 12)))
```

```
12 olcut, 3 karar, hata esigi yuzde 5. Son dort sutun: geri okunan olcut / desteklenen karar.

duzen                    gosterilen  bakis   butce 3   butce 5   butce 8  butce 12
eklenme sirasi                   12      1       1/0       1/0       1/0       2/0
her olcute bir gosterim          12      1       1/0       2/0       4/0       6/0
karara gore bolunmus              9      3       9/3       9/3       9/3       9/3
```

Beş göz duraklık bütçede üç düzen sırasıyla 1, 2 ve 9 ölçüt geri okutuyor; desteklenen karar
sayısı 0, 0 ve 3.

Asıl bilgi son sütunda. Bütçe on ikiye çıkarıldığında, yani okuyucunun sayfayı baştan sona
taradığı varsayıldığında bile ilk iki düzen hiçbir kararı desteklemiyor. Eksik olan yer değil
**birlikteliktir**: bir karar üç ölçütün aynı anda dayanaklı ve eşik altı olmasını ister, ilk iki
düzende bu üçlü hiçbir bütçede tamamlanmaz. On iki ölçütün altısını geri okutan bir sayfa sıfır
karar destekleyebilir. Üçüncü düzenin bedeli de sayılıdır: dokuz ölçüt gösterir, üçünü dışarıda
bırakır ve bir yerine **üç bakış** ister.

## Okuyucunun Gördüğü Sayfa

```python

# Okuyucunun gordugu sey basilir; "<" geri okunmus olcutu isaretler.
def cizgi(k, kanal):
    if kanal == "uzunluk":
        n = kodla("uzunluk", DEG[k], TAVAN[k])
        return "#" * n + "." * (HUCRE - n)
    if kanal == "renk":
        return f"basamak {kodla('renk', DEG[k], TAVAN[k]) + 1}/{BASAMAK}".ljust(HUCRE)
    return f"{DEG[k]:.2f} {BIRIM[k]}".ljust(HUCRE)


def bas(baslik, bolumler, adlar=None, kes=None):
    print(f"--- {baslik} " + "-" * (52 - len(baslik)))
    for i, b in enumerate(bolumler):
        if adlar:
            print(f"  [karar: {adlar[i]}]")
        for j, (k, kanal, dayanak) in enumerate(b[:kes] if kes else b):
            im = " <" if j < BUTCE and dayanak and hata(kanal, k) <= ESIK else ""
            print(f"  {j + 1:>2}. {AD[k]:<36}{cizgi(k, kanal)}"
                  f"{'  dayanak var' if dayanak else '  dayanak yok'}{im}")


bas("duzen 1 — eklenme sirasi (bakisa giren bes satir)",
    DUZEN["eklenme sirasi"], kes=BUTCE)
print()
bas("duzen 3 — karara gore bolunmus", DUZEN["karara gore bolunmus"],
    [k[0] for k in KARAR])

gercek = DEG["O12"] - DEG["O4"]
okunan = coz("uzunluk", kodla("uzunluk", DEG["O12"], TAVAN["O12"]), TAVAN["O12"]) - \
    coz("uzunluk", kodla("uzunluk", DEG["O4"], TAVAN["O4"]), TAVAN["O4"])
print(f"\nO4 hatasi yuzde {hata('uzunluk', 'O4') * 100:.2f}, "
      f"O12 hatasi yuzde {hata('uzunluk', 'O12') * 100:.2f} — ikisi de esigin altinda.")
print(f"aradaki fark: kaynakta {gercek:.3f}, geri okunan {okunan:.3f}, "
      f"farkin hatasi yuzde {abs(okunan - gercek) / gercek * 100:.1f}")
```

```
--- duzen 1 — eklenme sirasi (bakisa giren bes satir) ---
   1. donem 3 toplam tuketim              15353.19 m3           dayanak yok
   2. abone basina ortalama               18.32 m3              dayanak yok
   3. donem 2-3 degisim orani             -6.91 %               dayanak var <
   4. eksik okuma orani                   36.95 %               dayanak yok
   5. sifir okuma sayisi                  28.00 adet            dayanak yok

--- duzen 3 — karara gore bolunmus ----------------------
  [karar: ek okuma turu hangi bolgeye]
   1. eksik okuma orani                   ###############.....  dayanak var <
   2. en yuksek eksik okuma orani (bati)  ################....  dayanak var <
   3. dogu-kuzey ortalama farki           4.46 m3               dayanak var <
  [karar: tarife basamagi siniri gozden gecirilsin mi]
   1. ortanca tuketim                     #########...........  dayanak var <
   2. 40 m3 ustu abone orani              ####................  dayanak var <
   3. 10-25 basamagindaki abone orani     ###############.....  dayanak var <
  [karar: donem 3 toplamasi yenilensin mi]
   1. sifir okuma sayisi                  ###########.........  dayanak var <
   2. donem 2-3 degisim orani             #######.............  dayanak var <
   3. hic okumasi olmayan abone           ##############......  dayanak var <

O4 hatasi yuzde 1.50, O12 hatasi yuzde 3.08 — ikisi de esigin altinda.
aradaki fark: kaynakta 1.861, geri okunan 2.500, farkin hatasi yuzde 34.3
```

Son iki satır düzenin kapatmadığı açığı gösteriyor. Birinci bölümdeki iki oran uzunluk kanalında
ayrı ayrı yüzde 1,50 ve yüzde 3,08 hatayla, ikisi de eşiğin çok altında geri okunuyor. Ama
okuyucunun o bölümde yaptığı iş tek tek değerleri okumak değil **aralarındaki farkı** okumaktır.
Kaynakta 1,861 puan olan fark 2,500 okunuyor: yüzde 34,3 hata. İki küçük hata aynı yöne düşmediği
için farkta büyüyor.

Bu, eşiğin yanlış seçildiğini değil ölçülen şeyin değiştiğini gösterir. Bir karar bir farka
dayanıyorsa geri okuma hatası **farkın üzerinde** ölçülmelidir: raporun en küçük karşılaştırması
yüzde 5 iken kanalın farkta ürettiği yüzde 34,3 o karşılaştırmayı çevirecek büyüklüktedir.

## Özet

- Bir ölçüt üç koşul birden sağlanırsa geri okunmuş sayılır: bakış bütçesinin içinde olmak, geri
  okuma hatasının eşiğin altında kalması, bir dayanağının bulunması.
- Aynı on iki ölçüt beş göz duraklık bakışta üç düzende sırasıyla 1, 2 ve 9 kez geri okunuyor;
  desteklenen karar sayısı 0, 0 ve 3'tür. Bütçe on ikiye çıkarıldığında ilk iki düzen 2 ve 6 ölçüt
  geri okutur ama yine hiçbir kararı desteklemez.
- Karara göre bölünmüş düzenin bedeli sayılıdır: dokuz ölçüt gösterir, üçünü dışarıda bırakır ve
  bir yerine üç bakış ister. Çıplak sayı hatasız okunur ama dayanaksız olduğu için karar beslemez.
- Tek tek yüzde 1,50 ve yüzde 3,08 hatayla okunan iki oranın arasındaki 1,861'lik fark 2,500
  okunur; farkın hatası yüzde 34,3'tür.

## Sonraki Adım

Bu ders ölçütleri verilmiş kabul etti ve yalnız sayfada nasıl durduklarını ölçtü. Ölçütün kendisi
sorgulanmadı: eksik okuma oranı neyin oranıdır, paydasında kim vardır, bir okuma hangi anda okuma
sayılır. Bir ölçüt karar üretmeye başladığı andan itibaren ölçtüğü şeyi oynatmadan da
oynatılabilir hâle gelir. Sonraki ders bunu sayar: aynı eksik okuma oranı, ölçüm ağında hiçbir şey
değişmeden kaç yoldan oynatılabiliyor, her yol ölçütü ne kadar oynatıyor ve ölçüt yeniden
tanımlandığında bu yolların kaçı kapanıyor.
