---
title: 'Kullanıcı Deneyimi ve Davranış Tasarımı'
source: 'https://academia.sh/tr/kurslar/kullanici-deneyimi'
language: tr
updated: '2026-08-17T04:41:16+00:00'
license: 'CC BY-SA 4.0'
lessons: 24
outcomes:
    - 'Kullanıcı araştırmasından tasarım kararına giden zinciri kurar'
    - 'Bilgi mimarisi ve akış tasarımıyla görev tamamlamayı kolaylaştırır'
    - 'Davranış modellerini etik sınırlar içinde uygular'
---

# Kullanıcı Deneyimi ve Davranış Tasarımı

Kullanıcı araştırmasından tasarım kararına giden zinciri kuran; bilgi mimarisi, akış tasarımı ve davranış modellerini etik sınırlar içinde ölçülebilir kararlara çeviren kurs.

## Araştırma ve Tanımlama

Gözlem, görüşme ve anketin ne zaman seçildiği; verilerden kullanıcı profili, görev listesi ve yolculuk haritası çıkarma; mevcut çözümlerin okunması ve problemin çözümden önce yazılması.

### Kullanıcı Araştırması Yöntemleri

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/kullanici-arastirmasi-yontemleri

Gözlem, görüşme ve anketin hangi soruya yanıt verdiği; görüşme doygunluğunun ölçülmesi, küçük örneklemden yaygınlık kestirimi çıkarmanın sınırı ve araştırmanın etik çerçevesi.

Arayüz Tasarımının Temelleri kursu bir ekranın içini ölçtü: hiyerarşi, ızgara, aralık,
kontrast eşikleri, bileşen durumları. O kursta katalog arayüzünün akışı — arama alanı,
sonuç listesi, kayıt ayrıntısı, ödünç alma — baştan verilmişti ve niçin bu akış olduğu
sorulmadı. Bu kurs o soruyla açılır. Ölçülecek şey artık bir ekranın içi değil, ekranlar
arasındaki yoldur.

Yolun başlangıcı bir varsayımdır: arayüzün desteklemesi gereken görevleri bilmek. Bu bilgi
tasarımcının kendi kullanımından çıkarılamaz; tasarımcı arayüzün nasıl çalıştığını bildiği
için hiçbir kullanıcının içinde bulunmadığı bir konumdadır. Bilginin kaynağı araştırmadır.
Bu ders üç temel yöntemi — gözlem, görüşme ve anket — hangi sorulara yanıt verdiklerine
göre ayırır ve her birinin ne söyleyip ne söyleyemeyeceğini sayıyla gösterir.

#### Üç Yöntem, Üç Ayrı Soru

Yöntem seçimi bir bütçe kararı değil, soru türü kararıdır. Üç yöntem üç ayrı soruya yanıt
verir ve birinin yanıtı diğerinin yerine geçmez.

**Gözlem (observation)**, kişinin görevi gerçekten nasıl yaptığını kaydeder. Katalog
arayüzünde bir kullanıcının aramayı yazdıktan sonra sonuç listesinin kaçıncı satırına
baktığı, geri döndüğünde ne yaptığı, rafta bulamayınca nereye gittiği gözlemle görülür.
Gözlemin gücü, kişinin **söylemediği** ve çoğu zaman farkında olmadığı davranışları
yakalamasıdır. Sınırı, gerekçeyi vermemesidir: kullanıcının niçin geri döndüğü
gözlemlenemez, ancak sorulabilir.

**Görüşme (interview)**, gerekçeyi ve bağlamı toplar. Kişinin görevi niçin yaptığını, hangi
alternatifleri denediğini, arayüzden bağımsız hangi kısıtları taşıdığını görüşme açığa
çıkarır. Sınırı iki katmanlıdır. Birincisi, insan kendi davranışını yanlış hatırlar;
"genellikle konu başlığından ararım" diyen bir kişi gözlemde yazar adından arayabilir.
İkincisi, görüşme az sayıda kişiyle yapılır ve **sayısal bir yaygınlık kestirimi vermez**.

**Anket (survey)**, bir olgunun ne kadar yaygın olduğunu ölçer. Yalnızca zaten bilinen
seçenekler arasında ölçüm yapabilir: ankete koymadığınız bir sorun, anketten çıkmaz. Bu
yüzden anket araştırmanın başında değil, keşfin ardında durur.

Sıralama buradan çıkar: gözlem ve görüşme neyin var olduğunu bulur, anket ise bulunanın ne kadar
yaygın olduğunu ölçer. Ters sırada yürütülen bir araştırma, yalnızca araştırmacının baştan aklında
olan seçenekleri doğrular.

#### Araştırmanın Etik Çerçevesi

Araştırma, insanlardan veri toplamaktır ve bu üç kural yöntemin süsü değil parçasıdır.

**Bilgilendirilmiş onay.** Katılımcı, oturumun başında verinin ne için toplandığını, ne
kadar süreceğini, kaydın hangi biçimde tutulacağını ve istediği an ayrılabileceğini öğrenir
ve buna açıkça onay verir. Onay kapsamı sonradan genişletilemez: görüşme için alınan onay,
kaydın bir tanıtım metninde kullanılmasını kapsamaz.

**Kimliksizleştirme.** Notlar kodlanırken katılımcı adı yerine `K01` gibi bir kod kullanılır
ve ad ile kod arasındaki eşleme, çözümleme verisinden ayrı tutulur. Kimliksizleştirmenin
ölçüsü, veriden kimliğe geri gidilememesidir; "adı sildim" yetmez. Serbest metin
alıntılarında kişiyi tek başına tanımlayabilecek ayrıntılar da temizlenir. Katalog
örneğinde "üçüncü kattaki tek gece görevlisi" bir addır.

**Saklama sınırı.** Her veri kümesi için saklama süresi araştırma başlamadan yazılır ve
süre dolduğunda veri silinir. Ham kayıt en kısa sürede kodlanmış nota dönüştürülür; kodlanan
not saklanır, ham kayıt silinir. Sınırı olmayan saklama, ileride ne için kullanılacağı
bilinmeyen bir veri yığını üretir ve onayın kapsamını fiilen sonsuza genişletir.

Bu kurallar araştırmayı yavaşlatmaz; kapsamını belirler. Onaysız toplanan veri, çözümlemede
kullanılamayacağı için zaten yoktur.

#### Görüşme Kaç Kişiyle Yapılır

Görüşme sayısının ölçütü temsil değil **doygunluktur (saturation)**: yeni görüşmelerin yeni
kod üretmeyi bıraktığı nokta. Kod, not içindeki bir olgunun kısa adıdır; aynı olgu farklı
katılımcılarda farklı sözcüklerle anlatılsa bile aynı kodu alır.

```js
// doygunluk.mjs — gorusme notlarinin kodlanmasi, doygunluk ve kod sikligi

// 12 gorusmenin kodlanmis notlari (ders icin kurulmus veri)
const GORUSMELER = [
  ["K01", ["es-adli-kayit", "raf-kodu-anlasilmiyor", "odunc-durumu-gec", "konu-taramasi-zor"]],
  ["K02", ["raf-kodu-anlasilmiyor", "geri-donusta-arama-kayip", "es-adli-kayit"]],
  ["K03", ["odunc-durumu-gec", "filtre-gorunmuyor", "es-adli-kayit", "yazar-yazim-farki"]],
  ["K04", ["konu-taramasi-zor", "geri-donusta-arama-kayip", "raf-kodu-anlasilmiyor"]],
  ["K05", ["uzatma-yolu-bilinmiyor", "odunc-durumu-gec", "es-adli-kayit"]],
  ["K06", ["filtre-gorunmuyor", "dar-ekranda-liste", "raf-kodu-anlasilmiyor", "konu-taramasi-zor"]],
  ["K07", ["es-adli-kayit", "yazar-yazim-farki", "geri-donusta-arama-kayip"]],
  ["K08", ["rezervasyon-sirasi-belirsiz", "odunc-durumu-gec", "raf-kodu-anlasilmiyor"]],
  ["K09", ["konu-taramasi-zor", "es-adli-kayit", "dar-ekranda-liste"]],
  ["K10", ["raf-kodu-anlasilmiyor", "odunc-durumu-gec", "geri-donusta-arama-kayip", "filtre-gorunmuyor"]],
  ["K11", ["es-adli-kayit", "konu-taramasi-zor", "uzatma-yolu-bilinmiyor"]],
  ["K12", ["odunc-durumu-gec", "raf-kodu-anlasilmiyor", "yazar-yazim-farki"]],
];

// Doygunluk: her gorusmenin getirdigi yeni kod
const gorulen = new Set();
console.log("gorusme  kod  yeni kod  toplam benzersiz kod");
for (const [ad, kodlar] of GORUSMELER) {
  const yeni = kodlar.filter((k) => !gorulen.has(k));
  yeni.forEach((k) => gorulen.add(k));
  console.log(
    `${ad.padEnd(8)} ${String(kodlar.length).padStart(3)} ${String(yeni.length).padStart(9)} ${String(gorulen.size).padStart(21)}`
  );
}

// Kod sikligi: bir kod kac katilimcinin notunda gecti
const siklik = new Map();
for (const [, kodlar] of GORUSMELER) {
  for (const k of new Set(kodlar)) siklik.set(k, (siklik.get(k) ?? 0) + 1);
}
const N = GORUSMELER.length;
console.log("\nkod                          katilimci  oran");
for (const [k, c] of [...siklik].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))) {
  console.log(`${k.padEnd(28)} ${String(c).padStart(9)}  ${((c / N) * 100).toFixed(1)}%`);
}
console.log(`\ntoplam benzersiz kod: ${siklik.size}, son yeni kod: ${GORUSMELER.length - 4}. gorusmede`);
```

```
gorusme  kod  yeni kod  toplam benzersiz kod
K01        4         4                     4
K02        3         1                     5
K03        4         2                     7
K04        3         0                     7
K05        3         1                     8
K06        4         1                     9
K07        3         0                     9
K08        3         1                    10
K09        3         0                    10
K10        4         0                    10
K11        3         0                    10
K12        3         0                    10

kod                          katilimci  oran
es-adli-kayit                        7  58.3%
raf-kodu-anlasilmiyor                7  58.3%
odunc-durumu-gec                     6  50.0%
konu-taramasi-zor                    5  41.7%
geri-donusta-arama-kayip             4  33.3%
filtre-gorunmuyor                    3  25.0%
yazar-yazim-farki                    3  25.0%
dar-ekranda-liste                    2  16.7%
uzatma-yolu-bilinmiyor               2  16.7%
rezervasyon-sirasi-belirsiz          1  8.3%

toplam benzersiz kod: 10, son yeni kod: 8. gorusmede
```

İlk tablo doygunluğu gösteriyor. İlk dört görüşme on kodun yedisini getirdi; sekizinci
görüşmeden sonra yeni kod gelmedi. Son dört görüşme çözümlemeye yeni bir olgu eklemedi.

Bu, "sekiz görüşme yeter" biçiminde bir kurala dönüştürülemez. Doygunluk noktası
katılımcıların çeşitliliğine bağlıdır: on iki kişinin hepsi aynı bölümden seçilseydi eğri
daha erken düzleşir ve bu erken düzleşme yeterlilik değil, örneklemin darlığı olurdu.
Doygunluk bir durma ölçütüdür, örneklem büyüklüğü sözü değil. Uygulamadaki karşılığı şudur:
yeni görüşmeler yeni kod getirmediği sürece durulur, ama katılımcı profili değiştirilerek
bir kez daha denenir.

#### Görüşme Oranları Yaygınlık Değildir

İkinci tablo bir tuzak içeriyor. "Katılımcıların %58.3'ü eş adlı kayıt sorunundan söz etti"
cümlesi doğru ama yanıltıcıdır; bu oran bir kullanıcı kitlesi hakkında bir kestirim gibi
okunur. Oranın hangi belirsizlikle taşındığını hesaplamak gerekir.

```js
// kesinlik.mjs — gorusme sayilarinin yayginlik kestirimi olarak sinirlari

const N = 12; // gorusme sayisi
const Z = 1.96; // %95 guven duzeyi
const GOZLEM = [
  ["es-adli-kayit", 7],
  ["odunc-durumu-gec", 6],
  ["rezervasyon-sirasi-belirsiz", 1],
];

const wald = (basari, n) => {
  const p = basari / n;
  const yari = Z * Math.sqrt((p * (1 - p)) / n);
  return [p - yari, p + yari];
};
const wilson = (basari, n) => {
  const p = basari / n;
  const payda = 1 + (Z * Z) / n;
  const merkez = (p + (Z * Z) / (2 * n)) / payda;
  const yari = (Z / payda) * Math.sqrt((p * (1 - p)) / n + (Z * Z) / (4 * n * n));
  return [merkez - yari, merkez + yari];
};

console.log("kod                          gozlem  Wald araligi     Wilson araligi   genislik");
for (const [ad, c] of GOZLEM) {
  const [wa, wb] = wald(c, N);
  const [sa, sb] = wilson(c, N);
  console.log(
    `${ad.padEnd(28)} ${`${c}/${N}`.padStart(6)}  ` +
      `${`${(wa * 100).toFixed(1)} - ${(wb * 100).toFixed(1)}`.padEnd(16)} ` +
      `${`${(sa * 100).toFixed(1)} - ${(sb * 100).toFixed(1)}`.padEnd(16)} ` +
      `${((sb - sa) * 100).toFixed(1)} puan`
  );
}

console.log("\nornek buyuklugu  %95 hata payi (p = 0.5)  %45 ile %55 ayirt edilir mi");
for (const n of [8, 12, 30, 100, 400, 1000]) {
  const yari = Z * Math.sqrt(0.25 / n);
  console.log(
    `${String(n).padStart(15)}  ${`+/- ${(yari * 100).toFixed(1)} puan`.padStart(21)}  ${yari * 100 < 5 ? "evet" : "hayir"}`
  );
}
console.log(`\n+/- 5 puan icin gereken en kucuk ornek: ${Math.ceil((Z / 0.05) ** 2 * 0.25)}`);
```

```
kod                          gozlem  Wald araligi     Wilson araligi   genislik
es-adli-kayit                  7/12  30.4 - 86.2      32.0 - 80.7      48.7 puan
odunc-durumu-gec               6/12  21.7 - 78.3      25.4 - 74.6      49.2 puan
rezervasyon-sirasi-belirsiz    1/12  -7.3 - 24.0      1.5 - 35.4       33.9 puan

ornek buyuklugu  %95 hata payi (p = 0.5)  %45 ile %55 ayirt edilir mi
              8          +/- 34.6 puan  hayir
             12          +/- 28.3 puan  hayir
             30          +/- 17.9 puan  hayir
            100           +/- 9.8 puan  hayir
            400           +/- 4.9 puan  evet
           1000           +/- 3.1 puan  evet

+/- 5 puan icin gereken en kucuk ornek: 385
```

Yedi kişinin sözünü ettiği sorunun aralığı %32 ile %81 arasında; genişliği 48.7 puan. Bu aralık,
"kullanıcıların yarısından fazlası" ile "kullanıcıların üçte biri" iddialarının ikisini de içerir.
On iki görüşmeden çıkan oran bir kestirim olarak kullanılamaz.

Wald aralığının üçüncü satırda **eksi** bir alt sınır üretmesi ayrıca öğreticidir: normal
yaklaşım küçük örneklemde ve uç oranlarda geçerliliğini yitirir, olasılık için olanaksız bir
değer verir. Wilson aralığı aynı veriyi %1.5 ile %35.4 arasına yerleştirir. Bir kez
gözlenmiş bir olgunun yaygınlığı hakkında söylenebilecek tek şey, bunun sıfır olmadığıdır.

İkinci tablo anketin fiyatını veriyor. Yüz kişilik bir ankette hata payı ±9.8 puandır ve
%45 ile %55 arasındaki bir farkı ayırt edemez; ±5 puan kesinliğe inmek için en az 385 yanıt
gerekir. Örnek büyüklüğünün dörde katlanması hata payını yarıya indirir — kesinlik, örnekle
karekök hızında iyileşir.

#### Yöntem Seçim Kuralı

Yukarıdaki hesaplar tek bir seçim kuralına indirgenir.

- Soru "insanlar bunu nasıl yapıyor" ise **gözlem** seçilir; söylenen değil yapılan ölçülür.
- Soru "niçin böyle yapıyor" ya da "hangi kısıtlar altında" ise **görüşme** seçilir; çıktısı
  kodlanmış olgulardır, oran değil.
- Soru "bu ne kadar yaygın" ise **anket** seçilir ve gerekli örneklem büyüklüğü baştan hesaplanır;
  hesabın karşılanamayacağı anlaşılırsa anket yapılmaz, çünkü küçük anket yanıt vermez.

Üçünün ortak kuralı, sorunun yöntemden önce yazılmasıdır. Yöntemle başlayan bir araştırma,
o yöntemin yanıtlayabileceği soruya kendini uydurur.

#### Özet

- Gözlem yapılanı, görüşme gerekçeyi, anket yaygınlığı ölçer; keşif gözlem ve görüşmeyle,
  ölçüm anketle yapılır ve sıra tersine çevrilemez.
- Bilgilendirilmiş onay, kimliksizleştirme ve saklama sınırı yöntemin parçasıdır; onayın
  kapsamı sonradan genişletilemez ve ham kayıt kodlandıktan sonra silinir.
- Görüşme sayısının ölçütü doygunluktur; örnek veride sekizinci görüşmeden sonra yeni kod
  gelmedi, ancak doygunluk katılımcı çeşitliliğine bağlıdır ve sabit bir sayı vermez.
- On iki görüşmeden çıkan %58.3 oranının %95 aralığı %32 ile %81 arasındadır; nitel örneklem
  yaygınlık kestirimi üretmez.
- Anket kesinliği örneklemin kareköküyle artar: ±5 puan için en az 385 yanıt gerekir, yüz
  kişilik bir anket 10 puanlık farkları ayırt edemez.

#### Sonraki Adım

Bu ders on iki görüşmeden on kod çıkardı ama katılımcıları hâlâ `K01`–`K12` kodlarından
ibaret bir liste olarak bıraktı. Tasarım kararı vermek için bu listenin yapısını görmek
gerekir: bazı katılımcılar birbirine benziyor mu, benziyorlarsa hangi eksende? Sonraki ders
katılımcıları özelliklerine göre kümeler, davranışa göre yapılan gruplamayla demografiye
göre yapılan gruplamanın aynı sonucu vermediğini hesapla gösterir ve gerçek veriye dayanan
bir kullanıcı profilinin nasıl kurulduğunu ortaya koyar.

### Kullanıcı Profilleri

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/kullanici-profilleri

Profilin uydurulmuş bir kişi değil, veriden türetilmiş bir davranış kümesi olması; katılımcıların kümelemesi, rol tabanlı gruplamanın açıklama gücünün hesaplanması ve profilin etik sınırı.

Önceki ders on iki görüşmeden on kod çıkardı, ama katılımcıları hâlâ `K01`–`K12` biçiminde
bir liste olarak bıraktı. Bu listeyle tasarım kararı verilemez: on iki ayrı kişiye ayrı
arayüz tasarlanmaz. Karar verebilmek için listenin yapısını görmek gerekir — kimler
birbirine benziyor, benzerlik hangi eksende ve bu eksen tasarımı değiştiriyor mu?

Bu sorunun yaygın yanıtı yanlıştır. Katılımcılar çoğu zaman rollerine göre gruplanır:
lisans öğrencisi, lisansüstü öğrenci, akademisyen, kütüphane çalışanı, dışarıdan üye. Bu
gruplama yönetilebilir görünür, çünkü roller zaten kayıtlıdır. Bu ders, aynı veri üzerinde
iki gruplamayı karşılaştırır ve rolün davranışı ne kadar açıkladığını hesaplar.

#### Profil Nedir, Ne Değildir

**Kullanıcı profili (persona)**, araştırma verisinden türetilmiş ve bir davranış kümesini
temsil eden bir tanımdır. Üç parçası vardır:

- **Amaç:** kişinin arayüzü kullanma nedeni. "Kaynak taramak" ile "bilinen bir kitabı
  bulmak" ayrı amaçlardır ve ayrı arayüz kararları doğururlar.
- **Davranış:** amacın gözlenmiş biçimi. Oturum süresi, arama türü, ödünç alma sıklığı,
  hangi ekrandan girdiği.
- **Kısıt:** kişinin değiştiremediği koşullar. Zaman, ekran, dil, erişilebilirlik gereksinimi.

Profil bu üçünün dışında bir şey içerdiğinde tasarım kararı üretmeyi bırakır. Uydurulmuş bir
ad, bir yaş, bir fotoğraf ve bir yaşam öyküsü profili "canlı" göstermeye çalışır ama hiçbir
karar bu ayrıntılara dayandırılamaz. Katalog arayüzünde sonuç listesinin kaç satır
göstereceği kararı, kullanıcının otuz iki mi kırk beş mi yaşında olduğuna değil, oturumunun
dört mü yirmi iki dakika mı sürdüğüne bağlıdır.

Ölçüt şudur: profilde yazan her satırın karşılığında bir tasarım kararı gösterilebilmelidir.
Karşılığı olmayan satır profilden çıkarılır.

#### Katılımcıları Ölçülene Göre Kümelemek

Gözlem oturumlarından dört ölçü çıkarıldı: konu taramasıyla geçen oturum oranı, ortalama
oturum süresi, aylık ödünç alma sayısı ve dar ekrandan girilen oturum oranı. Bu ölçüler
farklı birimlerde olduğu için önce ortak bir aralığa taşınır, sonra katılımcılar arası
uzaklık hesaplanır ve birbirine yakın olanlar birleştirilir.

```js
// profil.mjs — davranisa gore gruplama ile role gore gruplamanin karsilastirilmasi

// Gozlem oturumlarindan cikan olculer (ders icin kurulmus veri).
// kesif: konu taramasi ile gecen oturum orani, sure: ortalama oturum dakikasi,
// odunc: aylik odunc alma sayisi, darEkran: dar ekrandan girilen oturum orani.
const K = [
  { ad: "K01", rol: "lisans",      kesif: 0.15, sure: 4,  odunc: 6, darEkran: 0.10 },
  { ad: "K02", rol: "lisansustu",  kesif: 0.85, sure: 22, odunc: 2, darEkran: 0.20 },
  { ad: "K03", rol: "lisans",      kesif: 0.45, sure: 6,  odunc: 2, darEkran: 0.85 },
  { ad: "K04", rol: "lisans",      kesif: 0.80, sure: 19, odunc: 3, darEkran: 0.15 },
  { ad: "K05", rol: "akademisyen", kesif: 0.20, sure: 5,  odunc: 8, darEkran: 0.05 },
  { ad: "K06", rol: "disaridan",   kesif: 0.50, sure: 7,  odunc: 1, darEkran: 0.90 },
  { ad: "K07", rol: "calisan",     kesif: 0.40, sure: 5,  odunc: 3, darEkran: 0.80 },
  { ad: "K08", rol: "calisan",     kesif: 0.10, sure: 3,  odunc: 7, darEkran: 0.15 },
  { ad: "K09", rol: "akademisyen", kesif: 0.90, sure: 25, odunc: 2, darEkran: 0.10 },
  { ad: "K10", rol: "lisansustu",  kesif: 0.48, sure: 8,  odunc: 2, darEkran: 0.88 },
  { ad: "K11", rol: "disaridan",   kesif: 0.78, sure: 20, odunc: 1, darEkran: 0.25 },
  { ad: "K12", rol: "lisansustu",  kesif: 0.18, sure: 5,  odunc: 6, darEkran: 0.12 },
];
const OLCU = ["kesif", "sure", "odunc", "darEkran"];

// Olculer farkli birimlerde; her birini 0-1 araligina tasi.
const enAz = {}, enCok = {};
for (const o of OLCU) {
  enAz[o] = Math.min(...K.map((k) => k[o]));
  enCok[o] = Math.max(...K.map((k) => k[o]));
}
const vektor = (k) => OLCU.map((o) => (k[o] - enAz[o]) / (enCok[o] - enAz[o]));
const V = K.map(vektor);
const uzaklik = (a, b) => Math.hypot(...a.map((v, i) => v - b[i]));

// Tam bag ile birlestirmeli kumeleme: en yakin iki kumeyi birlestir, k kumede dur.
function kumele(hedef) {
  let kumeler = V.map((_, i) => [i]);
  while (kumeler.length > hedef) {
    let enIyi = [0, 1], enKucuk = Infinity;
    for (let i = 0; i < kumeler.length; i++)
      for (let j = i + 1; j < kumeler.length; j++) {
        let d = 0;
        for (const a of kumeler[i]) for (const b of kumeler[j]) d = Math.max(d, uzaklik(V[a], V[b]));
        if (d < enKucuk) { enKucuk = d; enIyi = [i, j]; }
      }
    const [i, j] = enIyi;
    kumeler = kumeler.filter((_, x) => x !== i && x !== j).concat([kumeler[i].concat(kumeler[j])]);
  }
  return kumeler.map((c) => c.sort((a, b) => a - b)).sort((a, b) => a[0] - b[0]);
}

// Grup ici kare toplami: her uyenin grup ortalamasina uzakliginin karesi
const kareToplam = (gruplar) =>
  gruplar.reduce((t, g) => {
    const ort = OLCU.map((_, d) => g.reduce((s, i) => s + V[i][d], 0) / g.length);
    return t + g.reduce((s, i) => s + uzaklik(V[i], ort) ** 2, 0);
  }, 0);

const TUMU = kareToplam([K.map((_, i) => i)]);
const rolGruplari = [...new Set(K.map((k) => k.rol))].map((r) =>
  K.map((k, i) => [k, i]).filter(([k]) => k.rol === r).map(([, i]) => i)
);
const davranisGruplari = kumele(3);

console.log("davranisa gore kumeler (k = 3)");
for (const g of davranisGruplari) {
  const ort = OLCU.map((_, d) => g.reduce((s, i) => s + K[i][OLCU[d]], 0) / g.length);
  console.log(
    `  ${g.map((i) => K[i].ad).join(" ").padEnd(20)} n=${g.length}  ` +
      `kesif ${ort[0].toFixed(2)}  sure ${ort[1].toFixed(1)} dk  odunc ${ort[2].toFixed(1)}  dar ekran ${ort[3].toFixed(2)}`
  );
  console.log(`     roller: ${[...new Set(g.map((i) => K[i].rol))].sort().join(", ")}`);
}

console.log("\nrole gore gruplar");
for (const g of rolGruplari) {
  console.log(`  ${K[g[0]].rol.padEnd(12)} ${g.map((i) => K[i].ad).join(" ").padEnd(16)} n=${g.length}`);
}

const rolK = kareToplam(rolGruplari), davK = kareToplam(davranisGruplari);
console.log("\ngruplama          grup sayisi  grup ici kare toplami  aciklanan degisim");
console.log(`role gore         ${String(rolGruplari.length).padStart(11)}  ${rolK.toFixed(3).padStart(21)}  ${((1 - rolK / TUMU) * 100).toFixed(1)}%`);
console.log(`davranisa gore    ${String(davranisGruplari.length).padStart(11)}  ${davK.toFixed(3).padStart(21)}  ${((1 - davK / TUMU) * 100).toFixed(1)}%`);
console.log(`toplam degisim (tek grup): ${TUMU.toFixed(3)}`);

// Her kumenin en temsili uyesi: kume icindeki uzaklik toplami en kucuk olan
console.log("\nkume  temsili katilimci  kume ici uzaklik toplami");
for (const g of davranisGruplari) {
  const puanlar = g.map((i) => [i, g.reduce((s, j) => s + uzaklik(V[i], V[j]), 0)]);
  puanlar.sort((a, b) => a[1] - b[1]);
  console.log(`${g.map((i) => K[i].ad).join("+").padEnd(20)} ${K[puanlar[0][0]].ad}  ${puanlar[0][1].toFixed(3)}`);
}
```

```
davranisa gore kumeler (k = 3)
  K01 K05 K08 K12      n=4  kesif 0.16  sure 4.3 dk  odunc 6.8  dar ekran 0.11
     roller: akademisyen, calisan, lisans, lisansustu
  K02 K04 K09 K11      n=4  kesif 0.83  sure 21.5 dk  odunc 2.0  dar ekran 0.17
     roller: akademisyen, disaridan, lisans, lisansustu
  K03 K06 K07 K10      n=4  kesif 0.46  sure 6.5 dk  odunc 2.0  dar ekran 0.86
     roller: calisan, disaridan, lisans, lisansustu

role gore gruplar
  lisans       K01 K03 K04      n=3
  lisansustu   K02 K10 K12      n=3
  akademisyen  K05 K09          n=2
  disaridan    K06 K11          n=2
  calisan      K07 K08          n=2

gruplama          grup sayisi  grup ici kare toplami  aciklanan degisim
role gore                   5                  4.885  22.3%
davranisa gore              3                  0.261  95.8%
toplam degisim (tek grup): 6.286

kume  temsili katilimci  kume ici uzaklik toplami
K01+K05+K08+K12      K01  0.538
K02+K04+K09+K11      K02  0.605
K03+K06+K07+K10      K03  0.450
```

#### Rol Bir Profil Değildir

Karşılaştırmanın sonucu tek satırda okunur. Role göre gruplama **beş** grup üretiyor ve
davranıştaki değişimin %22.3'ünü açıklıyor; davranışa göre gruplama **üç** grupla %95.8'ini
açıklıyor. Bu karşılaştırma rolün lehinedir, çünkü daha çok grup her zaman daha küçük grup
içi değişim üretme eğilimindedir. Daha az grupla daha yüksek açıklama, farkın veriden
geldiğini gösterir.

Bunun nedeni kümelerin bileşiminde görünüyor: üç davranış kümesinin her birinde dört ayrı rol var.
Aynı rolden iki kişi birbirine benzemiyor; farklı rollerden dört kişi benziyor. Lisans öğrencisi
K01 ile akademisyen K05 aynı kümede — ikisi de bilinen bir kaydı bulup çıkmak istiyor. Lisans
öğrencisi K04 ile akademisyen K09 başka bir kümede — ikisi de konu tarıyor. Rol, kütüphane
kaydında yazılı olduğu için ölçülmesi ucuzdur; davranışı açıklamadığı için tasarımda karşılığı
yoktur.

Üç kümenin ortalamaları profillerin çekirdeğini veriyor.

- **Bilinen kaydı arayan.** Konu taraması oranı 0.16, oturum 4.3 dakika, ayda 6.8 ödünç. Bu
  profil için sonuç listesinin ilk satırı belirleyicidir; kullanıcı listeyi taramaz, ilk
  eşleşmeyi doğrular ve çıkar.
- **Konu tarayan.** Konu taraması oranı 0.83, oturum 21.5 dakika, ayda 2.0 ödünç. Bu profil
  listeyi gerçekten okur, karşılaştırır ve çoğu oturumda ödünç almadan ayrılır. Onun için
  değerli olan işlem değil, listeye geri dönebilmektir.
- **Dar ekrandan bakan.** Oturumların 0.86'sı dar ekranda, süre 6.5 dakika. Bu profilin
  kısıtı ekrandır: aynı sonuç listesi ona daha az satır gösterir, aynı eylem şeridi de ona sığmaz.

Üçüncü tablo her kümenin **temsili katılımcısını** veriyor: küme içindeki uzaklık toplamı en
küçük olan üye. Profil metni yazılırken bu katılımcının notları kullanılır, çünkü kümenin
ortasında duran gerçek bir kayıttır. Ortalama bir kişi değildir; ortalamaya en yakın kişidir.

#### Profilin Etik Sınırı

Profil, araştırma verisinden türetildiği için katılımcı verisinin taşıdığı bütün
yükümlülükleri devralır.

**Tek kişilik küme profil değildir.** Bir küme tek üyeye inerse, o profil bir kişinin
davranış kaydıdır; adı silinmiş olsa bile ekipteki biri onu tanır. Kural şudur: bir profil
en az üç katılımcının davranışını temsil etmiyorsa profil olarak yazılmaz, gözlem olarak
kalır. Yukarıdaki kümelerin üçü de dört üyelidir.

**Temsili katılımcının alıntısı da kimliksizleştirilir.** Profil metnine katılımcı sözü
alınırken kişiyi tanımlanabilir kılan ayrıntılar çıkarılır. Önceki derste konan ölçüt burada
da geçerlidir: veriden kimliğe geri gidilememelidir.

**Profil, onayın kapsamı içinde kalır.** Katılımcı araştırmaya katıldığında verisinin
tasarım kararlarında kullanılmasına onay verdi; adının bir profil kartında görünmesine değil.
Profillere uydurma ad verilmesinin tek savunulabilir gerekçesi budur, ama uydurma ad da
gerçek adı çağrıştırmayacak biçimde seçilir.

**Profil bir dışlama aracına dönüşmemelidir.** "Bu profil bizim kullanıcımız değil" cümlesi
kapsam kararı olarak yazılabilir, ama kimin ölçülmediğiyle birlikte yazılır. Üç profilin
hiçbiri ekran okuyucu kullanan bir katılımcıdan türemediyse, bu bir bulgu değil örneklem
eksikliğidir ve profil belgesine böyle geçer.

#### Özet

- Kullanıcı profili amaç, davranış ve kısıt üçlüsüdür; profildeki her satırın karşılığında
  bir tasarım kararı gösterilebilmelidir.
- Katılımcılar ölçülen davranışa göre kümelenir; ölçüler ortak aralığa taşınır ve uzaklık
  üzerinden birleştirilir.
- Örnek veride role göre gruplama beş grupla değişimin %22.3'ünü, davranışa göre gruplama
  üç grupla %95.8'ini açıkladı; rol ucuz ölçülür ama davranışı açıklamaz.
- Her kümenin temsili üyesi, küme içi uzaklık toplamı en küçük olan gerçek katılımcıdır;
  profil metni ortalama bir kişiden değil bu kayıttan yazılır.
- Bir profil en az üç katılımcıyı temsil etmiyorsa yazılmaz; profil, katılımcıyı yeniden
  tanımlanabilir kılmamalı ve örneklemin dışında kalanları bulgu gibi göstermemelidir.

#### Sonraki Adım

Üç profil elde edildi, ama profil tek başına bir yapılacak listesi değildir. "Konu tarayan"
profilinin oturumu yirmi bir buçuk dakika sürüyor — bu sürede tam olarak ne yapıyor, hangi
adımları sırayla izliyor ve hangi adımda ne beklemesi gerekiyor? Sonraki ders ihtiyacı eyleme
çevirir: kullanıcı hikâyesinin hangi biçimde yazıldığını, içine çözümün nasıl sızdığını ve
görevlerin sıklık ile başarısızlık verisine göre nasıl sıralandığını ele alır.

### Kullanıcı Hikâyeleri ve Görevler

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/kullanici-hikayeleri-ve-gorevler

İhtiyacın hikâyeye, hikâyenin göreve çevrilmesi; çözümün hikâyeye sızmasının denetlenmesi ve görev envanterinin sıklık, başarısızlık oranı ile kayıp deneme ölçütlerine göre sıralanması.

Önceki ders üç kullanıcı profili üretti: bilinen kaydı arayan, konu tarayan ve dar ekrandan
bakan. Profiller kimin geldiğini söylüyor, ne yaptığını söylemiyor. "Konu tarayan"
profilinin oturumu yirmi bir buçuk dakika sürüyor; bu sürede hangi adımlar var, hangi adım
hangi adımı gerektiriyor ve tasarımın hangisine öncelik vermesi gerekiyor?

Bu ders ihtiyacı eyleme çevirir. Önce ihtiyaç, hikâye ve görev ayrımını kurar; sonra bir
hikâyenin içine çözümün nasıl sızdığını denetler; en sonda gözlem verisinden çıkan görev
envanterini üç ayrı ölçütle sıralar ve bu sıralamaların birbirini tutmadığını gösterir.

#### İhtiyaç, Hikâye ve Görev

Üç kavram sık sık birbirinin yerine kullanılır ve karıştıkları yerde tasarım kararı
bulanıklaşır.

**İhtiyaç (need)** arayüzden bağımsızdır. "Bir konuda ne yazılmış olduğunu bilmek" bir
ihtiyaçtır; katalog arayüzü olmadan da vardır, kütüphaneci sorularak da karşılanabilir.

**Kullanıcı hikâyesi (user story)** ihtiyacı bir role ve bir amaca bağlar. Biçimi kısadır ve
üç parça taşır: kim, ne, niçin. Hikâye tek başına bir çözüm önermez; çözüm alanını
daraltır.

**Görev (task)** hikâyenin gözlenebilir karşılığıdır: başlangıcı, bitişi ve başarı ölçütü
olan bir eylem dizisi. "Konu tara" bir görevdir; başlar, biter ve başarılı sayılıp
sayılmadığı ölçülebilir. Görevler alt görevlere ayrıştırılır: konu taramanın içinde "sonucu
daralt", "kaydı aç", "listeye dön" adımları vardır.

Zincir tek yönlüdür. İhtiyaçtan hikâyeye, hikâyeden göreve, görevden arayüz kararına
inilir. Ters yönde yürünürse — önce bir arayüz ögesi düşünülüp sonra onu haklı çıkaracak
hikâye yazılırsa — araştırma verisi karar üretmez, kararı süsler.

#### Hikâyeye Çözüm Sızması

Hikâyenin en sık bozulma biçimi, ihtiyacın yerine bir arayüz ögesinin yazılmasıdır. "Yayın
yılı filtresi istiyorum" cümlesi ihtiyaç gibi görünür ama bir çözümdür; ihtiyaç "güncel
kaynakları ayırt etmek"tir ve filtre bunun tek karşılığı değildir. Aşağıdaki denetim
hikâyeleri biçim, rol ve sözcük düzeyinde tarar.

```js
// hikaye.mjs — kullanici hikayelerinin bicim ve cozum sizintisi denetimi

const HIKAYELER = [
  "Lisans öğrencisi olarak arama sonuçlarında yayın yılı filtresi istiyorum, böylece güncel kaynakları ayırabilirim",
  "Konu tarayan biri olarak bir kaydı açtıktan sonra sonuç listeme dönebilmek istiyorum, böylece karşılaştırmayı sürdürebilirim",
  "Akademisyen olarak açılır menüden dil seçmek istiyorum",
  "Kütüphane çalışanı olarak bir kaydın rafta olup olmadığını görmek istiyorum, böylece okuyucuya doğru bilgi verebilirim",
  "Kullanıcı olarak daha iyi bir arama ekranı istiyorum, böylece daha rahat ararım",
  "Dışarıdan üye olarak ödünç süremi uzatmak istiyorum, böylece kitabı iade etmeden çalışmayı sürdürebilirim",
];

// Bicim: <rol> olarak <ihtiyac> istiyorum, boylece <amac>
const BICIM = /^(.+?) olarak (.+?) istiyorum, böylece (.+)$/;
// Cozum sozlugu: arayuz ogesi adlandiran sozcukler
const COZUM = ["filtre", "düğme", "açılır menü", "sekme", "onay kutusu", "ekran", "sayfa", "form", "kaydırıcı"];
// Rol yerine gecmeyen genel adlar
const GENEL_ROL = ["kullanıcı", "kişi", "herkes", "insan"];

console.log("no  bicim  rol             bulgu");
HIKAYELER.forEach((h, i) => {
  const m = h.match(BICIM);
  const bulgular = [];
  if (!m) bulgular.push("bicim eksik (amac yazilmamis)");
  const rol = m ? m[1] : (h.split(" olarak ")[0] ?? "");
  if (GENEL_ROL.includes(rol.toLocaleLowerCase("tr"))) bulgular.push("rol genel");
  const sizan = COZUM.filter((c) => h.toLocaleLowerCase("tr").includes(c));
  if (sizan.length) bulgular.push(`cozum sizintisi: ${sizan.join(", ")}`);
  console.log(
    `${String(i + 1).padStart(2)}  ${(m ? "tam" : "eksik").padEnd(5)}  ${rol.slice(0, 14).padEnd(14)}  ${bulgular.length ? bulgular.join(" | ") : "-"}`
  );
});

const temiz = HIKAYELER.filter((h) => {
  const m = h.match(BICIM);
  const rol = m ? m[1] : "";
  return m && !GENEL_ROL.includes(rol.toLocaleLowerCase("tr")) &&
    !COZUM.some((c) => h.toLocaleLowerCase("tr").includes(c));
});
console.log(`\ndenetimi gecen hikaye: ${temiz.length} / ${HIKAYELER.length}`);
```

```
no  bicim  rol             bulgu
 1  tam    Lisans öğrenci  cozum sizintisi: filtre
 2  tam    Konu tarayan b  -
 3  eksik  Akademisyen     bicim eksik (amac yazilmamis) | cozum sizintisi: açılır menü
 4  tam    Kütüphane çalı  -
 5  tam    Kullanıcı       rol genel | cozum sizintisi: ekran
 6  tam    Dışarıdan üye   -

denetimi gecen hikaye: 3 / 6
```

Altı hikâyenin üçü denetimden geçiyor. Denetim bir doğruluk ölçüsü değil, bir gözden geçirme
aracıdır: sözcük listesine dayandığı için listede olmayan bir çözümü yakalamaz ve masum bir
kullanımı yanlışlıkla işaretleyebilir. İşlevi, tartışmayı üslup düzeyinden yapı düzeyine
taşımaktır.

Üç bulgunun her biri ayrı bir kusuru gösteriyor. Birinci hikâyede amaç doğru yazılmış ama
ihtiyacın yerini çözüm almış; düzeltilmiş biçimi "yayınları güncellik sırasına göre
görebilmek" olur ve filtre, sıralama, tarih aralığı gibi birden çok çözümü açık bırakır.
Üçüncü hikâyede amaç hiç yok: dil seçiminin niçin gerektiği yazılmadığı için hikâye
sınanamaz. Beşinci hikâyede rol "kullanıcı" — üç profilin hangisi olduğu belirsizdir ve
"daha rahat" ölçülemez.

#### Görev Envanteri ve Öncelik

Hikâyeler görevlere çevrildikten sonra sıra hangisinin önce ele alınacağındadır. Gözlem
döneminde her görev için deneme ve başarı sayıları kaydedildi.

```js
// gorev.mjs — gorev envanterinin siklik, basarisizlik orani ve kayip deneme ile siralanmasi

// Dort haftalik gozlem doneminde kaydedilen gorev denemeleri (ders icin kurulmus veri)
const GOREVLER = [
  { ad: "bilinen kaydi bul",  deneme: 148, basari: 132 },
  { ad: "raf konumunu bul",   deneme: 121, basari: 79 },
  { ad: "odunc al",           deneme: 94,  basari: 88 },
  { ad: "konu tara",          deneme: 86,  basari: 51 },
  { ad: "odunc suresini uzat", deneme: 37, basari: 19 },
  { ad: "rezerve et",         deneme: 22,  basari: 12 },
  { ad: "okuma listesine ekle", deneme: 14, basari: 13 },
];

for (const g of GOREVLER) {
  g.kayip = g.deneme - g.basari;
  g.oran = g.kayip / g.deneme;
}

console.log("gorev                  deneme  basari  kayip  basarisizlik orani");
for (const g of GOREVLER) {
  console.log(
    `${g.ad.padEnd(22)} ${String(g.deneme).padStart(6)} ${String(g.basari).padStart(7)} ${String(g.kayip).padStart(6)}  ${(g.oran * 100).toFixed(1)}%`
  );
}

const siraliAdlar = (anahtar) =>
  [...GOREVLER].sort((a, b) => b[anahtar] - a[anahtar]).map((g) => g.ad);
const SIRALAMALAR = {
  "siklik (deneme)": siraliAdlar("deneme"),
  "basarisizlik orani": siraliAdlar("oran"),
  "kayip deneme": siraliAdlar("kayip"),
};

console.log("\nsira  siklik                  basarisizlik orani      kayip deneme");
for (let i = 0; i < GOREVLER.length; i++) {
  console.log(
    `${String(i + 1).padStart(4)}  ${SIRALAMALAR["siklik (deneme)"][i].padEnd(23)} ` +
      `${SIRALAMALAR["basarisizlik orani"][i].padEnd(23)} ${SIRALAMALAR["kayip deneme"][i]}`
  );
}

// Ayni gorevin uc siralamadaki basamagi
console.log("\ngorev                  siklik  oran  kayip  en buyuk basamak farki");
let enBuyuk = { ad: "", fark: -1 };
for (const g of GOREVLER) {
  const s = Object.values(SIRALAMALAR).map((l) => l.indexOf(g.ad) + 1);
  const fark = Math.max(...s) - Math.min(...s);
  if (fark > enBuyuk.fark) enBuyuk = { ad: g.ad, fark };
  console.log(`${g.ad.padEnd(22)} ${String(s[0]).padStart(6)} ${String(s[1]).padStart(5)} ${String(s[2]).padStart(6)}  ${fark}`);
}
console.log(`\nen cok yer degistiren gorev: ${enBuyuk.ad} (${enBuyuk.fark} basamak)`);
console.log(`toplam kayip deneme: ${GOREVLER.reduce((t, g) => t + g.kayip, 0)}`);
const ilkIki = [...GOREVLER].sort((a, b) => b.kayip - a.kayip).slice(0, 2);
console.log(
  `kayip denemelerin ${((ilkIki.reduce((t, g) => t + g.kayip, 0) / GOREVLER.reduce((t, g) => t + g.kayip, 0)) * 100).toFixed(1)}%'i iki gorevde: ` +
    ilkIki.map((g) => g.ad).join(", ")
);
```

```
gorev                  deneme  basari  kayip  basarisizlik orani
bilinen kaydi bul         148     132     16  10.8%
raf konumunu bul          121      79     42  34.7%
odunc al                   94      88      6  6.4%
konu tara                  86      51     35  40.7%
odunc suresini uzat        37      19     18  48.6%
rezerve et                 22      12     10  45.5%
okuma listesine ekle       14      13      1  7.1%

sira  siklik                  basarisizlik orani      kayip deneme
   1  bilinen kaydi bul       odunc suresini uzat     raf konumunu bul
   2  raf konumunu bul        rezerve et              konu tara
   3  odunc al                konu tara               odunc suresini uzat
   4  konu tara               raf konumunu bul        bilinen kaydi bul
   5  odunc suresini uzat     bilinen kaydi bul       rezerve et
   6  rezerve et              okuma listesine ekle    odunc al
   7  okuma listesine ekle    odunc al                okuma listesine ekle

gorev                  siklik  oran  kayip  en buyuk basamak farki
bilinen kaydi bul           1     5      4  4
raf konumunu bul            2     4      1  3
odunc al                    3     7      6  4
konu tara                   4     3      2  2
odunc suresini uzat         5     1      3  4
rezerve et                  6     2      5  4
okuma listesine ekle        7     6      7  1

en cok yer degistiren gorev: bilinen kaydi bul (4 basamak)
toplam kayip deneme: 128
kayip denemelerin 60.2%'i iki gorevde: raf konumunu bul, konu tara
```

Üç sıralama üç ayrı listeye çıkıyor ve hiçbir görev üçünde de aynı basamakta değil.

**Sıklığa göre** birinci sırada "bilinen kaydı bul" var; en çok denenen görev budur. Ama
başarısızlık oranı %10.8'dir ve yüz kırk sekiz denemenin yalnızca on altısı kayıptır.
Sıklık tek başına tasarım önceliği vermez; çok yapılan ama iyi çalışan bir görev iyileştirme
alanı değildir.

**Başarısızlık oranına göre** birinci sırada "ödünç süresini uzat" var: %48.6. Bu oran
sorunun ciddiyetini doğru anlatır ama büyüklüğünü anlatmaz; görev otuz yedi kez denendi ve
on sekiz kayıp üretti.

**Kayıp denemeye göre** birinci sırada "raf konumunu bul" var: kırk iki kayıp. Bu görev
sıklıkta ikinci, başarısızlık oranında dördüncü — iki listede de birinci değil, ama toplam
zararın en büyük payını üretiyor. Toplam yüz yirmi sekiz kayıp denemenin %60.2'si iki
görevde toplanıyor.

Öncelik sıralaması, üçünden biri seçilerek değil, sorunun ne olduğu tanımlanarak kurulur.
Amaç toplam zararı azaltmaksa kayıp deneme sıralaması kullanılır. Amaç bir görevin
güvenilirliğini eşiğin üstüne çıkarmaksa başarısızlık oranı kullanılır. Sıklık ise tek
başına bir öncelik ölçütü değil, diğer ikisinin çarpanıdır: az denenen bir görevdeki yüksek
oran, çok denenen bir görevdeki düşük orandan daha az kayıp üretebilir.

Bir uyarı gerekir: bu sayılar yalnızca **denenmiş** görevleri sayar. Kullanıcının yapmak
isteyip yolunu bulamadığı ve hiç denemediği görev envantere girmez. "Okuma listesine ekle"
görevinin on dört denemesi, bu görevin ender olduğunu değil, ender **bulunduğunu** da
gösteriyor olabilir. Envanterin körlüğü budur ve ancak görüşmeyle kapatılır.

#### Görev Verisinin Etik Sınırı

Görev envanteri kişi başına oturum kaydından üretilir; bu, araştırma verisinin en
tanımlayıcı biçimidir. Üç kural burada da geçerlidir. Oturum kaydı **onay alınmış**
katılımcılardan toplanır; genel kullanıma açık bir arayüzde herkesin kaydını tutmak
araştırma değil izlemedir. Çözümlemeye giren veri **toplulaştırılmış** hâldir: yukarıdaki
tabloda kişi yok, görev var. Kişi başına kayıt, toplulaştırma yapıldıktan sonra **saklama
sınırı** içinde silinir; yalnızca sayılar kalır.

Buna bağlı bir tasarım kuralı da vardır: envanteri zenginleştirmek için toplanan her yeni
alan, kimliğe geri gitmenin bir yolunu daha açar. Görevin başarılı olup olmadığını bilmek
için kimin denediğini bilmek gerekmez.

#### Kabul Ölçütü Hikâyeyi Sınanabilir Kılar

Denetimden geçen bir hikâye bile tek başına yeterli değildir; ne zaman karşılandığı yazılı
olmalıdır. **Kabul ölçütü (acceptance criteria)**, hikâyenin doğrulanabilir karşılığıdır ve
görev üzerinden yazılır.

İkinci hikâye — "bir kaydı açtıktan sonra sonuç listeme dönebilmek" — şu ölçütlere bağlanır:
geri dönüşte arama terimi, uygulanan daraltmalar ve listedeki konum korunur; kullanıcının
daha önce açtığı kayıt listede işaretli kalır; dönüş, aramanın yeniden çalıştırılmasını
gerektirmez. Üçü de gözlenebilir; üçü de sınanabilir.

Ölçüt yazılırken çözüm yine dışarıda tutulur. "Geri düğmesi eklenir" bir ölçüt değil bir
karardır; ölçüt, hangi düğmeyle olursa olsun sonucun ne olması gerektiğini söyler.

#### Özet

- İhtiyaç arayüzden bağımsızdır, hikâye ihtiyacı role ve amaca bağlar, görev ise hikâyenin
  başlangıcı, bitişi ve başarı ölçütü olan gözlenebilir karşılığıdır.
- Hikâyeye çözüm sızması en sık bozulmadır; sözcük ve biçim denetimi bir doğruluk ölçüsü
  değil gözden geçirme aracıdır ve örnek altı hikâyenin üçünü işaretledi.
- Aynı görev envanteri sıklık, başarısızlık oranı ve kayıp deneme ölçütlerine göre üç ayrı
  sıralama üretir; örnek veride bir görev üç sıralama arasında dört basamak yer değiştirdi.
- Öncelik ölçütü sorunun tanımından türetilir: toplam zarar için kayıp deneme, güvenilirlik
  için başarısızlık oranı kullanılır; sıklık tek başına öncelik vermez.
- Envanter yalnızca denenmiş görevleri sayar; hiç denenmemiş görev görünmez ve bu körlük
  ancak görüşmeyle kapatılır.
- Oturum kaydı onaylı katılımcılardan toplanır, çözümlemeye toplulaştırılmış girer ve kişi
  başına kayıt saklama sınırı içinde silinir.

#### Sonraki Adım

Görev envanteri her görevi ayrı bir satır olarak gösteriyor, oysa kullanıcı bunları arka
arkaya yapıyor: bir kaydı buluyor, raf konumuna bakıyor, rafa gidiyor, bulamıyor ve
kataloğa geri dönüyor. Kayıp denemelerin en büyük payını üreten "raf konumunu bul" görevi,
ekranda başlayıp ekranın dışında biten bir adımdır. Sonraki ders bu zinciri uçtan uca
çıkarır: yolculuk haritasının hangi sütunlardan oluştuğunu, aşamaların süresiyle bırakma
noktalarının niçin aynı yerde olmadığını ve ekran dışındaki adımların haritaya nasıl
girdiğini gösterir.

### Yolculuk Haritaları

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/yolculuk-haritalari

Uçtan uca deneyimin aşamalara ayrılması; kanal payının, terk oranının ve kayıp kişi-dakikanın hesaplanması; en uzun aşamayla en çok bırakılan aşamanın niçin aynı olmadığı.

Görev envanteri her görevi ayrı bir satır olarak gösterdi, oysa kullanıcı bunları arka
arkaya yapıyor. "Raf konumunu bul" görevi ekranda başlıyor, rafın önünde bitiyor ve
başarısız olduğunda kullanıcı kataloğa geri dönüyor. Envanter bu zinciri göremez; her
görevi bağımsız bir olay olarak sayar.

**Yolculuk haritası (journey map)**, tek bir amacın uçtan uca izlenmesidir: kullanıcı nerede
başlar, hangi aşamalardan geçer, her aşamada ne kadar kalır ve nerede vazgeçer. Bu ders
haritanın sütunlarını kurar, bırakma noktalarını hesaplar ve en uzun aşamanın niçin en kötü
aşama olmadığını gösterir.

#### Haritanın Sütunları

Bir yolculuk haritası dört soruya sütun ayırır.

- **Aşama.** Kullanıcının amacı yolunda attığı bir adım. Aşama sınırı, kullanıcının bir
  karar verdiği ya da ortam değiştirdiği yerdedir; arayüz ekranlarıyla birebir örtüşmez.
- **Kanal.** Aşamanın geçtiği ortam. Katalog arayüzünde üç kanal var: ekran, kütüphanenin
  fiziksel alanı ve ödünç bankosu. Kanal sütunu olmayan bir harita, ekranda başlayıp ekranda
  biten bir yolculuk varsayar.
- **Ölçüm.** Aşamaya kaç kişi girdi, kaçı sonraki aşamaya geçti, aşamada ne kadar zaman
  geçti. Bu sütun gözlem verisinden gelir.
- **Bulgu.** Aşamada ne olduğu ve niçin olduğu. Bu sütun görüşmeden gelir; sayı değil,
  kodlanmış olgudur.

Son iki sütunun ayrı tutulması önemlidir. Ölçüm nerede kaybedildiğini söyler, bulgu niçin
kaybedildiğini söyler ve biri diğerinin yerine geçmez.

#### Yolculuğu Ölçmek

Aşağıdaki hesap "bilinen kaydı bul ve ödünç al" amacını yüz başlangıçtan izliyor. Her aşama
için giren ve çıkan sayısı ile aşamada geçen ortalama süre kaydedildi.

```js
// yolculuk.mjs — ucdan uca yolculugun asama asama sure, birakma ve kayip zaman hesabi

// "Bilinen kaydi bul ve odunc al" yolculugunun 100 baslangicta izlenmesi
// (ders icin kurulmus veri). kanal: asamanin gectigi ortam.
const ASAMALAR = [
  { ad: "katalogu ac",        kanal: "ekran",   giren: 100, cikan: 97, sure: 0.4 },
  { ad: "aramayi yaz",        kanal: "ekran",   giren: 97,  cikan: 92, sure: 1.1 },
  { ad: "sonuc listesini tara", kanal: "ekran", giren: 92,  cikan: 74, sure: 2.3 },
  { ad: "kayit ayrintisini oku", kanal: "ekran", giren: 74, cikan: 68, sure: 1.6 },
  { ad: "raf kodunu not et",  kanal: "ekran",   giren: 68,  cikan: 61, sure: 0.5 },
  { ad: "rafa git",           kanal: "fiziksel", giren: 61, cikan: 58, sure: 6.2 },
  { ad: "kitabi rafta bul",   kanal: "fiziksel", giren: 58, cikan: 39, sure: 4.8 },
  { ad: "odunc islemini yap", kanal: "banko",   giren: 39,  cikan: 37, sure: 2.1 },
];

console.log("asama                  kanal      giren  cikan  birakan  birakma orani  sure  toplam sure");
let toplamSure = 0;
for (const a of ASAMALAR) {
  a.birakan = a.giren - a.cikan;
  a.birakmaOrani = a.birakan / a.giren;
  toplamSure += a.sure;
  console.log(
    `${a.ad.padEnd(22)} ${a.kanal.padEnd(9)} ${String(a.giren).padStart(6)} ${String(a.cikan).padStart(6)} ` +
      `${String(a.birakan).padStart(8)} ${(a.birakmaOrani * 100).toFixed(1).padStart(13)}% ${a.sure.toFixed(1).padStart(5)} ${toplamSure.toFixed(1).padStart(11)}`
  );
}
console.log(`\nucdan uca tamamlama: ${ASAMALAR.at(-1).cikan} / ${ASAMALAR[0].giren}  (${ASAMALAR.at(-1).cikan}%)`);
console.log(`ucdan uca sure (tamamlayan icin): ${toplamSure.toFixed(1)} dk`);

// Kanal payi: yolculugun ne kadari ekranda gecti
const kanalSure = {};
for (const a of ASAMALAR) kanalSure[a.kanal] = (kanalSure[a.kanal] ?? 0) + a.sure;
console.log("\nkanal      sure   yolculuk payi");
for (const [k, s] of Object.entries(kanalSure)) {
  console.log(`${k.padEnd(10)} ${s.toFixed(1).padStart(4)} dk  ${((s / toplamSure) * 100).toFixed(1)}%`);
}

// Uc ayri "en kotu asama" tanimi ayni asamayi gostermiyor
const enBuyuk = (anahtar) => [...ASAMALAR].sort((a, b) => b[anahtar] - a[anahtar])[0];
for (const a of ASAMALAR) a.kayipDakika = a.birakan * a.sure;
console.log("\nolcut                    en kotu asama          deger");
console.log(`${"en uzun asama".padEnd(24)} ${enBuyuk("sure").ad.padEnd(24)} ${enBuyuk("sure").sure.toFixed(1)} dk`);
console.log(`${"en cok birakan".padEnd(24)} ${enBuyuk("birakan").ad.padEnd(24)} ${enBuyuk("birakan").birakan} kisi`);
console.log(`${"en yuksek birakma orani".padEnd(24)} ${enBuyuk("birakmaOrani").ad.padEnd(24)} ${(enBuyuk("birakmaOrani").birakmaOrani * 100).toFixed(1)}%`);
console.log(`${"en cok kayip dakika".padEnd(24)} ${enBuyuk("kayipDakika").ad.padEnd(24)} ${enBuyuk("kayipDakika").kayipDakika.toFixed(1)} kisi-dakika`);

// Birakanlarin harcadigi zaman: yolculuga girip cikamayanlarin toplam dakikasi
let harcanan = 0, tamamlayanZaman = ASAMALAR.at(-1).cikan * toplamSure;
for (let i = 0; i < ASAMALAR.length; i++) {
  harcanan += ASAMALAR[i].giren * ASAMALAR[i].sure;
}
console.log(`\ntoplam harcanan zaman: ${harcanan.toFixed(1)} kisi-dakika`);
console.log(`tamamlayanlarin zamani: ${tamamlayanZaman.toFixed(1)} kisi-dakika`);
console.log(`sonuca varmayan zaman orani: ${(((harcanan - tamamlayanZaman) / harcanan) * 100).toFixed(1)}%`);
```

```
asama                  kanal      giren  cikan  birakan  birakma orani  sure  toplam sure
katalogu ac            ekran        100     97        3           3.0%   0.4         0.4
aramayi yaz            ekran         97     92        5           5.2%   1.1         1.5
sonuc listesini tara   ekran         92     74       18          19.6%   2.3         3.8
kayit ayrintisini oku  ekran         74     68        6           8.1%   1.6         5.4
raf kodunu not et      ekran         68     61        7          10.3%   0.5         5.9
rafa git               fiziksel      61     58        3           4.9%   6.2        12.1
kitabi rafta bul       fiziksel      58     39       19          32.8%   4.8        16.9
odunc islemini yap     banko         39     37        2           5.1%   2.1        19.0

ucdan uca tamamlama: 37 / 100  (37%)
ucdan uca sure (tamamlayan icin): 19.0 dk

kanal      sure   yolculuk payi
ekran       5.9 dk  31.1%
fiziksel   11.0 dk  57.9%
banko       2.1 dk  11.1%

olcut                    en kotu asama          deger
en uzun asama            rafa git                 6.2 dk
en cok birakan           kitabi rafta bul         19 kisi
en yuksek birakma orani  kitabi rafta bul         32.8%
en cok kayip dakika      kitabi rafta bul         91.2 kisi-dakika

toplam harcanan zaman: 1249.2 kisi-dakika
tamamlayanlarin zamani: 703.0 kisi-dakika
sonuca varmayan zaman orani: 43.7%
```

#### Haritanın Söyledikleri

**Uçtan uca tamamlama %37.** Sekiz aşamanın hiçbirinde terk oranı üçte birden yüksek
değil, ama çarpımları yüzden otuz yediye indiriyor. Aşamaların tek tek "kabul edilebilir"
görünmesi, zincirin kabul edilebilir olduğu anlamına gelmez. Bir yolculuk haritasının ilk
işlevi, aşama başına iyi görünen sayıların çarpımını göstermektir.

**Ekran, yolculuğun yalnızca %31.1'i.** On dokuz dakikalık yolculuğun on bir dakikası fiziksel
alanda, iki dakikası bankoda geçiyor. Bu, katalog arayüzünün ölçümüyle görülemeyen bir bölgedir:
ekran ölçümü kullanıcının kataloğu kapattığı anda kör olur. Kullanıcı Profilleri dersindeki oturum
sürelerinin "bilinen kaydı arayan" profil için 4.3 dakika çıkması bu körlüğün sonucudur; bu
yolculukta kullanıcı altı dakika ekranda, on üç dakika ekranın dışındadır.

**En uzun aşama en kötü aşama değil.** "Rafa git" 6.2 dakikayla en uzun aşama, ama bırakma
oranı %4.9. Kullanıcı bu süreyi bekliyor ve kabul ediyor; yolculuğun beklenen bir
parçasıdır. "Kitabı rafta bul" aşaması 4.8 dakika sürüyor ve giren elli sekiz kişinin on
dokuzunu kaybediyor. Uzunluk bir sorun göstergesi değildir; sorun, harcanan zamanın sonuç
üretmemesidir.

**Kayıp kişi-dakika, aşamaları ortak bir birime çevirir.** Bırakan kişi sayısını aşamada
geçen süreyle çarpmak, o aşamada boşa giden zamanı verir. "Kitabı rafta bul" 91.2 kişi-dakika
üretiyor; toplam bin iki yüz kırk dokuz kişi-dakikanın %43.7'si sonuca varmayan zamandır.
Bu oran tasarım tartışmasını değiştirir: sorun "%37 tamamlama düşük" değil, "harcanan
zamanın kırk üç puanı karşılıksız" biçiminde konur.

**Ekran kararı, ekran dışı aşamayı etkiler.** En büyük kaybın ekran dışında olması, çözümün
de ekran dışında olduğu anlamına gelmez. "Raf kodunu not et" aşamasında altmış sekiz kişiden
yedisi düşüyor; geri kalanların bir kısmı da kodu yanlış not ediyor olabilir ve bunun bedeli
bir sonraki aşamada ödeniyor. Kayıt ayrıntısında raf kodunun nasıl gösterildiği, rafta
geçirilen 4.8 dakikayı doğrudan belirler. Harita bu bağı görünür kılar; görev envanteri
kılmaz.

#### Bırakma Noktası ile Bulgunun Ayrılması

Tablonun söylemediği şey, on dokuz kişinin rafta niçin bulamadığıdır. Olası nedenler
birbirinden çok farklı çözümler gerektirir: kitap ödünçtedir ama katalog güncel değildir,
kitap yanlış rafa konmuştur, raf kodu okunmuştur ama raf düzeni anlaşılmamıştır, ya da
kullanıcı doğru rafın önünde durup kitabı gözden kaçırmıştır.

Bunlardan hangisinin geçerli olduğu ölçümle değil, aşamanın ardından yapılan kısa görüşmeyle
belirlenir. İlk derste kodlanan `raf-kodu-anlasilmiyor` kodu on iki katılımcının yedisinde
geçmişti; bu bulgu üçüncü olasılığı destekler ama tek başına kanıtlamaz. Haritanın bulgu
sütunu, kodun hangi aşamaya ait olduğunu kaydeder — kod bir aşamaya bağlanmadığı sürece
tasarım kararına çevrilemez.

#### Ekran Dışı Gözlemin Etik Sınırı

Yolculuk haritası kullanıcıyı fiziksel alanda izlemeyi gerektirir ve bu, ekran kaydından
farklı yükümlülükler doğurur.

**Onay, izleme için ayrıca alınır.** Katalog kullanımına verilen onay, kişinin raflar
arasında izlenmesini kapsamaz. Eşlik eden gözlemde katılımcı gözlemcinin varlığını bilir;
gizli izleme araştırma yöntemi değildir.

**Üçüncü kişiler kayda girmez.** Fiziksel alanda yapılan gözlemde, onay vermemiş başka
kullanıcılar da görüş alanındadır. Not tutulurken yalnızca katılımcının davranışı yazılır;
çevredeki kişilerin görüntüsü, sesi ya da tanımlayıcı ayrıntısı kaydedilmez.

**Konum verisi en kısa sürede aşamaya indirgenir.** "Üçüncü kat, 4 numaralı raf, 11.20'de"
biçiminde bir kayıt kişiyi zaman ve mekânda tanımlar. Çözümlemeye giren veri aşama adı ve
süredir; ham konum ve saat, toplulaştırma yapıldıktan sonra saklama sınırı içinde silinir.

#### Özet

- Yolculuk haritası aşama, kanal, ölçüm ve bulgu sütunlarından oluşur; ölçüm nerede
  kaybedildiğini, bulgu niçin kaybedildiğini söyler ve biri diğerinin yerine geçmez.
- Aşama başına kabul edilebilir görünen terk oranları çarpılır; örnek veride sekiz
  aşamanın hiçbiri üçte biri aşmadığı hâlde uçtan uca tamamlama %37'de kaldı.
- Örnek yolculuğun yalnızca %31.1'i ekranda geçiyor; ekran ölçümü kullanıcı arayüzü
  kapattığında kör olur ve oturum süresi yolculuk süresi değildir.
- En uzun aşama en kötü aşama değildir; kayıp kişi-dakika ölçütü aşamaları ortak birime
  çevirir ve örnek veride harcanan zamanın %43.7'si sonuca varmadı.
- Fiziksel alandaki gözlem için ayrıca onay alınır, üçüncü kişiler kayda girmez ve ham
  konum–saat verisi aşamaya indirgendikten sonra silinir.

#### Sonraki Adım

Harita kendi arayüzümüzün nerede kaybettiğini gösteriyor, ama bu kayıpların kaçınılmaz olup
olmadığını söylemiyor. Aynı görevi çözen başka sistemler var ve onların hangi kararları
verdiği ölçülebilir bir veridir: kaç adımda tamamlıyorlar, hangi bilgiyi hangi ekranda
gösteriyorlar, hangi kararda birbirlerinden ayrılıyorlar? Sonraki ders var olan çözümlerin
nasıl okunacağını ele alır: adım sayısının karşılaştırılması, yerleşik alışkanlıkların
sapmadan ayrılması ve bir kararın niçin herkeste aynı olduğunun anlaşılması.

### Rakip ve Mevcut Durum Çözümlemesi

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/rakip-ve-mevcut-durum-cozumlemesi

Var olan çözümlerin karar karar okunması; yerleşik alışkanlığın benimseme oranıyla saptanması, sapmanın bedelinin adım sayısıyla ölçülmesi ve inceleme sırasında uyulan sınırlar.

Yolculuk haritası kendi arayüzümüzün nerede kaybettiğini gösterdi ama bu kayıpların
kaçınılmaz olup olmadığını söylemedi. Aynı işi yapan başka sistemler var ve verdikleri
kararlar dışarıdan gözlenebilir. Bu ders o gözlemi bir veri kümesine çevirir.

Amaç taklit değil. Var olan çözümlerin okunması iki ayrı bilgi verir. Birincisi, hangi
kararların **yerleşik** olduğu: bütün sistemlerde aynı biçimde çözülmüş bir sorun, kullanıcının
zaten öğrendiği bir örüntüdür ve ondan sapmak öğrenme maliyeti doğurur. İkincisi, hangi
kararların **açık** olduğu: sistemlerin birbirinden ayrıldığı yerler, tasarımcının gerçekten
karar vereceği yerlerdir.

#### Sistemleri Karara Ayırmak

Çözümleme, "hangisi daha iyi" sorusuyla değil, "hangi kararlar alınmış" sorusuyla başlar.
Her sistem bir karar listesine indirgenir ve liste bütün sistemler için aynıdır; ancak o
zaman karşılaştırılabilir.

Karar, gözlenebilir ve iki değerli olmalıdır: sistemde var mı, yok mu. "Arama iyi çalışıyor"
bir karar değil, bir yargıdır. "Kayıt açıldıktan sonra listeye dönüldüğünde arama terimi
korunuyor" bir karardır; bakılır ve yanıtı yazılır.

```js
// mevcut-durum.mjs — yerlesik aliskanliklarin saptanmasi ve adim sayisi karsilastirmasi

// A: su anki katalog arayuzumuz. B-E: ayni isi yapan, incelenen dort sistem.
// (ders icin kurulmus veri)
const SISTEMLER = ["A", "B", "C", "D", "E"];
const KARARLAR = [
  { ad: "arama alani ust orta", var: ["A", "B", "C", "D", "E"] },
  { ad: "odunc al kayit ayrintisinda", var: ["A", "B", "C", "D", "E"] },
  { ad: "geri donuste arama korunur", var: ["B", "C", "D", "E"] },
  { ad: "sonuc sayisi gosterilir", var: ["A", "B", "D", "E"] },
  { ad: "listede rafta mi rozeti", var: ["B", "C", "D"] },
  { ad: "daraltmalar solda", var: ["A", "B", "D"] },
  { ad: "okuma listesi", var: ["A", "C", "E"] },
  { ad: "konu agacindan gezinme", var: ["C", "D"] },
  { ad: "raf kodu listede", var: ["C"] },
  { ad: "kayit yeni sekmede acilir", var: ["E"] },
];

const N = SISTEMLER.length;
const sinif = (o) => (o >= 0.8 ? "yerlesik" : o >= 0.4 ? "bolunmus" : "ayirt edici");

console.log("karar                        benimseyen  oran  sinif        bizde");
const sapmalar = [];
for (const k of KARARLAR) {
  const oran = k.var.length / N;
  const bizde = k.var.includes("A");
  if (sinif(oran) === "yerlesik" && !bizde) sapmalar.push(k.ad);
  console.log(
    `${k.ad.padEnd(28)} ${k.var.join("").padEnd(11)} ${oran.toFixed(2)}  ${sinif(oran).padEnd(12)} ${bizde ? "var" : "YOK"}`
  );
}
console.log(`\nyerlesik aliskanliktan sapma: ${sapmalar.length ? sapmalar.join(", ") : "yok"}`);

// Ayni gorevin her sistemde kac ekran adimiyla tamamlandigi (sayarak gozlendi)
const GOREVLER = [
  { ad: "bilinen kaydi bul ve odunc al", adim: { A: 7, B: 5, C: 6, D: 5, E: 8 } },
  { ad: "konu tara ve uc kaydi karsilastir", adim: { A: 13, B: 9, C: 11, D: 12, E: 10 } },
];
const ortanca = (dizi) => {
  const s = [...dizi].sort((x, y) => x - y);
  const o = s.length >> 1;
  return s.length % 2 ? s[o] : (s[o - 1] + s[o]) / 2;
};

console.log("\ngorev                               " + SISTEMLER.map((s) => s.padStart(2)).join(" ") + "  en az  ortanca  bizim farkimiz");
for (const g of GOREVLER) {
  const degerler = SISTEMLER.map((s) => g.adim[s]);
  const ort = ortanca(degerler);
  const fark = g.adim.A - ort;
  console.log(
    `${g.ad.padEnd(34)} ${degerler.map((v) => String(v).padStart(2)).join(" ")}  ` +
      `${String(Math.min(...degerler)).padStart(5)}  ${String(ort).padStart(7)}  ${(fark >= 0 ? "+" : "") + fark} adim`
  );
}

// Karsilastirma gorevinin adim adim modeli: durum korunuyor mu korunmuyor mu
function adimSayisi(durumKorunur, kayitSayisi) {
  let a = 3; // terimi yaz, aramayi calistir, daraltmayi uygula
  for (let i = 0; i < kayitSayisi; i++) {
    a += 2; // kaydi ac, listeye don
    if (!durumKorunur && i < kayitSayisi - 1) a += 2; // terimi yeniden yaz, daraltmayi yeniden uygula
  }
  return a;
}
console.log("\nkarsilastirma gorevi modeli (3 kayit)");
console.log(`  durum korunuyor  : ${adimSayisi(true, 3)} adim`);
console.log(`  durum korunmuyor : ${adimSayisi(false, 3)} adim`);
console.log(`  farkin kaynagi   : ${adimSayisi(false, 3) - adimSayisi(true, 3)} adim, tek bir karardan`);
console.log(`  gozlenen A       : ${GOREVLER[1].adim.A} adim,  gozlenen en az (B): ${Math.min(...SISTEMLER.map((s) => GOREVLER[1].adim[s]))} adim`);

// Kayit sayisi arttikca fark nasil buyuyor
console.log("\nkarsilastirilan kayit  korunur  korunmaz  fark");
for (const k of [2, 3, 5, 8]) {
  const e = adimSayisi(true, k), h = adimSayisi(false, k);
  console.log(`${String(k).padStart(21)}  ${String(e).padStart(7)}  ${String(h).padStart(8)}  ${h - e}`);
}
```

```
karar                        benimseyen  oran  sinif        bizde
arama alani ust orta         ABCDE       1.00  yerlesik     var
odunc al kayit ayrintisinda  ABCDE       1.00  yerlesik     var
geri donuste arama korunur   BCDE        0.80  yerlesik     YOK
sonuc sayisi gosterilir      ABDE        0.80  yerlesik     var
listede rafta mi rozeti      BCD         0.60  bolunmus     YOK
daraltmalar solda            ABD         0.60  bolunmus     var
okuma listesi                ACE         0.60  bolunmus     var
konu agacindan gezinme       CD          0.40  bolunmus     YOK
raf kodu listede             C           0.20  ayirt edici  YOK
kayit yeni sekmede acilir    E           0.20  ayirt edici  YOK

yerlesik aliskanliktan sapma: geri donuste arama korunur

gorev                                A  B  C  D  E  en az  ortanca  bizim farkimiz
bilinen kaydi bul ve odunc al       7  5  6  5  8      5        6  +1 adim
konu tara ve uc kaydi karsilastir  13  9 11 12 10      9       11  +2 adim

karsilastirma gorevi modeli (3 kayit)
  durum korunuyor  : 9 adim
  durum korunmuyor : 13 adim
  farkin kaynagi   : 4 adim, tek bir karardan
  gozlenen A       : 13 adim,  gozlenen en az (B): 9 adim

karsilastirilan kayit  korunur  korunmaz  fark
                    2        7         9  2
                    3        9        13  4
                    5       13        21  8
                    8       19        33  14
```

#### Üç Karar Sınıfı

Benimseme oranı kararları üç sınıfa ayırır ve her sınıf ayrı bir tasarım tutumu gerektirir.

**Yerleşik karar (0.80 ve üstü).** Arama alanının üst ortada durması ve ödünç alma eyleminin
kayıt ayrıntısında bulunması beş sistemin beşinde de aynı. Bu kararlar tartışmaya açılmaz;
kullanıcı bunları başka yerlerde öğrenmiştir ve arayüz o öğrenmeyi devralır. Yerleşik
karardan sapmak yasak değildir, ama sapmanın karşılığında ölçülebilir bir kazanç
gösterilmelidir.

**Bölünmüş karar (0.40 – 0.80).** Rafta olma bilgisinin listede gösterilmesi, daraltmaların
konumu, okuma listesinin bulunması: sistemler ikiye ayrılıyor. Bu kararlar gerçek tasarım
kararlarıdır ve kendi kullanıcı verimizle çözülürler. Bölünmüş bir kararda "herkes böyle
yapıyor" savı kullanılamaz, çünkü herkes böyle yapmıyor.

**Ayırt edici karar (0.40 altı).** Raf kodunun listede gösterilmesi yalnızca C'de, kaydın
yeni sekmede açılması yalnızca E'de var. Bu kararlar ya bir üstünlüktür ya da denenip
yaygınlaşmamış bir seçimdir; ikisini ayırt etmenin tek yolu, o sistemin niçin böyle yaptığını
kendi bağlamında sormaktır. Kopyalanmaya en uygun görünen kararlar bunlardır ve en riskli
olanlar da bunlardır.

#### Sapmanın Bedeli Ölçülebilir

Karar listesinde tek bir yerleşik alışkanlık sapması var: geri dönüşte aramanın korunması
dört sistemde varken bizimkinde yok. İlk derste on iki görüşmenin dördünde geçen
`geri-donusta-arama-kayip` kodu ile aynı olguya bakıyoruz; şimdi bedeli sayıya bağlanıyor.

Adım modeli, üç kaydı karşılaştırma görevini iki koşulda kuruyor. Durum korunduğunda görev
dokuz adım, korunmadığında on üç adım. Fark dört adım ve tamamı tek bir karardan geliyor.
Gözlenen sayılar modeli doğruluyor: bizim arayüzümüz on üç adım, en az adımla tamamlayan
sistem dokuz adım.

Son tablo asıl kısıtı gösteriyor. Fark sabit değil; karşılaştırılan kayıt sayısıyla birlikte
büyüyor. İki kayıtta iki adım, üç kayıtta dört adım, sekiz kayıtta on dört adım. İkinci
derste kurulan "konu tarayan" profili tam olarak bu görevi yapıyor ve oturumu yirmi bir
buçuk dakika sürüyor. Sapmanın bedelini en çok ödeyen kullanıcı, arayüzü en çok kullanan
kullanıcıdır.

Buradan çıkan kural, karşılaştırmanın nasıl okunacağını belirler: **adım sayısı tek bir
görev için değil, görevin büyüklük aralığı için hesaplanır.** Küçük örnekte önemsiz görünen
bir fark, gerçek kullanımda doğrusal olarak büyüyebilir.

#### Ortanca ile En İyinin Farkı

Tabloda iki karşılaştırma ölçütü var ve ikisi ayrı sorulara yanıt veriyor. Ortancaya göre
fark, arayüzün alışılmış olandan ne kadar uzaklaştığını söyler; bilinen kaydı bulma görevinde
bir adım, karşılaştırma görevinde iki adım. En az adımla tamamlayan sisteme göre fark ise
ulaşılabilir sınırı söyler: karşılaştırma görevinde dört adım.

Hedef olarak ortanca seçilirse arayüz ortalama kalır. En iyi seçilirse hedef nettir ama o
sistemin başka kısıtları olabilir; sekiz adımla tamamlayan E sisteminin kaydı yeni sekmede
açması, bu görevde onu yavaşlatan ama başka bir görevde işine yarayan bir karardır. Bir
sistemin bir görevdeki üstünlüğü, bütün kararlarının doğru olduğu anlamına gelmez.

#### İncelemenin Sınırları

Var olan sistemleri incelemek, başkalarının arayüzüyle ve çoğu zaman başkalarının verisiyle
temas etmektir.

**Sıradan kullanıcı olarak incelenir.** Karar listesi, herkese açık arayüzde gözlenebilen
şeylerden oluşur. Kapalı bölümlere erişmek için sahte üyelik oluşturmak, başka bir kurumun
kayıtlarını toplu indirmek ya da erişim kısıtlarını aşmak inceleme değildir ve çözümlemenin
dışındadır.

**Başkasının kullanıcısı gözlenecekse aynı kurallar geçerlidir.** Bir başka kütüphanenin
kullanıcılarını izlemek, kendi katılımcılarımızı izlemekle aynı onay ve kimliksizleştirme
yükümlülüğünü doğurur; kurumun izni ayrıca alınır.

**İçerik değil karar aktarılır.** Bir sistemin kayıt açıklamaları, sınıflandırma verisi ya da
metinleri o kurumun emeğidir. Çözümlemeden alınan şey "arama terimi korunuyor" bilgisidir,
metnin kendisi değil.

**Karar listesi kaynağıyla birlikte saklanır.** Hangi sistemde, hangi tarihte, hangi görev
denenerek gözlendiği yazılır. Arayüzler değişir; tarihi olmayan bir karar listesi bir yıl
sonra doğrulanamaz.

#### Özet

- Çözümleme "hangisi daha iyi" sorusuyla değil, bütün sistemler için ortak ve iki değerli bir
  karar listesiyle yapılır.
- Benimseme oranı kararları yerleşik, bölünmüş ve ayırt edici olarak ayırır; yerleşikten
  sapmak ölçülebilir bir kazanç gerektirir, bölünmüş kararlar kendi verimizle çözülür.
- Örnek veride tek yerleşik sapma "geri dönüşte aramanın korunmaması"; adım modeli bu tek
  kararın üç kayıtlık karşılaştırmada dört adım eklediğini ve gözlenen sayılarla uyuştuğunu
  gösterdi.
- Sapmanın bedeli görev büyüklüğüyle birlikte artar: sekiz kaydın karşılaştırıldığı bir
  oturumda fark on dört adıma çıkıyor ve bedeli en çok arayüzü en çok kullanan öder.
- İnceleme herkese açık arayüzle sınırlıdır; sahte üyelik, toplu veri indirme ve içerik
  aktarımı çözümlemenin dışındadır ve karar listesi tarihiyle birlikte saklanır.

#### Sonraki Adım

Beş ders boyunca veri biriktirildi: on kod, üç profil, yedi görev, bir yolculuk haritası ve
bir karar listesi. Bu birikim henüz bir tasarım işi değil, bir malzeme yığınıdır. Sonraki
ders yığını tek bir cümleye indirger: problem tanımı. Bulguların hangi ölçütle
sıralanacağını, bir problem tanımının hangi parçalardan oluştuğunu ve içine çözümün
sızmasının niçin en sık yapılan hata olduğunu ele alır.

### Problem Tanımı

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/problem-tanimi

Beş dersin bulgularının tek tabloda birleştirilmesi; kanıt gücü ve kayıp zamana göre sıralama, problem tanımının parçaları ve çözümün tanıma sızmasının engellenmesi.

Beş ders boyunca veri biriktirildi: on kod, üç profil, yedi görev, bir yolculuk haritası ve
bir karar listesi. Bu birikim henüz bir tasarım işi değil. Elde tutulabilir hâle gelmesi
için tek bir soruya indirgenmesi gerekir: **hangi problem çözülüyor?**

Bu sorunun atlanması, araştırmanın en sık boşa gitme biçimidir. Bulgular toplanır, bir belgeye
yazılır, sonra da doğrudan ekran çizmeye geçilir. Çizilen ekran hangi bulguya yanıt verdiğini
söyleyemez; iyi ya da kötü olduğu sınanamaz, çünkü neyi çözmesi gerektiği yazılı değildir. Bu ders
önce bulguları sıralar, sonra sıralamanın tepesindeki bulguyu bir problem tanımına çevirir.

#### Bulguları Ortak Bir Birime Çevirmek

Bulgular farklı yöntemlerden geliyor ve doğrudan karşılaştırılamıyor: biri "yedi katılımcı
söz etti", öteki "kırk iki deneme kayıp", bir başkası "dört adım fazla". Karşılaştırma için
ortak bir birim gerekir. En savunulabilir birim, kullanıcının ödediği zamandır.

```js
// problem.mjs — bulgularin kanit gucu ve kayip zamana gore siralanmasi

// Bes dersin verisi tek tabloda birlestirildi (ders icin kurulmus veri).
// anan: 12 gorusmenin kacinda gecti. kaynak: bulguyu bagimsiz olarak gosteren
// veri turleri. deneme: dort haftalik donemde kayip deneme sayisi.
// dkBasina: bir kayip denemenin gozlenen ortalama maliyeti (dakika).
const BULGULAR = [
  { ad: "kitap rafta bulunamiyor", anan: 7, kaynak: ["gorusme", "gorev", "yolculuk"], deneme: 42, dkBasina: 4.8 },
  { ad: "geri donuste arama kayip", anan: 4, kaynak: ["gorusme", "gorev", "mevcut durum"], deneme: 35, dkBasina: 3.1 },
  { ad: "es adli kayit karisiyor", anan: 7, kaynak: ["gorusme", "gorev"], deneme: 16, dkBasina: 1.6 },
  { ad: "uzatma yolu bulunamiyor", anan: 2, kaynak: ["gorusme", "gorev"], deneme: 18, dkBasina: 2.4 },
  { ad: "daraltmalar gorunmuyor", anan: 3, kaynak: ["gorusme"], deneme: 12, dkBasina: 1.9 },
  { ad: "dar ekranda liste okunmuyor", anan: 2, kaynak: ["gorusme", "gorev"], deneme: 9, dkBasina: 2.7 },
];

const DONEM = 13; // yilda 13 tane dort haftalik donem
for (const b of BULGULAR) b.kayip = b.deneme * b.dkBasina;
const toplam = BULGULAR.reduce((t, b) => t + b.kayip, 0);

console.log("bulgu                        anan  kaynak  kayip dk/4 hafta  pay    yillik saat");
for (const b of [...BULGULAR].sort((a, c) => c.kayip - a.kayip)) {
  console.log(
    `${b.ad.padEnd(28)} ${String(b.anan).padStart(4)} ${String(b.kaynak.length).padStart(7)} ` +
      `${b.kayip.toFixed(1).padStart(17)}  ${((b.kayip / toplam) * 100).toFixed(1).padStart(4)}%  ${((b.kayip * DONEM) / 60).toFixed(1).padStart(11)}`
  );
}
console.log(`\ntoplam: ${toplam.toFixed(1)} dk / 4 hafta  =  ${((toplam * DONEM) / 60).toFixed(1)} saat / yil`);

// Iki siralama ayni sonucu vermiyor
const sirala = (anahtar) => [...BULGULAR].sort((a, b) => b[anahtar] - a[anahtar]).map((b) => b.ad);
const gorusmeSirasi = sirala("anan"), kayipSirasi = sirala("kayip");
console.log("\nsira  gorusmede anilma            kayip zaman");
for (let i = 0; i < BULGULAR.length; i++) {
  console.log(`${String(i + 1).padStart(4)}  ${gorusmeSirasi[i].padEnd(28)} ${kayipSirasi[i]}`);
}

// Kumulatif pay: kac bulgu kaybin cogunu acikliyor
console.log("\nkumulatif pay");
let birikim = 0;
[...BULGULAR].sort((a, b) => b.kayip - a.kayip).forEach((b, i) => {
  birikim += b.kayip;
  console.log(`  ilk ${i + 1} bulgu: ${((birikim / toplam) * 100).toFixed(1)}%`);
});

// Kanit gucu: tek kaynakli bulgu problem tanimina girmeden once dogrulanir
const zayif = BULGULAR.filter((b) => b.kaynak.length < 2);
console.log(`\ntek kaynakli bulgu: ${zayif.map((b) => b.ad).join(", ") || "yok"} (problem tanimindan once dogrulanir)`);
```

```
bulgu                        anan  kaynak  kayip dk/4 hafta  pay    yillik saat
kitap rafta bulunamiyor         7       3             201.6  47.3%         43.7
geri donuste arama kayip        4       3             108.5  25.5%         23.5
uzatma yolu bulunamiyor         2       2              43.2  10.1%          9.4
es adli kayit karisiyor         7       2              25.6   6.0%          5.5
dar ekranda liste okunmuyor     2       2              24.3   5.7%          5.3
daraltmalar gorunmuyor          3       1              22.8   5.4%          4.9

toplam: 426.0 dk / 4 hafta  =  92.3 saat / yil

sira  gorusmede anilma            kayip zaman
   1  kitap rafta bulunamiyor      kitap rafta bulunamiyor
   2  es adli kayit karisiyor      geri donuste arama kayip
   3  geri donuste arama kayip     uzatma yolu bulunamiyor
   4  daraltmalar gorunmuyor       es adli kayit karisiyor
   5  uzatma yolu bulunamiyor      dar ekranda liste okunmuyor
   6  dar ekranda liste okunmuyor  daraltmalar gorunmuyor

kumulatif pay
  ilk 1 bulgu: 47.3%
  ilk 2 bulgu: 72.8%
  ilk 3 bulgu: 82.9%
  ilk 4 bulgu: 88.9%
  ilk 5 bulgu: 94.6%
  ilk 6 bulgu: 100.0%

tek kaynakli bulgu: daraltmalar gorunmuyor (problem tanimindan once dogrulanir)
```

Üç bulgu okunuyor.

**Anılma, maliyet değildir.** "Eş adlı kayıt karışıyor" görüşmelerde yedi kez anıldı ve
anılma sıralamasında ikinci; kayıp zaman sıralamasında dördüncü. Bunun nedeni maliyetinin
düşük olmasıdır: yanlış kaydı açan kullanıcı yanlışı bir buçuk dakikada fark eder ve geri
döner. Görüşmede çok anılan olgular, en rahatsız edici olanlardır; en pahalı olanlar
değil. Rahatsızlık ve maliyet ayrı ölçütlerdir ve ikisi de yazılır, ama karıştırılmaz.

**Kayıp yoğunlaşıyor.** İlk iki bulgu toplam kaybın %72.8'ini, ilk üçü %82.9'unu açıklıyor. Altı
bulgunun altısını da çözmeye çalışmak, ilk ikisini çözmenin üç katı iş demektir ve kazancın dörtte
birini ekler. Öncelik kararının dayanağı budur.

**Kanıt gücü ayrı bir sütundur.** "Daraltmalar görünmüyor" bulgusu yalnızca görüşmeden
geliyor; ne görev verisinde ne karar listesinde bağımsız bir karşılığı var. Tek kaynaklı bir
bulgu yanlış olmak zorunda değildir, ama problem tanımına girmeden önce ikinci bir yöntemle
doğrulanır. Kanıt gücü düşük bir bulguyu tanıma yazmak, araştırmanın otoritesini
doğrulanmamış bir iddiaya ödünç vermektir.

Yıllık saat sütunu bir kestirimdir ve sınırı açıkça yazılmalıdır: dört haftalık bir
gözlemin on üç dönemle çarpılmasıdır, mevsimsel değişimi hesaba katmaz. Dönem başına
denemelerin dönem dışında da aynı kaldığı varsayılmıştır. Bu varsayım yazılmadığı sürece sayı
bir ölçüm gibi okunur, oysa bir çarpımdır.

#### Problem Tanımının Parçaları

Sıralamanın tepesindeki bulgu bir problem değil, bir gözlemdir. Problem tanımı beş parça
taşır.

- **Kim.** Hangi profil etkileniyor. "Kullanıcılar" değil; ikinci derste kurulan üç profilden
  hangisi.
- **Bağlam.** Sorun hangi görevde, hangi aşamada ve hangi koşulda ortaya çıkıyor.
- **Olgu.** Ne olmuyor. Gözlenebilir bir eksiklik olarak yazılır, bir istek olarak değil.
- **Kanıt.** Hangi ölçüm ve hangi yöntemle. Sayı ve kaynak birlikte yazılır.
- **Ölçüt.** Problem çözülmüş sayılırsa hangi sayı ne olacak. Ölçütü olmayan bir tanım
  kapanamaz.

Birinci bulgunun tanımı şöyle yazılır:

> Bilinen kaydı arayan ve dar ekrandan bakan profillerdeki kullanıcılar, raf koduyla rafın
> önüne gittiklerinde kitabı bulamıyor. Rafta arama aşamasına giren elli sekiz kullanıcının
> on dokuzu bu aşamada vazgeçiyor (%32.8); dört haftalık dönemde 201.6 kişi-dakika sonuçsuz
> harcanıyor. Bulgu üç kaynakta bağımsız olarak görülüyor: on iki görüşmenin yedisi, görev
> verisindeki kırk iki kayıp deneme ve yolculuk haritasındaki bırakma noktası. Problem,
> rafta arama aşamasındaki vazgeçme oranı %15'in altına indiğinde çözülmüş sayılır.

Bu metinde hiçbir arayüz ögesi geçmiyor. Raf kodunun nasıl gösterileceği, haritanın
eklenip eklenmeyeceği, kat planının konması gerekip gerekmediği tanımın dışındadır; hepsi
aynı tanımı karşılayabilecek adaylardır ve aralarında seçim yapılacaktır.

#### Tanımın Bozulma Biçimleri

Üç bozulma sık görülür ve üçü de tanımı sınanamaz kılar.

**Çözümün tanıma sızması.** "Kayıt ayrıntısında raf haritası eksik" bir problem tanımı değil,
seçilmiş bir çözümdür. Sızıntının belirtisi şudur: tanım bir arayüz ögesi adlandırıyorsa,
tasarım kararı zaten verilmiş demektir ve araştırma o kararı doğrulamak için kullanılıyordur.
Ayırt etme ölçütü, üçüncü derste konan ölçütün aynısıdır — tanımdan en az iki farklı çözüm
türetilebiliyor olmalıdır.

**Kullanıcının suçlanması.** "Kullanıcılar raf kodunu doğru okumuyor" cümlesi olguyu
kullanıcının kusuru olarak yazar ve tasarımı kapsam dışına çıkarır. Aynı olgu "raf kodu,
rafın önündeyken eşleştirilebilecek biçimde sunulmuyor" olarak yazıldığında çözüm alanı geri
açılır. Kural şudur: **problem tanımı arayüzün yapmadığı şeyi anlatır, kullanıcının yapmadığı
şeyi değil.**

**Ölçütün eksik kalması.** Ölçütü olmayan bir tanım hiçbir zaman kapanmaz; her yeni tasarım
"daha iyi" sayılır ve hiçbiri yeterli sayılmaz. Ölçüt seçilirken erişilebilir bir hedef
konur; %32.8'lik bir oranı sıfıra indirmeyi hedeflemek, kitabın gerçekten ödünçte olduğu
durumları da yok saymak demektir.

#### Problem Tanımının Etik Yükü

Tanım, araştırmanın kamuya dönük yüzüdür ve verinin bütün yükümlülüklerini taşır.

**Tanım katılımcıyı göstermez.** Metinde geçen sayılar toplulaştırılmış olmalıdır. "Gece
görevlisi olan katılımcı rafta bulamıyor" cümlesi bir kişiyi işaret eder; bu bilgi tanımda
değil, silinmiş ham notta kalır.

**Kapsam dışı bırakılanlar yazılır.** Örneklemde ekran okuyucu kullanan katılımcı yoksa,
tanım bu grubun sorunu hakkında bir şey söylemiyor demektir. Sessizlik yokluk değildir;
tanımın altına "bu grup ölçülmedi" satırı yazılır. İkinci derste profil için konan kural
burada tanım düzeyinde yinelenir.

**Sayının kaynağı izlenebilir kalır.** Tanımdaki her sayı, hangi yöntemle ve hangi dönemde
elde edildiğine geri götürülebilmelidir. Kaynağı gösterilemeyen bir sayı tanımdan çıkarılır;
kaynağı olmayan sayı, kanıt değil süstür.

#### Özet

- Farklı yöntemlerden gelen bulgular ortak bir birime — kullanıcının ödediği zamana —
  çevrilmeden karşılaştırılamaz.
- Görüşmede en çok anılan bulgu en pahalı bulgu değildir; örnek veride bir bulgu anılmada
  ikinci, maliyette dördüncü sırada çıktı.
- Kayıp yoğunlaşır: örnek veride ilk iki bulgu toplamın %72.8'ini açıkladı ve öncelik kararı
  bu yoğunlaşmaya dayanır.
- Kanıt gücü ayrı bir sütundur; tek kaynaklı bir bulgu problem tanımına girmeden önce ikinci
  bir yöntemle doğrulanır.
- Problem tanımı kim, bağlam, olgu, kanıt ve ölçüt parçalarını taşır; ölçütü olmayan tanım
  kapanmaz ve tanımdan en az iki farklı çözüm türetilebilmelidir.
- Tanım kullanıcının yapmadığını değil arayüzün yapmadığını anlatır, katılımcıyı göstermez ve
  ölçülmemiş grupları açıkça yazar.

#### Sonraki Adım

Problem tanımlandı: rafta arama aşamasındaki vazgeçme oranı düşürülecek ve konu tarayan
kullanıcının karşılaştırma yolu kısalacak. Çözüm alanı hâlâ açık ve ilk soru ekranların
kendisi değil, aralarındaki yapıdır. Katalog arayüzü binlerce kayıt, onlarca konu ve birkaç
işlem taşıyor; bunların hangi başlıklar altında toplanacağı bir üslup sorusu değildir.
Sonraki ders yapının içerikten nasıl türetildiğini gösterir: içerik envanterinin çıkarılması,
kart gruplama verisinin toplanması ve katılımcıların birlikte gruplama örüntüsünden benzerlik
matrisi kurulması.

## Bilgi Mimarisi ve Akış

İçerik envanterinden gruplamaya, gezinme modellerinden akış diyagramlarına; tel çerçeve ve prototip doğruluk düzeyleri, kullanılabilirlik sezgileri ve küçük örneklemle sorun bulma.

### İçerik Envanteri ve Gruplama

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/icerik-envanteri-ve-gruplama

Yapının içerikten türetilmesi; envanterin sütunları, kart gruplama verisinden benzerlik matrisi kurulması, eşikle gruplama ve üzerinde uzlaşılmayan kartların saptanması.

Problem tanımlandı ve çözüm alanı açık. İlk soru ekranların kendisi değil, aralarındaki
yapıdır. Katalog arayüzü binlerce kayıt, onlarca konu ve bir dizi işlem taşıyor; bunların
hangi başlıklar altında toplanacağı bir üslup sorusu değildir. Yanlış gruplama, kullanıcının
aradığı şeyi doğru yerde aramamasına ve hiçbir arama kutusunun kurtaramayacağı bir kayba yol
açar.

**Bilgi mimarisi (information architecture)**, içeriğin gruplanması, adlandırılması ve
aralarındaki ilişkilerin kurulmasıdır. Bu ders yapının nereden türetildiğini gösterir: önce
elde ne olduğunu sayan bir envanter, sonra kullanıcıların bu ögeleri nasıl grupladığını
ölçen bir çalışma.

#### Envanter Neyi Sayar

**İçerik envanteri (content inventory)**, arayüzün taşıdığı her ögenin listesidir. Liste
olmadan gruplama yapılamaz; gruplanan şeyin ne olduğu bilinmez. Envanterin beş sütunu vardır.

- **Öge.** İçeriğin adı. Ekran adı değil, içeriğin kendisi: "ödünç koşulları" bir ögedir,
  "yardım sayfası" bir kaptır.
- **Tür.** Kayıt mı, açıklama metni mi, işlem mi, dış bağlantı mı. Tür, ögenin nasıl
  gösterileceğini değil, nasıl gruplanabileceğini belirler.
- **Görev bağı.** Öge hangi göreve hizmet ediyor. Üçüncü derste kurulan görev envanterine
  bağlanır. Hiçbir göreve bağlanamayan öge, envanterde bir soru işaretiyle kalır.
- **Sahip.** İçeriği kim güncelliyor. Sahibi olmayan içerik eskir ve eskimiş içerik yanlış
  bilgidir.
- **Son güncelleme.** Ögenin ne kadar zamandır değişmediği.

Son iki sütun gruplama kararını doğrudan etkilemez ama envanterin en çok işe yarayan
parçasıdır: yapı kurulmadan önce silinmesi gereken içerik burada görünür. Katalog
arayüzünde hiçbir göreve bağlanamayan ve iki yıldır güncellenmemiş bir öge, gruplanacak
değil kaldırılacak bir ögedir.

#### Kullanıcı Gruplaması Ölçülür

Gruplamayı tasarım ekibinin yapması, kurumun kendi yapısını arayüze kopyalamasıyla
sonuçlanır. Kütüphanenin iç örgütlenmesinde "ödünç birimi" ile "referans birimi" ayrı
olabilir; kullanıcı bu ayrımı bilmez ve "kurumlar arası ödünç" ögesini hangi birimin
yürüttüğüne göre aramaz.

**Kart gruplama (card sorting)**, katılımcılara envanterdeki ögeleri kart olarak verip
kendilerine göre gruplamalarını istemektir. Grup adlarını katılımcı koyuyorsa açık, adlar
önceden veriliyorsa kapalı gruplamadır. Açık gruplama yapıyı ve adlandırmayı birlikte
ölçer; kapalı gruplama var olan bir yapının sınanmasına yarar.

Sonuç bir örüntü yığınıdır ve tek tek okunamaz. On katılımcının on ayrı gruplaması,
kartların birlikte gruplanma sayısına indirgenir.

```js
// kart-gruplama.mjs — kart gruplama verisinden benzerlik matrisi ve gruplama

// Envanterdeki 15 icerik ogesi ve her ogenin beklenen kumesi (dogrulanacak varsayim)
const KARTLAR = [
  ["arama ipuclari", "kesif"], ["konu basliklari", "kesif"], ["yeni gelenler", "kesif"],
  ["veri tabanlari", "kesif"], ["odunc kosullari", "odunc"], ["gecikme ucreti", "odunc"],
  ["uzatma", "odunc"], ["rezervasyon", "odunc"], ["kurumlar arasi odunc", "odunc"],
  ["raf plani", "yerinde"], ["calisma salonlari", "yerinde"], ["acilis saatleri", "yerinde"],
  ["uye olma", "hesap"], ["sifre yenileme", "hesap"], ["iletisim", "belirsiz"],
];
const KUMELER = ["kesif", "odunc", "yerinde", "hesap"];

// Belirlenimci sozde rastgele uretec (mulberry32)
function uretec(tohum) {
  let a = tohum >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = Math.imul(a ^ (a >>> 15), 1 | a);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}
const rnd = uretec(20260101);

// 10 katilimcinin kartlari gruplamasi: beklenen kumeye %80 uyum, "belirsiz" kart serbest
const KATILIMCI = 10;
const sortlar = [];
for (let k = 0; k < KATILIMCI; k++) {
  sortlar.push(
    KARTLAR.map(([, beklenen]) =>
      beklenen === "belirsiz" || rnd() > 0.8
        ? KUMELER[Math.floor(rnd() * KUMELER.length)]
        : beklenen
    )
  );
}

// Benzerlik matrisi: kac katilimci i ile j'yi ayni gruba koydu
const n = KARTLAR.length;
const M = Array.from({ length: n }, () => new Array(n).fill(0));
for (const s of sortlar)
  for (let i = 0; i < n; i++)
    for (let j = 0; j < n; j++) if (i !== j && s[i] === s[j]) M[i][j]++;

console.log("benzerlik matrisi (10 katilimcinin kaci ayni gruba koydu)");
console.log(" ".repeat(24) + KARTLAR.map((_, i) => String(i + 1).padStart(3)).join(""));
KARTLAR.forEach(([ad], i) => {
  console.log(
    `${String(i + 1).padStart(2)} ${ad.padEnd(21)}` +
      M[i].map((v, j) => (i === j ? "  ." : String(v).padStart(3))).join("")
  );
});

// Uzaklik = 1 - benzerlik; ortalama bag ile birlestir, esik 0.5'te dur
const uzak = (i, j) => 1 - M[i][j] / KATILIMCI;
let gruplar = KARTLAR.map((_, i) => [i]);
const bagUzakligi = (a, b) => {
  let t = 0;
  for (const i of a) for (const j of b) t += uzak(i, j);
  return t / (a.length * b.length);
};
const ESIK = 0.5;
while (gruplar.length > 1) {
  let en = Infinity, cift = null;
  for (let i = 0; i < gruplar.length; i++)
    for (let j = i + 1; j < gruplar.length; j++) {
      const d = bagUzakligi(gruplar[i], gruplar[j]);
      if (d < en) { en = d; cift = [i, j]; }
    }
  if (en > ESIK) break;
  const [i, j] = cift;
  gruplar = gruplar.filter((_, x) => x !== i && x !== j).concat([gruplar[i].concat(gruplar[j])]);
}
gruplar = gruplar.map((g) => g.sort((a, b) => a - b)).sort((a, b) => a[0] - b[0]);

console.log(`\nesik ${ESIK} ile olusan gruplar (${gruplar.length} grup)`);
for (const g of gruplar) console.log(`  ${g.map((i) => KARTLAR[i][0]).join(", ")}`);

// Her kartin kendi grubuna ve en yakin ikinci gruba baglilik farki
console.log("\nkart                 kendi grubu  en yakin diger  fark");
const ortBenzerlik = (i, g) => {
  const d = g.filter((x) => x !== i);
  return d.length ? d.reduce((t, j) => t + M[i][j], 0) / d.length / KATILIMCI : 0;
};
for (let i = 0; i < n; i++) {
  const kendi = gruplar.find((g) => g.includes(i));
  const a = ortBenzerlik(i, kendi);
  const digerleri = gruplar.filter((g) => g !== kendi).map((g) => ortBenzerlik(i, g));
  const b = digerleri.length ? Math.max(...digerleri) : 0;
  console.log(
    `${KARTLAR[i][0].padEnd(20)} ${a.toFixed(2).padStart(11)}  ${b.toFixed(2).padStart(14)}  ${(a - b).toFixed(2)}${a - b < 0.2 ? "  BELIRSIZ" : ""}`
  );
}
```

```
benzerlik matrisi (10 katilimcinin kaci ayni gruba koydu)
                          1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 1 arama ipuclari         .  9  8 10  1  1  0  0  1  0  1  1  2  0  2
 2 konu basliklari        9  .  7  9  1  1  0  0  1  0  2  2  2  0  2
 3 yeni gelenler          8  7  .  8  0  2  1  1  2  0  0  1  2  1  3
 4 veri tabanlari        10  9  8  .  1  1  0  0  1  0  1  1  2  0  2
 5 odunc kosullari        1  1  0  1  .  8  8  9  7  0  1  0  1  0  2
 6 gecikme ucreti         1  1  2  1  8  .  8  9  7  0  0  1  0  0  3
 7 uzatma                 0  0  1  0  8  8  .  9  7  0  1  0  1  1  3
 8 rezervasyon            0  0  1  0  9  9  9  .  8  0  1  0  0  0  3
 9 kurumlar arasi odunc   1  1  2  1  7  7  7  8  .  0  1  0  1  1  3
10 raf plani              0  0  0  0  0  0  0  0  0  .  6  8  2  1  5
11 calisma salonlari      1  2  0  1  1  0  1  1  1  6  .  7  0  1  3
12 acilis saatleri        1  2  1  1  0  1  0  0  0  8  7  .  1  0  3
13 uye olma               2  2  2  2  1  0  1  0  1  2  0  1  .  7  2
14 sifre yenileme         0  0  1  0  0  0  1  0  1  1  1  0  7  .  1
15 iletisim               2  2  3  2  2  3  3  3  3  5  3  3  2  1  .

esik 0.5 ile olusan gruplar (5 grup)
  arama ipuclari, konu basliklari, yeni gelenler, veri tabanlari
  odunc kosullari, gecikme ucreti, uzatma, rezervasyon, kurumlar arasi odunc
  raf plani, calisma salonlari, acilis saatleri
  uye olma, sifre yenileme
  iletisim

kart                 kendi grubu  en yakin diger  fark
arama ipuclari              0.90            0.20  0.70
konu basliklari             0.83            0.20  0.63
yeni gelenler               0.77            0.30  0.47
veri tabanlari              0.90            0.20  0.70
odunc kosullari             0.80            0.20  0.60
gecikme ucreti              0.80            0.30  0.50
uzatma                      0.80            0.30  0.50
rezervasyon                 0.88            0.30  0.57
kurumlar arasi odunc        0.72            0.30  0.42
raf plani                   0.70            0.50  0.20  BELIRSIZ
calisma salonlari           0.65            0.30  0.35
acilis saatleri             0.75            0.30  0.45
uye olma                    0.70            0.20  0.50
sifre yenileme              0.70            0.10  0.60
iletisim                    0.00            0.37  -0.37  BELIRSIZ
```

#### Matrisin Okunması

Matris, tek tek gruplamalardan çıkarılamayan bir yapıyı gösterir. Birinci ve dördüncü
kartlar — arama ipuçları ile veri tabanları — on katılımcının onunda aynı gruba konmuş.
Beşinci ile sekizinci kartlar dokuz katılımcıda birlikte. Bu değerler bir uzlaşma
ölçüsüdür: yüksek sayı, kullanıcıların o iki ögeyi aynı işin parçası saydığını gösterir.

Eşik 0.5 seçildi; yani iki öge, katılımcıların en az yarısında birlikte gruplanıyorsa aynı gruba
giriyor. Eşik bir doğa yasası değil, denetlenebilir bir karardır. Yükseltilirse daha çok ve daha
küçük grup çıkar; düşürülürse gruplar birleşir. Önemli olan eşiğin yazılmış olmasıdır: "bunlar
birlikte durmalı" cümlesi tartışılabilir, oysa "birlikte gruplanma oranı 0.7, eşik 0.5" cümlesi
denetlenebilir.

Beş grup çıktı ve dördü kendi içinde tutarlı. Beşinci "grup" tek kart taşıyor.

#### Uzlaşılmayan Kart Yapının En Önemli Bulgusudur

Son tablodaki bağlılık farkı, her kartın kendi grubuna olan ortalama bağlılığı ile en yakın
ikinci gruba olan bağlılığı arasındaki farktır. Fark büyükse kart yerini bulmuştur; küçükse
katılımcılar uzlaşmamıştır.

**İletişim** kartı hiçbir grubun içinde kalmadı. En yüksek bağlılığı 0.37 ile yerinde
kullanım grubuna; hiçbir eşiği geçmiyor. Bu bir veri kusuru değil, bir bulgudur: kullanıcılar
iletişim bilgisinin nerede aranacağı konusunda uzlaşmıyor. Böyle bir kart için üç seçenek
vardır ve seçim veriye göre yapılır.

- **Birden çok yerde gösterilir.** Bilgi ucuzsa ve kısaysa yinelenmesi zararsızdır; iletişim
  bilgisi hem yerinde kullanım grubunda hem hesap grubunda görünebilir.
- **Yapının dışına alınır.** Bazı ögeler gruplara değil, her ekranda erişilebilir bir alana
  aittir. Altbilgi bunun için vardır.
- **Bölünür.** "İletişim" tek bir öge olmayabilir: rafla ilgili soru sorma ile üyelik
  sorunu bildirme ayrı işlerdir ve ayrı gruplara giderler. Uzlaşmama, ögenin kendi içinde
  ikiye ayrıldığının işareti olabilir.

**Raf planı** kartı da işaretlendi: kendi grubuna bağlılığı 0.70 ama iletişim kartıyla
birlikte gruplanma oranı 0.50. Katılımcıların yarısı, rafın yerini sormakla rafın planına
bakmayı aynı iş sayıyor. Bu, dördüncü derste ölçülen "kitap rafta bulunamıyor" probleminin
bilgi mimarisi tarafındaki izidir: kullanıcı raf bilgisini nerede arayacağını bilmiyor.

#### Grupların Adlandırılması

Gruplar oluştu ama adları yok. Ad, kart gruplamanın açık biçiminde katılımcıların kendi
koyduğu adlardan çıkarılır; aynı grubu adlandıran on iki ifade içinden en sık kullanılan
sözcük seçilir. Kurumun iç sözlüğü buraya karışmamalıdır: kullanıcı "dolaşım hizmetleri"
demiyorsa başlık "dolaşım hizmetleri" olmaz.

Adlandırmada iki ölçüt vardır. Ad, grubun **bütününü** kapsamalıdır; "uzatma" başlığı beş
ögeli ödünç grubunun yalnızca birini adlandırır. Ad, komşu gruptan **ayırt edici**
olmalıdır; "kütüphane bilgileri" ile "genel bilgi" başlıkları yan yana durduğunda kullanıcı
hangisine gireceğini seçemez ve seçemediği için ikisini de dener.

#### Kart Gruplamanın Etik Çerçevesi

Kart gruplama bir araştırma oturumudur ve Kullanıcı Araştırması Yöntemleri dersinde kurulan
kurallar burada da geçerlidir: katılımcı ne için gruplama yaptığını bilerek onay verir, oturum
kaydı kod adıyla tutulur ve ham kayıt çözümlemeden sonra saklama sınırı içinde silinir. Yukarıdaki
matriste tek bir katılımcının gruplaması görünmüyor; yalnızca birlikte gruplanma sayıları var.

Envanterin kendisine ait iki kural daha eklenir. **Kişisel veri taşıyan içerik envanterde
işaretlenir**: ödünç geçmişi, üyelik bilgisi ve arama geçmişi kişiye bağlıdır ve bunların
gruplama kararı erişim kararıyla birlikte verilir. **Envanterde her kişisel veri ögesinin
saklama süresi yazılır**; süresi yazılmayan bir öge, arayüzde bir yere konmadan önce
belirsiz süreli saklanıyor demektir.

#### Özet

- İçerik envanteri öge, tür, görev bağı, sahip ve son güncelleme sütunlarını taşır; hiçbir
  göreve bağlanamayan ve güncellenmeyen öge gruplanacak değil kaldırılacak ögedir.
- Kart gruplama, yapının kurumun iç örgütlenmesinden değil kullanıcının zihinsel
  gruplamasından türetilmesini sağlar; açık biçim yapıyı ve adlandırmayı birlikte ölçer.
- Tek tek gruplamalar okunamaz; veri, kartların birlikte gruplanma sayısını veren benzerlik
  matrisine indirgenir ve yazılı bir eşikle gruplanır.
- Bağlılık farkı düşük olan kart bir kusur değil bulgudur; örnek veride bir kart hiçbir gruba
  bağlanamadı ve çözümü yineleme, yapının dışına alma ya da ögeyi bölmedir.
- Grup adları katılımcıların sözcüklerinden seçilir; ad grubun bütününü kapsamalı ve komşu
  gruptan ayırt edici olmalıdır.
- Kişisel veri taşıyan içerik envanterde işaretlenir ve saklama süresiyle birlikte yazılır.

#### Sonraki Adım

Beş grup ve grup adları elde edildi, ama bu henüz bir gezinme değil. Grupların kaç tanesinin
aynı anda gösterileceği, alt kırılımların kaç düzey ineceği ve kullanıcının bir ögeye kaç
tıklamayla ulaşacağı ayrı bir karardır. Sonraki ders hiyerarşik, düz ve matris gezinme
modellerini karşılaştırır; menü genişliği ile derinlik arasındaki ödünleşimi hesaplar ve
toplam tarama maliyetini en küçükleyen genişliği bulur.

### Gezinme Modelleri

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/gezinme-modelleri

Hiyerarşik, düz ve matris gezinmenin karşılaştırılması; menü genişliği ile derinlik arasındaki ödünleşimin hesaplanması ve yönelme maliyetinin en iyi genişliği nasıl kaydırdığı.

Kart gruplama beş grup ve grup adları üretti. Bu henüz bir gezinme değil. Grupların kaç tanesinin
aynı anda gösterileceği, alt kırılımların kaç düzey ineceği ve kullanıcının bir ögeye kaç adımda
ulaşacağı ayrı kararlardır ve birbirlerine bağlıdırlar: menü daraldıkça ağaç derinleşir ve
genişledikçe sığlaşır.

Bu ders üç gezinme modelini ayırır, sonra derinlik ile genişlik arasındaki ödünleşimi bir
maliyet modeliyle hesaplar. Sonuç, "menüde yedi öge olmalı" türünden bir kural değil,
hangi koşulda hangi genişliğin en ucuz olduğunu veren bir hesaptır.

#### Üç Model

**Hiyerarşik gezinme (hierarchical navigation)** ögeleri iç içe gruplara koyar. Kullanıcı
kökten başlar, her düzeyde bir seçim yapar ve yaprağa iner. Katalog arayüzünün konu ağacı
budur. Gücü, her düzeyde seçeneği azaltmasıdır; zayıflığı, hiyerarşinin **tek bir sıra**
dayatmasıdır — önce konu mu, önce materyal türü mü sorusunun bir yanıtı olmalıdır ve
kullanıcının zihnindeki sıra farklıysa bedel öder.

**Düz gezinme (flat navigation)** bütün ögeleri tek düzeyde gösterir. Derinlik yoktur,
kullanıcı hiçbir zaman kaybolmaz, her şey bir adım uzaktadır. Ölçeklenmez: öge sayısı
arttıkça tarama maliyeti doğrusal büyür.

**Matris gezinme (matrix navigation)** aynı ögelere birden çok bağımsız eksenden erişim
verir. Katalog arayüzünde bir kayda hem konudan hem materyal türünden ulaşılabiliyorsa
matris gezinme vardır. Gücü, kullanıcının kendi eksenini seçebilmesidir; bedeli, her
eksenin ayrı ayrı bakımıdır.

#### Genişlik ile Derinlik Arasındaki Ödünleşim

Bir ağaçta uç düğüm sayısı sabitken menü genişliği ile derinlik ters orantılıdır: genişlik `b`, uç
düğüm sayısı `N` ise derinlik yaklaşık `log_b N` olur. Genişlik arttıkça her düzeyde okunacak öge
artar; derinlik azaldıkça sayfa değişimi ve yeniden yönelme azalır. Hangi genişliğin daha ucuz
olduğu, bu iki maliyetin oranına bağlıdır.

```js
// derinlik-genislik.mjs — menu genisligi ile derinlik arasindaki odunlesim

const N = 1000;      // erisilecek uc dugum sayisi
const SAYFA = 1.2;   // her duzeyde sayfa degisimi ve yeniden yonelme (saniye)
const OGE = 0.12;    // menudeki bir ogeyi okuma (saniye)

const derinlik = (b) => Math.ceil(Math.log(N) / Math.log(b));

console.log(`N = ${N} uc dugum, duzey basina ${SAYFA} sn yonelme, oge basina ${OGE} sn okuma`);
console.log("genislik  derinlik  taranan oge  toplam sure");
let enIyi = { b: 0, sure: Infinity };
for (const b of [2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 20, 32, 64]) {
  const d = derinlik(b);
  const sure = d * (SAYFA + OGE * b);
  if (sure < enIyi.sure) enIyi = { b, sure };
  console.log(
    `${String(b).padStart(8)}  ${String(d).padStart(8)}  ${String(b * d).padStart(11)}  ${sure.toFixed(2).padStart(11)} sn`
  );
}
console.log(`\nen kucuk sure: genislik ${enIyi.b}, ${enIyi.sure.toFixed(2)} sn`);

// Yalnizca taranan oge sayisi olculseydi hangi genislik secilirdi
let enAzOge = { b: 0, oge: Infinity };
for (let b = 2; b <= 64; b++) {
  const t = b * derinlik(b);
  if (t < enAzOge.oge) enAzOge = { b, oge: t };
}
console.log(`yalnizca taranan oge olculseydi: genislik ${enAzOge.b}, ${enAzOge.oge} oge`);

// Yonelme maliyeti degistikce en iyi genislik nasil kayar
console.log("\nduzey basina yonelme  en iyi genislik  derinlik  sure");
for (const s of [0.0, 0.4, 1.2, 3.0, 6.0]) {
  let en = { b: 0, sure: Infinity, d: 0 };
  for (let b = 2; b <= 64; b++) {
    const d = derinlik(b), sure = d * (s + OGE * b);
    if (sure < en.sure) en = { b, sure, d };
  }
  console.log(
    `${s.toFixed(1).padStart(20)}  ${String(en.b).padStart(15)}  ${String(en.d).padStart(8)}  ${en.sure.toFixed(2)} sn`
  );
}
```

```
N = 1000 uc dugum, duzey basina 1.2 sn yonelme, oge basina 0.12 sn okuma
genislik  derinlik  taranan oge  toplam sure
       2        10           20        14.40 sn
       3         7           21        10.92 sn
       4         5           20         8.40 sn
       5         5           25         9.00 sn
       6         4           24         7.68 sn
       7         4           28         8.16 sn
       8         4           32         8.64 sn
      10         3           30         7.20 sn
      12         3           36         7.92 sn
      16         3           48         9.36 sn
      20         3           60        10.80 sn
      32         2           64        10.08 sn
      64         2          128        17.76 sn

en kucuk sure: genislik 10, 7.20 sn
yalnizca taranan oge olculseydi: genislik 2, 20 oge

duzey basina yonelme  en iyi genislik  derinlik  sure
                 0.0                2        10  2.40 sn
                 0.4                4         5  4.40 sn
                 1.2               10         3  7.20 sn
                 3.0               10         3  12.60 sn
                 6.0               32         2  19.68 sn
```

Üç sonuç okunuyor.

**En iyi genişlik ölçüte bağlıdır.** Yalnızca taranan öge sayısı sayılsaydı ikili menü
kazanırdı: yirmi öge okunur ve bu, tablodaki en küçük değerdir. Ama on düzey inmek gerekir
ve her düzeyin bir yönelme maliyeti vardır. Süre ölçüldüğünde ikili menü en pahalı
seçeneklerden biri olur: 14.40 saniye.

**Toplam süre yassı bir eğridir.** Genişlik 6 ile 12 arasında süre 7.20 ile 8.64 saniye arasında
kalıyor. Bu aralıkta seçim, hesabın değil başka kısıtların işidir: dar ekranda kaç ögenin sığdığı,
grup adlarının uzunluğu, kart gruplamadan çıkan grupların doğal sayısı. Hesap kararı vermez,
kararın hangi aralıkta serbest olduğunu söyler.

**Yönelme pahalıysa menü genişler.** Düzey başına yönelme sıfır olsaydı en iyi genişlik 2
olurdu; 1.2 saniyede 10'a, 6.0 saniyede 32'ye çıkıyor. Bunun tasarımdaki karşılığı doğrudan
bir kuraldır: sayfa geçişi yavaşsa, geçiş sırasında yer imi kayboluyorsa ya da kullanıcı her
düzeyde yeniden yön bulmak zorundaysa **derin ağaç pahalıya gelir ve menü genişletilir**.
Tersine, düzey geçişi anlıksa ve bağlam korunuyorsa derin ağaç ucuzdur.

Bu, beşinci derste ölçülen bir olguyla doğrudan bağlantılıdır: bizim arayüzümüzde geri dönüşte
arama durumu korunmuyor. Durumun korunmaması yönelme maliyetini yükseltir, yönelme maliyetinin
yükselmesi de derinliği pahalılaştırır. Aynı kusur iki ayrı yerde fatura çıkarıyor.

#### Kullanıcının Ekseni ile Menünün Ekseni

Hiyerarşinin dayattığı sıra ölçülebilir bir maliyet üretir. Katalog koleksiyonu iki eksenle
sınıflanabiliyor: yirmi dört konu başlığı ve beş materyal türü.

```js
// gezinme-modelleri.mjs — duz, hiyerarsik ve matris gezinmenin tarama maliyeti

const KONU = 24;   // konu basligi sayisi
const TUR = 5;     // materyal turu sayisi
const UC = KONU * TUR; // 120 uc dugum
const GERI = 1;    // yanlis eksende basladiktan sonra geri adim

// Ortalama tarama: aradigini bulana kadar listenin yarisi okunur
const duz = UC / 2;
const eslesen = KONU / 2 + TUR / 2;        // kullanicinin ekseni ile menunun ekseni ayni
const eslesmeyen = KONU + TUR / 2 + GERI;  // kullanici once tur dusunuyor, menu konu ile basliyor
const matris = KONU / 2 + TUR / 2;         // kullanici kendi ekseninden basliyor

console.log(`koleksiyon: ${KONU} konu x ${TUR} tur = ${UC} uc dugum`);
console.log("\nmodel              giris noktasi  uc dugume yol  ortalama taranan oge");
console.log(`${"duz".padEnd(18)} ${String(UC).padStart(13)} ${String(1).padStart(14)} ${duz.toFixed(1).padStart(21)}`);
console.log(`${"hiyerarsik".padEnd(18)} ${String(KONU).padStart(13)} ${String(1).padStart(14)} ${"degisken".padStart(21)}`);
console.log(`${"matris".padEnd(18)} ${String(KONU + TUR).padStart(13)} ${String(2).padStart(14)} ${matris.toFixed(1).padStart(21)}`);

console.log("\nhiyerarsik modelde kullanicinin ekseni menuyle eslesiyor mu");
console.log(`  eslesiyor   : ${eslesen.toFixed(1)} oge`);
console.log(`  eslesmiyor  : ${eslesmeyen.toFixed(1)} oge`);

console.log("\ntur ekseniyle dusunen oran  hiyerarsik  matris  fark");
for (const p of [0, 0.1, 0.2, 0.3, 0.4, 0.5]) {
  const h = eslesen * (1 - p) + eslesmeyen * p;
  console.log(
    `${p.toFixed(2).padStart(26)}  ${h.toFixed(2).padStart(10)}  ${matris.toFixed(2).padStart(6)}  ${(h - matris).toFixed(2)}`
  );
}

// Matrisin bedeli: iki eksen de her uc dugumu kapsamak zorunda
console.log("\nmatrisin bakim yuku");
console.log(`  konu ekseninde tutulacak baglanti : ${UC}`);
console.log(`  tur ekseninde tutulacak baglanti  : ${UC}`);
console.log(`  hiyerarside tutulacak baglanti    : ${UC}`);
console.log(`  matriste toplam                   : ${2 * UC}  (${((2 * UC) / UC).toFixed(1)} kat)`);
```

```
koleksiyon: 24 konu x 5 tur = 120 uc dugum

model              giris noktasi  uc dugume yol  ortalama taranan oge
duz                          120              1                  60.0
hiyerarsik                    24              1              degisken
matris                        29              2                  14.5

hiyerarsik modelde kullanicinin ekseni menuyle eslesiyor mu
  eslesiyor   : 14.5 oge
  eslesmiyor  : 27.5 oge

tur ekseniyle dusunen oran  hiyerarsik  matris  fark
                      0.00       14.50   14.50  0.00
                      0.10       15.80   14.50  1.30
                      0.20       17.10   14.50  2.60
                      0.30       18.40   14.50  3.90
                      0.40       19.70   14.50  5.20
                      0.50       21.00   14.50  6.50

matrisin bakim yuku
  konu ekseninde tutulacak baglanti : 120
  tur ekseninde tutulacak baglanti  : 120
  hiyerarside tutulacak baglanti    : 120
  matriste toplam                   : 240  (2.0 kat)
```

Düz gezinme yüz yirmi ögede ortalama altmış öge taratıyor; hiyerarşi ve matris on dört buçuk.
Bu, gruplamanın kendisinin dörtte birden fazla tasarruf ettiğini gösterir ve düz gezinmenin
sınırını verir: birkaç düzine ögeye kadar iyidir, yüzlerce ögede değildir.

Hiyerarşi ile matris arasındaki fark, kullanıcıların ne kadarının menünün ekseniyle
düşündüğüne bağlı. Herkes konudan düşünüyorsa fark sıfır. Beşte biri materyal türünden
düşünüyorsa hiyerarşi 2.6 öge daha pahalı; yarısı düşünüyorsa 6.5 öge. Matrisin kazancı
sabit bir üstünlük değil, **eksen uyuşmazlığının oranıyla** doğru orantılı bir kazançtır.

Bu oran tahmin edilmez, ölçülür. Önceki dersteki kart gruplama verisi tam olarak bunun
içindir: katılımcılar kartları hangi eksende grupladıysa, gezinmenin birincil ekseni odur.

Matrisin bedeli son bloktadır: her uç düğüm iki eksende de yer aldığı için tutulacak bağlantı
sayısı iki katına çıkar. Bu, çalışma zamanındaki maliyet değil bakım maliyetidir. Yeni bir
konu başlığı eklendiğinde iki eksenin de güncellenmesi gerekir ve eksenlerden biri güncel
kalmazsa aynı içerik iki farklı yerde iki farklı gerçeklik gösterir. Matris gezinme, iki
gezinmeyi tutarlı tutmayı üstlenebilen ekipler içindir.

#### Modelin Sınırları

Yukarıdaki hesaplar iki varsayıma dayanıyor ve ikisi de açıkça yazılmalıdır.

Birincisi, kullanıcının menüyü baştan sona tarayıp doğru ögeyi tanıdığı varsayılıyor.
Gerçekte kullanıcı bazen doğru ögeyi **tanımaz**: "kurumlar arası ödünç" başlığını arayan
kişi "ödünç işlemleri" grubuna girmeyi düşünmeyebilir. Bu durumda maliyet tarama değil,
yanlış dala girip geri dönme maliyetidir ve modelde yoktur.

İkincisi, arama kutusu hesaba katılmadı. Aramanın var olduğu bir arayüzde gezinme tek yol
değildir; kullanıcıların bir bölümü hiçbir menüye girmeden arar. Gezinme yapısı yine de
gerekir: arama ne aradığını bilene yarar, gezinme ne aradığını bilmeyene. İkinci derste
kurulan "konu tarayan" profili tam olarak ikinci gruptadır.

#### Özet

- Hiyerarşik gezinme her düzeyde seçeneği azaltır ama tek bir sıra dayatır; düz gezinme
  ölçeklenmez; matris gezinme birden çok eksenden erişim verir.
- Genişlik ile derinlik ters orantılıdır ve en iyi genişlik ölçüte bağlıdır: taranan öge
  sayısı en aza indirilecekse dar menü, süre en aza indirilecekse geniş menü kazanır.
- Örnek modelde toplam süre genişlik 6 ile 12 arasında yassı kalıyor; hesap kararı vermez,
  kararın hangi aralıkta serbest olduğunu söyler.
- Düzey başına yönelme maliyeti arttıkça en iyi genişlik büyür; durumun korunmaması gibi
  kusurlar yönelmeyi pahalılaştırarak derin ağaçları da pahalılaştırır.
- Matrisin hiyerarşiye üstünlüğü, kullanıcıların ne kadarının menünün ekseni dışında
  düşündüğüyle orantılıdır ve bedeli tutulacak bağlantı sayısının iki katına çıkmasıdır.

#### Sonraki Adım

Gezinme yapısı ögelere nasıl ulaşıldığını anlatıyor, ama bir görevin içindeki kararları
anlatmıyor. Ödünç alma eylemi tek bir tıklama değildir: üyelik doğrulanır, kaydın durumu
denetlenir, ödünçteyse rezervasyon önerilir ve üyenin gecikmiş kitabı varsa işlem durur. Bu
dallanmalar yazıyla anlatıldığında hangi durumun hangi duruma bağlandığı kaybolur. Sonraki ders
akışı bir çizge olarak kurar ve iki kusuru hesapla arar: başlangıçtan erişilemeyen durum ve çıkışı
olmayan düğüm.

### Akış Diyagramları

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/akis-diyagramlari

Akışın çizge olarak kurulması; erişilemeyen durumun ve çıkışsız düğümün hesapla aranması, çevrimin kusur olup olmadığının ayrılması ve yol sayısının sınama yükünü belirlemesi.

Gezinme yapısı ögelere nasıl ulaşıldığını anlatıyor ama bir görevin içindeki kararları anlatmıyor.
Ödünç alma tek bir tıklama değildir: oturum açık mı diye bakılır, kaydın durumu denetlenir, kayıt
ödünçteyse rezervasyon önerilir ve üyenin gecikmiş kitabı varsa işlem durur. Bu dallanmalar düz
yazıyla anlatıldığında hangi durumun hangi duruma bağlandığı kaybolur ve eksik dallar fark
edilmez.

**Akış diyagramı (flow diagram)** bu yapıyı açık hâle getirir: her durum bir düğüm, her
geçiş bir kenardır. Diyagramın değeri çizim olmasında değil, **denetlenebilir** olmasındadır.
Veri Yapıları kursunda tanıtılan çizge kavramı burada doğrudan işe yarar: bir akış çizge
olarak yazıldığı anda, üzerinde çalışan sorular hesapla yanıtlanır.

#### Akışın Düğümleri ve Geçişleri

Üç düğüm türü vardır ve ayrılmaları gerekir.

- **Durum düğümü.** Kullanıcının bulunduğu bir yer: giriş ekranı, kayıt ayrıntısı, ödünç
  onayı. Kullanıcı burada bir şey görür.
- **Karar düğümü.** Sistemin ya da kullanıcının bir dallanma ürettiği nokta: oturum var mı,
  gecikmiş kitap var mı. Karar düğümünün çıkışları **birbirini dışlamalı** ve **bütün
  durumları kapsamalıdır**; iki dallı bir karardan yalnızca bir dal çıkıyorsa diyagram
  eksiktir.
- **Bitiş düğümü.** Akışın tamamlandığı yer. Bir akışta birden çok bitiş olabilir ve
  hepsi başarı olmak zorunda değildir; vazgeçme de bir bitiştir ve yazılır.

Yazılmayan bitiş, tasarlanmamış bitiştir. Kullanıcı yine de vazgeçer, ama nereye düştüğü
belirsizdir.

#### İki Kusurun Aranması

Çizge yazıldıktan sonra iki kusur hesapla aranır. **Erişilemeyen durum**, başlangıçtan hiçbir
geçiş dizisiyle ulaşılamayan düğümdür; tasarlanmış ama akışa bağlanmamış bir ekrandır.
**Çıkışsız düğüm**, hiçbir bitişe ulaşamayan düğümdür; kullanıcının içine düşüp
çıkamayacağı bir yerdir.

```js
// akis.mjs — akis cizgesinde erisilemeyen durum, cikissiz dugum ve yol sayimi

// Odunc alma akisinin dugumleri ve gecisleri (ders icin kurulmus veri)
const BASLANGIC = "basla";
const BITISLER = ["odunc basarili", "rezervasyon basarili", "vazgec"];
const GECIS = {
  "basla": ["oturum var mi"],
  "oturum var mi": ["kayit durumu", "giris ekrani"],
  "giris ekrani": ["kayit durumu", "giris hatasi"],
  "giris hatasi": ["giris ekrani", "vazgec"],
  "kayit durumu": ["rafta", "oduncte"],
  "rafta": ["gecikmis kitap var mi"],
  "gecikmis kitap var mi": ["borc odeme", "odunc onayi"],
  "borc odeme": ["odunc onayi"],
  "odunc onayi": ["odunc basarili", "sistem hatasi"],
  "oduncte": ["rezervasyon onerisi"],
  "rezervasyon onerisi": ["rezervasyon onayi", "vazgec"],
  "rezervasyon onayi": ["rezervasyon basarili"],
  "uye degil bilgisi": ["vazgec"],
  "sistem hatasi": [],
  "odunc basarili": [],
  "rezervasyon basarili": [],
  "vazgec": [],
};
const DUGUMLER = Object.keys(GECIS);

// 1. Baslangictan erisilebilen dugumler
const gez = (baslangic, komsu) => {
  const g = new Set([baslangic]), yigit = [baslangic];
  while (yigit.length) for (const k of komsu(yigit.pop())) if (!g.has(k)) { g.add(k); yigit.push(k); }
  return g;
};
const erisilen = gez(BASLANGIC, (d) => GECIS[d]);

// 2. Bir bitise ulasabilen dugumler (ters cizgede gezinme)
const TERS = {};
for (const d of DUGUMLER) TERS[d] = [];
for (const [d, komsular] of Object.entries(GECIS)) for (const k of komsular) TERS[k].push(d);
const ulasan = new Set();
for (const b of BITISLER) for (const d of gez(b, (x) => TERS[x])) ulasan.add(d);

console.log("dugum                    giris  cikis  baslangictan  bitise");
for (const d of DUGUMLER) {
  console.log(
    `${d.padEnd(24)} ${String(TERS[d].length).padStart(5)} ${String(GECIS[d].length).padStart(6)} ` +
      `${(erisilen.has(d) ? "erisilir" : "ERISILMEZ").padStart(13)} ${(ulasan.has(d) ? "ulasir" : "ULASMAZ").padStart(7)}`
  );
}

const erisilemez = DUGUMLER.filter((d) => !erisilen.has(d));
const cikissiz = DUGUMLER.filter((d) => !ulasan.has(d));
console.log(`\nerisilemeyen dugum : ${erisilemez.join(", ") || "yok"}`);
console.log(`cikissiz dugum     : ${cikissiz.join(", ") || "yok"}`);

// 3. Cevrim var mi (donen yol)
const RENK = {};
const cevrimler = [];
(function ara(d, yol) {
  RENK[d] = 1;
  for (const k of GECIS[d]) {
    if (RENK[k] === 1) cevrimler.push([...yol.slice(yol.indexOf(k)), k].join(" -> "));
    else if (!RENK[k]) ara(k, [...yol, k]);
  }
  RENK[d] = 2;
})(BASLANGIC, [BASLANGIC]);
console.log(`cevrim             : ${cevrimler.join(" | ") || "yok"}`);

// 4. Baslangictan bitislere giden yinelemesiz yollar
const yollar = [];
(function yuru(d, yol) {
  if (BITISLER.includes(d)) { yollar.push(yol); return; }
  for (const k of GECIS[d]) if (!yol.includes(k)) yuru(k, [...yol, k]);
})(BASLANGIC, [BASLANGIC]);

console.log(`\nyinelemesiz yol sayisi: ${yollar.length}`);
const uzunluklar = yollar.map((y) => y.length - 1);
console.log(`en kisa yol: ${Math.min(...uzunluklar)} gecis, en uzun yol: ${Math.max(...uzunluklar)} gecis`);
console.log("\nbitis                 yol sayisi  en kisa");
for (const b of BITISLER) {
  const bunlar = yollar.filter((y) => y.at(-1) === b);
  console.log(
    `${b.padEnd(21)} ${String(bunlar.length).padStart(10)}  ${bunlar.length ? Math.min(...bunlar.map((y) => y.length - 1)) : "-"}`
  );
}
console.log("\nen kisa basarili yol:");
console.log("  " + yollar.filter((y) => y.at(-1) === "odunc basarili").sort((a, b) => a.length - b.length)[0].join(" -> "));
```

```
dugum                    giris  cikis  baslangictan  bitise
basla                        0      1      erisilir  ulasir
oturum var mi                1      2      erisilir  ulasir
giris ekrani                 2      2      erisilir  ulasir
giris hatasi                 1      2      erisilir  ulasir
kayit durumu                 2      2      erisilir  ulasir
rafta                        1      1      erisilir  ulasir
gecikmis kitap var mi        1      2      erisilir  ulasir
borc odeme                   1      1      erisilir  ulasir
odunc onayi                  2      2      erisilir  ulasir
oduncte                      1      1      erisilir  ulasir
rezervasyon onerisi          1      2      erisilir  ulasir
rezervasyon onayi            1      1      erisilir  ulasir
uye degil bilgisi            0      1     ERISILMEZ  ulasir
sistem hatasi                1      0      erisilir ULASMAZ
odunc basarili               1      0      erisilir  ulasir
rezervasyon basarili         1      0      erisilir  ulasir
vazgec                       3      0      erisilir  ulasir

erisilemeyen dugum : uye degil bilgisi
cikissiz dugum     : sistem hatasi
cevrim             : giris ekrani -> giris hatasi -> giris ekrani

yinelemesiz yol sayisi: 9
en kisa yol: 4 gecis, en uzun yol: 8 gecis

bitis                 yol sayisi  en kisa
odunc basarili                 4  6
rezervasyon basarili           2  6
vazgec                         3  4

en kisa basarili yol:
  basla -> oturum var mi -> kayit durumu -> rafta -> gecikmis kitap var mi -> odunc onayi -> odunc basarili
```

#### İki Kusurun Anlamı

**Üye değil bilgisi** düğümüne hiçbir geçiş girmiyor. Bu ekran tasarlanmış: üye olmayan bir
ziyaretçinin ödünç alamayacağını anlatıyor ve vazgeçmeye bağlanıyor. Ama akışta bu duruma
düşülmüyor. Giriş ekranından çıkan iki dal var — başarılı ve hatalı — ve "kişi zaten üye
değil" durumu hiçbirinde değil. Kusur ekranda değil, karar düğümünün eksik dallanmasında.
Erişilemeyen ekranlar çoğu zaman bir kararın eksik yazıldığının kanıtıdır.

**Sistem hatası** düğümünden hiçbir geçiş çıkmıyor. Kullanıcı ödünç onayı sırasında bir
sistem hatasıyla karşılaşırsa bu düğüme düşüyor ve hiçbir bitişe ulaşamıyor. Arayüz Tasarımının
Temelleri kursundaki Hata ve Uyarı Durumları dersinde konan kural burada çizge diliyle
yeniden ifade edilir: **her hata durumundan en az bir çıkış olmalıdır.** Çıkış "yeniden dene"
olabilir, "vazgeç" olabilir; olmaması bir seçenek değildir.

`basla` düğümünün giriş sayısının sıfır olması bir kusur değildir; başlangıç düğümü tanımı
gereği böyledir. Denetimin bunu ayırt etmesi için başlangıç ayrıca bildirilir.

#### Çevrim Bir Kusur Değildir

Denetim bir çevrim buldu: giriş ekranı ile giriş hatası arasında. Kullanıcı yanlış parola
girdiğinde hata ekranına düşüyor, oradan giriş ekranına dönüyor ve yeniden deniyor.

Bu bir kusur değil, tasarlanmış bir yeniden denemedir. Çevrimin kusur olup olmadığını
belirleyen tek ölçüt vardır: **çevrimden çıkan bir kenar var mı?** Giriş hatası düğümünün iki
çıkışı var — giriş ekranı ve vazgeç — dolayısıyla kullanıcı döngüde kilitlenmez. Çıkışı
olmayan bir çevrim, çıkışsız düğümün çok düğümlü hâlidir.

Çevrimin ikinci sorusu, kaç kez dönülebileceğidir. Sonsuz deneme parola güvenliği açısından
sorunlu, sıfır deneme kullanılabilirlik açısından sorunludur; diyagramda bu, geçişin
üzerine yazılan bir koşulla belirtilir ve koşul yazılmadıysa karar verilmemiş demektir.

#### Yol Sayısı Sınama Yükünü Belirler

Başlangıçtan bitişlere giden dokuz yinelemesiz yol var. Bu sayı doğrudan bir sınama
bütçesidir: akışı tam sınamak, dokuz ayrı senaryo yürütmek demektir. En kısa yol dört geçiş
(vazgeçmeye giden yol), en uzunu sekiz geçiş.

Başarılı ödünç almanın en kısa yolu altı geçiş ve dört farklı yolu var. Dört yolun kaynağı
iki ikili karardır: oturum açık mı ve gecikmiş kitap var mı. İki ikili karar dört bileşim
üretir; buna sistem hatası dalı eklenmediği için sayı dörtte kalıyor.

Yol sayısının hızla büyümesi, akış tasarımının en pratik ölçütünü verir: **her yeni ikili
karar, sınanacak yol sayısını yaklaşık iki katına çıkarır.** Bir kararın gerçekten gerekli
olup olmadığı bu maliyetle birlikte sorulur. "Gecikmiş kitap var mı" kararı gereklidir çünkü
kurumun kuralıdır; "kullanıcı daha önce bu kaydı görüntülemiş mi" kararı bir kolaylık
sağlayabilir ama sınama yükünü ikiye katlar.

Aynı hesap küçük bir sadeleştirme de öneriyor. Borç ödeme düğümünün tek çıkışı var ve doğrudan
ödünç onayına gidiyor; yani borç ödendikten sonra başarısızlık dalı yazılmamış. Ödeme başarısız
olabilecek bir işlemse diyagram eksik; olamayacak bir işlemse düğüm bir karar değil bir
bilgilendirmedir ve akıştan çıkarılabilir. Tek çıkışlı düğümler her zaman bu soruyu davet eder.

#### Diyagramın Sınırı

Akış çizgesi durumları ve geçişleri gösterir, **zamanı** göstermez. Bir geçişin ne kadar
sürdüğü, kullanıcının bir düğümde ne kadar beklediği ve bekleme sırasında ne gördüğü çizgede
yoktur; bunlar yolculuk haritasının ve bileşen durumlarının işidir.

İkinci sınır, çizgenin **kullanıcının zihnindeki** akışı değil sistemin akışını göstermesidir.
Kullanıcı "gecikmiş kitap var mı" diye bir karar vermez; borcunu ekranda görünce şaşırır.
Diyagramın doğru olması, akışın anlaşılır olduğu anlamına gelmez. Anlaşılırlık ayrıca
sınanır ve bu konunun son iki dersinin işidir.

#### Özet

- Akış diyagramı bir çizgedir: durum düğümleri, karar düğümleri ve bitiş düğümleri; karar
  düğümünün dalları birbirini dışlamalı ve bütün durumları kapsamalıdır.
- Erişilemeyen düğüm ileri gezinmeyle, çıkışsız düğüm ters çizgede bitişlerden gezinmeyle
  bulunur; örnek akışta biri eksik dallanmayı, öteki çıkışsız hata durumunu ortaya çıkardı.
- Çevrim kusur değildir; kusur, çevrimden çıkan kenarın bulunmaması ve dönüş sayısının
  koşula bağlanmamış olmasıdır.
- Yinelemesiz yol sayısı sınama yükünü verir; her yeni ikili karar yol sayısını yaklaşık iki
  katına çıkarır ve kararın gerekliliği bu maliyetle birlikte sorulur.
- Tek çıkışlı düğümler ya eksik bir başarısızlık dalını ya da akıştan çıkarılabilecek bir
  bilgilendirmeyi gösterir.

#### Sonraki Adım

Akış denetlendi ve gezinme yapısı kuruldu; ikisi de kâğıt üzerinde tutarlı. Tutarlı bir yapı
kullanılabilir bir arayüz demek değildir ve bunu anlamanın tek yolu birine göstermektir.
Ama neyi göstermeli — kutulardan oluşan kaba bir taslak mı, tıklanabilir bir kopya mı?
Sonraki ders doğruluk düzeyi kararını ele alır: hangi sorunun hangi düzeyde yanıtlandığını,
prototipin kaç düğümü kapsarsa kaç görevin uçtan uca sınanabileceğini ve bu iki oranın niçin
eşit olmadığını hesaplar.

### Tel Çerçeve ve Prototip

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/tel-cerceve-ve-prototip

Doğruluğun görsel, içerik ve etkileşim olmak üzere üç bağımsız ekseni; prototipin düğüm kapsamasıyla görev kapsamasının ayrılması ve doğruluk düzeyinin hazırlık maliyetine etkisi.

Akış denetlendi, gezinme yapısı kuruldu. İkisi de kâğıt üzerinde tutarlı, ama tutarlı bir
yapı kullanılabilir bir arayüz demek değildir. Bunu anlamanın tek yolu, yapıyı birine
göstermek ve bir görev vermektir.

Soru neyin gösterileceğidir. Kutulardan oluşan kaba bir taslak mı, tıklanabilir bir kopya
mı, gerçek metinlerle doldurulmuş görsel olarak tamamlanmış bir ekran mı? Bu ders doğruluk
düzeyi kararını ele alır ve prototipin kaç ekranı kapsarsa kaç görevin sınanabileceğini
hesaplar.

#### Tel Çerçeve ile Prototip Ayrı Sorulara Yanıt Verir

**Tel çerçeve (wireframe)**, tek bir ekranın yapısını gösterir: hangi bilgi var, hangi
hiyerarşide duruyor, hangi eylemler bulunuyor. Yanıtladığı soru "bu ekranda doğru şeyler
var mı" sorusudur. Tel çerçeve durağandır ve tek ekranlıdır; akışı sınayamaz.

**Prototip (prototype)**, ekranlar arası geçişi de içerir. Yanıtladığı soru "kullanıcı bu
görevi tamamlayabiliyor mu" sorusudur. Prototip, akış diyagramının çalıştırılabilir
karşılığıdır: düğümler ekranlara, geçişler tıklamalara karşılık gelir.

Aradaki fark bir olgunluk farkı değil, soru farkıdır. Ekranın içeriği tartışmalıysa tel
çerçeve yeterlidir ve prototip hazırlamak boşa emektir. Görevin tamamlanıp tamamlanmadığı
tartışmalıysa tel çerçeve hiçbir şey söylemez.

#### Doğruluk Tek Bir Eksen Değildir

Doğruluk düzeyi çoğu zaman "düşük" ile "yüksek" arasında tek bir kaydırıcı gibi düşünülür.
Aslında birbirinden bağımsız üç eksen vardır ve her biri ayrı ayarlanabilir.

- **Görsel doğruluk.** Renk, tipografi, aralık ve durum tasarımının gerçeğe ne kadar yakın
  olduğu. Düşük ucunda gri kutular, yüksek ucunda Arayüz Tasarımının Temelleri kursunda
  kurulan bütün kararların uygulanmış hâli vardır.
- **İçerik doğruluğu.** Ekrandaki metnin ve verinin gerçek olup olmadığı. Düşük ucunda yer
  tutucu metin, yüksek ucunda kataloğun gerçek kayıtları — uzun başlıklar, eş adlı ciltler,
  boş üstveri alanları dâhil.
- **Etkileşim doğruluğu.** Kaç geçişin çalıştığı. Düşük ucunda tek yol tıklanabilir, yüksek
  ucunda bütün dallar.

Bu eksenlerin bağımsızlığı pratik bir sonuç verir: **görsel doğruluğu düşük, içerik doğruluğu
yüksek** bir prototip, mikro metin ve bilgi mimarisi sorunlarını yakalamak için verimli bir
birleşimdir. Gri kutular içine gerçek kayıt başlıkları konduğunda, uzun başlıkların kırpma sorunu
ve birinci konuda ölçülen eş adlı kayıt sorunu görünür hâle gelir; renk kararları ise tartışmayı
dağıtmadan bekler.

Ters birleşim — görsel doğruluk yüksek, içerik doğruluğu düşük — en yanıltıcı olanıdır.
Katılımcı gördüğü ekranı bitmiş sanır ve yapıya değil renge yorum yapar; ayrıca yer tutucu
metinlerin hepsi aynı uzunlukta olduğu için hiçbir kırpma sorunu ortaya çıkmaz.

#### Kaç Ekran, Kaç Görev

Prototip hazırlanırken kaç düğümün uygulanacağı bir bütçe kararıdır. Bu kararın ölçütü
kapsanan ekran oranı değil, uçtan uca sınanabilen görev oranıdır.

```js
// prototip-kapsama.mjs — prototipin dugum kapsamasi ile gorev kapsamasi ayni degildir

const TUM_DUGUMLER = [
  "basla", "oturum var mi", "giris ekrani", "giris hatasi", "kayit durumu", "rafta",
  "gecikmis kitap var mi", "borc odeme", "odunc onayi", "oduncte", "rezervasyon onerisi",
  "rezervasyon onayi", "odunc basarili", "rezervasyon basarili", "vazgec",
];

// Her gorev, akista gecilmesi gereken dugum dizisi
const GOREVLER = {
  "odunc al (oturum acik)": ["basla", "oturum var mi", "kayit durumu", "rafta", "gecikmis kitap var mi", "odunc onayi", "odunc basarili"],
  "odunc al (giris gerekli)": ["basla", "oturum var mi", "giris ekrani", "kayit durumu", "rafta", "gecikmis kitap var mi", "odunc onayi", "odunc basarili"],
  "borcu ode ve odunc al": ["basla", "oturum var mi", "kayit durumu", "rafta", "gecikmis kitap var mi", "borc odeme", "odunc onayi", "odunc basarili"],
  "oduncteki kaydi rezerve et": ["basla", "oturum var mi", "kayit durumu", "oduncte", "rezervasyon onerisi", "rezervasyon onayi", "rezervasyon basarili"],
  "yanlis parola sonrasi vazgec": ["basla", "oturum var mi", "giris ekrani", "giris hatasi", "vazgec"],
  "rezervasyondan vazgec": ["basla", "oturum var mi", "kayit durumu", "oduncte", "rezervasyon onerisi", "vazgec"],
};

// Prototipin surumleri: her surum bir oncekine dugum ekliyor
const EKLENEN = [
  ["P1 ana yol", ["basla", "oturum var mi", "kayit durumu", "rafta", "gecikmis kitap var mi", "odunc onayi", "odunc basarili"]],
  ["P2 giris", ["giris ekrani", "giris hatasi", "vazgec"]],
  ["P3 rezervasyon", ["oduncte", "rezervasyon onerisi", "rezervasyon onayi", "rezervasyon basarili"]],
  ["P4 borc", ["borc odeme"]],
];

const gorevAdlari = Object.keys(GOREVLER);
const kapsanan = (kume, g) => GOREVLER[g].every((d) => kume.has(d));

console.log("surum            dugum  dugum kapsamasi  sinanabilir gorev  gorev kapsamasi");
const kume = new Set();
const surumler = [];
for (const [ad, yeni] of EKLENEN) {
  yeni.forEach((d) => kume.add(d));
  const sinanabilir = gorevAdlari.filter((g) => kapsanan(kume, g));
  surumler.push({ ad, dugum: kume.size, gorev: sinanabilir.length, kume: new Set(kume) });
  console.log(
    `${ad.padEnd(16)} ${String(kume.size).padStart(5)} ${((kume.size / TUM_DUGUMLER.length) * 100).toFixed(1).padStart(15)}% ` +
      `${String(sinanabilir.length).padStart(18)} ${((sinanabilir.length / gorevAdlari.length) * 100).toFixed(1).padStart(15)}%`
  );
}

// Bir surumde eksik kalan dugumlerden hangisi en cok gorevi acar
console.log("\nP1 sonrasi: eksik dugum  engelledigi gorev sayisi");
const p1 = surumler[0].kume;
const eksik = TUM_DUGUMLER.filter((d) => !p1.has(d));
const engel = eksik
  .map((d) => [d, gorevAdlari.filter((g) => !kapsanan(p1, g) && GOREVLER[g].includes(d)).length])
  .sort((a, b) => b[1] - a[1]);
for (const [d, c] of engel) console.log(`  ${d.padEnd(24)} ${c}`);

// Dogruluk duzeyinin maliyeti: dugum basina varsayilan hazirlik suresi
const BIRIM = { "dusuk (kagit)": 0.5, "orta (tiklanabilir)": 2, "yuksek (gorsel tam)": 6 };
console.log("\ndogruluk duzeyi        P1     P2     P3     P4   (saat)");
for (const [ad, saat] of Object.entries(BIRIM)) {
  console.log(
    `${ad.padEnd(22)} ${surumler.map((s) => (s.dugum * saat).toFixed(1).padStart(5)).join("  ")}`
  );
}
const enBuyuk = surumler.at(-1).dugum;
console.log(`\ntum gorevleri sinamak icin ${enBuyuk} dugum gerekiyor`);
console.log(`dusuk duzeyde ${(enBuyuk * BIRIM["dusuk (kagit)"]).toFixed(1)} saat, yuksek duzeyde ${(enBuyuk * BIRIM["yuksek (gorsel tam)"]).toFixed(1)} saat  (${(BIRIM["yuksek (gorsel tam)"] / BIRIM["dusuk (kagit)"]).toFixed(0)} kat)`);
```

```
surum            dugum  dugum kapsamasi  sinanabilir gorev  gorev kapsamasi
P1 ana yol           7            46.7%                  1            16.7%
P2 giris            10            66.7%                  3            50.0%
P3 rezervasyon      14            93.3%                  5            83.3%
P4 borc             15           100.0%                  6           100.0%

P1 sonrasi: eksik dugum  engelledigi gorev sayisi
  giris ekrani             2
  oduncte                  2
  rezervasyon onerisi      2
  vazgec                   2
  giris hatasi             1
  borc odeme               1
  rezervasyon onayi        1
  rezervasyon basarili     1

dogruluk duzeyi        P1     P2     P3     P4   (saat)
dusuk (kagit)            3.5    5.0    7.0    7.5
orta (tiklanabilir)     14.0   20.0   28.0   30.0
yuksek (gorsel tam)     42.0   60.0   84.0   90.0

tum gorevleri sinamak icin 15 dugum gerekiyor
dusuk duzeyde 7.5 saat, yuksek duzeyde 90.0 saat  (12 kat)
```

#### Ekran Saymak Görev Saymak Değildir

İlk tablonun iki sütunu birbirini izlemiyor. Ana yol prototipi düğümlerin %46.7'sini kapsıyor ama
görevlerin yalnızca %16.7'sini uçtan uca sınatabiliyor. Üçüncü sürümde düğüm kapsaması %93.3'e
çıkıyor, oysa görev kapsaması %83.3'te kalıyor.

Nedeni bileşik bir koşuldur: bir görev, geçtiği **bütün** düğümler uygulanmışsa sınanabilir. Tek
bir eksik düğüm görevin tamamını kullanılamaz kılar. Yarısı hazır bir prototip, görevlerin
yarısını değil çok daha azını sınatabilir.

Bunun doğrudan bir uygulama sonucu var: prototip **ekran listesinden değil görev listesinden**
kurulur. Önce sınanacak görevler seçilir, sonra o görevlerin geçtiği düğümler kümesi çıkarılır ve
prototip o kümeyi kapsar. Ekran ekran ilerlemek, hazırlanan ekranların çoğu sınanamayan bir
prototip üretir.

İkinci tablo hangi düğümün önce yapılacağını söylüyor. Ana yol prototipinden sonra en çok
görevi açan düğümler giriş ekranı, ödünçte durumu, rezervasyon önerisi ve vazgeçme; her biri
iki görevi engelliyor. Bu, akış diyagramının yol sayımıyla aynı mantıktır ve öncelik
tartışmasını sayıya bağlar.

#### Maliyet Oranı, Maliyetin Kendisi Değil

Üçüncü tablodaki saat değerleri varsayılmış birim maliyetlerdir; gerçek sayılar ekibe,
araca ve ekranın karmaşıklığına göre değişir. Anlamlı olan mutlak süreler değil, aralarındaki
orandır: düşük doğruluklu bir prototip düğüm başına yüksek doğruluklu olandan on iki kat ucuza
geliyor. Bütün görevleri kapsayan bir prototip düşük doğrulukta 7.5 saat, yüksek doğrulukta
90 saat.

Bu oranın kararı belirlediği yer şurasıdır: **aynı bütçeyle ya bir görevi ayrıntısıyla ya da
on iki görevi kabaca sınayabilirsiniz.** Hangi sorunun sorulduğu bu seçimi belirler. Yapı
sorusu — kullanıcı görevi tamamlayabiliyor mu — geniş ve ucuz prototiple yanıtlanır. Görsel
karar sorusu — bu iki durum yeterince ayrışıyor mu — dar ve pahalı prototiple yanıtlanır.

Ucuz prototipin ikinci bir üstünlüğü vardır ve maliyetten daha önemlidir: **atılabilir**
olduğu için eleştirilmesi kolaydır. Doksan saat harcanmış bir prototip, üzerinde çalışan
ekipten değişiklik önerisi almayı zorlaştırır; hem tasarımcı hem katılımcı yatırımı savunma
eğilimine girer.

#### Prototipin Yanıtlayamadığı Sorular

Prototip bir kopyadır ve bazı sorularda sistematik olarak yanıltır.

**Veri ölçeği.** Prototipte on kayıt vardır, katalogda binlerce. Sonuç listesinin on kayıtla
iyi çalışması hiçbir şey kanıtlamaz; kırpma, sıralama ve daraltma sorunları ölçekle ortaya
çıkar. İçerik doğruluğunu yükseltmenin en ucuz yolu, kayıt sayısını değil kayıtların
**çeşitliliğini** gerçekçi tutmaktır: en uzun başlık, eş adlı iki cilt, üstverisi eksik bir
kayıt.

**Hata sıklığı.** Prototipte bağlantı kopmaz, işlem başarısız olmaz, oturum düşmez. Akış
diyagramında bulunan çıkışsız hata düğümü prototipte hiç görünmez, çünkü oraya düşmenin yolu
yoktur. Hata durumları prototipe ancak kasten yerleştirilirse sınanır.

**Zaman.** Prototipte her geçiş anlıktır. Bekleme durumlarının tasarımı — Arayüz Tasarımının
Temelleri kursundaki yükleme ve boş durumlar — prototipte doğal olarak sınanmaz; gecikme
elle eklenmedikçe kullanıcı hiç beklemez.

**Öğrenme.** Prototip oturumu bir kerelik bir karşılaşmadır. İlk kullanımda zor görünen bir
yapı, üçüncü kullanımda en hızlısı olabilir; ilk kullanımda kolay görünen bir yapı uzun
vadede yorucu olabilir. Prototip ilk karşılaşmayı ölçer ve bunu açıkça söylemek gerekir.

#### Özet

- Tel çerçeve tek ekranın içeriğini, prototip görevin tamamlanabilirliğini sorar; ikisi
  arasındaki fark olgunluk değil soru farkıdır.
- Doğruluk görsel, içerik ve etkileşim olmak üzere üç bağımsız eksendir; görsel düşük,
  içerik yüksek birleşimi bilgi mimarisi ve metin sorunlarını yakalamakta en verimlisidir.
- Düğüm kapsaması ile görev kapsaması aynı hızda artmaz; örnek veride %46.7 düğüm kapsaması
  görevlerin yalnızca %16.7'sini sınatabildi, çünkü tek eksik düğüm görevin tamamını kapatır.
- Prototip ekran listesinden değil görev listesinden kurulur; hangi eksik düğümün kaç görevi
  açtığı hesaplanarak sıralanır.
- Doğruluk düzeyinin anlamı mutlak maliyet değil orandır; aynı bütçeyle ya bir görev
  ayrıntısıyla ya da çok sayıda görev kabaca sınanır.
- Prototip veri ölçeğini, hata sıklığını, bekleme süresini ve öğrenmeyi sistematik olarak
  eksik gösterir; bu sınırlar bulguların yanına yazılır.

#### Sonraki Adım

Prototip hazır, ama katılımcı çağırmadan önce ucuz bir denetim yapılabilir. Bilinen
kullanılabilirlik sorunlarının büyük bölümü, yerleşik değerlendirme ölçütleri listesi elde
tutularak arayüzü gözden geçirmekle bulunur. Sonraki ders bu ölçütleri ilke ilke ele alır,
birden çok değerlendiricinin bulgularının ne kadar örtüştüğünü hesaplar ve tek bir uzmanın
niçin yetmediğini sayıyla gösterir.

### Kullanılabilirlik Sezgileri

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/kullanilabilirlik-sezgileri

Yerleşik değerlendirme ölçütlerinin ilke ilke uygulanması; birden çok değerlendiricinin bulgularının örtüşmesinin hesaplanması ve tek değerlendiricinin en ağır sorunu niçin kaçırdığı.

Prototip hazır ama katılımcı çağırmadan önce ucuz bir denetim yapılabilir. Kullanılabilirlik
sorunlarının bir bölümü, kullanıcıya hiç gösterilmeden, bilinen ölçütler elde tutularak
arayüz gözden geçirilerek bulunur. Bu yöntem katılımcı oturumunun yerini almaz; oturumu
gereksiz yere harcamamak için önce yapılır.

**Kullanılabilirlik sezgisi (usability heuristic)**, arayüzü değerlendirirken kullanılan
genel bir ölçüttür. "Sezgi" adı, kesin bir kural olmamasından gelir: ölçüt sağlanmadığında
kesin bir kusur değil, incelenmesi gereken bir aday çıkar. Bu ders yerleşik ölçüt kümesini
ilke ilke uygular ve kaç kişinin değerlendirmesi gerektiğini hesaplar.

#### Yerleşik Ölçüt Kümesi

Alanda uzun süredir kullanılan on ilke, kataloğun kararlarıyla eşleştirilerek okunur.

- **Sistem durumunun görünürlüğü.** Kullanıcı her an ne olduğunu bilir. Arama çalışırken bir
  bekleme durumu, ödünç alma sırasında bir ilerleme göstergesi.
- **Sistemin gerçek dünyayla örtüşmesi.** Arayüz kurumun değil kullanıcının sözlüğünü
  konuşur. "Dolaşım işlemleri" kurumun sözlüğüdür; "ödünç alma" kullanıcının.
- **Kullanıcı denetimi ve özgürlüğü.** Yanlış adım geri alınabilir, işlem yarıda
  bırakılabilir, önceki duruma dönülebilir.
- **Tutarlılık ve standartlar.** Aynı şey her yerde aynı adla ve aynı biçimde. Yinelenme ve
  Tutarlılık dersinde görsel için konan kuralın yapı düzeyindeki karşılığı.
- **Hatanın önlenmesi.** İyi bir hata iletisinden daha iyisi, hatanın hiç oluşmamasıdır.
  Gecikme ücreti tahsil edilecekse önce onaylatılır.
- **Hatırlamak yerine tanımak.** Kullanıcı önceki ekranda gördüğünü ezberlemek zorunda
  kalmaz. Raf kodunu akılda tutturmak yerine ödünç adımında yeniden göstermek.
- **Kullanımda esneklik ve verim.** Sık kullanan için kısa yol, yeni kullanan için açık yol;
  ikisi aynı arayüzde bulunur.
- **Ölçülü tasarım.** Ekranda gereksiz bilgi bulunmaz; her eklenen öge, asıl bilginin
  görünürlüğünü azaltır.
- **Hataların tanınması, tanılanması ve giderilmesi.** İleti ne olduğunu, niçin olduğunu ve ne
  yapılması gerektiğini söyler.
- **Yardım ve belgelendirme.** Yardım gerekiyorsa aranabilir, kısa ve göreve bağlıdır;
  yardıma gerek duyulmaması ise daha iyidir.

Ölçütlerin adları kalıp gibi kullanılmaz. Değerlendirmenin çıktısı "tutarlılık ilkesi
ihlal edilmiş" değil, "ödünç alma eylemi listede *Al*, kayıt ayrıntısında *Ödünç al*, onay
ekranında *Emanet* olarak adlandırılıyor" biçiminde yazılır. İlke, bulgunun sınıfını verir;
bulgu, ilkenin yerini tutmaz.

#### Oturumun Yürütülmesi

Değerlendirme üç kuralla yapılır.

**Bağımsız.** Her değerlendirici arayüzü tek başına gezer ve bulgularını kendi listesine
yazar. Birlikte gezilirse ilk konuşanın bulguları diğerlerinin dikkatini yönlendirir ve
bağımsız bulgu sayısı düşer.

**İki geçişli.** İlk geçiş akışı bütün olarak izler ve genel yapıyı kavrar; ikinci geçiş her
ekranı ölçüt listesiyle tek tek tarar. Tek geçişte yapılan değerlendirme, akışın bağlamını
bilmeden ekran yargılar.

**Şiddet puanlı.** Her bulguya bir şiddet verilir. Aşağıdaki hesapta dört düzeyli bir
ölçek kullanılıyor: 1 biçimsel bir kusur, 2 küçük bir engel, 3 görevi belirgin biçimde
zorlaştıran bir sorun, 4 görevi tamamlanamaz kılan ya da geri alınamaz zarar üreten bir
sorun. Puan, bulgular birleştirildikten sonra sıralamayı yapar.

#### Bir Değerlendirici Yetmez

Beş değerlendirici prototipi bağımsız olarak inceledi ve bulgular birleştirildi.

```js
// sezgi-degerlendirmesi.mjs — bes degerlendiricinin bulgularinin ortusmesi ve siddet uzlasisi

// Her bulgu: hangi ilkeye ait ve hangi degerlendirici kac siddet verdi (1 kucuk, 4 buyuk)
const BULGULAR = [
  { ad: "yukleme durumu gosterilmiyor", ilke: "durum gorunurlugu", puan: { D1: 2, D2: 3, D3: 2, D4: 2, D5: 3 } },
  { ad: "ayni eylem farkli adlarla", ilke: "tutarlilik", puan: { D1: 3, D2: 3, D4: 2 } },
  { ad: "odunc alma geri alinamiyor", ilke: "denetim ve ozgurluk", puan: { D2: 4, D3: 3, D5: 4 } },
  { ad: "hata iletisi nedeni yazmiyor", ilke: "hatadan kurtulma", puan: { D1: 3, D3: 4, D4: 3, D5: 3 } },
  { ad: "kurum sozlugu kullaniliyor", ilke: "gercek dunyayla ortusme", puan: { D2: 3, D5: 2 } },
  { ad: "geri donuste arama kayboluyor", ilke: "denetim ve ozgurluk", puan: { D1: 4, D2: 4, D3: 4, D4: 3, D5: 4 } },
  { ad: "ucret once onaylatilmiyor", ilke: "hatanin onlenmesi", puan: { D3: 4 } },
  { ad: "yer tutucu etiket yerine geciyor", ilke: "hatirlamak yerine tanimak", puan: { D1: 3, D4: 3 } },
  { ad: "raf kodu aciklanmiyor", ilke: "gercek dunyayla ortusme", puan: { D2: 3, D3: 3, D4: 4 } },
  { ad: "aramayi yineleme kisayolu yok", ilke: "esneklik ve verim", puan: { D5: 2 } },
  { ad: "uc eylem esit agirlikta", ilke: "olculu tasarim", puan: { D1: 3, D2: 2 } },
  { ad: "yardim derinde", ilke: "yardim ve belgelendirme", puan: { D4: 1 } },
];
const DEGERLENDIRICI = ["D1", "D2", "D3", "D4", "D5"];

const ortanca = (d) => {
  const s = [...d].sort((a, b) => a - b), o = s.length >> 1;
  return s.length % 2 ? s[o] : (s[o - 1] + s[o]) / 2;
};

console.log("bulgu                              ilke                        bulan  ortanca  aralik");
for (const b of BULGULAR) {
  const p = Object.values(b.puan);
  console.log(
    `${b.ad.padEnd(34)} ${b.ilke.padEnd(27)} ${String(p.length).padStart(5)} ${ortanca(p).toFixed(1).padStart(8)}  ${Math.min(...p)}-${Math.max(...p)}`
  );
}

console.log("\ndegerlendirici  buldugu bulgu  kapsama");
for (const d of DEGERLENDIRICI) {
  const n = BULGULAR.filter((b) => d in b.puan).length;
  console.log(`${d.padEnd(14)} ${String(n).padStart(14)}  ${((n / BULGULAR.length) * 100).toFixed(1)}%`);
}

// k degerlendiricinin butun altkumeleri uzerinden beklenen birlesim
const altKumeler = (dizi, k) =>
  k === 0 ? [[]] : dizi.flatMap((x, i) => altKumeler(dizi.slice(i + 1), k - 1).map((r) => [x, ...r]));
console.log("\ndegerlendirici sayisi  altkume  beklenen bulunan  beklenen kapsama");
for (let k = 1; k <= DEGERLENDIRICI.length; k++) {
  const kumeler = altKumeler(DEGERLENDIRICI, k);
  const toplam = kumeler.reduce(
    (t, kume) => t + BULGULAR.filter((b) => kume.some((d) => d in b.puan)).length, 0);
  const ort = toplam / kumeler.length;
  console.log(
    `${String(k).padStart(21)}  ${String(kumeler.length).padStart(7)}  ${ort.toFixed(2).padStart(16)}  ${((ort / BULGULAR.length) * 100).toFixed(1).padStart(15)}%`
  );
}

// Tek kisinin buldugu bulgular ve siddet uzlasisi
const tek = BULGULAR.filter((b) => Object.keys(b.puan).length === 1);
console.log(`\nyalniz bir degerlendiricinin buldugu bulgu: ${tek.length} / ${BULGULAR.length}  (${((tek.length / BULGULAR.length) * 100).toFixed(1)}%)`);
console.log(`  ${tek.map((b) => b.ad).join("; ")}`);

const cokBulan = BULGULAR.filter((b) => Object.keys(b.puan).length >= 3);
const yayilim = cokBulan.map((b) => Math.max(...Object.values(b.puan)) - Math.min(...Object.values(b.puan)));
console.log(`\nuc ve daha cok kisinin buldugu ${cokBulan.length} bulguda siddet yayilimi: ortalama ${(yayilim.reduce((a, c) => a + c, 0) / yayilim.length).toFixed(2)} puan, en cok ${Math.max(...yayilim)} puan`);

// Ilke basina bulgu sayisi
const ilkeler = new Map();
for (const b of BULGULAR) ilkeler.set(b.ilke, (ilkeler.get(b.ilke) ?? 0) + 1);
console.log("\nilke                        bulgu");
for (const [i, c] of [...ilkeler].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])))
  console.log(`${i.padEnd(27)} ${c}`);
```

```
bulgu                              ilke                        bulan  ortanca  aralik
yukleme durumu gosterilmiyor       durum gorunurlugu               5      2.0  2-3
ayni eylem farkli adlarla          tutarlilik                      3      3.0  2-3
odunc alma geri alinamiyor         denetim ve ozgurluk             3      4.0  3-4
hata iletisi nedeni yazmiyor       hatadan kurtulma                4      3.0  3-4
kurum sozlugu kullaniliyor         gercek dunyayla ortusme         2      2.5  2-3
geri donuste arama kayboluyor      denetim ve ozgurluk             5      4.0  3-4
ucret once onaylatilmiyor          hatanin onlenmesi               1      4.0  4-4
yer tutucu etiket yerine geciyor   hatirlamak yerine tanimak       2      3.0  3-3
raf kodu aciklanmiyor              gercek dunyayla ortusme         3      3.0  3-4
aramayi yineleme kisayolu yok      esneklik ve verim               1      2.0  2-2
uc eylem esit agirlikta            olculu tasarim                  2      2.5  2-3
yardim derinde                     yardim ve belgelendirme         1      1.0  1-1

degerlendirici  buldugu bulgu  kapsama
D1                          6  50.0%
D2                          7  58.3%
D3                          6  50.0%
D4                          7  58.3%
D5                          6  50.0%

degerlendirici sayisi  altkume  beklenen bulunan  beklenen kapsama
                    1        5              6.40             53.3%
                    2       10              9.00             75.0%
                    3       10             10.50             87.5%
                    4        5             11.40             95.0%
                    5        1             12.00            100.0%

yalniz bir degerlendiricinin buldugu bulgu: 3 / 12  (25.0%)
  ucret once onaylatilmiyor; aramayi yineleme kisayolu yok; yardim derinde

uc ve daha cok kisinin buldugu 6 bulguda siddet yayilimi: ortalama 1.00 puan, en cok 1 puan

ilke                        bulgu
denetim ve ozgurluk         2
gercek dunyayla ortusme     2
durum gorunurlugu           1
esneklik ve verim           1
hatadan kurtulma            1
hatanin onlenmesi           1
hatirlamak yerine tanimak   1
olculu tasarim              1
tutarlilik                  1
yardim ve belgelendirme     1
```

#### Sayıların Söylediği

**Tek değerlendirici yarıyı bulur.** Beş kişinin her biri on iki bulgunun yarısı
dolayındakini buldu; bütün tek kişilik altkümeler üzerinden beklenen kapsama %53.3.
Değerlendirmeyi tek kişinin yapması, sorunların yarısını görmemeyi baştan kabul etmektir.

**Kazanç azalarak artar.** İki değerlendiricide beklenen kapsama %75, üçte %87.5, dörtte
%95. Birinciden ikinciye geçmek 21.7 puan kazandırıyor, üçüncüden dördüncüye geçmek 7.5
puan. Değerlendirici sayısı üç ile dört arasında seçilir; beşinci kişi bu örnekte 5 puan
ekliyor ve aynı emek katılımcı oturumuna daha çok kazandırır.

**En ağır bulguyu tek kişi buldu.** "Ücret önce onaylatılmıyor" bulgusunun şiddeti 4 —
ölçekteki en yüksek değer — ve yalnızca üçüncü değerlendirici buldu. Beş kişilik havuzdan
rastgele seçilen tek bir değerlendiricinin bu bulguyu bulma olasılığı beşte birdir. Bu, tek
değerlendiriciyle çalışmanın asıl riskidir: kaçırılan bulgu, kaçırılan bulguların ortalaması
kadar önemsiz olmak zorunda değildir.

**Şiddet konusunda uzlaşma iyi, kapsama konusunda kötü.** Üç ve daha çok kişinin bulduğu
altı bulguda şiddet yayılımı ortalama bir puan; kimse aynı bulguya 1 ile 4 arasında değişen
puanlar vermedi. Değerlendiriciler bir sorunu gördüklerinde ağırlığı konusunda benzer
düşünüyorlar; ayrıştıkları yer sorunu görüp görmemeleri. Bu yüzden birleştirme aşamasında
tartışılacak şey puan değil, listede olmayan bulgudur.

**İki ilke öne çıkıyor.** Denetim ve özgürlük ile gerçek dünyayla örtüşme ilkelerinde ikişer
bulgu var; ikisi de kullanıcı araştırmasında ölçülen sorunlarla aynı yere işaret ediyor —
geri dönüşte kaybolan arama ve açıklanmayan raf kodu. Sezgi değerlendirmesi ile alan verisi
aynı bulguda buluştuğunda kanıt gücü artar; altıncı derste konan çok kaynaklılık ölçütü
burada da geçerlidir.

#### Sezgi Değerlendirmesinin Sınırı

Yöntem ucuzdur ve bu ucuzluk sınırının da kaynağıdır.

**Bulgular hipotezdir.** Değerlendirici arayüzü kullanıcı olarak değil, ölçüt listesiyle gezen bir
uzman olarak görür. "Yardım derinde" bulgusunun şiddeti 1 verildi; gerçek kullanıcılar hiç yardım
aramıyorsa şiddeti sıfırdır, aramaya çalışıp bulamıyorlarsa ise çok daha yüksektir. Bunu sezgi
değil ölçüm söyler.

**Yanlış bulgu üretebilir.** Ölçüt listesiyle gezmek, ihlal aramaya yönelten bir tutum
doğurur; her sapma bir kusur gibi görünür. Yerleşik bir ölçütten bilinçli olarak sapan bir
karar — beşinci derste tartışılan ayırt edici kararlar — sezgi değerlendirmesinde ihlal
olarak işaretlenir. Bu yüzden bulgular tasarım gerekçeleriyle birlikte gözden geçirilir.

**Ne yapılmak istendiğini söylemez.** Sezgi, arayüzün var olan hâlini ölçütlere göre
denetler. Kullanıcının aslında başka bir şey yapmak istediğini, aradığı bilginin arayüzde hiç
bulunmadığını ya da görevin tümüyle gereksiz olduğunu sezgi değerlendirmesi bulamaz. Bunlar
araştırmanın ve kullanıcı testinin alanıdır.

#### Özet

- Kullanılabilirlik sezgisi bir kural değil bir ölçüttür; sağlanmadığında kesin kusur değil,
  incelenecek aday çıkar ve bulgu ilke adıyla değil somut olguyla yazılır.
- Değerlendirme bağımsız, iki geçişli ve şiddet puanlı yürütülür; birlikte gezmek bağımsız
  bulgu sayısını düşürür.
- Örnek veride tek değerlendiricinin beklenen kapsaması %53.3; üç değerlendiricide %87.5,
  dörtte %95 ve kazanç azalarak artar.
- En yüksek şiddetli bulguyu beş değerlendiriciden yalnızca biri buldu; kaçırılan bulgunun
  ortalama kadar önemsiz olacağı varsayılamaz.
- Değerlendiriciler şiddet konusunda uzlaşıyor, kapsama konusunda ayrışıyor; birleştirmede
  tartışılacak olan puanlar değil listede eksik olanlardır.
- Sezgi değerlendirmesi hipotez üretir, yanlış bulgu verebilir ve kullanıcının ne yapmak
  istediğini söyleyemez.

#### Sonraki Adım

Sezgi değerlendirmesi on iki aday üretti ve her biri bir varsayım. Hangilerinin gerçek
kullanıcıyı gerçekten durdurduğu ölçülmeden bilinemez. Sonraki ders prototipi katılımcının
eline verir: oturumun nasıl kurulduğunu, kaç katılımcının yeterli olduğunu ve "beş kullanıcı
yeter" savının hangi koşulda doğru, hangi koşulda yanıltıcı olduğunu keşif eğrisini
hesaplayarak gösterir.

### Kullanılabilirlik Testi

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/kullanilabilirlik-testi

Küçük örneklemle sorun bulma; keşif eğrisinin hesaplanması, beş katılımcı savının tekdüze olmayan sorun kümesinde niçin çöktüğü ve küçük örneklemde süre ölçümünün belirsizliği.

Sezgi değerlendirmesi on iki aday üretti ve her biri bir varsayım. Hangilerinin gerçek
kullanıcıyı gerçekten durdurduğu, hangilerinin hiç fark edilmediği ölçülmeden bilinemez.
Bunu ölçmenin yolu prototipi bir katılımcının eline vermek ve bir görev vermektir.

**Kullanılabilirlik testi (usability test)**, katılımcının önceden belirlenmiş bir görevi
yapmaya çalışırken gözlenmesidir. Amacı görüş toplamak değildir; kullanıcının nerede
durakladığı, nereye tıkladığı ve nerede vazgeçtiği ölçülür. Bu ders oturumun nasıl
kurulduğunu, kaç katılımcı gerektiğini ve küçük örneklemin neyi söyleyip neyi
söyleyemediğini hesapla ele alır.

#### Oturumun Kurulması

Oturum üç parçadan oluşur ve her parçanın kendi kuralı vardır.

**Görev senaryosu.** Katılımcıya yapılacak iş bir bağlamla verilir, bir yönergeyle değil.
"Ödünç al düğmesine basın" bir yönergedir ve hiçbir şey ölçmez. "Bir arkadaşınız size bir
kitap önerdi; kütüphanede var mı, varsa nasıl alacağınızı bulun" bir senaryodur; kullanıcının
yolu kendi bulmasını gerektirir. Senaryo, arayüzün sözcüklerini kullanmaz — "daraltma"
sözcüğü senaryoda geçerse, o sözcüğün anlaşılıp anlaşılmadığı ölçülemez.

**Sesli düşünme.** Katılımcıdan ne yaptığını ve ne beklediğini sesli söylemesi istenir. Bu,
gözlemin göremediğini açığa çıkarır: kullanıcının bir ögeyi görüp de anlamadığını, ya da
ekranda olmayan bir şeyi aradığını yalnızca sözünden anlarız. Sesli düşünme süreyi uzatır;
bu yüzden süre ölçülecekse ayrı bir görev sessiz yaptırılır.

**Moderatörün yapmadıkları.** Moderatör yol göstermez, ipucu vermez, "orada" demez.
Katılımcı takıldığında beklenir; gerçekten durduğunda görev sonlandırılır ve bu bir bulgudur.
Moderatör ayrıca savunma yapmaz: "aslında oraya koymuştuk" cümlesi katılımcıyı susturur ve
oturumun geri kalanını değersizleştirir.

#### Testin Etik Çerçevesi

Kullanılabilirlik testi, katılımcının başarısız olmasının veri sayıldığı bir oturumdur; bu
onu etik açıdan araştırmanın en dikkat isteyen biçimlerinden biri yapar.

**Sınanan arayüzdür, katılımcı değildir.** Bu cümle oturumun başında açıkça söylenir ve
sözde kalmaz: görev tamamlanamadığında katılımcıya bunun arayüzün bulgusu olduğu hatırlatılır.
Katılımcının kendini sınanıyor hissetmesi hem etik bir sorundur hem de veriyi bozar.

**Onay ayrıntılıdır ve geri alınabilir.** Katılımcı neyin kaydedildiğini — ekran, ses,
tıklama izi — ve kaydın kimlerce görüleceğini bilerek onay verir. Oturumu istediği an
durdurabilir ve bunu gerekçelendirmesi gerekmez. Oturum sonunda kaydının silinmesini isterse
silinir.

**Kimliksizleştirme ve saklama sınırı.** Bulgular `K01` gibi kodlarla yazılır. Ekran
kaydında katılımcının hesabı görünüyorsa gerçek üyelik yerine sınama hesabı kullanılır;
kullanılamıyorsa kayıttaki tanımlayıcı alanlar çözümleme öncesinde temizlenir. Ham kayıt
kodlanmış nota dönüştürüldükten sonra, yazılı saklama süresi içinde silinir.

**Alıntı kullanımı ayrı bir onaydır.** Katılımcının sözünü rapora almak, kaydını
çözümlemekten farklı bir kullanımdır. Doğrudan alıntı yapılacaksa bu ayrıca sorulur.

#### Beş Katılımcı Savı

Küçük örneklemi savunan yaygın bir hesap vardır. Bir sorunun tek bir katılımcıda ortaya
çıkma olasılığı `p` ise, `n` katılımcıda en az bir kez görülme olasılığı `1 - (1 - p)^n`
olur. Bu eğri hızlı doyar ve beş katılımcının çoğu sorunu bulmaya yettiği sonucuna götürür.
Hesabın kendisi doğru; taşıdığı varsayım sorunludur.

```js
// kesif-egrisi.mjs — 1 - (1 - p)^n egrisi ve tekduze olmayan bulunma olasiliklari

// Tekduze varsayim: her sorun her katilimcida ayni olasilikla ortaya cikiyor
console.log("tekduze p ile bulunan sorun orani");
console.log("katilimci  p=0.10  p=0.20  p=0.31  p=0.50");
for (const n of [1, 2, 3, 5, 8, 10, 15, 20]) {
  const s = [0.1, 0.2, 0.31, 0.5].map((p) => ((1 - (1 - p) ** n) * 100).toFixed(1).padStart(6));
  console.log(`${String(n).padStart(9)}  ${s.join("  ")}`);
}

// Gercek sorun kumesi tekduze degildir: bazi sorunlar herkeste, bazilari nadiren cikar
const SORUNLAR = [
  { ad: "geri donuste arama kayip", p: 0.90, siddet: 4 },
  { ad: "raf kodu anlasilmiyor", p: 0.75, siddet: 3 },
  { ad: "es adli kayit karisiyor", p: 0.60, siddet: 3 },
  { ad: "yukleme durumu yok", p: 0.50, siddet: 2 },
  { ad: "ayni eylem farkli adlarla", p: 0.40, siddet: 3 },
  { ad: "yer tutucu etiket yerine", p: 0.30, siddet: 3 },
  { ad: "uc eylem esit agirlikta", p: 0.25, siddet: 2 },
  { ad: "hata iletisi nedensiz", p: 0.20, siddet: 3 },
  { ad: "uzatma yolu gizli", p: 0.15, siddet: 3 },
  { ad: "yardim derinde", p: 0.10, siddet: 1 },
  { ad: "kisayol yok", p: 0.08, siddet: 2 },
  { ad: "ucret onaylatilmiyor", p: 0.05, siddet: 4 },
];
const ortP = SORUNLAR.reduce((t, s) => t + s.p, 0) / SORUNLAR.length;
console.log(`\nsorun kumesinin ortalama p degeri: ${ortP.toFixed(4)}`);

console.log("\nkatilimci  tekduze p ile  gercek kume  siddetle agirlikli  bulunma olasiligi en dusuk sorun");
const siddetToplam = SORUNLAR.reduce((t, s) => t + s.siddet, 0);
for (const n of [1, 3, 5, 8, 12, 20, 32]) {
  const tekduze = (1 - (1 - ortP) ** n) * 100;
  const gercek = (SORUNLAR.reduce((t, s) => t + (1 - (1 - s.p) ** n), 0) / SORUNLAR.length) * 100;
  const agirlikli = (SORUNLAR.reduce((t, s) => t + s.siddet * (1 - (1 - s.p) ** n), 0) / siddetToplam) * 100;
  const enDusuk = Math.min(...SORUNLAR.map((s) => 1 - (1 - s.p) ** n)) * 100;
  console.log(
    `${String(n).padStart(9)}  ${tekduze.toFixed(1).padStart(12)}%  ${gercek.toFixed(1).padStart(10)}%  ${agirlikli.toFixed(1).padStart(17)}%  ${enDusuk.toFixed(1).padStart(30)}%`
  );
}

// Her sorunun 5 katilimcida bulunma olasiligi
console.log("\nsorun                       p     siddet  5 katilimcida bulunma");
for (const s of SORUNLAR) {
  const b = (1 - (1 - s.p) ** 5) * 100;
  console.log(`${s.ad.padEnd(26)} ${s.p.toFixed(2)}  ${String(s.siddet).padStart(6)}  ${b.toFixed(1).padStart(20)}%`);
}

// Her sorunun en az %80 olasilikla bulunmasi icin kac katilimci gerekir
const enNadir = SORUNLAR.reduce((a, b) => (a.p < b.p ? a : b));
const gerekli = Math.ceil(Math.log(0.2) / Math.log(1 - enNadir.p));
console.log(`\nen nadir sorun "${enNadir.ad}" (p = ${enNadir.p}) icin %80 bulma olasiligi: ${gerekli} katilimci`);
```

```
tekduze p ile bulunan sorun orani
katilimci  p=0.10  p=0.20  p=0.31  p=0.50
        1    10.0    20.0    31.0    50.0
        2    19.0    36.0    52.4    75.0
        3    27.1    48.8    67.1    87.5
        5    41.0    67.2    84.4    96.9
        8    57.0    83.2    94.9    99.6
       10    65.1    89.3    97.6    99.9
       15    79.4    96.5    99.6   100.0
       20    87.8    98.8    99.9   100.0

sorun kumesinin ortalama p degeri: 0.3567

katilimci  tekduze p ile  gercek kume  siddetle agirlikli  bulunma olasiligi en dusuk sorun
        1          35.7%        35.7%               38.7%                             5.0%
        3          73.4%        61.0%               63.3%                            14.3%
        5          89.0%        72.3%               73.9%                            22.6%
        8          97.1%        81.4%               82.2%                            33.7%
       12          99.5%        87.9%               88.1%                            46.0%
       20         100.0%        94.0%               93.7%                            64.2%
       32         100.0%        97.5%               97.1%                            80.6%

sorun                       p     siddet  5 katilimcida bulunma
geri donuste arama kayip   0.90       4                 100.0%
raf kodu anlasilmiyor      0.75       3                  99.9%
es adli kayit karisiyor    0.60       3                  99.0%
yukleme durumu yok         0.50       2                  96.9%
ayni eylem farkli adlarla  0.40       3                  92.2%
yer tutucu etiket yerine   0.30       3                  83.2%
uc eylem esit agirlikta    0.25       2                  76.3%
hata iletisi nedensiz      0.20       3                  67.2%
uzatma yolu gizli          0.15       3                  55.6%
yardim derinde             0.10       1                  41.0%
kisayol yok                0.08       2                  34.1%
ucret onaylatilmiyor       0.05       4                  22.6%

en nadir sorun "ucret onaylatilmiyor" (p = 0.05) icin %80 bulma olasiligi: 32 katilimci
```

#### Eğrinin Okunması

**Tekdüze varsayım savı ayakta tutuyor.** Bütün sorunların aynı `p` değerine sahip olduğu
varsayılırsa, `p = 0.31` için beş katılımcı sorunların %84.4'ünü buluyor. Bu hesap doğru
yapılmış ve sonuç iç tutarlıdır.

**Gerçek sorun kümesi tekdüze değildir.** Örnek kümenin ortalama `p` değeri 0.3567; tekdüze
kabul edilirse beş katılımcıda beklenen kapsama %89.0. Aynı ortalamayı taşıyan ama dağılımı
geniş olan gerçek kümede beklenen kapsama %72.3. Aradaki 16.7 puanlık fark tümüyle
dağılımdan geliyor: yüksek `p` değerli sorunlar zaten birinci katılımcıda çıkıyor ve
eğriyi yukarı çekiyor, düşük `p` değerli sorunlar ise katılımcı eklendikçe çok yavaş
yaklaşıyor. Ortalamanın üzerinden yapılan hesap, kolay bulunanları fazladan sayar.

**Kaçırılan sorun rastgele seçilmez.** Son tablo sorunları bulunma olasılığına göre
sıralıyor ve listenin en altında şiddeti 4 olan bir sorun var: ücretin önce onaylatılmaması.
Beş katılımcıda bulunma olasılığı %22.6. Bu, önceki derste sezgi değerlendirmesinde de
yalnızca bir kişinin bulduğu sorundu. İki yöntem de aynı sorunu aynı nedenle kaçırıyor:
**nadir görülen ve ağır sonuç doğuran sorunlar, sıklığa dayanan hiçbir yöntemle güvenilir
biçimde bulunamaz.** Bunlar akış diyagramı denetimi ve ölçüt taraması gibi yapısal
yöntemlerle aranır.

**Şiddetle ağırlıklandırmak tabloyu kurtarmıyor.** Ağırlıklı kapsama beş katılımcıda %73.9;
ağırlıksız kapsamaya çok yakın. Ağır sorunların bir bölümü sık, bir bölümü nadir olduğu için
ağırlıklandırma dengeleniyor. Ağır sorunların özellikle nadir olduğu bir arayüzde ağırlıklı
kapsama ağırlıksızın altına düşer.

**Her sorunu bulmak pahalıdır.** En nadir sorunun %80 olasılıkla bulunması için otuz iki
katılımcı gerekiyor. Bu sayı çoğu koşulda karşılanamaz ve karşılanması da gerekmez. Doğru
sonuç şudur: küçük örneklemli test **sık sorunları ucuza bulan** bir yöntemdir ve bulunanları
düzeltmeye yarar; bulunmayanların yokluğunu kanıtlamaz. "Beş kullanıcıyla test ettik, sorun
çıkmadı" cümlesi bir kanıt değildir.

Uygulamada bunun karşılığı, testi tek bir büyük oturum yerine **art arda küçük turlar** hâlinde
yürütmektir: beş katılımcı, düzeltme, yeni beş katılımcı. Her turda en sık sorunlar
temizlendiği için bir sonraki turda daha seyrek sorunlar görünür hâle gelir.

#### Küçük Örneklemde Süre Ölçmenin Sınırı

Testin ikinci çıktısı süre ölçümüdür ve burada küçük örneklemin sınırı daha serttir.

```js
// sure-olcumu.mjs — kucuk orneklemde ortanca sure ve belirsizligi

// Bes katilimcinin "bilinen kaydi bul ve odunc al" gorevindeki ekran suresi (saniye)
const SURE = [42, 55, 61, 78, 154];

const sirali = [...SURE].sort((a, b) => a - b);
const ortalama = SURE.reduce((a, b) => a + b, 0) / SURE.length;
const ortanca = sirali[(sirali.length - 1) / 2];
const geometrik = Math.exp(SURE.reduce((t, x) => t + Math.log(x), 0) / SURE.length);

console.log(`olculen sureler    : ${sirali.join(", ")} sn`);
console.log(`aritmetik ortalama : ${ortalama.toFixed(1)} sn`);
console.log(`geometrik ortalama : ${geometrik.toFixed(1)} sn`);
console.log(`ortanca            : ${ortanca.toFixed(1)} sn`);
console.log(`ortalama / ortanca : ${(ortalama / ortanca).toFixed(2)}`);
const engenis = Math.max(...SURE);
console.log(`en buyuk deger (${engenis} sn) cikarilirsa ortalama: ${(SURE.filter((x) => x !== engenis).reduce((a, b) => a + b, 0) / 4).toFixed(1)} sn`);

// Siralama istatistikleriyle ortanca icin dagilimdan bagimsiz guven araligi
const binom = (n, k) => {
  let r = 1;
  for (let i = 0; i < k; i++) r = (r * (n - i)) / (i + 1);
  return r;
};
const kapsama = (n, i, j) => {
  let t = 0;
  for (let k = i; k < j; k++) t += binom(n, k);
  return t / 2 ** n;
};

console.log("\nn = 5 icin siralama araliklarinin ortancayi kapsama olasiligi");
for (const [i, j] of [[1, 5], [2, 4]]) {
  console.log(
    `  [${i}. deger, ${j}. deger] = [${sirali[i - 1]}, ${sirali[j - 1]}] sn  ->  ${(kapsama(5, i, j) * 100).toFixed(2)}%`
  );
}

// En az %90 kapsama veren en dar siralama araligi
const enDarAralik = (n) => {
  for (let g = 1; g < n; g++)
    for (let i = 1; i + g <= n; i++)
      if (kapsama(n, i, i + g) >= 0.9) return [i, i + g, g, kapsama(n, i, i + g)];
  return null;
};
console.log("\nkatilimci  %90 kapsayan en dar aralik  kapsanan sira  orneklemin payi");
for (const n of [5, 8, 12, 20, 30, 50]) {
  const a = enDarAralik(n);
  console.log(
    `${String(n).padStart(9)}  ${`[${a[0]}. , ${a[1]}. ]`.padStart(24)}  ${String(a[2] + 1).padStart(13)}  ${(((a[2] + 1) / n) * 100).toFixed(1).padStart(15)}%`
  );
}
```

```
olculen sureler    : 42, 55, 61, 78, 154 sn
aritmetik ortalama : 78.0 sn
geometrik ortalama : 70.1 sn
ortanca            : 61.0 sn
ortalama / ortanca : 1.28
en buyuk deger (154 sn) cikarilirsa ortalama: 59.0 sn

n = 5 icin siralama araliklarinin ortancayi kapsama olasiligi
  [1. deger, 5. deger] = [42, 154] sn  ->  93.75%
  [2. deger, 4. deger] = [55, 78] sn  ->  62.50%

katilimci  %90 kapsayan en dar aralik  kapsanan sira  orneklemin payi
        5                [1. , 5. ]              5            100.0%
        8                [2. , 7. ]              6             75.0%
       12                [3. , 9. ]              7             58.3%
       20               [6. , 14. ]              9             45.0%
       30              [11. , 20. ]             10             33.3%
       50              [19. , 31. ]             13             26.0%
```

Görev süreleri sağa çarpıktır: alt sınır görevin fiziksel olarak yapılabileceği süredir, üst sınır
ise yoktur. Bir katılımcı takılıp 154 saniye harcadığında aritmetik ortalama 78 saniyeye çıkıyor;
bu değer beş katılımcının dördünden büyüktür ve hiçbirini temsil etmez. O tek değer çıkarıldığında
ortalama 59 saniyeye iniyor. Ortanca 61 saniye ve tek bir uç değerden etkilenmiyor. Süre ölçütü
olarak ortanca kullanılır.

İkinci tablo asıl uyarıyı veriyor. Beş katılımcıyla, gerçek ortancayı %93.75 olasılıkla
kapsayan aralık örneklemin **tamamıdır**: 42 ile 154 saniye arası. Daha dar bir aralık —
55 ile 78 saniye — yalnızca %62.5 kapsıyor. Beş katılımcıdan çıkan 61 saniyelik ortanca bir
ölçüm değil, çok geniş bir aralığın orta noktasıdır.

Son tablo bunun nasıl daraldığını gösteriyor. Otuz katılımcıda %90 kapsayan aralık, sıralı
değerlerin ortadaki onunu kaplıyor — örneklemin üçte biri; elli katılımcıda dörtte biri.
Süre karşılaştırması yapılacaksa gereken örneklem, sorun bulmak için gerekenden bir
büyüklük basamağı fazladır.

Bunun uygulamadaki karşılığı sert bir ayrımdır: **küçük örneklemli test sorun bulur, sayı
üretmez.** Beş katılımcılı bir oturumdan "görev süresi 61 saniye" cümlesi çıkarılmaz;
"beş katılımcının dördü bir dakikanın altında tamamladı, biri raf kodunu arayarak takıldı"
cümlesi çıkarılır. İkincisi hem doğrudur hem karar ürettirir.

#### Özet

- Kullanılabilirlik testi görüş toplamaz; görev senaryosu verilir, sesli düşünme istenir ve
  moderatör yol göstermez, savunma yapmaz.
- Sınanan arayüzdür; onay ayrıntılı ve geri alınabilirdir, bulgular kodla yazılır, ham kayıt
  saklama sınırı içinde silinir ve alıntı kullanımı ayrıca sorulur.
- Keşif eğrisi tekdüze bulunma olasılığı varsayar; örnek kümede aynı ortalamayla tekdüze
  hesap beş katılımcıda %89.0, gerçek dağılım %72.3 verdi.
- Kaçırılan sorunlar rastgele değildir: nadir ve ağır sorunlar sıklığa dayanan yöntemlerle
  bulunamaz, yapısal denetimlerle aranır; örnek kümenin en ağır sorunlarından biri beş
  katılımcıda ancak %22.6 olasılıkla görünüyor.
- Küçük örneklemli test sık sorunları ucuza bulur ve art arda turlarla yürütülür; bulgu
  çıkmaması sorun olmadığını kanıtlamaz.
- Süre ölçütü ortancadır; beş katılımcıda gerçek ortancayı %93.75 kapsayan aralık örneklemin
  tamamıdır, dolayısıyla küçük örneklemli test sorun bulur, sayı üretmez.

#### Sonraki Adım

Test, kullanıcının nerede takıldığını gösteriyor. Raf kodunu arayarak takılan katılımcının
ekranda o bilgiye baktığı ama kullanmadığı görülüyor; eş adlı iki cilt arasında yanlış olanı
seçen katılımcının başlığın tamamını okumadığı görülüyor. Gözlem her ikisini de kaydediyor
ama hiçbirini açıklamıyor. Kullanıcı niçin baktığı bilgiyi kullanmadı, niçin okumadan seçti?
Bunlar dikkatsizlik değildir; kararın nasıl verildiğine ilişkin sorulardır. Sonraki konunun
ilk dersi olan Çift Süreçli Düşünme, kararların hızlı ve sezgisel bir süreçle mi yoksa yavaş
ve düşünsel bir süreçle mi alındığını ayırır ve arayüzün hangisine hitap ettiğini sorar.

## Davranış Tasarımı

Sezgisel ve düşünsel karar verme, bilişsel yük, motivasyon–yetenek–tetikleyici çerçevesi, alışkanlık döngüsü, varsayılanların etkisi ve karanlık kalıpların tanınması.

### Çift Süreçli Düşünme

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/cift-surecli-dusunme

Kararın hızlı sezgisel sistemle mi yavaş düşünsel sistemle mi verildiği, sonuç listesinde belirginliğin seçimi belirlemesi ve düşünsel sisteme geçişin süre bedelinin hesaplanması.

Kullanılabilirlik testi kullanıcının **nerede** takıldığını gösterir. Katılımcı sonuç
listesinde duraksadı, üçüncü kaydı açtı, geri döndü, ikinci kaydı açtı ve ödünç aldı —
kayıt tuttunuz, süreleri yazdınız, sorunu bir adıma sabitlediniz. Testin
söylemediği şey, o duraksamanın **neden** olduğu. Aynı gözlem iki farklı nedenden
doğabilir: kullanıcı listede aradığı bilgiyi bulamamış olabilir ya da bulmuş ama görsel
düzenin işaret ettiği kayda güvenmiş, sonra yanıldığını fark etmiş olabilir. İki neden
farklı tasarım kararı gerektirir.

Bu konu, gözlenen davranışın altındaki karar mekanizmalarını ele alır. İlk soru şudur:
bir kullanıcı katalogda kayıt seçerken ne kadarını okur, ne kadarını görür?

#### İki Karar Kipi

İnsan kararı tek bir mekanizmadan çıkmaz. **Çift süreçli düşünme (dual-process
thinking)** modeli, kararın birbirinden ayrı iki işleyişle verilebildiğini söyler.

**Sezgisel sistem** hızlıdır, örüntü eşlemesiyle çalışır, çaba istemez ve neredeyse
kesintisiz açıktır. Bir listeye baktığınızda hangi ögenin "öne çıktığını" okumadan
bilirsiniz; bu bilgi boyut, ağırlık, konum ve karşıtlıktan gelir — Arayüz Tasarımının
Temelleri kursunda **görsel ağırlık** adıyla ölçülen büyüklüklerdir. Sezgisel sistem bu
ağırlığı bir alaka işareti olarak okur.

**Düşünsel sistem** yavaştır, sıralıdır, dikkat ister ve yorulur. Kayıt başlığını okumak,
yayın yılıyla aradığınız baskıyı karşılaştırmak, iki kaydın hangisinin sizin aradığınız
cilt olduğunu çıkarmak bu sistemin işidir.

İki sistem yarışmaz; biri diğerine devreder. Sezgisel sistem sürekli bir yanıt üretir;
düşünsel sistem yalnızca bir çelişki, bir belirsizlik ya da bir maliyet işareti
gördüğünde devreye girer. Tasarımın belirlediği şey, **hangisinin kararı verdiğidir.**

#### Sonuç Listesinde Hangi Sistem Karar Veriyor

Katalog arayüzünde bir arama sekiz kayıt döndürüyor. Kullanıcının aradığı, sorguya en
uygun kayıt. Arayüz ise kayıtları bir ölçüte göre sıralayıp vurguluyor. İki ölçüt aynı
olmak zorunda değil.

Aşağıdaki benzetim üç arayüz seçeneğini karşılaştırıyor: kayıtları yayın yılına göre
öne çıkaran, kapak görseli olanı öne çıkaran ve sorguya uygunluğa göre öne çıkaran.
Kullanıcı iki kipte davranabiliyor: en belirgin kaydı seçmek (sezgisel) ya da sekiz
kaydı da okuyup karşılaştırmak (düşünsel).

```js
// belirginlik.mjs — sonuc listesinde belirginligin secimi belirlemesi

// Belirlenimci sozde rastgele uretec (dogrusal eslesik uretec).
function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

const LISTE_UZUNLUGU = 8;
const DENEME = 500;

// Bir arama sonucu listesi uret: her kaydin uygunlugu (0-100) ve yayin yili.
function liste(rnd) {
  const kayitlar = [];
  for (let i = 0; i < LISTE_UZUNLUGU; i++) {
    kayitlar.push({
      uygunluk: Math.round(rnd() * 100),   // sorguya gercek uyum
      yil: 1980 + Math.round(rnd() * 45),  // yayin yili
      kapak: rnd() < 0.35,                 // kapak gorseli var mi
    });
  }
  return kayitlar;
}

// Uc arayuz: her biri kayda gorsel agirlik atar.
const ARAYUZLER = {
  "yila gore": (k) => k.yil - 1980,                       // en yeni en ustte ve en buyuk
  "kapak gorseline gore": (k) => (k.kapak ? 80 : 20) + (k.yil - 1980) / 10,
  "uygunluga gore": (k) => k.uygunluk,                    // gorsel agirlik = uyum
};

const OKUMA_SURESI = 1.4;   // saniye / kayit — bir kaydi okuyup degerlendirme
const TARAMA_SURESI = 0.6;  // saniye — listeyi tarayip en belirgini secme

const enBuyuk = (kayitlar, olcut) =>
  kayitlar.reduce((a, b) => (olcut(b) > olcut(a) ? b : a));

console.log("arayuz                 sezgisel dogru  sezgisel sure  dusunsel dogru  dusunsel sure");
for (const [ad, agirlik] of Object.entries(ARAYUZLER)) {
  const rnd = uretec(20240701);
  let sezgiselDogru = 0;
  for (let d = 0; d < DENEME; d++) {
    const kayitlar = liste(rnd);
    const enUygun = enBuyuk(kayitlar, (k) => k.uygunluk);
    const enBelirgin = enBuyuk(kayitlar, agirlik);
    if (enBelirgin.uygunluk === enUygun.uygunluk) sezgiselDogru++;
  }
  console.log(
    `${ad.padEnd(22)} ${((sezgiselDogru / DENEME * 100).toFixed(1) + " %").padStart(14)} ${(TARAMA_SURESI.toFixed(1) + " sn").padStart(14)}` +
    `  ${("100.0 %").padStart(14)} ${((TARAMA_SURESI + LISTE_UZUNLUGU * OKUMA_SURESI).toFixed(1) + " sn").padStart(13)}`
  );
}

// Karma davranis: kullanici belirgin kayda guvenir, ancak ilk iki kayit gorsel
// agirlik bakimindan birbirine yakinsa okumaya gecer.
console.log("\nkarma davranis (ilk iki kayit gorsel agirlikta %15'ten yakinsa okuma)");
console.log("arayuz                 dogru oran  ortalama sure  okumaya gecis");
for (const [ad, agirlik] of Object.entries(ARAYUZLER)) {
  const rnd = uretec(20240701);
  let dogru = 0, sure = 0, okuma = 0;
  for (let d = 0; d < DENEME; d++) {
    const kayitlar = liste(rnd);
    const enUygun = enBuyuk(kayitlar, (k) => k.uygunluk);
    const sirali = [...kayitlar].sort((a, b) => agirlik(b) - agirlik(a));
    const fark = agirlik(sirali[0]) === 0 ? 1 : (agirlik(sirali[0]) - agirlik(sirali[1])) / Math.abs(agirlik(sirali[0]));
    if (fark < 0.15) {
      okuma++;
      sure += TARAMA_SURESI + LISTE_UZUNLUGU * OKUMA_SURESI;
      dogru++;
    } else {
      sure += TARAMA_SURESI;
      if (sirali[0].uygunluk === enUygun.uygunluk) dogru++;
    }
  }
  console.log(
    `${ad.padEnd(22)} ${((dogru / DENEME * 100).toFixed(1) + " %").padStart(10)} ${((sure / DENEME).toFixed(2) + " sn").padStart(14)}` +
    ` ${((okuma / DENEME * 100).toFixed(1) + " %").padStart(14)}`
  );
}

// Yanlis secimin bedeli: secilen kayit ile en uygun kayit arasindaki uygunluk farki
console.log("\narayuz                 ortalama uygunluk kaybi (sezgisel secim)");
for (const [ad, agirlik] of Object.entries(ARAYUZLER)) {
  const rnd = uretec(20240701);
  let kayip = 0;
  for (let d = 0; d < DENEME; d++) {
    const kayitlar = liste(rnd);
    kayip += enBuyuk(kayitlar, (k) => k.uygunluk).uygunluk - enBuyuk(kayitlar, agirlik).uygunluk;
  }
  console.log(`${ad.padEnd(22)} ${(kayip / DENEME).toFixed(1).padStart(10)} puan`);
}
```

```
arayuz                 sezgisel dogru  sezgisel sure  dusunsel dogru  dusunsel sure
yila gore                      13.6 %         0.6 sn         100.0 %       11.8 sn
kapak gorseline gore           12.6 %         0.6 sn         100.0 %       11.8 sn
uygunluga gore                100.0 %         0.6 sn         100.0 %       11.8 sn

karma davranis (ilk iki kayit gorsel agirlikta %15'ten yakinsa okuma)
arayuz                 dogru oran  ortalama sure  okumaya gecis
yila gore                  70.6 %        7.95 sn         65.6 %
kapak gorseline gore       87.8 %       10.16 sn         85.4 %
uygunluga gore            100.0 %        7.97 sn         65.8 %

arayuz                 ortalama uygunluk kaybi (sezgisel secim)
yila gore                    39.5 puan
kapak gorseline gore         37.8 puan
uygunluga gore                0.0 puan
```

#### Sezgisel Sistem Yanılmaz, Yanlış Beslenir

İlk tablonun ilk sütunu bu dersin çekirdeğidir. Sezgisel kip aynı kural ile çalışıyor —
"en belirgin olanı seç" — ama doğruluğu yüzde 13'ten yüzde 100'e çıkıyor. Değişen tek
şey arayüzün neyi belirgin yaptığı.

Bu, sezgisel sistemin kusurlu olduğu anlamına gelmez. Kural doğru bir kuraldır: gerçek
dünyada göze çarpan şey çoğu zaman aranan şeydir. Kuralın çıktısı, girdisi kadar iyidir.
Girdiyi tasarımcı seçer. Kayıtları yayın yılına göre vurgulayan arayüz, kullanıcının
sezgisel sistemine "en yeni olan en uygun olandır" bilgisini besler; kullanıcı bu bilgiyi
seçmemiştir, arayüz vermiştir.

Üçüncü tablo hatanın büyüklüğünü veriyor. Yayın yılına göre vurgulanan listede sezgisel
seçim, ortalama 39.5 uygunluk puanı daha kötü bir kayıtla sonuçlanıyor. Yüz puanlık bir
ölçekte bu, listenin en uygun kaydı yerine orta sıralardan bir kaydın alınmasıdır.
Kullanıcı yanlış kitabı ödünç alıyor ve bunu ancak kitabı eline aldığında anlıyor.

Buradan çıkan ilk tasarım kuralı: **görsel ağırlık, kullanıcının karar ölçütüyle aynı
büyüklüğe bağlanır.** Sıralama ölçütü ile vurgu ölçütü ayrışıyorsa arayüz kullanıcıya
yanlış bilgi veriyordur — yazılı olarak değil, biçim yoluyla.

#### Düşünsel Sisteme Geçmenin Bedeli Süredir

İkinci tablo daha ilginç bir şey ölçüyor. Burada kullanıcı katı değil: en belirgin iki
kayıt birbirine yakınsa, yani vurgu net bir yanıt vermiyorsa, okumaya geçiyor.

Yayın yılına göre vurgulanan arayüzde kullanıcı denemelerin yüzde 65.6'sında okumaya geçiyor,
ortalama süre 0.6 saniyeden 7.95 saniyeye çıkıyor ve doğruluk yüzde 70.6'da kalıyor. Kapak
görseline göre vurgulanan arayüzde okumaya geçiş yüzde 85.4'e, süre 10.16 saniyeye çıkıyor;
doğruluk yüzde 87.8. Daha çok okumak daha doğru sonuç veriyor ama süreyi yüzde yirmi sekiz
uzatıyor.

Uygunluğa göre vurgulanan arayüzde okumaya geçiş oranı yüzde 65.8, süre 7.97 saniye —
yayın yılına göre vurgulayan arayüzle neredeyse aynı. Doğruluk ise yüzde 100. Aynı süre,
aynı okuma miktarı, farklı sonuç. Fark, okumanın **ne işe yaradığındadır**: birinde
kullanıcı arayüzün hatasını düzeltmek için okuyor, diğerinde arayüzün verdiği yanıtı
doğrulamak için.

Bu ayrım, kullanılabilirlik testinde gözlenen duraksamanın iki nedenini birbirinden
ayırır. Kullanıcı okuyorsa ve sonunda arayüzün önerdiği kaydı alıyorsa, okuma bir
doğrulamadır; süre maliyeti vardır ama sonuç doğrudur. Kullanıcı okuyor ve arayüzün
önerdiğinden farklı bir kaydı alıyorsa, arayüz onu yanlış yönlendirmiştir ve okuma bir
onarımdır. Test kaydında ikisi aynı görünür: "katılımcı listede duraksadı".

#### Bu Modelin Sınırları

Yukarıdaki sayılar bir benzetimden çıkıyor, ölçümden değil. Okuma süresi 1.4 saniye,
tarama süresi 0.6 saniye ve yüzde 15'lik yakınlık eşiği varsayımdır; başka değerler
başka sayılar verir. Modelin taşıdığı sonuç sayılar değil, sayıların **yönüdür**: vurgu
ölçütü karar ölçütünden ayrıştığında sezgisel seçim bozulur ve düzeltme süre olarak
ödenir. Bu yön varsayımların makul aralığında değişmez.

Modelin ölçmediği bir şey daha var. Burada kullanıcı, okumaya geçtiğinde her zaman doğru
kararı veriyor. Gerçek kullanıcı yorulur; düşünsel sistem sınırsız değildir. Sekiz
kaydın karşılaştırılması sekiz ayrı kararla değil, çok daha hızlı tükenen bir dikkat
bütçesiyle yapılır. O bütçenin nasıl harcandığı sonraki dersin konusudur.

#### Tasarımcının Sorumluluğu Nerede Başlar

Sezgisel sistemin girdisini tasarımcı seçtiği için, o girdinin doğruluğu tasarımcının
sorumluluğundadır. Bu, bu konunun tamamına yayılan bir ölçütün ilk biçimidir:

**Kullanıcı, arayüzün ona ne söylediğini bilseydi de aynı kararı verecek miydi?**

Uygunluğa göre vurgulanan listede yanıt evettir: kullanıcı "bu kayıt en üstte çünkü
sorguna en çok uyuyor" bilgisini bilse de aynı kaydı seçerdi. Yayın yılına göre
vurgulanan listede yanıt hayırdır: kullanıcı "bu kayıt en üstte çünkü en yeni basım"
bilgisini bilseydi listeyi okumaya geçerdi. İkinci arayüz, kararın gücünü kullanıcının
bilgisizliğinden alıyor.

Bu ölçüt, bu noktada bir tasarım kalitesi ölçütü gibi görünüyor; konunun sonunda bir
etik ölçüte dönüşecek. Aradaki tek fark, ayrışmanın kazayla mı yoksa bilerek mi
kurulduğudur.

#### Özet

- Çift süreçli düşünme, kararın hızlı ve çabasız sezgisel sistemle mi yavaş ve dikkat
  isteyen düşünsel sistemle mi verildiğini ayırır; arayüz hangisinin karar verdiğini
  belirler.
- Sezgisel sistem "en belirgin olanı seç" kuralını uygular; kuralın doğruluğu, arayüzün
  neyi belirgin yaptığına bağlıdır — benzetimde aynı kural yüzde 13 ile yüzde 100
  arasında sonuç verdi.
- Vurgu ölçütü karar ölçütünden ayrıştığında sezgisel seçimin bedeli ölçülebilir: sekiz
  kayıtlık listede ortalama 39.5 uygunluk puanı kayıp.
- Düşünsel sisteme geçiş hatayı azaltır ama süreyi yaklaşık yirmi kat artırır; kullanıcının
  okuması ya bir doğrulamadır ya da arayüzün hatasının onarımıdır.
- Kullanılabilirlik testindeki "duraksama" gözlemi bu iki durumu ayırmaz; ayrım, hangi
  kaydın seçildiğine bakılarak yapılır.
- Sezgisel sistemin girdisini tasarımcı seçtiği için, kullanıcının bu bilgiyi bilse de
  aynı kararı verip vermeyeceği sorusu tasarımcının sorusudur.

#### Sonraki Adım

Bu ders düşünsel sistemin bir bedeli olduğunu gösterdi ama bedeli sabit varsaydı: her
kayıt 1.4 saniye. Gerçekte bedel seçenek sayısıyla birlikte artar ve artış doğrusal
değildir. Sonraki ders bu artışı ölçer: bir listedeki seçenek sayısı karar süresini nasıl
belirler, ekrandaki bağımsız karar noktaları nasıl sayılır ve seçenekleri gruplamanın
karar süresine etkisi niçin beklenenin tersi çıkar?

### Bilişsel Yük

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/bilissel-yuk

Seçenek sayısının karar süresine etkisinin Hick–Hyman bağıntısıyla hesaplanması, gruplamanın beklenenin tersi sonucu, ekrandaki bağımsız karar noktalarının sayımı ve karar yorgunluğunun hata oranına etkisi.

Önceki ders düşünsel sisteme geçmenin bir bedeli olduğunu gösterdi ama bedeli sabit
varsaydı: her kayıt 1.4 saniye. Bu varsayım listedeki kayıt sayısı değişmediği sürece
işe yarar. Katalog arayüzünde ise seçenek sayısı her ekranda başka bir değer alır: süzgeç
panelinde yirmi dört ölçüt, sıralama açılırında beş, teslim şubesi listesinde altı.

Bu ders seçenek sayısıyla karar süresi arasındaki bağıntıyı kurar, ödünç alma akışındaki
bağımsız karar noktalarını sayar ve yükün hata oranına dönüşümünü hesaplar. Çıkan
sonuçlardan biri, alışılmış bir tasarım öğüdünün ölçüyle uyuşmadığını gösterecek.

#### Karar Süresi Seçenek Sayısının Logaritmasıdır

Eş olasılıklı $n$ seçenek arasından seçim yapmanın süresi, seçenek sayısıyla değil
seçeneklerin taşıdığı **bilgi miktarıyla** orantılıdır. **Hick–Hyman bağıntısı** bunu
şöyle yazar:

$$T = a + b \cdot \log_2(n + 1)$$

Burada $a$ karar dışı sabit gecikmedir (algılama ve eylem), $b$ ise bit başına karar
süresidir. $n + 1$ terimi "hiçbirini seçmeme" seçeneğini hesaba katar.

Bağıntının taşıdığı sezgi şudur: seçim, ikili bir arama gibi işler. Kullanıcı seçenekleri
teker teker gözden geçirmez; kümeyi ardışık olarak ikiye böler. Seçenek sayısını iki
katına çıkarmak süreye tek bir bit ekler.

**Bilişsel yük (cognitive load)** bu bitlerin toplamıdır: kullanıcının bir görevi
tamamlamak için işlemek zorunda olduğu bilgi miktarı. Yük ölçülebilir bir büyüklük
olduğu için tasarım kararı da ölçülebilir hâle gelir.

#### Ödünç Alma Akışının Yükünü Saymak

Aşağıdaki hesap üç şeyi yapıyor: seçenek sayısı–süre eğrisini çıkarıyor, düz liste ile
gruplanmış listeyi karşılaştırıyor ve katalog arayüzünün ödünç alma akışındaki bağımsız
karar noktalarını sayıp toplam yükü veriyor.

```js
// yuk.mjs — Hick-Hyman karar suresi, gruplama ve ekrandaki karar noktalari

const A = 0.20;  // sn — karar disi sabit gecikme (algi + eylem)
const B = 0.15;  // sn/bit — bit basina karar suresi

const log2 = (x) => Math.log(x) / Math.LN2;
const esOlasiSure = (n) => A + B * log2(n + 1);          // Hick yasasi
const entropi = (p) => -p.reduce((t, x) => t + (x > 0 ? x * log2(x) : 0), 0);
const entropiliSure = (p) => A + B * entropi(p);          // Hyman genellemesi

// 1) Suzgec panelindeki secenek sayisinin karar suresine etkisi
console.log("secenek  bilgi (bit)  karar suresi");
for (const n of [2, 4, 8, 12, 16, 24, 32]) {
  console.log(`${String(n).padStart(7)} ${log2(n + 1).toFixed(3).padStart(12)} ${(esOlasiSure(n).toFixed(3) + " sn").padStart(13)}`);
}

// 2) Duz liste ile iki asamali gruplama karsilastirmasi (24 suzgec secenegi)
console.log("\n24 suzgec secenegi icin duzen karsilastirmasi");
const duz = esOlasiSure(24);
const grup = esOlasiSure(4) + esOlasiSure(6);      // once grup, sonra grup icinden
const grup3 = esOlasiSure(3) + esOlasiSure(8);
const grup2 = esOlasiSure(2) + esOlasiSure(12);
console.log(`duz liste (24)          ${duz.toFixed(3)} sn`);
console.log(`4 grup x 6 secenek      ${grup.toFixed(3)} sn   (fark ${(grup - duz).toFixed(3)} sn)`);
console.log(`3 grup x 8 secenek      ${grup3.toFixed(3)} sn   (fark ${(grup3 - duz).toFixed(3)} sn)`);
console.log(`2 grup x 12 secenek     ${grup2.toFixed(3)} sn   (fark ${(grup2 - duz).toFixed(3)} sn)`);

// 3) Kullanim dagilimi es olasili degilse: Hyman entropisi
console.log("\nkullanim dagilimi es olasili olmadiginda (24 secenek)");
const esOlasili = Array(24).fill(1 / 24);
// Gozlenen kullanim: uc suzgec agirlikli, kalan 21 seyrek
const gozlenen = [];
const agir = [0.34, 0.26, 0.17];
for (const p of agir) gozlenen.push(p);
for (let i = 0; i < 21; i++) gozlenen.push((1 - 0.77) / 21);
console.log(`es olasili dagilim      entropi ${entropi(esOlasili).toFixed(3)} bit   sure ${entropiliSure(esOlasili).toFixed(3)} sn`);
console.log(`gozlenen dagilim        entropi ${entropi(gozlenen).toFixed(3)} bit   sure ${entropiliSure(gozlenen).toFixed(3)} sn`);
console.log(`siklik sirasina koymanin kazanci: ${(entropiliSure(esOlasili) - entropiliSure(gozlenen)).toFixed(3)} sn`);
console.log(`gruplamanin kazanci (es olasili varsayimiyla):  ${(duz - grup).toFixed(3)} sn`);

// 4) Odunc alma akisindaki bagimsiz karar noktalarinin sayimi
// Her karar noktasi: kullanicinin secim yapmak zorunda oldugu, birbirinden bagimsiz alan.
const AKIS = [
  { ekran: "arama", noktalar: [["arama alani", 1], ["kapsam secimi", 3], ["siralama", 5]] },
  { ekran: "sonuc listesi", noktalar: [["suzgec paneli", 24], ["siralama", 5], ["sayfa boyutu", 4], ["kayit secimi", 20]] },
  { ekran: "kayit ayrinti", noktalar: [["nusha secimi", 3], ["odunc / rezerve / listeye ekle", 3]] },
  { ekran: "odunc onayi", noktalar: [["teslim subesi", 6], ["sure secimi", 3], ["hatirlatma tercihi", 4], ["onay", 2]] },
];
console.log("\nekran            karar noktasi  toplam bit  karar suresi");
let toplamBit = 0, toplamSure = 0, toplamNokta = 0;
for (const { ekran, noktalar } of AKIS) {
  const bit = noktalar.reduce((t, [, n]) => t + log2(n + 1), 0);
  const sure = noktalar.reduce((t, [, n]) => t + esOlasiSure(n), 0);
  toplamBit += bit; toplamSure += sure; toplamNokta += noktalar.length;
  console.log(`${ekran.padEnd(16)} ${String(noktalar.length).padStart(13)} ${bit.toFixed(2).padStart(11)} ${(sure.toFixed(2) + " sn").padStart(13)}`);
}
console.log(`${"TOPLAM".padEnd(16)} ${String(toplamNokta).padStart(13)} ${toplamBit.toFixed(2).padStart(11)} ${(toplamSure.toFixed(2) + " sn").padStart(13)}`);

// 5) Karar yorgunlugu: harcanan bit arttikca hata olasiligi yukselir
// p_hata(x) = p0 + k * (x / butce)^2 ; x = o ana kadar harcanan bit
const P0 = 0.02, K = 0.16, BUTCE = 32;
function akisHatasi(akis) {
  let harcanan = 0, beklenenHata = 0;
  for (const { noktalar } of akis) {
    for (const [, n] of noktalar) {
      const bit = log2(n + 1);
      const p = Math.min(1, P0 + K * Math.pow(harcanan / BUTCE, 2));
      beklenenHata += p;
      harcanan += bit;
    }
  }
  return { harcanan, beklenenHata };
}
const once = akisHatasi(AKIS);
console.log(`\nharcanan bilgi ${once.harcanan.toFixed(2)} bit, beklenen hatali secim sayisi ${once.beklenenHata.toFixed(3)}`);

// 6) Azaltilmis akis: varsayilanlari olan alanlar karar noktasi olmaktan cikar
const AZALTILMIS = [
  { ekran: "arama", noktalar: [["arama alani", 1]] },
  { ekran: "sonuc listesi", noktalar: [["suzgec paneli (4 grup)", 4], ["grup ici secim", 6], ["kayit secimi", 20]] },
  { ekran: "kayit ayrinti", noktalar: [["odunc / rezerve / listeye ekle", 3]] },
  { ekran: "odunc onayi", noktalar: [["onay", 2]] },
];
const sonra = akisHatasi(AZALTILMIS);
const azSure = AZALTILMIS.reduce((t, e) => t + e.noktalar.reduce((s, [, n]) => s + esOlasiSure(n), 0), 0);
const azNokta = AZALTILMIS.reduce((t, e) => t + e.noktalar.length, 0);
console.log(`azaltilmis akis: ${azNokta} karar noktasi, ${sonra.harcanan.toFixed(2)} bit, ${azSure.toFixed(2)} sn, beklenen hatali secim ${sonra.beklenenHata.toFixed(3)}`);
console.log(`kazanc: ${(toplamNokta - azNokta)} karar noktasi, ${(toplamSure - azSure).toFixed(2)} sn, ${((1 - sonra.beklenenHata / once.beklenenHata) * 100).toFixed(1)} % daha az beklenen hata`);
```

```
secenek  bilgi (bit)  karar suresi
      2        1.585      0.438 sn
      4        2.322      0.548 sn
      8        3.170      0.675 sn
     12        3.700      0.755 sn
     16        4.087      0.813 sn
     24        4.644      0.897 sn
     32        5.044      0.957 sn

24 suzgec secenegi icin duzen karsilastirmasi
duz liste (24)          0.897 sn
4 grup x 6 secenek      1.169 sn   (fark 0.273 sn)
3 grup x 8 secenek      1.175 sn   (fark 0.279 sn)
2 grup x 12 secenek     1.193 sn   (fark 0.296 sn)

kullanim dagilimi es olasili olmadiginda (24 secenek)
es olasili dagilim      entropi 4.585 bit   sure 0.888 sn
gozlenen dagilim        entropi 2.967 bit   sure 0.645 sn
siklik sirasina koymanin kazanci: 0.243 sn
gruplamanin kazanci (es olasili varsayimiyla):  -0.273 sn

ekran            karar noktasi  toplam bit  karar suresi
arama                        3        5.58       1.44 sn
sonuc listesi                4       13.94       2.89 sn
kayit ayrinti                2        4.00       1.00 sn
odunc onayi                  4        8.71       2.11 sn
TOPLAM                      13       32.24       7.44 sn

harcanan bilgi 32.24 bit, beklenen hatali secim sayisi 0.943
azaltilmis akis: 6 karar noktasi, 14.11 bit, 3.32 sn, beklenen hatali secim 0.170
kazanc: 7 karar noktasi, 4.12 sn, 82.0 % daha az beklenen hata
```

#### Seçenek Eklemek Ucuzdur, Seçenek Kümesi Eklemek Pahalıdır

İlk tablo logaritmik artışın ne demek olduğunu gösteriyor. Seçenek sayısı ikiden otuz
ikiye, yani on altı katına çıkarken karar süresi 0.438 saniyeden 0.957 saniyeye, yani
yalnızca 2.2 katına çıkıyor. Sekiz seçenekten on altıya geçmenin bedeli 0.138 saniye.

Bu, tek bir açılır listeye seçenek eklemenin ucuz olduğu anlamına gelir. Pahalı olan
başka bir şeydir ve dördüncü tabloda görünür: **ayrı bir karar noktası eklemek.** Her
karar noktası $a$ sabitini yeniden ödetir. Üçüncü ekrandaki iki karar noktası 1.00
saniye tutuyor; bunun 0.40 saniyesi, yani yüzde 40'ı, seçeneklerin sayısından değil
karar noktalarının sayısından geliyor.

Kural şudur: **on iki seçenekli bir alan, üç seçenekli dört alandan daha ucuzdur.**
Hesap bunu doğruluyor — on iki seçenekli tek alan 0.755 saniye, üç seçenekli dört alan
$4 \times 0.500 = 2.000$ saniye.

#### Gruplamanın Etkisi Beklenenin Tersidir

İkinci tablo, sık verilen bir tasarım öğüdüyle çelişiyor. Yirmi dört seçenekli düz liste
0.897 saniye; aynı yirmi dört seçenek dört gruba bölündüğünde 1.169 saniye. Gruplama
karar süresini **0.273 saniye artırıyor**, azaltmıyor. Nedeni önceki paragraftaki
kuraldır: gruplama, tek bir karar noktasını iki karar noktasına çeviriyor ve $a$ sabiti
iki kez ödeniyor.

Bu sonuç gruplamanın yanlış olduğu anlamına gelmez; gruplamanın **karar süresi için
yapılmadığı** anlamına gelir. Gruplama başka bir maliyeti düşürür: kullanıcının aradığı
seçeneği listede **bulma** maliyetini. Yirmi dört ögelik etiketsiz bir listede kullanıcı
ögeleri okumak zorundadır; dört başlıklı bir listede yalnızca bir başlığın altını okur.
Hick–Hyman bağıntısı seçeneğin zaten bilindiğini varsayar — arama maliyetini hesaba
katmaz. İki maliyet ayrı ayrı ölçülür ve ayrı ayrı gerekçelendirilir.

Üçüncü tablo daha büyük bir kazanç gösteriyor. Süzgeç kullanımı eş olasılıklı değilse —
kullanıcıların yüzde 77'si yalnızca üç ölçütü kullanıyorsa — entropi 4.585 bitten 2.967
bite düşüyor ve süre 0.888 saniyeden 0.645 saniyeye iniyor. Sık kullanılanı öne koymanın
kazancı 0.243 saniye; gruplamanın "kazancı" ise eksi 0.273 saniye. Yük düşürmenin en
verimli yolu seçenekleri yeniden düzenlemek değil, **kullanım dağılımını arayüze
yansıtmaktır.**

Bunun bir önkoşulu var: kullanım dağılımının bilinmesi. Bu dağılım tahminle değil
ölçümle elde edilir; ölçme konusunun konusudur.

#### Yorgunluk Yükün İkinci Faturasıdır

Beşinci hesap yükün süre dışında bir bedeli daha olduğunu modelliyor. Kullanıcının
dikkati sınırlıdır ve harcandıkça hata olasılığı yükselir. Modelde hata olasılığı, o ana
kadar harcanmış bit sayısının karesiyle artıyor.

Ödünç alma akışının tamamı on üç karar noktası ve 32.24 bit tutuyor. Bu yükte beklenen
hatalı seçim sayısı 0.943 — akışı tamamlayan her kullanıcı ortalama bir kararı yanlış
veriyor. Yanlış verilen karar akışın sonundaki bir karar olma eğilimindedir; en yorgun
anlar en son ekrandadır. Katalog arayüzünde bu ekran ödünç onayıdır: teslim şubesi, süre
ve hatırlatma tercihi burada seçilir. Yanlış şubeye ısmarlanan bir kitap, kullanıcının
en pahalı hatasıdır.

Altıncı hesap yedi karar noktasını kaldırıyor. Kaldırılan alanlar yok olmuyor;
**varsayılan** değer alıyorlar. Teslim şubesi kullanıcının bağlı olduğu şube, süre en
uzun süre, hatırlatma tercihi açık geliyor. Kullanıcı isterse değiştirebiliyor ama
değiştirmediği sürece karar vermek zorunda kalmıyor. Sonuç: 7.44 saniye yerine 3.32
saniye ve yüzde 82 daha az beklenen hata.

Buradan iki ayrı sonuç çıkar ve karıştırılmamalıdırlar. Birincisi bir tasarım
kazancıdır: kullanıcıdan istenmeyen karar, verilmeyen karardan iyidir. İkincisi bir
uyarıdır: varsayılan koymak, kararı kullanıcıdan alıp tasarımcıya vermektir. Yukarıdaki
üç varsayılan kullanıcının yararınadır — kullanıcı bilseydi de aynısını seçerdi. Aynı
mekanizma kullanıcının aleyhine kurulabilir. Varsayılanların gücü ve o gücün sınırı ayrı
bir dersin konusudur.

#### Yükü Ölçmenin Pratik Yolu

Bir ekranın yükünü ölçmek için tasarım aracına gerek yok; sayım yeter.

**Bağımsız karar noktalarını say.** Kullanıcının değer atamak zorunda olduğu her alan bir
noktadır. Değeri önceden dolu ve kullanıcı dokunmadan geçebiliyorsa nokta sayılmaz.

**Her noktanın seçenek sayısını yaz ve $\log_2(n+1)$ topla.** Toplam, ekranın bit
cinsinden yüküdür. Ekranlar arasında karşılaştırma bu sayıyla yapılır.

**Aynı akıştaki toplam biti izle.** Yorgunluk akış boyunca birikir; tek tek makul
görünen ekranlar toplandığında makul olmayabilir.

**Sırayı kullanım dağılımına göre kur.** Sıklık sırası, gruplamadan daha büyük bir
kazanç verir ve karar noktası eklemez.

#### Özet

- Hick–Hyman bağıntısı karar süresini seçenek sayısının logaritmasına bağlar:
  $T = a + b \log_2(n+1)$; seçenek sayısını ikiye katlamak süreye bir bit ekler.
- Seçenek eklemek ucuz, karar noktası eklemek pahalıdır; on iki seçenekli tek alan,
  üç seçenekli dört alandan yaklaşık 2.6 kat hızlı seçilir.
- Gruplama karar süresini düşürmez, hesapta 0.273 saniye artırır; gruplamanın gerekçesi
  karar süresi değil, seçeneği listede bulma maliyetidir.
- Kullanım dağılımı eş olasılıklı olmadığında entropi düşer; süzgeçleri sıklık sırasına
  koymak 0.243 saniye kazandırır ve karar noktası eklemez.
- Yük akış boyunca birikir ve hata olasılığını yükseltir; on üç karar noktalı ödünç akışı
  altı noktaya indiğinde beklenen hatalı seçim yüzde 82 azalır.
- Varsayılan vermek kararı kullanıcıdan alıp tasarımcıya devretmektir; kazancı da riski
  de buradan gelir.

#### Sonraki Adım

Bu ders kullanıcının bir kararı **ne kadar zor** verdiğini ölçtü. Ölçmediği şey, kararı
hiç vermemesi. Katalog kullanıcısı ödünç alma akışını tamamlamayabilir; yük düşük olsa
bile başlamayabilir. Sonraki ders davranışın gerçekleşmesi için hangi üç koşulun aynı
anda sağlanması gerektiğini kurar ve bu koşullardan hangisine müdahale etmenin daha çok
kullanıcıyı akışa soktuğunu hesaplar.

### Davranış Modelleri

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/davranis-modelleri

Bir davranışın gerçekleşmesi için motivasyon, yetenek ve tetikleyicinin aynı anda gerekmesi; iki müdahale türünün nüfus üzerindeki etkisinin hesaplanması ve motivasyon kazancının niçin sönümlendiği.

Önceki ders ödünç alma akışının yükünü on üç karar noktasından altıya indirdi ve süreyi
7.44 saniyeden 3.32 saniyeye çekti. Bu, akışa **giren** kullanıcının işini kolaylaştıran
bir kazançtır. Cevaplanmayan soru şudur: kullanıcı akışa niye girsin? Katalog
kullanıcılarının çoğu kayıt ayrıntısını açar, okur ve ödünç almadan çıkar. Yük düşük
olsa bile davranış gerçekleşmeyebilir.

Bu ders bir davranışın gerçekleşmesi için hangi koşulların aynı anda sağlanması
gerektiğini kurar ve bu koşullardan hangisine müdahale etmenin daha çok kullanıcıyı
eyleme geçirdiğini hesaplar.

#### Üç Koşul Aynı Anda Gerekir

Yaygın kullanılan **davranış modeli**, bir davranışın üç koşulun kesişiminde
gerçekleştiğini söyler.

**Motivasyon (motivation)**, kullanıcının o davranışı yapmayı isteme derecesidir.
Katalogda bir kaydı ödünç almanın motivasyonu, kullanıcının o kitaba duyduğu ihtiyaçtan
gelir; arayüz bu ihtiyacı yaratmaz, olsa olsa görünür kılar.

**Yetenek (ability)**, davranışı yapabilme kolaylığıdır. Yetenek yalnızca kullanıcının
becerisi değildir; görevin maliyetiyle birlikte belirlenir. Aynı kullanıcı, on üç karar
noktalı bir akışta altı karar noktalı akıştakinden daha düşük yeteneğe sahiptir.

**Tetikleyici (trigger)**, davranışı o anda başlatan işarettir. Kayıt ayrıntısındaki
"Ödünç al" düğmesi bir tetikleyicidir; teslim tarihi yaklaşan kitabı bildiren ileti de
öyle.

Üçü **çarpımsal** biçimde işler: biri sıfırsa davranış olmaz. Motivasyonu yüksek ama
tetikleyiciyi görmeyen kullanıcı ödünç almaz. Tetikleyiciyi gören ama akışı tamamlayacak
yeteneği olmayan kullanıcı da almaz. Bu, gözlenen bir "dönüşüm düşüklüğünün" en az üç
farklı nedeni olabileceği anlamına gelir ve hangisi olduğu tahminle bulunmaz.

#### İki Müdahalenin Nüfus Üzerindeki Etkisi

Aşağıdaki hesap iki bin kullanıcılık bir nüfus kuruyor. Her kullanıcının bir motivasyonu
ve bir temel becerisi var. Yetenek, beceriyle akış maliyetinin birlikte belirlediği bir
büyüklük: maliyet arttıkça yetenek düşüyor. Davranış, motivasyon ile yeteneğin çarpımı
bir eşiği geçtiğinde ve tetikleyici görüldüğünde gerçekleşiyor.

İki müdahale karşılaştırılıyor: motivasyonu on beş puan artırmak (ödünç almanın
yararını görünür kılan bir metin) ve akışı on üç karardan altı karara indirmek.

```js
// davranis.mjs — motivasyon, yetenek ve tetikleyici cercevesinin nufus uzerinde hesabi

function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

const NUFUS = 2000;
const ESIK = 20;          // motivasyon x yetenek bu esigi gecmelidir

// Nufus: her kullanicinin motivasyonu (0-100) ve temel becerisi (0.2-1.0)
function nufus() {
  const rnd = uretec(19770401);
  const k = [];
  for (let i = 0; i < NUFUS; i++) {
    k.push({ motivasyon: rnd() * 100, beceri: 0.2 + rnd() * 0.8 });
  }
  return k;
}

// Akis maliyeti yetenegi asagi ceker; maliyet 02. dersteki karar suresidir.
const yetenek = (beceri, maliyet) => beceri * (4 / (4 + maliyet));

function oran(kisiler, { maliyet, motivasyonEki = 0, tetikleyiciOrani = 1 }) {
  let eyleme = 0;
  for (const k of kisiler) {
    const m = Math.min(100, k.motivasyon + motivasyonEki);
    if (m * yetenek(k.beceri, maliyet) >= ESIK) eyleme++;
  }
  return (eyleme / kisiler.length) * tetikleyiciOrani * 100;
}

const K = nufus();
const TAM_AKIS = 7.44;      // 02. ders: 13 karar noktali akis
const AZALTILMIS = 3.32;    // 02. ders: 6 karar noktali akis

console.log("mudahale                              akis maliyeti  eyleme gecen");
const temel = oran(K, { maliyet: TAM_AKIS });
console.log(`yok (temel durum)                         ${TAM_AKIS.toFixed(2)} sn   ${temel.toFixed(1).padStart(6)} %`);
const motivasyonlu = oran(K, { maliyet: TAM_AKIS, motivasyonEki: 15 });
console.log(`motivasyon +15                            ${TAM_AKIS.toFixed(2)} sn   ${motivasyonlu.toFixed(1).padStart(6)} %`);
const yetenekli = oran(K, { maliyet: AZALTILMIS });
console.log(`akis 13 karardan 6 karara indirildi       ${AZALTILMIS.toFixed(2)} sn   ${yetenekli.toFixed(1).padStart(6)} %`);
const ikisi = oran(K, { maliyet: AZALTILMIS, motivasyonEki: 15 });
console.log(`ikisi birlikte                            ${AZALTILMIS.toFixed(2)} sn   ${ikisi.toFixed(1).padStart(6)} %`);

// Tetikleyici: kullanici o an eylem cagrisini gormuyorsa davranis gerceklesmez
console.log("\ntetikleyici gorunurlugu  eyleme gecen (azaltilmis akis)");
for (const t of [0.3, 0.6, 0.9, 1.0]) {
  console.log(`${(t * 100).toFixed(0).padStart(21)} %  ${oran(K, { maliyet: AZALTILMIS, tetikleyiciOrani: t }).toFixed(1).padStart(6)} %`);
}

// Hangi mudahale kimi eyleme geciriyor: nufusu dort bolgeye ayir
const bolge = (k) => (k.motivasyon >= 50 ? "yuksek motivasyon" : "dusuk motivasyon") +
  (k.beceri >= 0.6 ? " / yuksek beceri" : " / dusuk beceri");
const BOLGELER = ["yuksek motivasyon / yuksek beceri", "yuksek motivasyon / dusuk beceri",
  "dusuk motivasyon / yuksek beceri", "dusuk motivasyon / dusuk beceri"];

function bolgeOranlari(ayar) {
  const sayac = {}, toplam = {};
  for (const b of BOLGELER) { sayac[b] = 0; toplam[b] = 0; }
  for (const k of K) {
    const b = bolge(k);
    toplam[b]++;
    const m = Math.min(100, k.motivasyon + (ayar.motivasyonEki ?? 0));
    if (m * yetenek(k.beceri, ayar.maliyet) >= ESIK) sayac[b]++;
  }
  return BOLGELER.map((b) => ({ b, oran: (sayac[b] / toplam[b]) * 100, n: toplam[b] }));
}

console.log("\nbolge                                 kisi   temel  motivasyon+15  akis kisaltma");
const t0 = bolgeOranlari({ maliyet: TAM_AKIS });
const t1 = bolgeOranlari({ maliyet: TAM_AKIS, motivasyonEki: 15 });
const t2 = bolgeOranlari({ maliyet: AZALTILMIS });
for (let i = 0; i < BOLGELER.length; i++) {
  console.log(
    `${BOLGELER[i].padEnd(36)} ${String(t0[i].n).padStart(5)} ${(t0[i].oran.toFixed(1) + " %").padStart(8)}` +
    ` ${(t1[i].oran.toFixed(1) + " %").padStart(14)} ${(t2[i].oran.toFixed(1) + " %").padStart(14)}`
  );
}

// Ikinci ziyaret: motivasyon eki soner, akis kisaltmasi kalir
console.log("\nziyaret  motivasyon mudahalesi  akis kisaltmasi");
for (const z of [1, 2, 3]) {
  const ek = z === 1 ? 15 : 0;               // ikna metni yalniz ilk ziyarette etkili
  const m = oran(K, { maliyet: TAM_AKIS, motivasyonEki: ek });
  const y = oran(K, { maliyet: AZALTILMIS });
  console.log(`${String(z).padStart(7)}  ${(m.toFixed(1) + " %").padStart(20)}  ${(y.toFixed(1) + " %").padStart(15)}`);
}

// Esik egrisi: bir davranisin gerceklesmesi icin gereken en az motivasyon
console.log("\nyetenek  gereken en az motivasyon");
for (const bec of [0.2, 0.3, 0.4, 0.6, 0.8, 1.0]) {
  const tam = ESIK / yetenek(bec, TAM_AKIS);
  const az = ESIK / yetenek(bec, AZALTILMIS);
  console.log(`${bec.toFixed(1).padStart(7)}  tam akis ${(tam > 100 ? "erisilemez" : tam.toFixed(1)).padStart(10)}   azaltilmis akis ${(az > 100 ? "erisilemez" : az.toFixed(1)).padStart(10)}`);
}
```

```
mudahale                              akis maliyeti  eyleme gecen
yok (temel durum)                         7.44 sn     14.6 %
motivasyon +15                            7.44 sn     23.5 %
akis 13 karardan 6 karara indirildi       3.32 sn     34.6 %
ikisi birlikte                            3.32 sn     47.0 %

tetikleyici gorunurlugu  eyleme gecen (azaltilmis akis)
                   30 %    10.4 %
                   60 %    20.8 %
                   90 %    31.2 %
                  100 %    34.6 %

bolge                                 kisi   temel  motivasyon+15  akis kisaltma
yuksek motivasyon / yuksek beceri      531   55.0 %         84.0 %         96.8 %
yuksek motivasyon / dusuk beceri       501    0.2 %          2.2 %         26.3 %
dusuk motivasyon / yuksek beceri       485    0.0 %          2.7 %          9.7 %
dusuk motivasyon / dusuk beceri        483    0.0 %          0.0 %          0.0 %

ziyaret  motivasyon mudahalesi  akis kisaltmasi
      1                23.5 %           34.6 %
      2                14.6 %           34.6 %
      3                14.6 %           34.6 %

yetenek  gereken en az motivasyon
    0.2  tam akis erisilemez   azaltilmis akis erisilemez
    0.3  tam akis erisilemez   azaltilmis akis erisilemez
    0.4  tam akis erisilemez   azaltilmis akis       91.5
    0.6  tam akis       95.3   azaltilmis akis       61.0
    0.8  tam akis       71.5   azaltilmis akis       45.8
    1.0  tam akis       57.2   azaltilmis akis       36.6
```

#### Yeteneğe Müdahale Motivasyona Müdahaleden Fazlasını Getirir

İlk tablo iki müdahaleyi aynı ölçekte karşılaştırıyor. Motivasyonu on beş puan artırmak
eyleme geçen oranını yüzde 14.6'dan 23.5'e taşıyor. Akışı kısaltmak aynı oranı 34.6'ya
taşıyor. İkisi birlikte 47.0.

Bu karşılaştırmanın adil olması için iki müdahalenin de "on beş birim" olması gerekirdi;
öyle değil. Karşılaştırmayı anlamlı kılan şey, iki müdahalenin **maliyetlerinin** de
benzer olmasıdır: bir metin yazmak ile yedi alanı varsayılana bağlamak birbirine yakın
işlerdir. Aynı emeğe karşılık ikinci müdahale iki katından fazla kullanıcıyı akışa
sokuyor.

Nedeni üçüncü tabloda görünür. Motivasyon müdahalesi "yüksek motivasyon / yüksek beceri"
bölgesinde yüzde 55'ten 84'e çıkıyor — zaten eyleme geçmeye yakın olan grup. Diğer üç
bölgede etkisi yüzde 3'ün altında. Akış kısaltması ise "yüksek motivasyon / düşük
beceri" bölgesinde yüzde 0.2'den 26.3'e çıkarıyor. Bu bölge nüfusun dörtte biri ve
kitabı gerçekten isteyen ama akışı tamamlayamayan kullanıcılardan oluşuyor.

Son tablo bu farkın nedenini net biçimde veriyor. Yeteneği 0.4 ve altında olan
kullanıcılar için tam akış **erişilemez**: motivasyon yüz puan bile olsa eşik geçilmiyor.
Akış kısaldığında 0.4 yetenekli kullanıcı için gerekli motivasyon 91.5'e, 0.6 yetenekli
kullanıcı için 95.3'ten 61.0'a iniyor. Motivasyon müdahalesi bu kullanıcılara hiçbir şey
yapamaz; onların sorunu istememek değil, yapamamaktır. Yeteneği 0.3 ve altında olan
kullanıcı için ise akışı kısaltmak da yetmiyor — bu grup için altı karar noktası hâlâ
fazla ve tasarımın yapması gereken, akışı biraz daha kısaltmak değil, o kullanıcının
görevi niçin tamamlayamadığını araştırmaktır.

#### Motivasyon Sönümlenir, Yetenek Kalır

Dördüncü tablo zaman boyutunu ekliyor. İkna metni ilk ziyarette yüzde 23.5 veriyor;
ikinci ziyarette kullanıcı aynı metni okumuş olduğu için etkisi kalmıyor ve oran temel
duruma, yüzde 14.6'ya dönüyor. Akış kısaltması her ziyarette yüzde 34.6 veriyor.

Bu, iki müdahale türü arasındaki en pratik farktır. Motivasyon müdahalesi tekrar
gerektirir; her tekrarda etkisi azalır ve etkiyi korumak için dozun artırılması gerekir.
Dozun artması, ifadenin abartılmasıdır. Abartma bir noktadan sonra doğruluktan ayrılır
ve bu ayrılma bu konunun sonunda ele alınacak sınırın ta kendisidir.

Yetenek müdahalesi tekrar gerektirmez; akış bir kez kısaltıldığında kısa kalır. Bir
kararı kullanıcıdan almanın kalıcı olması, aynı zamanda o kararın doğru varsayılana
bağlanmasını daha önemli hâle getirir.

#### Tetikleyici Çarpandır, Toplanan Değil

İkinci tablo tetikleyicinin farklı bir büyüklük olduğunu gösteriyor. Görünürlük yüzde
30'ken eyleme geçen oran 10.4; yüzde 100'ken 34.6. İlişki doğrusal, çünkü tetikleyici
diğer iki koşulun çarpanıdır: kullanıcı hazır olsa bile o an işareti görmüyorsa davranış
gerçekleşmez.

Tetikleyicinin tasarımında iki ayrı soru vardır ve karıştırılırlar. Birincisi
**görünürlük**: eylem çağrısı kullanıcının baktığı yerde mi? Bu, Arayüz Tasarımının
Temelleri kursundaki görsel hiyerarşi sorusudur. İkincisi **zamanlama**: tetikleyici,
kullanıcının motivasyonunun ve yeteneğinin eşiği geçtiği anda mı geliyor?

İkinci soru ayrımın kaynağıdır. Teslim tarihi yaklaşan kitabı bildiren bir ileti,
kullanıcının o bilgiye ihtiyaç duyduğu anda gelir; kullanıcı bu iletiyi istediğini
bilseydi de isterdi. Kullanıcının hiç ilgilenmediği bir konuda gönderilen bir ileti ise
bir tetikleyici değil, bir kesintidir. İkisi arasındaki fark, iletinin kullanıcının
mevcut motivasyonuna mı yaslandığı yoksa motivasyon yaratmaya mı çalıştığıdır.

#### Model Ne Söylemez

Bu çerçeve bir tanımlama aracıdır, bir tahmin aracı değil. Eşik değeri, çarpımsal biçim ve
motivasyon–yetenek dağılımı varsayımdır; başka varsayımlar başka sayılar verir. Hesabın taşıdığı
sonuç şudur: **davranış gerçekleşmediğinde eksik olan koşul belirlenmeden müdahale seçilemez.**
Yetenek eksikse ikna metni işe yaramaz: düşük becerili bölgede motivasyonu artırmak katılımı yüzde
0.2'den yalnız 2.2'ye çıkarırken akışı kısaltmak 26.3'e çıkarıyor. İki koşul birden eksikse hiçbir
müdahale sonuç vermiyor.

Bir şey daha söylemez. Model, davranışın gerçekleşmesinin **iyi** olduğunu varsaymaz.
Modelde eyleme geçen oranını artırmanın bir yolu da eşiği düşürmek, yani kullanıcının
kararını yeterince düşünmeden vermesini sağlamaktır. Ödünç alma akışında bu, kullanıcıyı
istemediği bir kitapla baş başa bırakır. Ölçüt burada da aynıdır: kullanıcı,
tasarımcının bu değişikliği niçin yaptığını bilseydi de aynı kararı verir miydi? Akışın
kısaltılmasında yanıt evettir. Kararın düşünülmesini engelleyen bir hızlandırmada
değildir.

#### Özet

- Bir davranış motivasyon, yetenek ve tetikleyicinin çarpımı bir eşiği geçtiğinde
  gerçekleşir; biri sıfırsa davranış olmaz.
- Yetenek kullanıcının becerisi değil, beceriyle görev maliyetinin birlikte belirlediği
  büyüklüktür; akışı kısaltmak yeteneği artırır.
- Hesapta motivasyon müdahalesi eyleme geçen oranını yüzde 14.6'dan 23.5'e, akış
  kısaltması 34.6'ya taşıdı; ikisi birlikte 47.0.
- Motivasyon müdahalesi zaten eşiğe yakın olan gruba etki eder; düşük yetenekli grup için
  tam akış motivasyon yüz puan olsa bile erişilemezdir.
- Motivasyon kazancı ikinci ziyarette sönümlenir ve korunması için dozun artırılmasını
  gerektirir; yetenek kazancı her ziyarette aynı kalır.
- Eyleme geçen oranını artırmanın bir yolu da kullanıcının kararını düşünmesini
  engellemektir; ölçüt, kullanıcının değişikliği bilseydi de aynı kararı verip
  vermeyeceğidir.

#### Sonraki Adım

Bu ders tek bir davranışı ele aldı: kullanıcı bir kez ödünç alıyor. Katalog arayüzünün
asıl sorusu tekrardır — kullanıcı ikinci, beşinci, yirminci kez geri geliyor mu? Tekrar
eden davranış tek seferlik davranıştan farklı bir yapıyla açıklanır. Sonraki ders bu
yapıyı kurar: ipucu, rutin ve ödülün oluşturduğu döngü, tekrarla nasıl güçlenir ve
tasarımcının bu döngüyü kurmaya hakkı hangi koşulda vardır?

### Alışkanlık Döngüsü

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/aliskanlik-dongusu

İpucu, rutin ve ödülün oluşturduğu döngünün tekrarla güçlenmesi, üç parçadan birini zayıflatmanın bedeli ve alışkanlık gücünün kullanıcıya sağlanan yararla aynı şey olmaması.

Önceki ders tek bir davranışın gerçekleşme koşullarını kurdu: motivasyon, yetenek ve
tetikleyicinin çarpımı bir eşiği geçmeli. Bu çerçeve ilk ödünç almayı açıklıyor.
Katalog arayüzünün asıl sorusu ise tekrardır. Kullanıcı ikinci kez, beşinci kez,
yirminci kez geri geliyor mu?

Tekrar eden davranış her seferinde baştan hesaplanmaz. Yeterince tekrarlandığında
davranış, motivasyon eşiğini geçme işi olmaktan çıkar ve bir işarete verilen doğrudan
yanıt hâline gelir. Bu ders o dönüşümün yapısını kurar ve tasarımcının bu yapıyı kurmaya
hangi koşulda hakkı olduğunu tartışır.

#### Döngünün Üç Parçası

**Alışkanlık döngüsü (habit loop)** üç parçadan oluşur.

**İpucu (cue)**, davranışı başlatan işarettir. Önceki dersteki tetikleyiciden farkı,
ipucunun **yinelenen ve bağlama bağlı** olmasıdır: her salı günü gelen teslim
hatırlatması bir ipucudur; bir kerelik duyuru değildir. İpucunun gücü öngörülebilirliğinden
gelir.

**Rutin (routine)**, ipucunun ardından yapılan davranıştır. Katalog arayüzünde rutin,
ödünç aldığı kitabın süresini uzatmak ya da rafına yeni bir kitap eklemektir. Rutinin
maliyeti önceki iki dersin konusuydu: karar noktası sayısı, karar süresi, yetenek.

**Ödül (reward)**, rutinin sonunda gelen ve davranışı pekiştiren sonuçtur. Ödül bir
oyunlaştırma ögesi olmak zorunda değildir; aradığı kitabın rafta bulunması, süre
uzatmanın anında onaylanması ya da teslim tarihini artık takip etmek zorunda olmadığını
bilmek de ödüldür.

Üç parça bir döngü kurar: ipucu rutini başlatır, rutin ödüle götürür ve ödül bir sonraki ipucunun
etkisini artırır. **Alışkanlık gücü**, bu döngünün kaç kez tamamlandığıyla birlikte artan bir
büyüklüktür.

#### Döngünün Tekrarla Güçlenmesi

Aşağıdaki benzetim beş yüz kullanıcının yirmi altı haftasını izliyor. Her hafta ipucu gelebilir ya
da gelmeyebilir; ipucu geldiğinde kullanıcı rutini tamamlayabilir ya da tamamlamayabilir;
tamamladığında ödül gelebilir ya da gelmeyebilir. Alışkanlık gücü ödüllü tekrarda artıyor ve
tekrarsız haftada sönüyor.

Beş tasarım karşılaştırılıyor. Dördü döngünün bir parçasını zayıflatıyor; beşincisi üç
parçayı da güçlendiriyor ama ziyaretin kullanıcıya yarar sağlama oranını düşürüyor.

```js
// aliskanlik.mjs — ipucu, rutin ve odul dongusunun tekrarla guclenmesi

function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

const ALFA = 0.22;   // pekismis her tekrarin guc kazanci
const DELTA = 0.06;  // tekrar olmayan haftada sonme
const HAFTA = 26;
const KISI = 500;

// Bir tasarim: ipucu guvenilirligi, rutin maliyeti (0-1), odul guvenilirligi ve
// ziyaretin kullaniciya gercekten yarar saglama orani.
const TASARIMLAR = [
  { ad: "ipucu yok", ipucu: 0.15, maliyet: 0.45, odul: 0.90, fayda: 0.85 },
  { ad: "odul guvenilmez", ipucu: 0.90, maliyet: 0.45, odul: 0.30, fayda: 0.85 },
  { ad: "rutin agir", ipucu: 0.90, maliyet: 0.80, odul: 0.90, fayda: 0.85 },
  { ad: "ucu de yerinde", ipucu: 0.90, maliyet: 0.25, odul: 0.90, fayda: 0.85 },
  { ad: "sik ipucu, ilgisiz icerik", ipucu: 0.98, maliyet: 0.20, odul: 0.95, fayda: 0.18 },
];

// Tek kullanicinin 26 haftasi. kesme verilirse o haftadan sonra ipucu seyreklesir.
function kisi(t, rnd, kesme = null) {
  let h = 0.05;
  let ziyaret = 0, yararli = 0, esik = null;
  const h_ = {};
  for (let hafta = 1; hafta <= HAFTA; hafta++) {
    const ipucuOrani = kesme !== null && hafta > kesme ? 0.15 : t.ipucu;
    const ipucuGeldi = rnd() < ipucuOrani;
    // Rutini tamamlama: ipucu gerekli; olasilik aliskanlik gucuyle artar, maliyetle azalir
    const tamamlar = ipucuGeldi && rnd() < (0.35 + 0.6 * h) * (1 - t.maliyet);
    if (tamamlar) {
      ziyaret++;
      if (rnd() < t.fayda) yararli++;
      h = rnd() < t.odul ? h + ALFA * (1 - h) : h * (1 - DELTA);
    } else {
      h = h * (1 - DELTA);
    }
    if (esik === null && h >= 0.5) esik = hafta;
    h_[hafta] = h;
  }
  return { h_, ziyaret, yararli, esik };
}

function nufus(t, kesme = null) {
  const rnd = uretec(20250115);
  let ziyaret = 0, yararli = 0, esikSayisi = 0, esikToplam = 0;
  const h = { 6: 0, 12: 0, 18: 0, 26: 0 };
  const kesmeH = {};
  for (let i = 0; i < KISI; i++) {
    const k = kisi(t, rnd, kesme);
    ziyaret += k.ziyaret; yararli += k.yararli;
    for (const w of [6, 12, 18, 26]) h[w] += k.h_[w] / KISI;
    if (kesme !== null) kesmeH[kesme] = (kesmeH[kesme] ?? 0) + k.h_[kesme] / KISI;
    if (k.esik !== null) { esikSayisi++; esikToplam += k.esik; }
  }
  return {
    h, ziyaret: ziyaret / KISI, yararli: yararli / KISI,
    esikOrani: (esikSayisi / KISI) * 100,
    esikHafta: esikSayisi === 0 ? null : esikToplam / esikSayisi,
    kesmeH: kesme === null ? null : kesmeH[kesme],
  };
}

console.log("tasarim                    h(6)  h(12)  h(18)  h(26)  0.5'i gecen  ort. gecis  ziyaret");
const S = {};
for (const t of TASARIMLAR) {
  const s = nufus(t);
  S[t.ad] = s;
  console.log(
    `${t.ad.padEnd(25)} ${[6, 12, 18, 26].map((w) => s.h[w].toFixed(2)).join("   ")}` +
    `  ${(s.esikOrani.toFixed(1) + " %").padStart(11)}  ${(s.esikHafta === null ? "-" : s.esikHafta.toFixed(1) + ". hafta").padStart(10)}  ${s.ziyaret.toFixed(1).padStart(7)}`
  );
}

// Dongunun uc parcasindan birini zayiflatmanin bedeli
console.log("\nreferans: ucu de yerinde (h(26) = " + S["ucu de yerinde"].h[26].toFixed(2) + ", ziyaret " + S["ucu de yerinde"].ziyaret.toFixed(1) + ")");
const ref = S["ucu de yerinde"];
for (const ad of ["ipucu yok", "odul guvenilmez", "rutin agir"]) {
  const s = S[ad];
  console.log(`${ad.padEnd(25)} h(26) referansin ${(s.h[26] / ref.h[26] * 100).toFixed(0)} %'i, ziyaret referansin ${(s.ziyaret / ref.ziyaret * 100).toFixed(0)} %'i`);
}

// Ziyaret sayisi ile kullaniciya saglanan yarar ayni sey degildir
console.log("\ntasarim                    ziyaret  yararli  yararsiz  yararli oran");
for (const t of TASARIMLAR) {
  const s = S[t.ad];
  console.log(
    `${t.ad.padEnd(25)} ${s.ziyaret.toFixed(1).padStart(7)}  ${s.yararli.toFixed(1).padStart(7)}` +
    `  ${(s.ziyaret - s.yararli).toFixed(1).padStart(8)}  ${((s.yararli / s.ziyaret * 100).toFixed(1) + " %").padStart(12)}`
  );
}

// Ipucu 14. haftada seyreklestirilirse aliskanlik ne kadar dayanir
console.log("\nipucu 14. haftadan sonra seyreklestirilirse");
for (const ad of ["ucu de yerinde", "sik ipucu, ilgisiz icerik"]) {
  const t = TASARIMLAR.find((x) => x.ad === ad);
  const s = nufus(t, 14);
  console.log(`${ad.padEnd(25)} h(14) ${s.kesmeH.toFixed(2)} -> h(26) ${s.h[26].toFixed(2)}  (${(s.h[26] / s.kesmeH * 100).toFixed(0)} % kaldi), ziyaret ${s.ziyaret.toFixed(1)}`);
}
```

```
tasarim                    h(6)  h(12)  h(18)  h(26)  0.5'i gecen  ort. gecis  ziyaret
ipucu yok                 0.06   0.07   0.08   0.10        1.0 %  19.4. hafta      0.9
odul guvenilmez           0.10   0.12   0.14   0.18       10.0 %  17.1. hafta      5.4
rutin agir                0.10   0.14   0.16   0.20       13.2 %  15.5. hafta      2.0
ucu de yerinde            0.30   0.49   0.61   0.69       95.4 %  11.1. hafta     10.8
sik ipucu, ilgisiz icerik 0.36   0.59   0.72   0.81       98.8 %  9.3. hafta     13.6

referans: ucu de yerinde (h(26) = 0.69, ziyaret 10.8)
ipucu yok                 h(26) referansin 14 %'i, ziyaret referansin 8 %'i
odul guvenilmez           h(26) referansin 25 %'i, ziyaret referansin 50 %'i
rutin agir                h(26) referansin 29 %'i, ziyaret referansin 19 %'i

tasarim                    ziyaret  yararli  yararsiz  yararli oran
ipucu yok                     0.9      0.7       0.1        86.0 %
odul guvenilmez               5.4      4.6       0.8        85.6 %
rutin agir                    2.0      1.7       0.3        85.9 %
ucu de yerinde               10.8      9.2       1.6        85.5 %
sik ipucu, ilgisiz icerik    13.6      2.4      11.2        17.8 %

ipucu 14. haftadan sonra seyreklestirilirse
ucu de yerinde            h(14) 0.51 -> h(26) 0.31  (62 % kaldi), ziyaret 5.6
sik ipucu, ilgisiz icerik h(14) 0.64 -> h(26) 0.39  (61 % kaldi), ziyaret 7.2
```

#### Üç Parça da Gereklidir, Ama Aynı Biçimde Değil

İlk tablo döngünün parçalarını tek tek zayıflatmanın sonucunu veriyor. Üçü de yerinde
olan tasarımda alışkanlık gücü altıncı haftada 0.30, yirmi altıncı haftada 0.69;
kullanıcıların yüzde 95.4'ü 0.5 eşiğini geçiyor. Bir parça zayıfladığında yirmi altıncı
haftadaki güç referansın yüzde 14 ile 29'u arasına düşüyor.

İkinci tablo parçaların **farklı biçimde** başarısız olduğunu gösteriyor. İpucu yoksa kullanıcı
yirmi altı haftada ortalama 0.9 kez geliyor: döngü hiç başlamıyor. Ödül güvenilmezse ziyaret
sayısı referansın yüzde 50'sinde kalıyor ama alışkanlık gücü yüzde 25'te — kullanıcı geliyor,
rutini yapıyor ama pekişme olmuyor. Rutin ağırsa ziyaret yüzde 19'a düşüyor ama gelenler
pekişiyor; güç oranı (yüzde 29) ziyaret oranından (yüzde 19) yüksek.

Tasarım sonucu şudur: **hangi parçanın zayıf olduğu, gözlenen sayı örüntüsünden
okunabilir.** Ziyaret az ve güç az ise ipucu eksiktir. Ziyaret var ama güç yoksa ödül
eksiktir. Ziyaret az ama gelenler kalıcıysa rutin ağırdır. Bu üçü aynı "düşük tekrar"
göstergesi altında toplanır ve ayrılmadan müdahale edilemez.

#### Alışkanlık Gücü Bir Başarı Ölçütü Değildir

Üçüncü tablo bu dersin ağırlık merkezidir. "Sık ipucu, ilgisiz içerik" tasarımı bütün
alışkanlık göstergelerinde birinci: en yüksek güç (0.81), en yüksek eşik geçme oranı
(yüzde 98.8), en erken eşik geçişi (9.3. hafta) ve en çok ziyaret (13.6). Üçü de yerinde
olan tasarımı her sütunda geçiyor.

Aynı tabloda son sütun tersini söylüyor. On üç buçuk ziyaretin yalnızca 2.4'ü kullanıcıya
bir yarar sağlıyor; on bir ziyaret boşa gidiyor. Üçü de yerinde olan tasarımda 10.8
ziyaretin 9.2'si yararlı. İkinci tasarım daha az ziyaret üretiyor ama **dört kat fazla
yararlı ziyaret**.

Ziyaret sayısı, oturum süresi ve geri dönüş sıklığı alışkanlığı ölçer, yararı ölçmez.
Bir arayüz bu göstergelere göre eniyilenirse, kullanıcının vaktini alan ama ona bir şey
vermeyen bir tasarım "başarılı" görünür. Ölçüt bu kursta baştan beri aynıdır: kullanıcı,
kendisine haftada iki kez ipucu gönderildiğini ve bu ipuçlarının onda ikisinin işine
yaradığını bilseydi, bu ipuçlarını almayı sürdürür müydü? Yanıt hayırsa alışkanlık
kullanıcının değil, göstergenin lehinedir.

Bu, tasarımcının alışkanlık kurmasının yanlış olduğu anlamına gelmez. Kütüphane
kullanıcısının teslim tarihini kaçırmama alışkanlığı kullanıcının yararınadır; kullanıcı
bu hatırlatmayı bilse de ister. Ayrım, alışkanlığın kime hizmet ettiğindedir ve bu
üçüncü tablodaki son sütunla ölçülür.

#### Alışkanlık Kendi Kendini Taşımaz

Son tablo, sık dile getirilen bir varsayımı sınıyor: alışkanlık bir kez kurulduğunda
kendi kendine devam eder mi?

İpucu on dördüncü haftadan sonra seyrekleştirildiğinde iki tasarımda da alışkanlık gücü
yaklaşık yüzde 61 seviyesine düşüyor. Üçü de yerinde olan tasarımda 0.51'den 0.31'e,
diğerinde 0.64'ten 0.39'a. İki tasarım arasında anlamlı bir fark yok.

Sonuç şudur: bu modelde alışkanlık ipucuya bağımlı kalır. İpucu kesildiğinde davranış
söner. Bunun iki karşılığı var. Tasarım açısından: bir hatırlatmayı kaldırmak, kullanıcının
o davranışı sürdüreceği anlamına gelmez; kaldırma kararı ölçülerek verilir. Etik
açısından: kullanıcıyı bir ipucuya bağımlı hâle getiren tasarım, o ipucuyu kesme gücünü
de elinde tutar. Bu güç, ipucunun kullanıcının işine yaradığı durumda bir hizmettir;
yaramadığı durumda bir bağımlılıktır.

Modelin sınırı burada belirtilmelidir. Benzetim, kullanıcının kendi içsel nedenlerini
hesaba katmıyor: gerçek kullanıcı, hatırlatma gelmese de aradığı kitabı arayabilir.
Modelin verdiği sonuç, alışkanlığın **arayüzün ürettiği kısmının** ipucuya bağımlı
olduğudur; kullanıcının kendi motivasyonundan gelen kısmı bu benzetimin dışındadır.

#### Döngüyü Kurmanın Kuralları

Katalog arayüzünde alışkanlık kurmanın meşru biçimi dört kuralla özetlenir.

**İpucu kullanıcının takvimine bağlanır, tasarımcının takvimine değil.** Teslim tarihi
yaklaştığında gelen hatırlatma kullanıcının durumundan doğar. Haftanın belirli bir günü
"yeni gelenler" göndermek arayüzün durumundan doğar; kullanıcının o an bir ihtiyacı
olduğunu varsaymaz.

**Rutin kısaltılır, ama karar silinmez.** Önceki derste ölçüldüğü gibi rutinin maliyetini
düşürmek döngüyü güçlendirir. Düşürülecek şey karar sayısıdır; kullanıcının ödünç
aldığını fark etme fırsatı değil.

**Ödül rutinin doğal sonucudur.** Süre uzatmanın ödülü, sürenin uzamış olmasıdır. Rutinle
ilgisiz bir ödül (rozet, sayaç, seri) döngüyü besler ama kullanıcının yararına
bağlanmadığı için üçüncü tablodaki son sütunu düşürür.

**Yararlı ziyaret oranı ayrı bir gösterge olarak izlenir.** Ziyaret sayısı tek başına
raporlanırsa, yararsız ziyaret üreten her değişiklik iyileşme gibi görünür.

#### Özet

- Alışkanlık döngüsü ipucu, rutin ve ödülden oluşur; üçü tekrarla birbirini besler ve
  alışkanlık gücü bu tekrarlarla birikir.
- Parçaların başarısızlık örüntüleri farklıdır: ipucu eksikse ziyaret de güç de düşer; ödül
  eksikse ziyaret var güç yok; rutin ağırsa ziyaret az ama gelenler pekişir.
- Alışkanlık göstergelerinin tamamında birinci olan tasarım, yararlı ziyaret oranında
  yüzde 17.8'de kalabilir; alışkanlık gücü bir başarı ölçütü değildir.
- Yararlı ziyaret oranı ayrı bir gösterge olarak izlenmezse, kullanıcının vaktini alan
  her değişiklik iyileşme gibi görünür.
- Benzetimde alışkanlık ipucuya bağımlı kalır: ipucu seyreldiğinde güç yaklaşık yüzde 61
  seviyesine düşer; alışkanlık kendi kendini taşımaz.
- Meşruluk ölçütü aynıdır: kullanıcı ipuçlarının hangi oranda işine yaradığını bilseydi
  de onları almayı sürdürür müydü?

#### Sonraki Adım

Bu ders davranışı tekrarlatmayı ele aldı ve rutinin maliyetini düşürmenin döngüyü
güçlendirdiğini gösterdi. Maliyeti düşürmenin en güçlü aracı önceki derste geçmişti ama
ölçülmedi: karar noktalarını varsayılana bağlamak. Varsayılan, kullanıcının hiçbir şey
yapmadığında sahip olduğu değerdir ve etkisi hem şaşırtıcı derecede büyük hem de
tasarımcının elindeki en tartışmalı güçtür. Sonraki ders bu etkiyi iki senaryoda
hesaplar ve bir varsayılanı meşru kılan ölçütü sayıya bağlar.

### Varsayılanların Gücü

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/varsayilanlarin-gucu

Seçim mimarisinin katılım oranına etkisinin iki ayarda hesaplanması, pişmanlık oranının bir meşruluk ölçütü olarak tanımlanması ve değiştirme maliyetinin varsayılanı tuzağa çevirmesi.

Önceki iki ders rutinin maliyetini düşürmenin döngüyü güçlendirdiğini gösterdi. Maliyeti
düşürmenin en güçlü aracı Bilişsel Yük dersinde geçmişti ama ölçülmedi: karar noktalarını
varsayılana bağlamak. On üç karar noktalı ödünç akışını altıya indiren şey buydu.

**Varsayılan (default)**, kullanıcı hiçbir şey yapmadığında geçerli olan değerdir.
Kullanıcının çoğu bu değeri değiştirmez — değiştirmemek, karar vermemektir ve karar
vermemek her zaman daha ucuzdur. Bu, tasarımcının elindeki en güçlü ve en tartışmalı
araçtır: bir onay kutusunun başlangıç durumunu belirlemek, kullanıcıların çoğunluğunun
sonucunu belirlemektir.

Bu ders o gücü iki ayarda ölçer ve bir varsayılanı meşru kılan ölçütü sayıya bağlar.

#### Seçim Mimarisi ve Üç Düzen

**Seçim mimarisi (choice architecture)**, seçeneklerin kullanıcıya sunulma biçimidir:
hangisinin önceden işaretli olduğu, hangi sırayla göründükleri, değiştirmenin kaç adım
sürdüğü. Seçim mimarisi tarafsız olamaz — bir onay kutusu ya işaretlidir ya değildir ve
her iki durum da bir sonucu diğerinden olası kılar.

Katalog arayüzünün ödünç onayı ekranında iki ayar var. Birincisi **teslim hatırlatması**:
teslim tarihi yaklaştığında kullanıcıya bildirim gönderilsin mi? İkincisi **haftalık
öneri bülteni**: kullanıcıya haftada bir öneri listesi gönderilsin mi?

Üç düzen karşılaştırılacak:

- **Kapalı varsayılan**: ayar başlangıçta kapalı; isteyen açar.
- **Açık varsayılan**: ayar başlangıçta açık; istemeyen kapatır.
- **Etkin seçim**: varsayılan yok; kullanıcı akışı sürdürmek için birini seçmek zorunda.

Ölçülecek iki büyüklük var. **Katılım oranı**, ayarın açık kaldığı kullanıcı oranıdır.
**Pişmanlık oranı**, kullanıcının, hiçbir engel olmasa seçeceğinden farklı bir durumda
kalma oranıdır. İkinci büyüklük bu dersin asıl ölçütüdür.

#### İki Ayarın Üç Düzendeki Sonucu

Benzetim dört bin kullanıcı kuruyor. Her kullanıcının bir tercih şiddeti var: pozitifse
ayarı ister, negatifse istemez, mutlak değeri ne kadar isteyip istemediğini verir.
Varsayılanı değiştirmek bir maliyet gerektiriyor; kullanıcı ancak tercih şiddeti bu
maliyeti aşarsa varsayılanı değiştiriyor.

```js
// varsayilan.mjs — varsayilanin katilim oranina ve pismanlik oranina etkisi

function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

// Belirlenimci normal dagilim (Box-Muller), tercih siddetini uretmek icin.
function normalUretec(tohum) {
  const rnd = uretec(tohum);
  return () => {
    const u1 = Math.max(rnd(), 1e-12), u2 = rnd();
    return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
  };
}

const KISI = 4000;
const DEGISTIRME_MALIYETI = 0.55;  // varsayilani degistirmek icin gereken tercih siddeti

// Iki ayar. mu: tercih dagiliminin merkezi; artiysa cogunluk ayari ister.
const AYARLAR = [
  { ad: "teslim hatirlatmasi", mu: 0.78 },
  { ad: "haftalik oneri bulteni", mu: -0.78 },
];

function nufus(mu, tohum) {
  const n = normalUretec(tohum);
  const u = [];
  for (let i = 0; i < KISI; i++) u.push(mu + n());
  return u;
}

// Uc duzen: acik varsayilan (opt-out), kapali varsayilan (opt-in), etkin secim.
function sonuc(u, duzen, maliyet) {
  if (duzen === "etkin secim") return u > 0;            // kullanici dogrudan secer
  const varsayilanAcik = duzen === "acik varsayilan";
  const degistirir = varsayilanAcik ? (u < 0 && -u > maliyet) : (u > 0 && u > maliyet);
  return varsayilanAcik ? !degistirir : degistirir;
}

const DUZENLER = ["kapali varsayilan", "acik varsayilan", "etkin secim"];

console.log("ayar                    bilgili tercih  duzen               katilim  pismanlik");
for (const a of AYARLAR) {
  const u = nufus(a.mu, 20260318);
  const bilgili = u.filter((x) => x > 0).length / KISI;
  for (const d of DUZENLER) {
    let acik = 0, pisman = 0;
    for (const x of u) {
      const s = sonuc(x, d, DEGISTIRME_MALIYETI);
      if (s) acik++;
      if (s !== x > 0) pisman++;
    }
    console.log(
      `${a.ad.padEnd(23)} ${((bilgili * 100).toFixed(1) + " %").padStart(14)}  ${d.padEnd(18)}` +
      ` ${((acik / KISI * 100).toFixed(1) + " %").padStart(7)} ${((pisman / KISI * 100).toFixed(1) + " %").padStart(10)}`
    );
  }
}

// Degistirme maliyeti buyudukce pismanlik nasil degisir
console.log("\ndegistirme maliyeti  teslim hatirlatmasi (acik vars.)  oneri bulteni (acik vars.)");
console.log("                     katilim  pismanlik                katilim  pismanlik");
const uA = nufus(AYARLAR[0].mu, 20260318);
const uB = nufus(AYARLAR[1].mu, 20260318);
for (const m of [0.0, 0.25, 0.55, 1.0, 1.5, 2.5]) {
  const olc = (u) => {
    let acik = 0, pisman = 0;
    for (const x of u) {
      const s = sonuc(x, "acik varsayilan", m);
      if (s) acik++;
      if (s !== x > 0) pisman++;
    }
    return [(acik / KISI * 100).toFixed(1), (pisman / KISI * 100).toFixed(1)];
  };
  const [ka, pa] = olc(uA), [kb, pb] = olc(uB);
  console.log(`${m.toFixed(2).padStart(19)}  ${(ka + " %").padStart(7)} ${(pa + " %").padStart(10)}                ${(kb + " %").padStart(7)} ${(pb + " %").padStart(10)}`);
}

// Etkin secim pismanligi sifirlar ama bir karar noktasi ekler.
// 02. ders: her karar noktasi akisi uzatir; uzayan akista bir kisim kullanici cikar.
console.log("\netkin secimin bedeli (oneri bulteni ayari)");
const EK_KARAR_SURESI = 0.44;  // 02. ders: uc secenekli alan icin A + B*log2(4)
for (const terk of [0.0, 0.03, 0.06, 0.10]) {
  const tamamlayan = 1 - terk;
  let dogruAcik = 0;
  for (const x of uB) if (x > 0) dogruAcik++;
  const etkinAcik = (dogruAcik / KISI) * tamamlayan;
  const acikVars = uB.filter((x) => sonuc(x, "acik varsayilan", DEGISTIRME_MALIYETI)).length / KISI;
  const acikPisman = uB.filter((x) => sonuc(x, "acik varsayilan", DEGISTIRME_MALIYETI) !== x > 0).length / KISI;
  console.log(
    `terk ${(terk * 100).toFixed(0).padStart(2)} %  akisi tamamlayan ${(tamamlayan * 100).toFixed(0)} %  ` +
    `etkin secimle katilim ${(etkinAcik * 100).toFixed(1)} % / pismanlik 0.0 %  ` +
    `acik varsayilanla ${(acikVars * 100).toFixed(1)} % / ${(acikPisman * 100).toFixed(1)} %`
  );
}
console.log(`etkin secimin akisa ekledigi sure: ${EK_KARAR_SURESI.toFixed(2)} sn`);
```

```
ayar                    bilgili tercih  duzen               katilim  pismanlik
teslim hatirlatmasi             78.0 %  kapali varsayilan   58.7 %     19.4 %
teslim hatirlatmasi             78.0 %  acik varsayilan     90.8 %     12.8 %
teslim hatirlatmasi             78.0 %  etkin secim         78.0 %      0.0 %
haftalik oneri bulteni          22.1 %  kapali varsayilan    9.0 %     13.1 %
haftalik oneri bulteni          22.1 %  acik varsayilan     40.9 %     18.8 %
haftalik oneri bulteni          22.1 %  etkin secim         22.1 %      0.0 %

degistirme maliyeti  teslim hatirlatmasi (acik vars.)  oneri bulteni (acik vars.)
                     katilim  pismanlik                katilim  pismanlik
               0.00   78.0 %      0.0 %                 22.1 %      0.0 %
               0.25   84.8 %      6.7 %                 29.9 %      7.8 %
               0.55   90.8 %     12.8 %                 40.9 %     18.8 %
               1.00   96.2 %     18.1 %                 58.2 %     36.1 %
               1.50   98.8 %     20.7 %                 76.3 %     54.2 %
               2.50   99.9 %     21.9 %                 95.8 %     73.7 %

etkin secimin bedeli (oneri bulteni ayari)
terk  0 %  akisi tamamlayan 100 %  etkin secimle katilim 22.1 % / pismanlik 0.0 %  acik varsayilanla 40.9 % / 18.8 %
terk  3 %  akisi tamamlayan 97 %  etkin secimle katilim 21.4 % / pismanlik 0.0 %  acik varsayilanla 40.9 % / 18.8 %
terk  6 %  akisi tamamlayan 94 %  etkin secimle katilim 20.8 % / pismanlik 0.0 %  acik varsayilanla 40.9 % / 18.8 %
terk 10 %  akisi tamamlayan 90 %  etkin secimle katilim 19.9 % / pismanlik 0.0 %  acik varsayilanla 40.9 % / 18.8 %
etkin secimin akisa ekledigi sure: 0.44 sn
```

#### Aynı Düzen, İki Ayarda İki Farklı Şey

İlk tablonun katılım sütunu varsayılanın gücünü ölçüyor. Teslim hatırlatması kapalı varsayılanla
yüzde 58.7, açık varsayılanla yüzde 90.8. Öneri bülteni kapalı varsayılanla yüzde 9.0, açık
varsayılanla yüzde 40.9. Her iki ayarda da varsayılanı çevirmek katılımı yaklaşık otuz iki puan
değiştiriyor; oran olarak bu, teslim hatırlatmasında bir buçuk, öneri bülteninde dört buçuk kata
denk geliyor. Değişen tek şey bir onay kutusunun başlangıç durumu.

Katılım sütununa bakan biri her iki ayarda da aynı sonuca varır: açık varsayılan daha
iyidir. Pişmanlık sütunu bunu çürütüyor.

Teslim hatırlatmasında açık varsayılanın pişmanlık oranı yüzde 12.8, kapalı varsayılanın
yüzde 19.4. Açık varsayılan, kullanıcıları bilgili tercihlerine **yaklaştırıyor**.
Kapalı varsayılan, hatırlatmayı isteyen ama açmak için uğraşmayan yüzde 19.4'lük bir
kitleyi hatırlatmasız bırakıyor.

Öneri bülteninde işaretler ters dönüyor. Açık varsayılanın pişmanlık oranı yüzde 18.8,
kapalı varsayılanın yüzde 13.1. Açık varsayılan kullanıcıları bilgili tercihlerinden
**uzaklaştırıyor**: bülteni istemeyen 3116 kullanıcının bir kısmı bülten almaya devam
ediyor.

Buradan dersin kuralı çıkar. **Varsayılan, pişmanlık oranını en aza indirecek biçimde
seçilir.** Bu, "çoğunluğun bilgili tercihi hangi yöndeyse varsayılan o yönde olur"
demenin ölçülebilir hâlidir. Teslim hatırlatmasında çoğunluk istiyor, varsayılan açık
olur. Öneri bülteninde çoğunluk istemiyor, varsayılan kapalı olur.

Kural, katılım oranına hiç bakmaz. Öneri bülteninde katılımı yüzde 9'dan 40.9'a çıkarmak
mümkündür ve bu artışın tamamı, ayarı istemeyen kullanıcılardan gelir.

#### Değiştirme Maliyeti Varsayılanı Tuzağa Çevirir

İkinci tablo, varsayılanın gücünün nereden geldiğini gösteriyor: değiştirme maliyetinden.

Maliyet sıfırken pişmanlık her iki ayarda da sıfır. Herkes istediği duruma geçiyor;
varsayılanın hiçbir etkisi kalmıyor. Maliyet arttıkça katılım da pişmanlık da yükseliyor.

İki ayardaki yükseliş hızları farklı. Teslim hatırlatmasında maliyet 0'dan 2.5'e
çıkarken katılım yüzde 78'den 99.9'a, pişmanlık yüzde 0'dan 21.9'a çıkıyor. Öneri
bülteninde katılım yüzde 22.1'den 95.8'e, pişmanlık ise yüzde 0'dan **73.7'ye** çıkıyor.
Maliyet 2.5 olduğunda öneri bülteni alan her dört kullanıcıdan üçü onu istemiyor.

Bu sayı, "zorlaştırılmış iptal" kalıbının niceliksel tanımıdır. Bir ayarı kapatmak zor
hâle getirildiğinde katılım oranı yükselir; yükselişin tamamı pişmanlıktan gelir.
Katılım oranını raporlayan bir gösterge tablosunda bu iki durum ayırt edilemez: yüzde
95.8 katılım, kullanıcıların istediği bir ayarda da istemediği bir ayarda da yüzde 95.8
görünür.

Ayrımı yapan tek büyüklük pişmanlık oranıdır ve pişmanlık oranı arayüz kütüklerinden
okunmaz. Kullanıcının bilgili tercihini bilmek gerekir; bu da ölçme konusunun sorusudur.

#### Etkin Seçimin Bedeli ve Yeri

Etkin seçim her iki ayarda da pişmanlığı sıfırlıyor: kullanıcı doğrudan seçtiği için
istemediği bir durumda kalmıyor. Bedeli üçüncü tabloda.

Etkin seçim akışa bir karar noktası ekliyor; Bilişsel Yük dersindeki hesaba göre bu
0.44 saniye. Süreden daha önemlisi terk: uzayan akışta bir kısım kullanıcı ödünç almayı
tamamlamıyor. Yüzde 10 terk oranında bülteni isteyen kullanıcı oranı yüzde 22.1'den
19.9'a düşüyor — bültenin kendisi değil, ödünç alma işlemi kaybediliyor.

Bu, etkin seçimin her yerde kullanılamayacağı anlamına gelir. Kararın ne zaman
kullanıcıya bırakılacağı üç ölçütle verilir:

**Sonuç geri alınabilir mi?** Bülten aboneliği her an kapatılabilir; bir kitabın yanlış
şubeye ısmarlanması ısmarlandıktan sonra düzeltilemez. Geri alınamayan kararlarda etkin
seçim, terk maliyetine değer.

**Tercihler bölünmüş mü?** Bilgili tercih yüzde 78'e yüzde 22 gibi bir dağılım
gösteriyorsa varsayılan çoğunluğa hizmet eder. Dağılım yüzde 50'ye yakınsa hiçbir
varsayılan pişmanlığı düşüremez ve etkin seçim tek doğru düzendir.

**Karar kimin lehine?** Ayarın açık olması arayüzün işine yarıyor ve kullanıcının işine
yaramıyorsa, varsayılan seçimi tasarımcının çıkar çatışması içinde olduğu bir seçimdir.
Bu durumda karar kullanıcıya bırakılır.

#### Varsayılan Koymanın Kuralları

**Varsayılan, bilgili çoğunluğun tercihi yönünde konur.** Bunun bilinmesi ölçüm gerektirir;
tahmine dayanan varsayılan bir varsayım değil, bir dayatmadır.

**Değiştirme maliyeti mümkün olduğunca düşürülür.** Varsayılanın meşruluğu, onu
değiştirmenin kolaylığıyla doğru orantılıdır. Değiştirmeyi zorlaştıran her adım
pişmanlık oranını yükseltir.

**Varsayılan görünür yazılır.** Kullanıcının hangi değerin geçerli olduğunu görmediği bir
ayar, varsayılan değil gizli bir karardır. Ödünç onayı ekranında "teslim şubesi: merkez"
yazması, kullanıcının o kararın verildiğini bilmesini sağlar.

**Katılım oranı ile pişmanlık oranı birlikte raporlanır.** Yalnız katılım raporlandığında,
pişmanlığı artıran her değişiklik iyileşme gibi görünür.

#### Özet

- Varsayılan, kullanıcı hiçbir şey yapmadığında geçerli olan değerdir; benzetimde
  varsayılanı çevirmek katılım oranını otuz puandan fazla değiştirdi.
- Katılım oranı bir varsayılanın doğruluğunu göstermez; aynı düzen bir ayarda pişmanlığı
  düşürürken (yüzde 19.4'ten 12.8'e) diğerinde yükseltir (yüzde 13.1'den 18.8'e).
- Meşruluk ölçütü pişmanlık oranıdır: varsayılan, kullanıcıların bilgili tercihlerinden
  farklı bir durumda kalma oranını en aza indirecek yönde konur.
- Varsayılanın gücü değiştirme maliyetinden gelir; maliyet sıfırken varsayılanın etkisi
  yoktur, maliyet büyüdükçe katılım artışının tamamı pişmanlıktan gelir — hesapta yüzde
  95.8 katılıma karşılık yüzde 73.7 pişmanlık.
- Etkin seçim pişmanlığı sıfırlar ama bir karar noktası ekler ve terk üretir; geri
  alınamayan kararlarda, bölünmüş tercihlerde ve çıkar çatışması olan ayarlarda seçilir.
- Katılım oranı tek başına raporlandığında zorlaştırılmış iptal ile isabetli varsayılan
  aynı görünür.

#### Sonraki Adım

Varsayılan, kullanıcının kararını sessizce yönlendirir. Arayüzün elinde bir de açıkça
konuşan bir araç var: başkalarının ne yaptığını göstermek. Katalogda "bu kaydı ödünç
alanlar şunları da aldı" ya da "bu ay en çok ödünç alınanlar" biçimindeki bilgiler
kullanıcının kararını değiştirir. Sonraki ders bu değiştirmenin mekanizmasını kurar,
gösterilen sayının kendi kendini besleyen bir döngü yaratıp yaratmadığını hesaplar ve
sosyal kanıtın hangi noktada bilgi olmaktan çıkıp yönlendirmeye dönüştüğünü ele alır.

### Sosyal Kanıt ve Otorite

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/sosyal-kanit-ve-otorite

Görünür sayımların bilgi çağlayanı üreterek bağımsız kararı bastırması, popülerlik listesinin kendini beslemesi ve otorite işaretinin ancak kullanıcının kendi bilgisinden güvenilirse değer taşıması.

Önceki ders varsayılanın kullanıcının kararını sessizce yönlendirdiğini gösterdi.
Arayüzün elinde açıkça konuşan bir araç daha var: başkalarının ne yaptığını göstermek.
Katalogda "bu kaydı ödünç alanlar şunları da aldı", "bu ay en çok ödünç alınanlar" ya da
bir kaydın yanındaki ödünç alma sayısı bu türdendir.

**Sosyal kanıt (social proof)**, kişinin belirsiz bir durumda başkalarının davranışını
bir bilgi kaynağı olarak kullanmasıdır. Mekanizma temelde makuldür: başkalarının seçimi,
onların bildiği bir şeyi taşıyor olabilir. Bu ders makullüğün nerede bittiğini ölçer.

#### Görünür Sayım Bağımsız Bilgiyi Yok Eder

İlk hesap bir katalog durumunu modelliyor. Bir eserin iki baskısı var; biri gerçekten
daha uygun (daha eksiksiz, daha okunaklı). Her kullanıcı kendi başına bakınca doğru
baskıyı yüzde 68 olasılıkla ayırt edebiliyor — iyi ama kusurlu bir işaret.

Kırk kullanıcı sırayla geliyor. İki düzen karşılaştırılıyor: her kullanıcının yalnızca
kendi işaretini gördüğü düzen ve o ana kadarki ödünç alma sayımlarını da gördüğü düzen.

```js
// sosyal.mjs — gorunur sayimin bilgi tasima kapasitesine etkisi

function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

const ISARET = 0.68;      // kullanicinin kendi isaretinin dogrulugu
const KULLANICI = 40;
const KOSU = 4000;

// ---- 1) Cogunlugun dogru karari: bagimsiz oy ile gorunur sayim ----
// Iki baski var, biri gercekten daha uygun (1). Her kullanici %68 dogru isaret aliyor.
function ardisik(gorunurSayim, rnd) {
  let n0 = 0, n1 = 0, kendiIsareti = 0, caglayanBasi = null;
  for (let i = 0; i < KULLANICI; i++) {
    const isaret = rnd() < ISARET ? 1 : 0;
    const fark = n1 - n0;
    let secim;
    if (!gorunurSayim || Math.abs(fark) < 2) { secim = isaret; kendiIsareti++; }
    else { secim = fark >= 2 ? 1 : 0; if (caglayanBasi === null) caglayanBasi = i; }
    if (secim === 1) n1++; else n0++;
  }
  return { n0, n1, kendiIsareti, caglayanBasi };
}

// k bagimsiz isaretin cogunlugunun dogru olma olasiligi
function ikiliKatsayi(n, k) {
  let r = 1;
  for (let i = 1; i <= k; i++) r = (r * (n - k + i)) / i;
  return r;
}
function cogunlukDogrulugu(k, q) {
  let t = 0;
  for (let i = Math.floor(k / 2) + 1; i <= k; i++) t += ikiliKatsayi(k, i) * q ** i * (1 - q) ** (k - i);
  return t;
}

console.log("duzen           cogunluk dogru  kendi isaretini kullanan  caglayanin basladigi sira");
const olculen = {};
for (const gorunur of [false, true]) {
  const rnd = uretec(20260527);
  let cogunlukDogru = 0, kendi = 0, bas = 0, basSayisi = 0;
  for (let k = 0; k < KOSU; k++) {
    const r = ardisik(gorunur, rnd);
    if (r.n1 > r.n0) cogunlukDogru++;
    kendi += r.kendiIsareti;
    if (r.caglayanBasi !== null) { bas += r.caglayanBasi; basSayisi++; }
  }
  const oran = cogunlukDogru / KOSU;
  olculen[gorunur ? "gorunur" : "gizli"] = oran;
  console.log(
    `${(gorunur ? "sayim gorunur" : "sayim gizli").padEnd(15)} ${((oran * 100).toFixed(1) + " %").padStart(14)}` +
    ` ${(kendi / KOSU).toFixed(1).padStart(24)} ${(basSayisi === 0 ? "-" : (bas / basSayisi).toFixed(1) + ". kullanici").padStart(27)}`
  );
}

// Gorunur sayimli duzen kac bagimsiz oya denk dusuyor
console.log("\nbagimsiz oy sayisi  cogunlugun dogru olma olasiligi");
for (const k of [1, 3, 5, 11, 21, 41]) {
  console.log(`${String(k).padStart(18)}  ${(cogunlukDogrulugu(k, ISARET) * 100).toFixed(1)} %`);
}
let denk = 1;
while (denk < 41 && cogunlukDogrulugu(denk, ISARET) < olculen.gorunur) denk += 2;
console.log(`sayim gorunurken 40 kullanici, ${denk} bagimsiz oya denk dusuyor`);

// ---- 2) "En cok odunc alinanlar" listesinin kendini besleme etkisi ----
const KAYIT = 200, TUR = 60, TUR_KULLANICI = 100, LISTE = 10, LISTE_ETKISI = 6;

function siraKorelasyonu(a, b) {                 // Spearman sira korelasyonu
  const sira = (v) => {
    const s = v.map((x, i) => [x, i]).sort((p, q) => q[0] - p[0]);
    const r = new Array(v.length);
    s.forEach(([, i], k) => { r[i] = k + 1; });
    return r;
  };
  const ra = sira(a), rb = sira(b), n = a.length, ort = (n + 1) / 2;
  let pay = 0, pa = 0, pb = 0;
  for (let i = 0; i < n; i++) {
    pay += (ra[i] - ort) * (rb[i] - ort);
    pa += (ra[i] - ort) ** 2; pb += (rb[i] - ort) ** 2;
  }
  return pay / Math.sqrt(pa * pb);
}

function popularite(listeVar) {
  const rnd = uretec(20260601);
  const nitelik = Array.from({ length: KAYIT }, () => 0.2 + rnd() * 0.8);
  const sayim = new Array(KAYIT).fill(0), ilkTur = new Array(KAYIT).fill(0);
  for (let tur = 0; tur < TUR; tur++) {
    const enCok = [...sayim.keys()].sort((a, b) => sayim[b] - sayim[a]).slice(0, LISTE);
    const listede = new Set(listeVar ? enCok : []);
    const agirlik = nitelik.map((q, i) => q * (listede.has(i) ? LISTE_ETKISI : 1));
    const toplam = agirlik.reduce((a, b) => a + b, 0);
    for (let u = 0; u < TUR_KULLANICI; u++) {
      let x = rnd() * toplam, i = 0;
      while (x > agirlik[i] && i < KAYIT - 1) { x -= agirlik[i]; i++; }
      sayim[i]++;
      if (tur === 0) ilkTur[i]++;
    }
  }
  return { nitelik, sayim, ilkTur };
}

console.log("\nliste                nitelikle korelasyon  ilk turdaki sansla korelasyon  ilk 10'da gercek ilk 10");
for (const listeVar of [false, true]) {
  const { nitelik, sayim, ilkTur } = popularite(listeVar);
  const enIyi = new Set([...nitelik.keys()].sort((a, b) => nitelik[b] - nitelik[a]).slice(0, LISTE));
  const enCok = [...sayim.keys()].sort((a, b) => sayim[b] - sayim[a]).slice(0, LISTE);
  console.log(
    `${(listeVar ? "liste gosteriliyor" : "liste yok").padEnd(20)} ${siraKorelasyonu(sayim, nitelik).toFixed(3).padStart(21)}` +
    ` ${siraKorelasyonu(sayim, ilkTur).toFixed(3).padStart(29)} ${(enCok.filter((i) => enIyi.has(i)).length + " / 10").padStart(24)}`
  );
}

// ---- 3) Otorite isareti kendi isaretinin yerini ne zaman alir ----
console.log("\notorite dogrulugu  otoriteye uyma  kendi isareti  en guvenilire uyma  5 bagimsiz oy");
const besOy = cogunlukDogrulugu(5, ISARET);
for (const a of [0.50, 0.60, 0.68, 0.80, 0.92]) {
  console.log(
    `${a.toFixed(2).padStart(17)}  ${((a * 100).toFixed(1) + " %").padStart(14)} ${((ISARET * 100).toFixed(1) + " %").padStart(14)}` +
    ` ${((Math.max(a, ISARET) * 100).toFixed(1) + " %").padStart(19)} ${((besOy * 100).toFixed(1) + " %").padStart(14)}`
  );
}
```

```
duzen           cogunluk dogru  kendi isaretini kullanan  caglayanin basladigi sira
sayim gizli             98.4 %                     40.0                           -
sayim gorunur           82.1 %                      3.5              3.5. kullanici

bagimsiz oy sayisi  cogunlugun dogru olma olasiligi
                 1  68.0 %
                 3  75.8 %
                 5  80.9 %
                11  89.7 %
                21  95.8 %
                41  99.2 %
sayim gorunurken 40 kullanici, 7 bagimsiz oya denk dusuyor

liste                nitelikle korelasyon  ilk turdaki sansla korelasyon  ilk 10'da gercek ilk 10
liste yok                            0.918                         0.177                   7 / 10
liste gosteriliyor                   0.858                         0.290                   1 / 10

otorite dogrulugu  otoriteye uyma  kendi isareti  en guvenilire uyma  5 bagimsiz oy
             0.50          50.0 %         68.0 %              68.0 %         80.9 %
             0.60          60.0 %         68.0 %              68.0 %         80.9 %
             0.68          68.0 %         68.0 %              68.0 %         80.9 %
             0.80          80.0 %         68.0 %              80.0 %         80.9 %
             0.92          92.0 %         68.0 %              92.0 %         80.9 %
```

#### Bilgi Çağlayanı ve Etkin Oy Sayısı

İlk tablo tersine bir sonuç veriyor. Sayım gizliyken kırk kullanıcının çoğunluğu doğru
baskıyı yüzde 98.4 oranında buluyor. Sayım görünürken bu oran yüzde 82.1'e düşüyor.
Kullanıcılara **daha çok bilgi** verildiğinde toplu karar **kötüleşiyor**.

Nedeni ikinci sütunda. Sayım gizliyken kırk kullanıcının kırkı da kendi işaretini
kullanıyor. Sayım görünürken yalnızca 3.5'i kullanıyor. Ortalama 3.5. kullanıcıdan
sonra sayım farkı iki oya çıkıyor ve o noktadan sonra hiçbir kullanıcının kendi işareti
kararını değiştirmeye yetmiyor. Herkes sayıma uyuyor, sayım büyüyor, uyma nedeni
güçleniyor.

Bu yapıya **bilgi çağlayanı (information cascade)** denir. (CSS'teki basamaklama ile
karıştırılmamalıdır; burada basamaklanan biçem kuralları değil kararlardır.) Çağlayanın
kritik özelliği şudur: dördüncü kullanıcıdan sonra gelen otuz altı kişinin sahip olduğu
bilgi hiçbir zaman sisteme girmez. Sayım büyür ama içindeki bilgi büyümez.

Üçüncü blok bunu tek bir sayıya indiriyor. Bağımsız oyların çoğunluğu 5 oyda yüzde 80.9,
41 oyda yüzde 99.2 doğruluk veriyor. Sayımın görünür olduğu düzende kırk kullanıcının
ürettiği yüzde 82.1'lik doğruluk, **yedi bağımsız oya** denk düşüyor. Kırk kullanıcının
otuz üçü toplu bilgiye hiçbir katkı yapmıyor.

Tasarım karşılığı nettir: sayının gösterildiği an önemlidir. Kullanıcı kendi kararını
verdikten **sonra** gösterilen bir sayım bilgiyi bozmaz; karar verilmeden **önce**
gösterilen sayım, o kullanıcıdan sonraki bütün kullanıcıların bilgisini bastırır.

#### Popülerlik Listesi Kendi Kendini Besler

İkinci hesap iki yüz kayıtlı bir katalogda altmış tur boyunca ödünç almaları izliyor.
Her kaydın bir niteliği var. İki düzen karşılaştırılıyor: "en çok ödünç alınan on kayıt"
listesinin gösterildiği düzen ve gösterilmediği düzen.

Liste yokken sıralamanın nitelikle sıra korelasyonu 0.918, ilk turdaki rastlantıyla 0.177;
sonuçtaki ilk on kaydın yedisi gerçekten en nitelikli on kayıt. Liste gösterildiğinde
nitelik korelasyonu 0.858'e düşüyor, rastlantı korelasyonu 0.290'a çıkıyor ve sonuçtaki
ilk onun yalnızca **biri** gerçek ilk onda.

Bu üçüncü sayı, ilk iki sayının gizlediği şeyi açığa çıkarıyor. Genel korelasyon çok az
bozuluyor (0.918'den 0.858'e) çünkü listenin dışındaki yüz doksan kaydın sıralaması hâlâ
nitelikle belirleniyor. Bozulan yer tam olarak listenin kendisi: ilk turda şansı yaver
giden kayıtlar listeye giriyor, listede olmak onlara altı kat görünürlük veriyor, bu
görünürlük sayımlarını artırıyor ve listede kalmalarını sağlıyor. Nitelikli ama ilk turda
şanssız kayıtlar bir daha yukarı çıkamıyor.

Sonuç, listenin **iddia ettiği şeyi ölçmemesidir**. "En çok ödünç alınanlar" başlığı
kullanıcıya bir nitelik sıralaması vaat eder; ölçtüğü şey büyük ölçüde erken
görünürlüktür. Kullanıcı bu listenin nasıl üretildiğini bilseydi ona bir nitelik işareti
olarak bakmazdı.

Bu, popülerlik listesinin her koşulda yanlış olduğu anlamına gelmez. Bozulmayı üreten
şey **geri besleme döngüsüdür**: listede olmanın listede kalmayı kolaylaştırması. Döngüyü
kıran tasarım kararları vardır — listeyi dar bir zaman penceresiyle sınırlamak, listeye
giren kayıtları bir süre listeden çıkarmak, listeyi ödünç sayısı yerine tamamlanma ya da
iade sonrası değerlendirme gibi daha zor taklit edilen bir ölçüte bağlamak. Her biri
görünürlük kazancını sayımdan koparır.

#### Otorite Ancak Daha Güvenilirse Bilgidir

Son tablo otorite işaretini ele alıyor: "bölüm okuma listesinde", "kütüphaneci önerisi",
"öğretim üyesi seçkisi" gibi etiketler.

Kullanıcının kendi işareti yüzde 68 doğru. Otoritenin doğruluğu 0.50 iken otoriteye
uymanın doğruluğu yüzde 50 — kullanıcı kendi başına karar verse yüzde 68 alacaktı.
Otorite doğruluğu 0.68'e çıktığında iki seçenek eşitleniyor. Ancak 0.80 ve 0.92'de
otoriteye uymak kazandırıyor.

Kural şudur: **otorite işareti, kullanıcının kendi yargısından daha güvenilir olduğu
ölçüde bilgidir; değilse yalnızca kararı devralmıştır.** Arayüzde bir etiket
gösterildiğinde kullanıcı bu karşılaştırmayı yapamaz, çünkü etiketin doğruluğunu bilmez.
Etiketi anlamlı kılan şey, dayanağının görünür olmasıdır: "hangi dersin okuma listesi",
"kim önerdi", "hangi ölçütle seçildi". Dayanağı yazılmayan bir otorite etiketi kullanıcıya
bir sayı değil, yalnızca bir yön verir.

Son sütun tabloyu bu dersin ilk bölümüne bağlıyor. Beş **bağımsız** kullanıcının
çoğunluğu yüzde 80.9 doğruluk veriyor — 0.80 doğruluklu bir otoriteden daha iyi. Kalabalık,
bağımsız olduğu sürece çoğu otoriteden güvenilirdir. İlk hesap ise görünür sayımın tam
olarak bu bağımsızlığı yok ettiğini gösterdi. Sosyal kanıtı değerli kılan şeyle onu
gösterme biçimi birbirini bozuyor.

#### Tanıma ve Reddetme Ölçütleri

Bir sosyal kanıt ya da otorite işaretinin meşru olup olmadığı üç soruyla denetlenir.

**Sayının doğrulanabilir bir dayanağı var mı?** "412 kullanıcı bu kaydı ödünç aldı"
sayılabilir bir olguya karşılık gelir. "Bu kayıt çok popüler" hiçbir şeye karşılık
gelmez ve denetlenemez. Denetlenemeyen ifade sosyal kanıt değil, sosyal kanıt görünümüdür.

**Sayı kullanıcının kararından önce mi sonra mı gösteriliyor?** Karardan önce gösterilen
sayım çağlayan üretir. Kaydı açan kullanıcıya ödünç sayısını göstermek yerine, ödünç
aldıktan sonra "bu kaydı alan kullanıcılar şunları da aldı" demek aynı bilgiyi bağımsızlığı
bozmadan verir.

**Kıtlık gerçek mi?** "Bu kaydın kalan tek nüshası" ifadesi katalog verisinden doğruysa
kullanıcının işine yarayan bir bilgidir: bekleme kararını değiştirir. Aynı ifade nüsha
sayısından bağımsız olarak gösteriliyorsa, kullanıcının aceleci karar vermesini sağlamak
için üretilmiş bir sahte kıtlık işaretidir. İkisi ekranda aynı görünür; ayrım verinin
kaynağındadır.

Bu üç sorunun ortak paydası, bu konunun baştan beri kullandığı ölçüttür. Kullanıcı,
gördüğü sayının nasıl üretildiğini bilseydi kararı değişir miydi? Ödünç sayısı gerçek
sayımdan geliyorsa değişmez. Popülerlik listesi kendi kendini besleyen bir döngüden
geliyorsa değişir. Kıtlık uyarısı stoktan bağımsız gösteriliyorsa değişir — ve o zaman
kararın gücü kullanıcının bilgisizliğinden geliyor demektir.

#### Özet

- Sosyal kanıt, başkalarının davranışının bir bilgi kaynağı olarak kullanılmasıdır;
  değeri, o davranışların bağımsız yargılardan doğmasına bağlıdır.
- Görünür sayım bilgi çağlayanı üretir: benzetimde çoğunluğun doğruluğu yüzde 98.4'ten
  82.1'e düştü ve kırk kullanıcıdan yalnızca 3.5'i kendi işaretini kullanabildi.
- Görünür sayımlı kırk kullanıcı, yedi bağımsız oya denk bilgi üretir; kalan kullanıcıların
  bilgisi sisteme hiç girmez.
- Popülerlik listesi geri besleme döngüsü kurar: hesapta sonuçtaki ilk onun yalnızca biri
  gerçekten en nitelikli on kayıt arasındaydı; liste niteliği değil erken görünürlüğü
  ölçüyor.
- Otorite işareti ancak kullanıcının kendi yargısından güvenilirse bilgi taşır; beş
  bağımsız kullanıcının çoğunluğu, 0.80 doğruluklu bir otoriteden daha isabetlidir.
- Denetim üç soruyla yapılır: sayının doğrulanabilir dayanağı var mı, karardan önce mi
  gösteriliyor, kıtlık gerçek mi?

#### Sonraki Adım

Bu ders arayüzün kullanıcıya **başkaları hakkında** verdiği bilgiyi ele aldı. Arayüzün
verdiği bir bilgi türü daha var ve doğrudan kullanıcının kendisiyle ilgili: nerede
olduğu, ne kadar yol aldığı, ne kadar kaldığı. Sonraki ders görünür ilerlemenin akışı
tamamlama üzerindeki etkisini hesaplar, geri bildirim gecikmesinin hangi eşiklerde
davranışı değiştirdiğini ele alır ve ilerleme göstergesinin ne zaman bilgi ne zaman süs
olduğunu ayırır.

### İlerleme ve Geri Bildirim

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/ilerleme-ve-geri-bildirim

İlerleme göstergesinin kalan işi doğru bildirip bildirmediğinin hesaplanması, tamamlama oranını yükselten yanıltmanın ayırt edilmesi ve geri bildirim gecikmesinin gösterge sınıflarına bağlanması.

Önceki ders arayüzün kullanıcıya başkaları hakkında verdiği bilgiyi ele aldı. Arayüzün
verdiği bir bilgi türü daha var ve doğrudan kullanıcının kendisiyle ilgili: akışın
neresinde olduğu, ne kadar yol aldığı, ne kadar kaldığı.

Bu bilgi kullanıcının tek bir kararını besler: devam etmek mi, çıkmak mı? Karar her adım
sonunda yeniden verilir ve kullanıcının elindeki tek girdi, kalan işin ne kadar olduğuna
dair tahminidir. Bu ders o tahmini ölçer, göstergenin tahmini nasıl değiştirdiğini
hesaplar ve tamamlama oranını yükselten bir göstergenin ne zaman bilgi ne zaman yanıltma
olduğunu ayırır.

#### Adım Sayısı Zamanı Ölçmez

Ödünç alma akışı altı adımdan oluşuyor ama adımlar eşit uzunlukta değil. Kayıt ayrıntısını
açmak 0.8 saniye, nüsha seçimi 5.1 saniye sürüyor. Bir ilerleme çubuğu iki farklı biçimde
doldurulabilir: adım sayısına göre (altı adımın üçü bitti, yüzde 50) ya da süreye göre
(harcanan sürenin toplam süreye oranı).

Aşağıdaki hesap iki çubuğun kalan süre tahminini karşılaştırıyor, sonra üç bin kullanıcının
devam etme kararını benzetiyor.

```js
// ilerleme.mjs — ilerleme gostergesinin dogrulugu ve terk uzerindeki etkisi

function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

// Odunc alma akisinin alti adimi ve gercek sureleri (sn).
const ADIMLAR = [
  ["arama", 1.2], ["sonuc listesi", 3.4], ["kayit ayrinti", 0.8],
  ["nusha secimi", 5.1], ["onay", 1.0], ["makbuz", 2.2],
];
const SURELER = ADIMLAR.map(([, d]) => d);
const TOPLAM = SURELER.reduce((a, b) => a + b, 0);
const gecen = SURELER.map((_, i) => SURELER.slice(0, i + 1).reduce((a, b) => a + b, 0));

// Iki gosterge: adim sayisina gore ilerleyen cubuk, sureye gore agirliklandirilmis cubuk.
const adimCubugu = (i) => (i + 1) / ADIMLAR.length;
const sureCubugu = (i) => gecen[i] / TOPLAM;

console.log("adim            sure  gecen  adim cubugu  sure cubugu  kalan (gercek)  adim cub. tahmini  sure cub. tahmini");
let adimHata = 0, sureHata = 0;
for (let i = 0; i < ADIMLAR.length - 1; i++) {
  const kalan = TOPLAM - gecen[i];
  const tA = gecen[i] * (1 - adimCubugu(i)) / adimCubugu(i);
  const tS = gecen[i] * (1 - sureCubugu(i)) / sureCubugu(i);
  adimHata += Math.abs(tA - kalan) / kalan;
  sureHata += Math.abs(tS - kalan) / kalan;
  console.log(
    `${ADIMLAR[i][0].padEnd(15)} ${SURELER[i].toFixed(1).padStart(4)} ${gecen[i].toFixed(1).padStart(6)}` +
    ` ${(adimCubugu(i) * 100).toFixed(0).padStart(10)} % ${(sureCubugu(i) * 100).toFixed(0).padStart(11)} %` +
    ` ${kalan.toFixed(1).padStart(15)} ${tA.toFixed(1).padStart(18)} ${tS.toFixed(1).padStart(18)}`
  );
}
const n = ADIMLAR.length - 1;
console.log(`ortalama bagil hata: adim cubugu ${(adimHata / n * 100).toFixed(1)} %, sure cubugu ${(sureHata / n * 100).toFixed(1)} %`);

// Terk karari: kullanici her adim sonunda kalan sureyi tahmin eder ve sabriyla karsilastirir.
// Dogru karar, GERCEK kalan sure sabri asmiyorsa devam etmektir.
const KISI = 3000;
const BELIRSIZLIK = 2.2;   // gosterge yokken kullanicinin kotumser carpani

function karar(gosterge) {
  const rnd = uretec(20260714);
  let tamamlayan = 0, gereksizTerk = 0, gereksizDevam = 0;
  for (let k = 0; k < KISI; k++) {
    const sabir = 5 + rnd() * 40;   // kabul edilen kalan sure (sn)
    let cikti = false;
    for (let i = 0; i < ADIMLAR.length - 1; i++) {
      const gercekKalan = TOPLAM - gecen[i];
      const dogruDevam = gercekKalan <= sabir;
      let tahmin;
      if (gosterge === "yok") tahmin = gecen[i] * BELIRSIZLIK;
      else if (gosterge === "adim cubugu") tahmin = gecen[i] * (1 - adimCubugu(i)) / adimCubugu(i);
      else tahmin = gecen[i] * (1 - sureCubugu(i)) / sureCubugu(i);
      const devam = tahmin <= sabir;
      if (devam && !dogruDevam) gereksizDevam++;
      if (!devam && dogruDevam) gereksizTerk++;
      if (!devam) { cikti = true; break; }
    }
    if (!cikti) tamamlayan++;
  }
  return { oran: (tamamlayan / KISI) * 100, gereksizTerk, gereksizDevam };
}

console.log("\ngosterge        tamamlama  gereksiz terk  gereksiz devam  yanlis karar");
for (const g of ["yok", "adim cubugu", "sure cubugu"]) {
  const t = karar(g);
  console.log(
    `${g.padEnd(15)} ${(t.oran.toFixed(1) + " %").padStart(9)} ${String(t.gereksizTerk).padStart(14)}` +
    ` ${String(t.gereksizDevam).padStart(15)} ${String(t.gereksizTerk + t.gereksizDevam).padStart(13)}`
  );
}
console.log(`(${KISI} kullanici, akisin gercek toplam suresi ${TOPLAM.toFixed(1)} sn)`);

// Geri bildirim gecikmesi siniflari ve her sinifin gerektirdigi gosterge
const ISLEMLER = [
  ["arama alanina yazma", 0.04], ["suzgec uygulama", 0.18], ["kayit acma", 0.7],
  ["nusha durumu sorgusu", 2.4], ["odunc kaydi olusturma", 6.5], ["makbuz uretimi", 14.0],
];
const sinif = (t) => t <= 0.1 ? "anlik" : t <= 1.0 ? "akis korunur" : t <= 10 ? "dikkat dagilir" : "dikkat kopar";
const gerekli = (t) => t <= 0.1 ? "gosterge gerekmez" : t <= 1.0 ? "durum degisimi yeter"
  : t <= 10 ? "belirsiz bekleme gostergesi" : "belirli ilerleme + kalan sure";
console.log("\nislem                     sure     sinif           gereken geri bildirim");
for (const [ad, t] of ISLEMLER) {
  console.log(`${ad.padEnd(25)} ${(t.toFixed(2) + " sn").padStart(8)}  ${sinif(t).padEnd(15)} ${gerekli(t)}`);
}

// Yapay gecikme: gosterilen ilerleme ile gercek is arasindaki bag
console.log("\ngosterilen ilerleme ile gercek is arasindaki iliski");
const gercekIs = [0.10, 0.25, 0.45, 0.70, 0.88, 1.00];
const durumlar = {
  "gercege bagli": gercekIs,
  "sabit hizli (yapay)": [0.17, 0.33, 0.50, 0.67, 0.83, 1.00],
  "sona takilan": [0.30, 0.60, 0.85, 0.93, 0.96, 1.00],
};
for (const [ad, g] of Object.entries(durumlar)) {
  let enBuyukSapma = 0, toplam = 0;
  for (let i = 0; i < g.length; i++) {
    const s = Math.abs(g[i] - gercekIs[i]);
    toplam += s;
    if (s > enBuyukSapma) enBuyukSapma = s;
  }
  console.log(`${ad.padEnd(22)} ortalama sapma ${(toplam / g.length * 100).toFixed(1)} puan, en buyuk sapma ${(enBuyukSapma * 100).toFixed(1)} puan`);
}
```

```
adim            sure  gecen  adim cubugu  sure cubugu  kalan (gercek)  adim cub. tahmini  sure cub. tahmini
arama            1.2    1.2         17 %           9 %            12.5                6.0               12.5
sonuc listesi    3.4    4.6         33 %          34 %             9.1                9.2                9.1
kayit ayrinti    0.8    5.4         50 %          39 %             8.3                5.4                8.3
nusha secimi     5.1   10.5         67 %          77 %             3.2                5.3                3.2
onay             1.0   11.5         83 %          84 %             2.2                2.3                2.2
ortalama bagil hata: adim cubugu 31.3 %, sure cubugu 0.0 %

gosterge        tamamlama  gereksiz terk  gereksiz devam  yanlis karar
yok                48.7 %           1226             558          1784
adim cubugu        89.2 %             11             476           487
sure cubugu        81.4 %              0               0             0
(3000 kullanici, akisin gercek toplam suresi 13.7 sn)

islem                     sure     sinif           gereken geri bildirim
arama alanina yazma        0.04 sn  anlik           gosterge gerekmez
suzgec uygulama            0.18 sn  akis korunur    durum degisimi yeter
kayit acma                 0.70 sn  akis korunur    durum degisimi yeter
nusha durumu sorgusu       2.40 sn  dikkat dagilir  belirsiz bekleme gostergesi
odunc kaydi olusturma      6.50 sn  dikkat dagilir  belirsiz bekleme gostergesi
makbuz uretimi            14.00 sn  dikkat kopar    belirli ilerleme + kalan sure

gosterilen ilerleme ile gercek is arasindaki iliski
gercege bagli          ortalama sapma 0.0 puan, en buyuk sapma 0.0 puan
sabit hizli (yapay)    ortalama sapma 4.7 puan, en buyuk sapma 8.0 puan
sona takilan           ortalama sapma 21.0 puan, en buyuk sapma 40.0 puan
```

#### Adım Çubuğunun Hatası Yönlüdür

İlk tabloda iki çubuk ilk adımda birbirinden ayrılıyor. Arama bittiğinde adım çubuğu
yüzde 17, süre çubuğu yüzde 9 gösteriyor. Kalan gerçek süre 12.5 saniye. Adım çubuğuna
bakan kullanıcı 6.0 saniye tahmin ediyor — gerçeğin yarısından az. Süre çubuğu 12.5
saniye veriyor.

Ortalama bağıl hata adım çubuğunda yüzde 31.3, süre çubuğunda yüzde 0. İkinci sayı bir
başarı değil, tanım gereği doğrudur: süre çubuğu zaten harcanan sürenin oranını
gösteriyor, dolayısıyla ondan türetilen tahmin gerçek kalan süreyi verir. Anlamlı olan
birinci sayıdır.

Adım çubuğunun hatası rastgele de değil. Uzun adım henüz gelmemişken çubuk iyimser
(6.0 yerine 12.5), uzun adım geçtikten sonra kötümser (5.3 yerine 3.2) tahmin ürettiriyor.
Yani kullanıcı akışın başında kalan işi olduğundan **az** sanıyor.

#### Tamamlama Oranı Yanlış Ölçüttür

İkinci tablo bu dersin ağırlık merkezidir. Gösterge yokken tamamlama oranı yüzde 48.7;
adım çubuğuyla yüzde 89.2; süre çubuğuyla yüzde 81.4.

Tamamlama oranına bakan biri adım çubuğunu seçer. Yanındaki üç sütun bu seçimin ne
olduğunu söylüyor. Süre çubuğunda yanlış karar sayısı sıfır: hiçbir kullanıcı, devam
etmeyi tercih edeceği bir akıştan çıkmıyor ve hiçbiri katlanmayacağı bir akışta
kalmıyor. Adım çubuğunda 476 kullanıcı **gereksiz devam** ediyor — kalan işi olduğundan
az sandıkları için, sabırlarının üzerinde bir akışı sürdürüyorlar.

Adım çubuğunun tamamlama oranını yüzde 81.4'ten 89.2'ye çıkarması, yedi virgül sekiz puanlık bir
kazanç gibi görünüyor. Kazancın kaynağı, kullanıcının kalan işi yanlış tahmin etmesidir. Bu,
Varsayılanların Gücü dersindeki pişmanlık oranıyla aynı yapıdır: gösterge tablosundaki sayı
yükseliyor, yükselişin tamamı yanılmadan geliyor.

Gösterge olmayan durum ise ayrı bir kayıp türü gösteriyor: 1226 **gereksiz terk**.
Bunlar, kalan iş sabırlarının altında olmasına rağmen belirsizlik yüzünden çıkan
kullanıcılar. Bu, ilerleme göstergesinin asıl gerekçesidir — gösterge, kullanıcıyı akışta
tutmak için değil, kullanıcının kararını gerçeğe dayandırmak için konur. Doğru göstergenin
tamamlama oranını yükseltmesi bu kararın bir sonucudur, amacı değil.

#### Geri Bildirim Gecikmesi Gösterge Sınıfını Belirler

Üçüncü tablo farklı bir soruyu ele alıyor: bir işlem sürerken kullanıcıya ne
gösterilmeli? Yanıt, işlemin süresine bağlıdır ve yerleşik üç eşikle sınıflandırılır.

**0.1 saniyeye kadar** kullanıcı gecikmeyi algılamaz; sonuç anında gelmiş gibi görünür.
Arama alanına yazma bu sınıftadır ve gösterge gerekmez. Bu sınıfta bir yükleme göstergesi
eklemek zarar verir: göstergenin belirip kaybolması, olmayan bir gecikmeyi görünür kılar.

**1 saniyeye kadar** gecikme algılanır ama kullanıcının düşünce akışı kesilmez. Süzgeç
uygulama ve kayıt açma bu sınıfta. Yeterli geri bildirim, sonucun kendisinin değişmesidir
— liste yenilenir, sayfa gelir. Ayrı bir bekleme göstergesi gerekmez.

**10 saniyeye kadar** kullanıcının dikkati dağılır; başka bir şeye bakmaya başlar. Nüsha
durumu sorgusu ve ödünç kaydı oluşturma bu sınıfta. Burada bir bekleme göstergesi
gereklidir; işin ne kadar süreceği bilinmiyorsa belirsiz bir gösterge yeterlidir, çünkü
kullanıcının verdiği tek karar "bekleyeyim mi" değil "arayüz çalışıyor mu" sorusudur.

**10 saniyenin üstünde** dikkat kopar. Makbuz üretimi bu sınıfta. Burada belirsiz gösterge
yetmez; kullanıcının işi bırakıp geri dönme kararını verebilmesi için ilerlemenin ve kalan
sürenin gösterilmesi gerekir. İkinci tablodaki hesabın uygulandığı yer burasıdır.

#### İlerleme Gerçek İşe Bağlanır

Son tablo bir denetim aracıdır: gösterilen ilerleme ile gerçekte tamamlanan işin oranı
arasındaki sapmayı ölçer.

Gerçeğe bağlı gösterge sıfır sapma verir. Sabit hızlı gösterge — çubuğun eşit aralıklarla
ilerlediği, işin gerçek dağılımını yansıtmadığı durum — ortalama 4.7, en fazla 8.0 puan
sapıyor. Sona takılan gösterge — çubuğun hızla yüzde 85'e çıkıp orada beklediği durum —
ortalama 21.0, en fazla 40.0 puan sapıyor.

Sapmanın işareti önemlidir. Sona takılan gösterge işi olduğundan **fazla** tamamlanmış
gösteriyor; kullanıcı "neredeyse bitti" diye bekliyor ve beklemesi uzuyor. Bu, tamamlama
oranını yükselten ama kullanıcının kararını yanlış bilgiye dayandıran bir tasarımdır.
Aynı yapının bir başka biçimi, işin gerçekte bitmiş olmasına rağmen bir bekleme
göstergesinin belirli bir süre tutulmasıdır; bu, yapılan işi olduğundan ağır göstermek
için eklenen bir gecikmedir.

Ölçüt bu konunun her dersindeki ölçütle aynıdır. Kullanıcı, çubuğun gerçek işe değil sabit
bir hıza bağlı olduğunu bilseydi ekranda beklemeye devam eder miydi? Sona takılan
göstergede yanıt hayırdır: kullanıcı beklemeyi, "yüzde 85 bitti" bilgisine güvendiği için
sürdürüyor. Gerçeğe bağlı göstergede yanıt evettir; kullanıcı zaten doğru bilgiyle karar
veriyor.

#### Özet

- İlerleme göstergesi kullanıcının tek bir kararını besler: devam etmek mi, çıkmak mı.
  Gösterge, kalan işi doğru bildirdiği ölçüde işe yarar.
- Adım sayısına göre ilerleyen çubuk, adımlar eşit uzunlukta değilse hatalı tahmin
  ürettirir; hesapta ortalama bağıl hata yüzde 31.3 ve hata akışın başında iyimser yönde.
- Tamamlama oranı yanlış ölçüttür: adım çubuğu tamamlamayı yüzde 81.4'ten 89.2'ye çıkarıyor
  ama bu kazanç 476 kullanıcının kalan işi az sanmasından geliyor.
- Doğru ölçüt yanlış karar sayısıdır; gösterge yokken 1226 kullanıcı gereksiz yere terk
  ediyor, süre çubuğuyla yanlış karar sayısı sıfır.
- Geri bildirim gecikmesi dört sınıfa ayrılır: 0.1 saniyeye kadar gösterge gerekmez,
  1 saniyeye kadar durum değişimi yeter, 10 saniyeye kadar belirsiz bekleme göstergesi,
  üstünde belirli ilerleme ve kalan süre gerekir.
- İlerleme çubuğu gerçek işe bağlanır; sabit hızlı ya da sona takılan gösterge kullanıcının
  bekleme kararını yanlış bilgiye dayandırır.

#### Sonraki Adım

Bu konunun yedi dersinde aynı ölçüt yedi kez ortaya çıktı: kullanıcı, tasarım kararının
nasıl alındığını bilseydi de aynı seçimi yapar mıydı? Belirginlikte, varsayılanda,
sosyal kanıtta, ilerleme çubuğunda her seferinde aynı ayrım belirdi — kararın gücü
kullanıcının bilgisinden mi geliyor, bilgisizliğinden mi? Sonraki ders bu ölçütü
sistemleştirir: acele ettirme, gizli maliyet, zorlaştırılmış iptal, onay tuzağı ve sahte
kıtlık kalıplarını sayılabilir göstergelere bağlar ve bir arayüzü bu göstergelerle
denetlemenin yolunu kurar.

### Karanlık Kalıplar ve Etik

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/karanlik-kaliplar-ve-etik

Bir tasarım kararının meşruluk ölçütünün sayılabilir göstergelere çevrilmesi, acele ettirme, gizli maliyet, zorlaştırılmış iptal, onay tuzağı ve sahte kıtlık kalıplarının tanınması ve reddedilmesi.

Bu konunun yedi dersinde aynı soru yedi kez ortaya çıktı. Çift süreçli düşünme dersinde: kullanıcı
listenin niçin bu sırayla dizildiğini bilseydi ilk kaydı seçer miydi? Varsayılanlar dersinde:
ayarın açık geldiğini fark etseydi açık bırakır mıydı? Sosyal kanıt dersinde: sayının nasıl
üretildiğini bilseydi ona güvenir miydi? İlerleme dersinde: çubuğun gerçek işe bağlı olmadığını
bilseydi beklemeyi sürdürür müydü?

Soru her seferinde aynıydı ve her seferinde iki yanıttan biri çıktı. Bu ders soruyu bir
ölçüte, ölçütü de denetlenebilir göstergelere çevirir.

#### Ölçüt

**Bir tasarım kararı, kullanıcı o kararın nasıl alındığını bilseydi de aynı seçimi
yapacaksa meşrudur. Kararın gücü kullanıcının bilgisizliğinden geliyorsa o karar bir
karanlık kalıptır.**

Ölçütün iki özelliği vardır. Birincisi, kullanıcının davranışını değiştirmeyi kendi
başına kusur saymaz — her tasarım kararı davranışı değiştirir; kayıtları uygunluğa göre
sıralamak da değiştirir. Kusur, değişimin bir yanlış inanç üzerine kurulmasıdır. İkincisi,
tasarımcının niyetini sormaz. Bir kalıp kazayla kurulmuş olabilir; ölçüt yine de aynı
sonucu verir ve düzeltme yükümlülüğü aynıdır.

**Karanlık kalıp (dark pattern)**, bu ölçütü sistematik olarak çiğneyen, kullanıcının
yanlış bilgisine dayanarak sonucu tasarımcının istediği yöne çeviren arayüz kalıbıdır.
Aşağıdaki beş kalıp bu dersin denetim listesidir.

**Acele ettirme**, kullanıcının düşünme süresini gerçek bir kısıt olmadan daraltan
kalıptır: sona ermeyen ya da her oturumda yeniden başlayan geri sayımlar.

**Gizli maliyet**, kullanıcının taahhüt ettiği bedelin bir kısmını taahhütten sonra
gösteren kalıptır.

**Zorlaştırılmış iptal**, bir duruma girmeyi kolay, çıkmayı orantısız biçimde zor yapan
kalıptır.

**Onay tuzağı**, kullanıcının onayladığını sandığı şeyle gerçekte onayladığı şeyin
ayrıştığı kalıptır: önceden işaretlenmiş kutular, ret seçeneğini görünmez kılan düzenler.

**Sahte kıtlık**, stok, süre ya da talep hakkında veriye dayanmayan bir azlık iddiasıdır.

Bunların hiçbiri burada uygulama tarifi olarak verilmemiştir; her biri **tanıma hedefi**
olarak tanımlanmıştır. Aşağıdaki hesap tanımayı ölçüye bağlar.

#### Göstergelerin Ölçülmesi

```js
// denetim.mjs — bir arayuzun karanlik kalip gostergelerinin olculmesi

// ---- 1) Caba asimetrisi: bir seye girmek ile cikmak arasindaki adim farki ----
const AKISLAR = [
  { ad: "odunc alma / iade", giris: 2, cikis: 2 },
  { ad: "teslim hatirlatmasi", giris: 1, cikis: 1 },
  { ad: "oneri bulteni", giris: 1, cikis: 4 },
  { ad: "uyelik", giris: 3, cikis: 7 },
];
console.log("akis                    giris adimi  cikis adimi  asimetri  esik (2x)");
for (const a of AKISLAR) {
  const asimetri = a.cikis / a.giris;
  console.log(
    `${a.ad.padEnd(23)} ${String(a.giris).padStart(11)} ${String(a.cikis).padStart(12)}` +
    ` ${(asimetri.toFixed(2) + "x").padStart(9)}  ${asimetri > 2 ? "ASILDI" : "gecti"}`
  );
}

// ---- 2) Gizli maliyet: ilk gorulen taahhut ile son toplam arasindaki fark ----
const MALIYETLER = [
  { ad: "odunc (ucretsiz)", ilk: 0, son: 0 },
  { ad: "gec iade cezasi", ilk: 0, son: 12 },
  { ad: "sube arasi tasima", ilk: 5, son: 5 },
  { ad: "rezervasyon + tasima + gecikme", ilk: 5, son: 23 },
];
console.log("\nkalem                            ilk gosterilen  son toplam  surpriz orani");
for (const m of MALIYETLER) {
  const surpriz = m.son === 0 ? 0 : (m.son - m.ilk) / m.son;
  console.log(
    `${m.ad.padEnd(32)} ${String(m.ilk).padStart(14)} ${String(m.son).padStart(11)}` +
    ` ${((surpriz * 100).toFixed(0) + " %").padStart(14)}  ${surpriz > 0.2 ? "ASILDI" : "gecti"}`
  );
}

// ---- 3) Kitlik iddiasinin veriyle bagi ----
// 12 kayit icin: gercek raf durumu ve arayuzde gosterilen "kalan nusha" iddiasi.
const GERCEK = [1, 4, 2, 7, 1, 3, 9, 2, 5, 1, 6, 8];
const IDDIALAR = {
  "veriden turetilen": [1, 4, 2, 7, 1, 3, 9, 2, 5, 1, 6, 8],
  "sabit uyari":       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  "kismen bagli":      [1, 3, 2, 3, 1, 3, 3, 2, 3, 1, 3, 3],
};
function korelasyon(a, b) {
  const n = a.length;
  const oa = a.reduce((x, y) => x + y, 0) / n, ob = b.reduce((x, y) => x + y, 0) / n;
  let pay = 0, pa = 0, pb = 0;
  for (let i = 0; i < n; i++) { pay += (a[i] - oa) * (b[i] - ob); pa += (a[i] - oa) ** 2; pb += (b[i] - ob) ** 2; }
  return pb === 0 ? 0 : pay / Math.sqrt(pa * pb);
}
console.log("\niddia bicimi          gercek stokla korelasyon  esik (0.9)");
for (const [ad, v] of Object.entries(IDDIALAR)) {
  const r = korelasyon(GERCEK, v);
  console.log(`${ad.padEnd(21)} ${r.toFixed(3).padStart(24)}  ${r >= 0.9 ? "gecti" : "ASILDI"}`);
}

// ---- 4) Geri sayimin gercek bir son tarihe bagli olup olmadigi ----
// Ayni kullanicinin ardisik oturumlarinda gorulen "kalan sure" (dakika).
const OTURUMLAR = {
  "gercek son tarih": [58, 41, 27, 12, 3],
  "her oturumda sifirlanan": [10, 10, 10, 10, 10],
  "sayfa yenilendiginde sifirlanan": [10, 10, 9, 10, 10],
};
console.log("\ngeri sayim                       oturumlar            azalan mi");
for (const [ad, v] of Object.entries(OTURUMLAR)) {
  let azalan = true;
  for (let i = 1; i < v.length; i++) if (v[i] >= v[i - 1]) azalan = false;
  console.log(`${ad.padEnd(32)} ${v.join(", ").padEnd(20)} ${azalan ? "evet" : "HAYIR"}`);
}

// ---- 5) Bes gosterge birlikte: bir tasarim kararinin denetimi ----
// Olcut: kullanici karari nasil alindigini bilseydi ayni secimi yapar miydi?
// Gostergeler tek tek olculur; biri bile asilirsa karar karanlik kalip sayilir.
const KARARLAR = [
  { ad: "teslim hatirlatmasi acik varsayilan", pismanlik: 0.128, asimetri: 1.0, surpriz: 0.0, kaynak: 1.00, geriSayim: null },
  { ad: "oneri bulteni acik varsayilan",       pismanlik: 0.188, asimetri: 4.0, surpriz: 0.0, kaynak: 1.00, geriSayim: null },
  { ad: "son nusha uyarisi (stoktan)",         pismanlik: 0.000, asimetri: 1.0, surpriz: 0.0, kaynak: 1.00, geriSayim: null },
  { ad: "son nusha uyarisi (sabit)",           pismanlik: 0.000, asimetri: 1.0, surpriz: 0.0, kaynak: 0.00, geriSayim: null },
  { ad: "rezervasyon geri sayimi",             pismanlik: 0.000, asimetri: 1.0, surpriz: 0.0, kaynak: 1.00, geriSayim: false },
  { ad: "gecikme cezasi son adimda",           pismanlik: 0.000, asimetri: 1.0, surpriz: 0.52, kaynak: 1.00, geriSayim: null },
];
const ESIKLER = { pismanlik: 0.15, asimetri: 2.0, surpriz: 0.20, kaynak: 0.90 };
console.log("\nkarar                                 asilan gosterge                 sonuc");
for (const k of KARARLAR) {
  const asilan = [];
  if (k.pismanlik > ESIKLER.pismanlik) asilan.push("pismanlik");
  if (k.asimetri > ESIKLER.asimetri) asilan.push("caba asimetrisi");
  if (k.surpriz > ESIKLER.surpriz) asilan.push("gizli maliyet");
  if (k.kaynak < ESIKLER.kaynak) asilan.push("dayanaksiz iddia");
  if (k.geriSayim === false) asilan.push("sahte aciliyet");
  console.log(
    `${k.ad.padEnd(37)} ${(asilan.length === 0 ? "-" : asilan.join(", ")).padEnd(31)}` +
    ` ${asilan.length === 0 ? "mesru" : "KARANLIK KALIP"}`
  );
}
```

```
akis                    giris adimi  cikis adimi  asimetri  esik (2x)
odunc alma / iade                 2            2     1.00x  gecti
teslim hatirlatmasi               1            1     1.00x  gecti
oneri bulteni                     1            4     4.00x  ASILDI
uyelik                            3            7     2.33x  ASILDI

kalem                            ilk gosterilen  son toplam  surpriz orani
odunc (ucretsiz)                              0           0            0 %  gecti
gec iade cezasi                               0          12          100 %  ASILDI
sube arasi tasima                             5           5            0 %  gecti
rezervasyon + tasima + gecikme                5          23           78 %  ASILDI

iddia bicimi          gercek stokla korelasyon  esik (0.9)
veriden turetilen                        1.000  gecti
sabit uyari                              0.000  ASILDI
kismen bagli                             0.807  ASILDI

geri sayim                       oturumlar            azalan mi
gercek son tarih                 58, 41, 27, 12, 3    evet
her oturumda sifirlanan          10, 10, 10, 10, 10   HAYIR
sayfa yenilendiginde sifirlanan  10, 10, 9, 10, 10    HAYIR

karar                                 asilan gosterge                 sonuc
teslim hatirlatmasi acik varsayilan   -                               mesru
oneri bulteni acik varsayilan         pismanlik, caba asimetrisi      KARANLIK KALIP
son nusha uyarisi (stoktan)           -                               mesru
son nusha uyarisi (sabit)             dayanaksiz iddia                KARANLIK KALIP
rezervasyon geri sayimi               sahte aciliyet                  KARANLIK KALIP
gecikme cezasi son adimda             gizli maliyet                   KARANLIK KALIP
```

#### Dört Göstergenin Okunması

**Çaba asimetrisi**, bir duruma girmek için gereken adım sayısının çıkmak için gereken
adım sayısına oranıdır. Ödünç alma ile iade her ikisi de iki adım; oran 1.00. Öneri
bülteni bir adımda açılıyor, dört adımda kapanıyor; oran 4.00. Bu ölçüm kütükten değil,
arayüzün kendisinden yapılır: iki akışı sayarak. Sayım hiçbir varsayım gerektirmediği için
en kolay denetlenen göstergedir.

**Sürpriz oranı**, son toplam bedelin taahhüt anında gösterilmemiş kısmının payıdır. Şube
arası taşıma ücreti baştan yazıldığı için oran sıfır. Gecikme cezası hiç gösterilmediği
için oran yüzde 100. Cezanın koşullu olması bir gerekçe değildir: kullanıcı ödünç alırken
gecikme durumunda ne olacağını bilmiyorsa, taahhüdünün bir kısmını görmemiştir.

**Kıtlık iddiasının veriyle bağı**, gösterilen azlık iddiasıyla gerçek stok arasındaki
korelasyondur. Veriden türetilen iddia 1.000 veriyor. Her kayda "son nüsha" yazan sabit
uyarı 0.000 veriyor — iddia hiçbir şeye karşılık gelmiyor. Üçüncü satır ara bir durumu
ölçüyor: iddia stokla kısmen ilişkili (0.807) ama stok üçün üstüne çıktığında sabitleniyor.
Kısmen doğru bir iddia, denetimi geçmez; kullanıcı sayıya baktığında onun bir ölçüm
olduğunu varsayar.

**Geri sayımın azalıyor olması**, aciliyetin gerçek bir son tarihe bağlı olup olmadığını
gösterir. Gerçek son tarihte ardışık oturumlarda görülen kalan süre azalır. Her oturumda
aynı değerden başlayan geri sayımda azalmaz. Üçüncü satır kolay kaçırılan bir biçimi
gösteriyor: değerler biraz oynuyor ama bir yöne gitmiyor; süre gerçekte akmıyor, yalnızca
akıyormuş gibi gösteriliyor.

#### Denetimin Sonucu ve Sınırları

Son tablo beş göstergeyi altı karara birlikte uyguluyor. Ödünç akışındaki kararlardan
ikisi bütün eşikleri geçiyor; dördü en az bir eşiği aşıyor. Denetim, hangi göstergenin
aşıldığını da yazdığı için doğrudan bir düzeltme listesi üretir: öneri bülteninin
varsayılanı kapatılır ve kapatma adımı bire indirilir; sabit uyarı stok verisine bağlanır
ya da kaldırılır; geri sayım gerçek bir son tarihe bağlanır ya da kaldırılır; gecikme
cezası ödünç onayı ekranında yazılır.

Denetimin sınırları açıkça belirtilmelidir.

**Eşikler bir uzlaşımdır.** Çaba asimetrisinde iki kat, sürpriz oranında yüzde 20,
korelasyonda 0.90 — bunlar hesaplanmış değil, seçilmiş değerlerdir. Değerlerin işlevi
tartışmayı denetime çevirmektir: eşik yazılıysa bir kararın onu aşıp aşmadığı tartışılmaz,
ölçülür. Eşiğin kendisi tartışılabilir ve tartışılmalıdır.

**Bütün eşikleri geçen bir karar yine de kusurlu olabilir.** Denetim, ölçülebilir izler
bırakan kalıpları yakalar. Kullanıcıyı utandıran bir ret metni ("hayır, tasarruf etmek
istemiyorum") hiçbir sayıyı bozmaz; onay tuzağının bu biçimi ancak metin okunarak
görülür. Denetim bir tarama aracıdır, bir kanıt değil.

**Hiçbir gösterge dönüşüm artışıyla dengelenemez.** Bir kalıbın ödünç alma sayısını
yükseltmesi, denetimden geçtiği anlamına gelmez; Varsayılanların Gücü dersinde ve
İlerleme dersinde ölçüldüğü gibi bu yükselişin kaynağı kullanıcının yanılmasıdır. Yanılma
üzerine kurulmuş bir sayının büyüklüğü, kararın gerekçesi olamaz.

#### Reddetmek

Bu konunun tamamı, tasarımcının kullanıcının kararı üzerinde ne kadar güç taşıdığını
göstermek içindi. Sonuç, gücün her tasarım kararında zaten kullanılıyor olmasıdır:
tarafsız bir varsayılan, tarafsız bir sıralama, tarafsız bir vurgu yoktur.

Bu yüzden mesleki tutum "etkilemekten kaçınmak" olamaz; kaçınmak mümkün değildir. Tutum
şudur:

**Kararın hangi göstergeyi yükselttiği yazılır.** Bir değişiklik önerildiğinde "neyi
artıracağı" açıkça söylenmelidir. Yükselen sayı ödünç alma mı, yoksa istemeden verilen
onay mı — bu ayrım yapılmadan tartışma yürütülemez.

**Ölçüt kullanıcı adına uygulanır.** Kullanıcı odada değildir; ölçütü onun yerine
uygulayacak olan tasarımcıdır. "Kullanıcı bunu bilseydi de aynı seçimi yapar mıydı"
sorusunun yanıtı hayırsa, karar reddedilir.

**Ret bir gerekçeyle verilir.** Yukarıdaki beş gösterge, reddin gerekçesini kişisel bir tercih
olmaktan çıkarıp denetlenebilir bir bulguya çevirir. "Bunu yapmak istemiyorum" yerine "bu kararın
çaba asimetrisi dört kat, eşik iki kat; kapatma adımı bire indirilebilir" denir.

**Meşru bir alternatif önerilir.** Denetimden kalan her kararın, aynı amacı ölçütü
çiğnemeden karşılayan bir karşılığı çoğu zaman vardır: sahte kıtlık yerine gerçek stok
bilgisi, zorlaştırılmış iptal yerine simetrik akış, gizli maliyet yerine taahhüt anında
tam bedel.

#### Özet

- Meşruluk ölçütü tektir: kullanıcı kararın nasıl alındığını bilseydi de aynı seçimi
  yapacaksa karar meşrudur; kararın gücü bilgisizlikten geliyorsa karanlık kalıptır.
- Beş kalıp tanıma hedefi olarak tanımlanır: acele ettirme, gizli maliyet, zorlaştırılmış
  iptal, onay tuzağı, sahte kıtlık.
- Dört gösterge ölçülebilir iz bırakır: çaba asimetrisi, sürpriz oranı, kıtlık iddiasının
  veriyle korelasyonu ve geri sayımın gerçekten azalıp azalmadığı.
- Denetim, aşılan göstergeyi yazdığı için doğrudan bir düzeltme listesi üretir; eşikler
  uzlaşımdır ve tartışmayı denetime çevirmek için yazılır.
- Denetim bir tarama aracıdır: bütün eşikleri geçen bir karar da kusurlu olabilir ve
  yükselen bir dönüşüm sayısı hiçbir göstergeyi dengelemez.
- Tasarımcının tutumu etkilemekten kaçınmak değil, kararın hangi sayıyı yükselttiğini
  yazmak, ölçütü kullanıcı adına uygulamak, reddi gerekçeye bağlamak ve meşru alternatifi
  önermektir.

#### Sonraki Adım

Bu konu boyunca ölçütün uygulanabilmesi için sürekli bir şeye ihtiyaç duyuldu:
kullanıcının bilgili tercihini, gerçek görev süresini, yararlı ziyaret oranını bilmeye.
Bunların hiçbiri tahminle elde edilmez. Sonraki konu ölçmeye ayrılmıştır ve en temel
soruyla başlar: bir arayüzün iyi olduğu nasıl gösterilir? Görev başarımı, süre ve hata
oranı nasıl ölçülür, bu üç sayı nasıl tek bir ölçüte indirgenir ve ortalamanın yanıltıcı
olduğu yerler nerelerdir?

## Ölçme

Görev başarımı, süre ve hata oranından bileşik ölçüt üretimi, dönüşüm hunisinde terk noktalarının saptanması, A/B ve çok değişkenli test tasarımı ve nicel bulgunun nitel gözlemle birleştirilmesi.

### Deneyim Ölçütleri

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/deneyim-olcutleri

Görev başarımının güven aralığıyla birlikte raporlanması, süre dağılımının çarpıklığı nedeniyle aritmetik ortalamanın yanıltması ve üç ölçütten ağırlıklı bileşik ölçüt üretilmesi.

Davranış Tasarımı konusu boyunca ölçütü uygulayabilmek için sürekli bir şeye ihtiyaç
duyuldu: kullanıcının bilgili tercihini, gerçek görev süresini, yararlı ziyaret oranını
bilmeye. Bunların hiçbiri tahminle elde edilmez.

Bu konu ölçmeye ayrılmıştır ve en temel soruyla başlar: bir arayüzün iyi olduğu nasıl
gösterilir? Kullanılabilirlik testinden çıkan ham kayıt üç sütun taşır — görev tamamlandı
mı, ne kadar sürdü, kaç hata yapıldı. Bu ders o üç sütunun nasıl okunduğunu ve ne zaman
yanılttığını ele alır.

#### Üç Temel Ölçüt

**Görev başarımı (task success)**, görevi tamamlayan katılımcı oranıdır. Tanımın işe
yaraması için "tamamlandı"nın önceden yazılmış olması gerekir. Katalog arayüzünde görev
"belirli bir cildi bulup ödünç almak" ise başarı ölçütü, doğru cildin ödünç kaydına
girmesidir; yanlış cildi ödünç alan katılımcı görevi tamamlamamıştır.

**Görev süresi (time on task)**, göreve başlama ile bitirme arasındaki süredir. Başarısız
oturumların süresi başarılı oturumlarınkiyle aynı havuzda toplanmaz: başarısız oturum
zaman sınırında kesilmiştir ve gerçek süresi bilinmez.

**Hata oranı (error rate)**, görev boyunca yapılan hatalı eylemlerin sayısıdır. Hata,
görevden uzaklaştıran her eylemdir: yanlış süzgeci uygulamak, yanlış kaydı açmak, geri
dönmek zorunda kalmak.

Aşağıdaki hesap on dört oturumluk bir kaydı bu üç ölçütle işliyor.

```js
// olcutler.mjs — gorev basarimi, sure ve hata oranindan bilesik olcut

// 14 oturumun ham kaydi: gorev tamamlandi mi, sure (sn), hata sayisi.
// Gorev: katalogda belirli bir cildi bulup odunc almak.
const OTURUMLAR = [
  ["K01", true, 42, 0], ["K02", true, 58, 1], ["K03", false, 180, 3],
  ["K04", true, 37, 0], ["K05", true, 91, 2], ["K06", true, 46, 0],
  ["K07", false, 180, 4], ["K08", true, 63, 1], ["K09", true, 39, 0],
  ["K10", true, 154, 2], ["K11", true, 51, 1], ["K12", false, 180, 2],
  ["K13", true, 44, 0], ["K14", true, 72, 1],
];

const n = OTURUMLAR.length;
const basarili = OTURUMLAR.filter(([, b]) => b);
const basariSayisi = basarili.length;

// ---- 1) Gorev basarimi ve Wilson guven araligi ----
function wilson(k, N, z = 1.96) {
  const p = k / N, d = 1 + z * z / N;
  const merkez = (p + z * z / (2 * N)) / d;
  const yari = (z * Math.sqrt(p * (1 - p) / N + z * z / (4 * N * N))) / d;
  return [merkez - yari, merkez + yari];
}
const [alt, ust] = wilson(basariSayisi, n);
console.log(`gorev basarimi: ${basariSayisi}/${n} = ${(basariSayisi / n * 100).toFixed(1)} %`);
console.log(`Wilson %95 guven araligi: [${(alt * 100).toFixed(1)} %, ${(ust * 100).toFixed(1)} %]`);

// ---- 2) Sure: aritmetik ortalama ile geometrik ortalama ----
const sureler = basarili.map(([, , s]) => s);
const aritmetik = sureler.reduce((a, b) => a + b, 0) / sureler.length;
const geometrik = Math.exp(sureler.reduce((a, s) => a + Math.log(s), 0) / sureler.length);
const sirali = [...sureler].sort((a, b) => a - b);
const ortanca = sirali.length % 2 ? sirali[(sirali.length - 1) / 2]
  : (sirali[sirali.length / 2 - 1] + sirali[sirali.length / 2]) / 2;
console.log(`\nbasarili oturum suresi (${sureler.length} oturum): ${sirali.join(", ")}`);
console.log(`aritmetik ortalama ${aritmetik.toFixed(1)} sn, geometrik ortalama ${geometrik.toFixed(1)} sn, ortanca ${ortanca.toFixed(1)} sn`);
console.log(`ortalamanin ustunde kalan oturum: ${sureler.filter((s) => s > aritmetik).length} / ${sureler.length}`);

// ---- 3) Hata orani ----
const toplamHata = OTURUMLAR.reduce((a, [, , , h]) => a + h, 0);
const hatasiz = OTURUMLAR.filter(([, , , h]) => h === 0).length;
console.log(`\ntoplam hata ${toplamHata}, oturum basina ${(toplamHata / n).toFixed(2)}, hatasiz oturum ${hatasiz}/${n}`);

// ---- 4) Uc olcutu tek sayiya indirgemek ----
// Her olcut once 0-1 araligina getirilir; sure ve hata ters cevrilir.
const SURE_HEDEFI = 40, SURE_TAVANI = 180, HATA_TAVANI = 4;
function oturumSkoru([, b, s, h]) {
  const basari = b ? 1 : 0;
  const sureSkoru = b ? Math.max(0, Math.min(1, (SURE_TAVANI - s) / (SURE_TAVANI - SURE_HEDEFI))) : 0;
  const hataSkoru = Math.max(0, 1 - h / HATA_TAVANI);
  return { basari, sureSkoru, hataSkoru, bilesik: 0.5 * basari + 0.3 * sureSkoru + 0.2 * hataSkoru };
}
console.log("\noturum  basari  sure  hata  sure skoru  hata skoru  bilesik");
for (const o of OTURUMLAR) {
  const s = oturumSkoru(o);
  console.log(
    `${o[0].padEnd(7)} ${(o[1] ? "evet" : "hayir").padEnd(7)} ${String(o[2]).padStart(4)} ${String(o[3]).padStart(5)}` +
    ` ${s.sureSkoru.toFixed(2).padStart(11)} ${s.hataSkoru.toFixed(2).padStart(11)} ${s.bilesik.toFixed(3).padStart(8)}`
  );
}
const bilesikler = OTURUMLAR.map((o) => oturumSkoru(o).bilesik);
const bOrt = bilesikler.reduce((a, b) => a + b, 0) / n;
const bSapma = Math.sqrt(bilesikler.reduce((a, b) => a + (b - bOrt) ** 2, 0) / (n - 1));
console.log(`bilesik olcut: ortalama ${bOrt.toFixed(3)}, standart sapma ${bSapma.toFixed(3)}, %95 aralik +-${(1.96 * bSapma / Math.sqrt(n)).toFixed(3)}`);

// ---- 5) Agirliklarin sonuca etkisi ----
console.log("\nagirlik (basari/sure/hata)  bilesik ortalama  en dusuk oturum");
const AGIRLIKLAR = [[0.5, 0.3, 0.2], [1.0, 0.0, 0.0], [0.34, 0.33, 0.33], [0.2, 0.6, 0.2]];
for (const [wb, ws, wh] of AGIRLIKLAR) {
  const skor = OTURUMLAR.map((o) => {
    const s = oturumSkoru(o);
    return wb * s.basari + ws * s.sureSkoru + wh * s.hataSkoru;
  });
  const ort = skor.reduce((a, b) => a + b, 0) / n;
  const enDusuk = OTURUMLAR[skor.indexOf(Math.min(...skor))][0];
  console.log(`${`${wb} / ${ws} / ${wh}`.padEnd(26)} ${ort.toFixed(3).padStart(16)} ${enDusuk.padStart(15)}`);
}
```

```
gorev basarimi: 11/14 = 78.6 %
Wilson %95 guven araligi: [52.4 %, 92.4 %]

basarili oturum suresi (11 oturum): 37, 39, 42, 44, 46, 51, 58, 63, 72, 91, 154
aritmetik ortalama 63.4 sn, geometrik ortalama 57.6 sn, ortanca 51.0 sn
ortalamanin ustunde kalan oturum: 3 / 11

toplam hata 17, oturum basina 1.21, hatasiz oturum 5/14

oturum  basari  sure  hata  sure skoru  hata skoru  bilesik
K01     evet      42     0        0.99        1.00    0.996
K02     evet      58     1        0.87        0.75    0.911
K03     hayir    180     3        0.00        0.25    0.050
K04     evet      37     0        1.00        1.00    1.000
K05     evet      91     2        0.64        0.50    0.791
K06     evet      46     0        0.96        1.00    0.987
K07     hayir    180     4        0.00        0.00    0.000
K08     evet      63     1        0.84        0.75    0.901
K09     evet      39     0        1.00        1.00    1.000
K10     evet     154     2        0.19        0.50    0.656
K11     evet      51     1        0.92        0.75    0.926
K12     hayir    180     2        0.00        0.50    0.100
K13     evet      44     0        0.97        1.00    0.991
K14     evet      72     1        0.77        0.75    0.881
bilesik olcut: ortalama 0.728, standart sapma 0.380, %95 aralik +-0.199

agirlik (basari/sure/hata)  bilesik ortalama  en dusuk oturum
0.5 / 0.3 / 0.2                       0.728             K07
1 / 0 / 0                             0.786             K03
0.34 / 0.33 / 0.33                    0.712             K07
0.2 / 0.6 / 0.2                       0.688             K07
```

#### Bir Oran Tek Başına Yanıltır

Görev başarımı 11/14, yani yüzde 78.6. Bu sayı bir raporda tek başına yazıldığında
kesinlik izlenimi verir. Wilson güven aralığı gerçeği söylüyor: yüzde 52.4 ile 92.4
arasında.

Aralık, on dört oturumun neyi belirleyip neyi belirlemediğini gösteriyor. Gerçek başarım
oranı yüzde 55 de olabilir, yüzde 90 da. Bu genişlikte bir aralık, "arayüz iyi mi" sorusuna
yanıt vermez. Yanıt verdiği soru başkadır: arayüz kullanıcıların yarısından fazlasında
işe yarıyor mu? Buna evet der.

Buradan iki kural çıkar. Birincisi, **oran her zaman güven aralığıyla yazılır**; aralıksız
bir oran, örneklem büyüklüğünü gizler. İkincisi, küçük örneklemli bir testin işi oran
kestirmek değil, sorun bulmaktır. Kullanılabilirlik testi az sayıda katılımcıyla sorunları
ortaya çıkarır; oranı hassas ölçmek için gereken katılımcı sayısı çok daha büyüktür.

Aralığın hesabında Wilson yönteminin kullanılması bir ayrıntı değil. Oranın standart
hatasına dayanan basit aralık, küçük örneklemlerde ve uçlara yakın oranlarda sınırların
dışına taşabilir; Wilson aralığı taşmaz ve küçük örneklemde daha güvenilirdir.

#### Süre Dağılımı Simetrik Değildir

Başarılı on bir oturumun süreleri 37 ile 154 saniye arasında. Aritmetik ortalama 63.4
saniye. Bu ortalamanın **üstünde yalnızca üç oturum** var; sekiz oturum altında.

Nedeni dağılımın çarpıklığıdır. Görev süresi aşağıdan sınırlıdır — hiçbir oturum sıfır
saniyeden kısa olamaz — ama yukarıdan sınırsızdır. Bir kullanıcı takılırsa süre iki üç
katına çıkar. Bu yapıdaki dağılımlarda aritmetik ortalama, birkaç uzun oturum tarafından
yukarı çekilir ve "tipik" kullanıcıyı temsil etmez.

Geometrik ortalama 57.6, ortanca 51.0 saniye. Ortanca, oturumların yarısının altında
kaldığı süredir ve tek bir uzun oturumdan etkilenmez. Geometrik ortalama, sürelerin
logaritmalarının ortalamasıdır; çarpık dağılımlarda merkezi aritmetik ortalamadan daha iyi
yakalar ve ortalamanın tersine, oturum sürelerinin oranlarıyla tutarlı davranır.

Kural: **süre raporlanırken ortanca ya da geometrik ortalama yazılır**; aritmetik ortalama
yazılacaksa dağılımın uçları da verilir. Katalog arayüzünde 154 saniyelik oturum bir aykırı değer
değil; ödünç akışında gerçek bir takılmanın izidir ve silinmez, ayrıca incelenir.

#### Bileşik Ölçüt ve Ağırlıkların Sınavı

Üç ölçüt ayrı ayrı raporlandığında karşılaştırma zorlaşır: bir tasarım başarımı
yükseltip süreyi uzatıyorsa hangisi iyidir? Bileşik ölçüt bu soruyu yanıtlamak için
kurulur.

Kurulum üç adımlıdır. Her ölçüt önce 0–1 aralığına getirilir; süre ve hata "yüksek kötüdür"
yönünde olduğu için ters çevrilir; sonra ağırlıklarla toplanır. Süre skoru için 40 saniye
hedef, 180 saniye tavan alınmış — bunlar ölçümden değil karardan gelen sayılardır ve
raporda yazılmaları gerekir.

Dördüncü tablo bileşik ölçütü oturum oturum veriyor. K10 oturumu görevi tamamlamış (başarı
1) ama 154 saniye sürmüş; bileşik değeri 0.656. K12 görevi tamamlayamamış ama az hata
yapmış; 0.100. Tek bir sayı, üç sütunun taşıdığı bilgiyi sıraya sokuyor.

Son tablo bileşik ölçütün en önemli sınavıdır: ağırlıklar değişirse sonuç değişir mi?
Ortalama bileşik değer 0.688 ile 0.786 arasında oynuyor — yüzde 14'lük bir aralık. Yani
**bileşik ölçütün mutlak düzeyi ağırlıklara bağlıdır ve tek başına anlam taşımaz.**

Aynı tabloda değişmeyen bir şey var: dört ağırlıklandırmanın üçünde en düşük oturum K07.
Sıralama ağırlıklara karşı daha dayanıklı. Bileşik ölçütün doğru kullanımı budur:
**iki tasarımı ya da iki oturumu sıralamak için kullanılır, bir eşiğe karşı ölçmek için
değil.** "Bileşik ölçüt 0.75'in üstünde olsun" biçiminde bir hedef, ağırlıkları seçen
kişinin hedefi belirlemesi anlamına gelir.

Bileşik değerin standart sapması 0.380 ve on dört oturumdaki yüzde 95 aralığı ±0.199.
Bu genişlik, iki tasarım arasında 0.2'den küçük bir bileşik farkın on dört oturumla
ayırt edilemeyeceğini söyler.

#### Ölçütlerin Birlikte Raporlanması

**Ham sayılar bileşikle birlikte verilir.** Bileşik ölçüt hangi bileşenin değiştiğini
gizler; başarımı düşürüp süreyi kısaltan bir değişiklik bileşikte iyileşme gösterebilir.

**Ağırlıklar ve eşikler yazılır.** Süre hedefi, süre tavanı, hata tavanı ve üç ağırlık
raporun parçasıdır. Yazılmadıklarında bileşik değer denetlenemez.

**Başarısız oturumlar süre havuzuna girmez.** Zaman sınırında kesilen oturumun süresi
ölçülmemiştir; havuza katılırsa süre dağılımını hem yukarı çeker hem de yapay bir tavan
üretir.

**Sorun listesi ölçütlerin yerine geçmez.** Bu ders sayıları ele aldı; sayılar hangi
adımın kötü olduğunu söylemez. O soru sonraki dersin konusudur.

#### Özet

- Görev başarımı oranı güven aralığıyla yazılır; on dört oturumdaki yüzde 78.6'lık başarım
  yüzde 52.4–92.4 aralığına karşılık gelir ve oran kestirmeye yetmez.
- Görev süresi dağılımı sağa çarpıktır; aritmetik ortalamanın üstünde on bir oturumdan
  yalnızca üçü kaldı, dolayısıyla ortanca ya da geometrik ortalama raporlanır.
- Başarısız oturumların süresi zaman sınırında kesilmiştir ve süre havuzuna katılmaz.
- Bileşik ölçüt üç ölçütü 0–1 aralığına getirip ağırlıklarla toplar; hedef, tavan ve
  ağırlık değerleri ölçümden değil karardan gelir ve raporda yazılır.
- Bileşik ölçütün mutlak düzeyi ağırlıklara duyarlıdır (0.688–0.786), sıralaması daha
  dayanıklıdır; bu yüzden karşılaştırma için kullanılır, eşik için değil.
- Ölçütlerin belirsizliği ölçülür: bileşik değerin yüzde 95 aralığı ±0.199, yani bundan
  küçük farklar bu örneklemle ayırt edilemez.

#### Sonraki Adım

Bu ders bir görevin bütününü ölçtü: tamamlandı mı, ne kadar sürdü, kaç hata yapıldı.
Ölçmediği şey, tamamlanmayan görevin **nerede** kaldığı. Üç başarısız oturumun üçü de
aynı adımda mı takıldı, yoksa üç ayrı yerde mi? Sonraki ders ödünç alma akışını adımlara
bölüp her adımdaki terki ayrı ayrı ölçer, en büyük kaybın hangi adımda olduğunu bulur ve
en yüksek terk oranı ile en çok kullanıcı kaybının aynı adım olmayabileceğini gösterir.

### Dönüşüm Hunisi

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/donusum-hunisi

Ödünç alma akışının adım adım terk çözümlemesi, en yüksek terk oranı ile en çok kullanıcı kaybının farklı adımlarda olması ve toplulaştırılmış huninin kesim farklarını gizlemesi.

Önceki ders bir görevin bütününü ölçtü: tamamlandı mı, ne kadar sürdü, kaç hata yapıldı.
On dört oturumun üçü görevi tamamlayamamıştı. Ölçülmeyen şey, o üç oturumun **nerede**
kaldığı.

Bu soru küçük örneklemli testle değil, tüm kullanıcıların davranış kaydıyla yanıtlanır.
**Dönüşüm hunisi (conversion funnel)**, bir görevi sıralı adımlara bölüp her adımı kaç
kullanıcının geçtiğini sayan çözümlemedir. Katalog arayüzünde huninin adımları ödünç alma
akışıdır: arama, sonuç listesi, kayıt ayrıntısı, nüsha seçimi, ödünç onayı, tamamlanma.

#### Huninin Üç Sütunu

Her adım için üç ayrı sayı vardır ve karıştırılırlar.

**Adım dönüşümü (step conversion)**, bir adıma girenlerin sonrakine geçme oranıdır.

**Terk oranı (drop-off rate)**, aynı adımda ayrılanların oranıdır; adım dönüşümünün
tümleyenidir.

**Kümülatif dönüşüm**, ilk adıma girenlerin o adıma kadar ulaşma oranıdır. Genel dönüşüm,
adım dönüşümlerinin **çarpımıdır** — huninin en önemli yapısal özelliği budur.

```js
// huni.mjs — odunc alma akisinin adim adim terk cozumlemesi

const HUNI = [
  ["arama yapildi", 10000],
  ["sonuc listesi goruldu", 8200],
  ["kayit ayrintisi acildi", 5330],
  ["nusha secildi", 4530],
  ["odunc onayi acildi", 2500],
  ["odunc tamamlandi", 2350],
];

function wilson(k, N, z = 1.96) {
  const p = k / N, d = 1 + z * z / N;
  const m = (p + z * z / (2 * N)) / d;
  const y = (z * Math.sqrt(p * (1 - p) / N + z * z / (4 * N * N))) / d;
  return [m - y, m + y];
}

console.log("adim                       giren  cikan  adim donusumu  terk orani  kaybedilen  kumulatif");
for (let i = 1; i < HUNI.length; i++) {
  const giren = HUNI[i - 1][1], cikan = HUNI[i][1];
  const oran = cikan / giren;
  const [a, u] = wilson(cikan, giren);
  console.log(
    `${HUNI[i][0].padEnd(24)} ${String(giren).padStart(6)} ${String(cikan).padStart(6)}` +
    ` ${((oran * 100).toFixed(1) + " %").padStart(14)} ${(((1 - oran) * 100).toFixed(1) + " %").padStart(11)}` +
    ` ${String(giren - cikan).padStart(11)} ${((cikan / HUNI[0][1] * 100).toFixed(1) + " %").padStart(10)}` +
    `   [${(a * 100).toFixed(1)}, ${(u * 100).toFixed(1)}]`
  );
}
const genel = HUNI[HUNI.length - 1][1] / HUNI[0][1];
console.log(`genel donusum: ${(genel * 100).toFixed(2)} %`);

// En buyuk terk orani ile en buyuk kullanici kaybi ayni adim mi
let enYuksekOran = 1, enYuksekOranAdim = "", enCokKayip = 0, enCokKayipAdim = "";
for (let i = 1; i < HUNI.length; i++) {
  const oran = HUNI[i][1] / HUNI[i - 1][1], kayip = HUNI[i - 1][1] - HUNI[i][1];
  if (oran < enYuksekOran) { enYuksekOran = oran; enYuksekOranAdim = HUNI[i][0]; }
  if (kayip > enCokKayip) { enCokKayip = kayip; enCokKayipAdim = HUNI[i][0]; }
}
console.log(`\nen yuksek terk orani: ${enYuksekOranAdim} (${((1 - enYuksekOran) * 100).toFixed(1)} %)`);
console.log(`en cok kullanici kaybi: ${enCokKayipAdim} (${enCokKayip} kullanici)`);

// Her adimi 0.98'e cikarmanin genel donusume etkisi (huni carpimsaldir)
console.log("\nadim                       simdiki oran  0.98'e cikarsa genel donusum  bagil kazanc");
for (let i = 1; i < HUNI.length; i++) {
  const oran = HUNI[i][1] / HUNI[i - 1][1];
  const yeni = genel * (0.98 / oran);
  console.log(
    `${HUNI[i][0].padEnd(24)} ${((oran * 100).toFixed(1) + " %").padStart(13)}` +
    ` ${((yeni * 100).toFixed(2) + " %").padStart(28)} ${("x" + (yeni / genel).toFixed(2)).padStart(13)}`
  );
}

// Toplulastirilmis huni iki kesimi gizleyebilir
const KESIMLER = {
  "ilk kez gelen": [6000, 4800, 2900, 2400, 900, 820],
  "kayitli kullanici": [4000, 3400, 2430, 2130, 1600, 1530],
};
console.log("\nkesim               n     adim donusumleri                          genel");
for (const [ad, v] of Object.entries(KESIMLER)) {
  const oranlar = [];
  for (let i = 1; i < v.length; i++) oranlar.push((v[i] / v[i - 1] * 100).toFixed(1) + "%");
  console.log(`${ad.padEnd(19)} ${String(v[0]).padStart(5)} ${oranlar.join("  ").padEnd(40)} ${(v[v.length - 1] / v[0] * 100).toFixed(2)} %`);
}
const toplam = HUNI.map((_, i) => Object.values(KESIMLER).reduce((a, v) => a + v[i], 0));
const toplamOran = [];
for (let i = 1; i < toplam.length; i++) toplamOran.push((toplam[i] / toplam[i - 1] * 100).toFixed(1) + "%");
console.log(`${"toplulastirilmis".padEnd(19)} ${String(toplam[0]).padStart(5)} ${toplamOran.join("  ").padEnd(40)} ${(toplam[5] / toplam[0] * 100).toFixed(2)} %`);

// Dorduncu adimda iki kesimin farki gercek mi
const [a1, u1] = wilson(KESIMLER["ilk kez gelen"][4], KESIMLER["ilk kez gelen"][3]);
const [a2, u2] = wilson(KESIMLER["kayitli kullanici"][4], KESIMLER["kayitli kullanici"][3]);
console.log(`\nodunc onayina gecis  ilk kez gelen [${(a1 * 100).toFixed(1)}, ${(u1 * 100).toFixed(1)}]  kayitli [${(a2 * 100).toFixed(1)}, ${(u2 * 100).toFixed(1)}]  araliklar ${u1 < a2 || u2 < a1 ? "ayrik" : "ortusuyor"}`);
```

```
adim                       giren  cikan  adim donusumu  terk orani  kaybedilen  kumulatif
sonuc listesi goruldu     10000   8200         82.0 %      18.0 %        1800     82.0 %   [81.2, 82.7]
kayit ayrintisi acildi     8200   5330         65.0 %      35.0 %        2870     53.3 %   [64.0, 66.0]
nusha secildi              5330   4530         85.0 %      15.0 %         800     45.3 %   [84.0, 85.9]
odunc onayi acildi         4530   2500         55.2 %      44.8 %        2030     25.0 %   [53.7, 56.6]
odunc tamamlandi           2500   2350         94.0 %       6.0 %         150     23.5 %   [93.0, 94.9]
genel donusum: 23.50 %

en yuksek terk orani: odunc onayi acildi (44.8 %)
en cok kullanici kaybi: kayit ayrintisi acildi (2870 kullanici)

adim                       simdiki oran  0.98'e cikarsa genel donusum  bagil kazanc
sonuc listesi goruldu           82.0 %                      28.09 %         x1.20
kayit ayrintisi acildi          65.0 %                      35.43 %         x1.51
nusha secildi                   85.0 %                      27.10 %         x1.15
odunc onayi acildi              55.2 %                      41.73 %         x1.78
odunc tamamlandi                94.0 %                      24.50 %         x1.04

kesim               n     adim donusumleri                          genel
ilk kez gelen        6000 80.0%  60.4%  82.8%  37.5%  91.1%        13.67 %
kayitli kullanici    4000 85.0%  71.5%  87.7%  75.1%  95.6%        38.25 %
toplulastirilmis    10000 82.0%  65.0%  85.0%  55.2%  94.0%        23.50 %

odunc onayina gecis  ilk kez gelen [35.6, 39.5]  kayitli [73.2, 76.9]  araliklar ayrik
```

#### En Yüksek Terk Oranı ile En Büyük Kayıp Aynı Adım Değildir

İlk tablo iki farklı "en kötü adım" veriyor. Terk oranı en yüksek adım ödünç onayına
geçiş: yüzde 44.8. En çok kullanıcı kaybeden adım ise kayıt ayrıntısının açılması: 2870
kullanıcı.

Fark, adımların farklı büyüklükteki kitlelerle çalışmasından gelir. Kayıt ayrıntısı
adımına 8200 kullanıcı giriyor; yüzde 35'lik terk 2870 kişi ediyor. Ödünç onayı adımına
4530 kullanıcı giriyor; daha yüksek olan yüzde 44.8'lik terk 2030 kişi ediyor.

İki sayı iki farklı soruya yanıt verir. Terk oranı **adımın kendisinin ne kadar kötü
olduğunu** söyler; kaybedilen kullanıcı sayısı **o adımın toplam kayba katkısını**
söyler. Bir rapor yalnız birini yazarsa, okuyan kişi diğerini varsayar.

#### Çarpımsal Huni ve İyileştirme Payı

İkinci tablo hangi adıma müdahale edileceğini belirliyor ve yanıt üçüncü bir sıralama
veriyor.

Genel dönüşüm adım oranlarının çarpımı olduğu için, bir adımın oranını $r$'den $r'$'ye
çıkarmak genel dönüşümü $r'/r$ katına çıkarır. Bu oran yalnızca o adımın **mevcut
oranına** bağlıdır; adıma kaç kullanıcının girdiğine bağlı değildir.

Tabloda her adımın oranı 0.98'e çıkarılırsa ne olacağı hesaplanmış. En büyük bağıl kazanç
ödünç onayı adımından geliyor: x1.78, yani genel dönüşüm yüzde 23.50'den 41.73'e. Kayıt
ayrıntısı adımı — en çok kullanıcı kaybeden adım — x1.51 veriyor. Tamamlanma adımı, oranı
zaten yüzde 94 olduğu için yalnızca x1.04.

Kural: **iyileştirme payı en düşük oranlı adımdadır**, en çok kullanıcı kaybeden adımda
değil. Sezgi ters yönde çalışır; en çok kişinin ayrıldığı yer en acil sorun gibi görünür.

Hesabın iki varsayımı yazılmalıdır. Birincisi, adımlar birbirinden bağımsız
sayılmıştır: bir adımın iyileştirilmesi sonraki adımların oranını değiştirmez. Gerçekte
değiştirebilir — daha çok kararsız kullanıcıyı bir sonraki adıma taşımak o adımın oranını
düşürebilir. İkincisi, 0.98 hedefi ulaşılabilirlik hesabı değil, ortak bir tavan olarak
seçilmiştir; her adım oraya çıkarılamaz. Tablo bir öncelik sıralaması verir, bir vaat
değil.

#### Toplulaştırılmış Huni Kesimleri Gizler

Üçüncü tablo huninin en yaygın hatasını gösteriyor. Ödünç onayına geçiş adımının
toplulaştırılmış oranı yüzde 55.2. Aynı adım, ilk kez gelen kullanıcılarda yüzde 37.5,
kayıtlı kullanıcılarda yüzde 75.1.

Yüzde 55.2 hiçbir kullanıcı kesimini tarif etmiyor; iki farklı davranışın karışım
oranından doğan bir sayı. Bu adıma yapılacak müdahale ilk kez gelen kullanıcıya göre
tasarlanmalı; toplulaştırılmış sayıya bakan biri sorunun büyüklüğünü yarı yarıya
küçümser.

Son satır farkın gerçek olup olmadığını sınıyor. İlk kez gelen kesimin yüzde 95 güven
aralığı [35.6, 39.5], kayıtlı kesimin [73.2, 76.9]. Aralıklar ayrık; fark örneklem
dalgalanmasıyla açıklanamaz.

Bu ayrım, davranış tasarımı konusundaki çerçeveye doğrudan bağlanır. İlk kez gelen
kullanıcı ödünç onayı ekranında üye kaydı, teslim şubesi ve süre kararlarıyla karşılaşır;
kayıtlı kullanıcının bu kararları zaten verilmiştir. Yetenek farkı bir motivasyon farkı
değildir ve motivasyon artırmaya çalışan bir müdahale bu adımda işe yaramaz.

#### Huniyi Kurmanın Kuralları

**Adımlar kullanıcının görevine göre tanımlanır.** "Sayfa görüntülendi" bir adım değildir;
"nüsha seçildi" adımdır. Arayüzün iç olaylarına göre kurulan huni, kullanıcının nerede
takıldığını değil sistemin ne kaydettiğini gösterir.

**Terk oranı ile kayıp sayısı birlikte yazılır.** Biri adımın kalitesini, diğeri katkısını
verir.

**Her adım oranı güven aralığıyla verilir.** Onbinlik bir huninin son adımlarında
kullanıcı sayısı hızla azalır; son adımlardaki oranlar daha belirsizdir.

**Huni en az bir boyutta ayrıştırılır.** İlk kez gelen ile kayıtlı kullanıcı, dar ekran
ile geniş ekran, arama ile gezinmeyle gelen. Ayrıştırma yapılmadan bulunan "en kötü adım"
çoğu zaman bir karışım etkisidir.

**Huni nedeni söylemez.** Ödünç onayı adımında ilk kez gelenlerin yüzde 62.5'i çıkıyor;
niçin çıktıkları bu tabloda yok. Huni, hangi adıma bakılacağını söyler.

#### Özet

- Dönüşüm hunisi görevi sıralı adımlara böler; genel dönüşüm adım oranlarının çarpımıdır.
- En yüksek terk oranı ile en çok kullanıcı kaybı farklı adımlarda olabilir: hesapta
  ödünç onayı adımı yüzde 44.8 terkle en kötü oran, kayıt ayrıntısı adımı 2870 kullanıcıyla
  en büyük kayıp.
- İyileştirme payı adımın mevcut oranına bağlıdır, kullanıcı sayısına değil; en düşük
  oranlı adımı 0.98'e çıkarmak genel dönüşümü x1.78, en çok kayıp veren adımı çıkarmak
  x1.51 katına taşıyor.
- Hesap adımları bağımsız varsayar ve 0.98'i ortak tavan alır; çıktısı bir öncelik
  sıralamasıdır, ulaşılabilir bir hedef değil.
- Toplulaştırılmış huni kesimleri gizler: yüzde 55.2'lik adım oranı, yüzde 37.5 ile 75.1
  arasında iki ayrı davranışın karışımıdır ve güven aralıkları ayrıktır.
- Huni hangi adıma bakılacağını söyler, o adımda ne olduğunu söylemez.

#### Sonraki Adım

Huni bir adımın kötü olduğunu gösterdiğinde sıradaki iş bir değişiklik denemektir. Ama
değişiklikten sonra ölçülen sayının farklı çıkması, değişikliğin işe yaradığı anlamına
gelmez; huni oranları haftadan haftaya kendiliğinden oynar. Sonraki ders bu ayrımı kurar:
bir değişikliği denemek için kaç kullanıcı gerekir, ölçülen fark ne zaman gerçektir,
deneyi erken durdurmak yanlış sonucu niçin şişirir ve aynı anda birkaç değişikliği sınamak
hangi düzeltmeyi gerektirir?

### A/B ve Çok Değişkenli Test

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/ab-ve-cok-degiskenli-test

Örneklem büyüklüğünün saptanmak istenen farkla ilişkisi, oran farkının güven aralığı, erken durdurmanın yanlış pozitif oranını şişirmesi ve çok değişkenli testte çoklu karşılaştırma düzeltmesi.

Önceki ders ödünç alma akışının en zayıf adımını buldu: ödünç onayına geçiş, yüzde 55.2.
Sıradaki iş bir değişiklik denemektir. Ama değişiklikten sonra ölçülen oranın farklı
çıkması, değişikliğin işe yaradığı anlamına gelmez — huni oranları hiçbir şey
değişmeden de haftadan haftaya oynar.

**A/B testi (A/B test)**, kullanıcıları rastgele iki gruba ayırıp birine mevcut arayüzü,
diğerine değiştirilmiş arayüzü göstererek farkı ölçen deneydir. Bu ders deneyin dört
sorusunu ele alır: kaç kullanıcı gerekir, ölçülen fark ne zaman gerçektir, deney niçin
erken durdurulmaz ve birkaç değişiklik aynı anda nasıl sınanır?

#### Dört Hesap

```js
// deney.mjs — ornekleme buyuklugu, guven araligi, erken durdurma ve coklu karsilastirma

function uretec(tohum) {
  let s = tohum >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; };
}

// Normal dagilim islevleri (Abramowitz-Stegun yaklasimi + ikili arama ile ters alma)
function normalDagilim(x) {
  const t = 1 / (1 + 0.2316419 * Math.abs(x));
  const d = 0.3989422804014327 * Math.exp(-x * x / 2);
  const p = d * t * (0.319381530 + t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + t * 1.330274429))));
  return x >= 0 ? 1 - p : p;
}
function z(p) {
  let alt = -10, ust = 10;
  for (let i = 0; i < 200; i++) {
    const orta = (alt + ust) / 2;
    if (normalDagilim(orta) < p) alt = orta; else ust = orta;
  }
  return (alt + ust) / 2;
}

// ---- 1) Ornekleme buyuklugu: iki oran arasindaki farki saptamak icin ----
// Huni dersinden: odunc onayi adiminin mevcut orani 0.552.
const TEMEL = 0.552;
function ornekBuyuklugu(p1, p2, alfa = 0.05, guc = 0.80) {
  const za = z(1 - alfa / 2), zb = z(guc);
  const ort = (p1 + p2) / 2;
  const pay = za * Math.sqrt(2 * ort * (1 - ort)) + zb * Math.sqrt(p1 * (1 - p1) + p2 * (1 - p2));
  return Math.ceil((pay * pay) / ((p1 - p2) ** 2));
}
console.log("saptanmak istenen fark  hedef oran  grup basina kullanici  toplam");
for (const fark of [0.01, 0.02, 0.03, 0.05, 0.08]) {
  const n = ornekBuyuklugu(TEMEL, TEMEL + fark);
  console.log(
    `${((fark * 100).toFixed(0) + " puan").padStart(22)} ${((TEMEL + fark).toFixed(3)).padStart(11)}` +
    ` ${String(n).padStart(22)} ${String(2 * n).padStart(7)}`
  );
}
console.log(`(temel oran ${TEMEL}, alfa 0.05 cift yonlu, guc 0.80)`);

// ---- 2) Oran farkinin guven araligi ----
console.log("\nA grubu        B grubu        fark      %95 guven araligi        sonuc");
const DENEYLER = [
  { na: 2000, ka: 1104, nb: 2000, kb: 1160 },
  { na: 2000, ka: 1104, nb: 2000, kb: 1260 },
  { na: 8000, ka: 4416, nb: 8000, kb: 4640 },
];
for (const d of DENEYLER) {
  const pa = d.ka / d.na, pb = d.kb / d.nb, fark = pb - pa;
  const se = Math.sqrt(pa * (1 - pa) / d.na + pb * (1 - pb) / d.nb);
  const [alt, ust] = [fark - 1.96 * se, fark + 1.96 * se];
  console.log(
    `${(d.ka + "/" + d.na).padEnd(14)} ${(d.kb + "/" + d.nb).padEnd(14)} ${((fark * 100).toFixed(2) + " p").padStart(8)}` +
    `  [${(alt * 100).toFixed(2)}, ${(ust * 100).toFixed(2)}] puan   ${alt > 0 || ust < 0 ? "fark var" : "belirsiz"}`
  );
}

// ---- 3) Erken durdurma: gercekte fark yokken kac kez "fark var" denir ----
const KOSU = 2000, GRUP = 8000, ARA = 500;
function aaDenemesi(rnd, kontrolNoktalari) {
  let ka = 0, kb = 0, sinyal = false;
  for (let i = 1; i <= GRUP; i++) {
    if (rnd() < TEMEL) ka++;
    if (rnd() < TEMEL) kb++;
    if (kontrolNoktalari && i % ARA === 0 && i >= ARA * 2) {
      if (Math.abs(zDegeri(ka, i, kb, i)) > 1.96) { sinyal = true; break; }
    }
  }
  if (!kontrolNoktalari) sinyal = Math.abs(zDegeri(ka, GRUP, kb, GRUP)) > 1.96;
  return sinyal;
}
function zDegeri(ka, na, kb, nb) {
  const pa = ka / na, pb = kb / nb, ort = (ka + kb) / (na + nb);
  const se = Math.sqrt(ort * (1 - ort) * (1 / na + 1 / nb));
  return se === 0 ? 0 : (pb - pa) / se;
}
console.log("\nA/A deneyi (iki grup da ayni arayuz, gercek fark sifir)");
for (const ara of [false, true]) {
  const rnd = uretec(20260909);
  let sinyalli = 0;
  for (let k = 0; k < KOSU; k++) if (aaDenemesi(rnd, ara)) sinyalli++;
  console.log(
    `${(ara ? `her ${ARA} kullanicida bakilirsa` : "yalniz sonda bakilirsa").padEnd(32)}` +
    ` yanlis "fark var": ${(sinyalli / KOSU * 100).toFixed(1)} % (${sinyalli}/${KOSU})`
  );
}

// ---- 4) Coklu karsilastirma: cok degiskenli testte aile duzeyi hata ----
console.log("\nkarsilastirma  duzeltmesiz aile hatasi  Bonferroni alfa  Sidak alfa");
for (const k of [1, 3, 7, 15]) {
  const aile = 1 - Math.pow(0.95, k);
  console.log(
    `${String(k).padStart(13)} ${((aile * 100).toFixed(1) + " %").padStart(23)}` +
    ` ${(0.05 / k).toFixed(4).padStart(16)} ${(1 - Math.pow(0.95, 1 / k)).toFixed(4).padStart(11)}`
  );
}

// 2x2x2 cok degiskenli test: 8 birlesim, kontrole karsi 7 karsilastirma
const K = 7, DUZELTILMIS = 0.05 / K;
console.log(`\n2x2x2 cok degiskenli test: 8 birlesim, ${K} karsilastirma`);
console.log(`duzeltmesiz aile hatasi ${((1 - Math.pow(0.95, K)) * 100).toFixed(1)} %, Bonferroni alfa ${DUZELTILMIS.toFixed(4)}`);
console.log(`duzeltilmis alfa ile 2 puanlik farki saptamak icin grup basina ${ornekBuyuklugu(TEMEL, TEMEL + 0.02, DUZELTILMIS)} kullanici`);
console.log(`8 birlesim icin toplam ${8 * ornekBuyuklugu(TEMEL, TEMEL + 0.02, DUZELTILMIS)} kullanici`);
console.log(`duzeltmesiz ve tek karsilastirmali A/B testinde toplam ${2 * ornekBuyuklugu(TEMEL, TEMEL + 0.02)} kullanici`);
```

```
saptanmak istenen fark  hedef oran  grup basina kullanici  toplam
                1 puan       0.562                  38734   77468
                2 puan       0.572                   9660   19320
                3 puan       0.582                   4282    8564
                5 puan       0.602                   1532    3064
                8 puan       0.632                    592    1184
(temel oran 0.552, alfa 0.05 cift yonlu, guc 0.80)

A grubu        B grubu        fark      %95 guven araligi        sonuc
1104/2000      1160/2000        2.80 p  [-0.27, 5.87] puan   belirsiz
1104/2000      1260/2000        7.80 p  [4.76, 10.84] puan   fark var
4416/8000      4640/8000        2.80 p  [1.26, 4.34] puan   fark var

A/A deneyi (iki grup da ayni arayuz, gercek fark sifir)
yalniz sonda bakilirsa           yanlis "fark var": 5.7 % (114/2000)
her 500 kullanicida bakilirsa    yanlis "fark var": 20.4 % (408/2000)

karsilastirma  duzeltmesiz aile hatasi  Bonferroni alfa  Sidak alfa
            1                   5.0 %           0.0500      0.0500
            3                  14.3 %           0.0167      0.0170
            7                  30.2 %           0.0071      0.0073
           15                  53.7 %           0.0033      0.0034

2x2x2 cok degiskenli test: 8 birlesim, 7 karsilastirma
duzeltmesiz aile hatasi 30.2 %, Bonferroni alfa 0.0071
duzeltilmis alfa ile 2 puanlik farki saptamak icin grup basina 15351 kullanici
8 birlesim icin toplam 122808 kullanici
duzeltmesiz ve tek karsilastirmali A/B testinde toplam 19320 kullanici
```

#### Örneklem Büyüklüğü Deneyden Önce Hesaplanır

İlk tablo, deneyin en çok atlanan adımını veriyor: kaç kullanıcı gerektiği, **kullanıcılar
gelmeden önce** hesaplanır.

Hesap dört girdi ister. Temel oran (0.552, huni dersinden), saptanmak istenen en küçük
fark, yanlış pozitif oranı $\alpha$ (0.05) ve güç (0.80 — gerçek bir fark varsa onu
yakalama olasılığı).

Tablonun taşıdığı asıl bilgi ölçek ilişkisidir: gereken örneklem, saptanmak istenen farkın
**karesiyle ters orantılıdır**. Sekiz puanlık bir farkı yakalamak grup başına 592
kullanıcı ister; bir puanlık farkı yakalamak 38734. Farkı sekizde birine indirmek örneklemi
altmış beş katına çıkarıyor.

Bunun pratik karşılığı, deneyin küçük iyileştirmeler için pahalı olmasıdır. Katalog
arayüzü haftada beş bin ödünç onayı görüyorsa, iki puanlık bir farkı ölçmek yaklaşık dört
hafta sürer; bir puanlık farkı ölçmek on beş hafta. Deneyin süresi, denenmek istenen
değişikliğin büyüklüğüne bağlıdır ve bu süre çıkmıyorsa deney yapılmaz — değişiklik başka
bir gerekçeyle savunulur ya da savunulmaz.

#### Aynı Fark, İki Farklı Sonuç

İkinci tablo, "fark var mı" sorusunun neye bağlı olduğunu gösteriyor. Birinci ve üçüncü
satırdaki ölçülen fark **birebir aynı**: 2.80 puan. Birinci satırda 2000'lik gruplarla
güven aralığı [-0.27, 5.87] ve sıfırı içeriyor; sonuç belirsiz. Üçüncü satırda 8000'lik
gruplarla aralık [1.26, 4.34] ve sıfırı içermiyor; fark var.

Aradaki tek fark örneklem büyüklüğü. "Yüzde 2.8'lik bir iyileşme ölçtük" cümlesi, örneklem
yazılmadan hiçbir şey söylemez.

İkinci satır ise karşıt durumu veriyor: 7.80 puanlık büyük bir fark, 2000'lik gruplarla
bile aralığın dışında kalıyor. Büyük etkiler küçük örneklemle saptanabilir; ilk tablodaki
ilişkinin aynısı.

Güven aralığının genişliği ayrıca bir karar bilgisi taşır. Üçüncü satırda gerçek fark 1.26
ile 4.34 puan arasında; değişikliğin maliyeti yalnızca 4 puanlık bir kazançta karşılanıyorsa
aralık bu kararı vermeye yetmez. "İstatistiksel olarak anlamlı" ile "kararı değiştirecek
kadar büyük" aynı şey değildir.

#### Erken Durdurma Yanlış Pozitifi Şişirir

Üçüncü hesap bir A/A deneyi kuruyor: iki grup da aynı arayüzü görüyor, gerçek fark sıfır.
Doğru çalışan bir sınama bu durumda kullanıcıların yüzde 5'inde yanlışlıkla "fark var"
demelidir.

Yalnızca deneyin sonunda bakıldığında oran yüzde 5.7 çıkıyor — beklenen yüzde 5'e yakın;
aradaki fark iki bin koşunun benzetim dalgalanmasıdır. Her 500 kullanıcıda bir bakılıp
sınır aşıldığında durulduğunda oran **yüzde 20.4**'e çıkıyor. Hiçbir gerçek fark yokken,
her beş deneyden biri "değişiklik işe yaradı" diyor.

Nedeni şudur: sınama her bakışta yüzde 5 yanılma payı taşır. On beş ayrı bakış, on beş ayrı
yanılma fırsatıdır. Rastgele dalgalanan bir fark er ya da geç sınırı bir kez aşar ve o an
durulduğunda aşan değer sonuç olarak kaydedilir.

Kural: **deney, hesaplanan örneklem büyüklüğüne ulaşana kadar durdurulmaz ve arada karar
verilmez.** Deney sürerken sayılara bakmak yasak değildir; bakıp durmak yasaktır. Ara
kararların gerekli olduğu durumlarda ara bakış sayısına göre sınırı sıkılaştıran ardışık
sınama yöntemleri kullanılır; sıradan sınırla ara karar verilmez.

#### Çok Değişkenli Testin Bedeli

Dördüncü tablo aynı sorunun bir başka biçimini veriyor. Bir deneyde birden çok karşılaştırma
yapıldığında, en az birinde yanılma olasılığı — **aile düzeyi hata** — karşılaştırma
sayısıyla birlikte yükselir. Yedi karşılaştırmada yüzde 30.2, on beşte yüzde 53.7.

**Çok değişkenli test (multivariate test)**, birden çok ögeyi aynı deneyde değiştirip
birleşimlerini karşılaştırır. İki değerli üç öge $2^3 = 8$ birleşim, kontrole karşı yedi
karşılaştırma üretir. Düzeltme yapılmazsa deneyin yüzde 30.2 olasılıkla en az bir yanlış
"kazanan" bildireceği anlamına gelir.

Düzeltme, her karşılaştırmanın sınırını sıkılaştırır. Bonferroni düzeltmesi $\alpha$'yı
karşılaştırma sayısına böler (0.0071); Šidák düzeltmesi aile hatasını doğrudan 0.05'e
sabitler (0.0073) ve biraz daha az sıkıdır.

Son blok bedeli veriyor. Düzeltilmiş sınırla iki puanlık farkı saptamak grup başına 15351
kullanıcı ister; sekiz birleşim için 122808 kullanıcı. Aynı farkı tek bir A/B testiyle
ölçmek 19320 kullanıcı ister. Çok değişkenli test, altı kattan fazla trafik istiyor.

Bu, çok değişkenli testin ne zaman seçileceğini belirler. Ögeler arasında bir etkileşim
bekleniyorsa — birinin etkisi diğerinin değerine bağlıysa — ayrı ayrı A/B testleri o
etkileşimi hiç göremez ve çok değişkenli test gereklidir. Etkileşim beklenmiyorsa ayrı ayrı
ve sırayla yapılan A/B testleri hem ucuzdur hem yorumlanması kolaydır.

#### Deneyin Kuralları

**Hipotez ve örneklem deneyden önce yazılır.** Hangi ölçütün, hangi yönde, en az ne kadar
değişmesinin aranacağı önceden belirlenir. Sonradan seçilen ölçüt, dördüncü tablodaki
çoklu karşılaştırma sorununun gizlenmiş biçimidir.

**Örneklem hedefine ulaşılmadan karar verilmez.** Üçüncü hesap bunun bedelini veriyor.

**Fark güven aralığıyla raporlanır.** Nokta kestirimi tek başına deneyin belirsizliğini
gizler.

**Kaç karşılaştırma yapıldığı yazılır.** Kesimlere ayrılmış sonuçlar da karşılaştırmadır;
"dar ekranda anlamlı çıktı" bulgusu, kesim sayısı kadar karşılaştırma yapıldığı anlamına
gelir.

**Deney meşruluk ölçütünü değiştirmez.** Bir değişikliğin dönüşümü artırdığını göstermek,
o değişikliğin Karanlık Kalıplar dersindeki denetimden geçtiğini göstermez. Deney "işe
yarıyor mu" sorusunu yanıtlar; "yapılmalı mı" sorusunu yanıtlamaz.

#### Özet

- Gereken örneklem, saptanmak istenen farkın karesiyle ters orantılıdır: 8 puanlık fark
  için grup başına 592, 1 puanlık fark için 38734 kullanıcı.
- Aynı ölçülen fark (2.80 puan) 2000'lik gruplarda belirsiz, 8000'lik gruplarda anlamlı
  çıkar; fark örneklem yazılmadan raporlanamaz.
- Güven aralığının genişliği ayrı bir karar bilgisidir; anlamlı olmak, kararı değiştirecek
  kadar büyük olmak demek değildir.
- Erken durdurma yanlış pozitifi şişirir: gerçek fark sıfırken sonda bakan sınama yüzde
  5.7, her 500 kullanıcıda bakan sınama yüzde 20.4 oranında "fark var" dedi.
- Çok değişkenli testte aile düzeyi hata karşılaştırma sayısıyla yükselir (7
  karşılaştırmada yüzde 30.2); Bonferroni ya da Šidák düzeltmesi sınırı sıkılaştırır ve
  gereken trafiği bu örnekte altı kattan fazlaya çıkarır.
- Deney bir değişikliğin işe yarayıp yaramadığını gösterir; yapılıp yapılmayacağı ayrı bir
  ölçütle karara bağlanır.

#### Sonraki Adım

Bu ders bir farkın gerçek olup olmadığını söylemeyi öğretti; farkın **niçin** olduğunu
söylemedi. Ödünç onayı ekranındaki değişiklik oranı 2.8 puan artırdıysa, kullanıcıların
neyi farklı yaptığı sayıda görünmez. Kursun son dersi bu boşluğu kapatır: aynı huni
adımındaki terk oranıyla o adımda yapılan görüşmelerin kodları yan yana konur, nicel
bulgunun hangi nitel gözlemle eşleştiği hesaplanır ve iki kaynağın birbirini yalanladığı
durumda ne yapılacağı ele alınır.

### Nicel ve Nitel Verinin Birleştirilmesi

Source: https://academia.sh/tr/kurslar/kullanici-deneyimi/nicel-ve-nitel-verinin-birlestirilmesi

İki kaynağın huni adımı ekseninde birleştirilmesi, sıralamalar örtüşmediğinde ortaya çıkan sorunun daraltılması, kapsamın raporlanması ve nitel oranın güven aralığıyla okunması.

Önceki ders bir farkın gerçek olup olmadığını söylemeyi öğretti; farkın niçin olduğunu
söylemedi. Ödünç formundaki terk oranı yüzde elli dördün üzerindeyse, kullanıcıların o
ekranda **ne yaptığı** sayıda görünmez. Tersi de doğrudur: on iki oturumluk bir gözlem
çalışmasında beş katılımcının aynı yerde takılması bir sorunun varlığını gösterir ama o
sorunun kaç kişiyi etkilediğini söylemez.

Bu ders iki kaynağı aynı eksende buluşturur. Eksen, huni adımıdır: nicel kayıt her adımda
kaç oturumun düştüğünü, nitel kayıt aynı adımda hangi sorunun kaç katılımcıda görüldüğünü
bildirir. Buluşma noktası olmadan iki kaynak yan yana konamaz; adım eşleşmesi bu dersin
ilk kuralıdır.

#### İki Kaydın Aynı Eksende Toplanması

Nicel taraf huni adımlarının giren ve tamamlayan sayılarından oluşur. Nitel taraf gözlem
oturumlarında kodlanmış olaylardır: her kayıt bir katılımcının bir adımda yaşadığı bir
sorunu bildirir. Kodlama işi Kullanıcı Araştırması Yöntemleri dersinde kurulmuştu; burada
kodların **hangi adıma** iliştirildiği önem kazanır.

İki kaydın ortak alanı adımdır, kullanıcı değil. Gözlem oturumundaki katılımcı ile alan
verisindeki oturum aynı kişi değildir ve olamaz; bu yüzden birleştirme kişi düzeyinde değil
adım düzeyinde yapılır. Aşağıdaki hesap bu birleştirmeyi kurar ve iki kaynağın sıralamasını
karşılaştırır.

```js
// karma.mjs — ayni adimda nicel terk orani ile nitel gozlem kodlarinin yan yana konmasi

// 1. Nicel kaynak: huni adimlari ve adima giren / adimi tamamlayan oturum sayilari.
const HUNI = [
  { adim: "arama-sonucu", giren: 4820, tamamlayan: 3140 },
  { adim: "kayit-ayrintisi", giren: 3140, tamamlayan: 2610 },
  { adim: "odunc-formu", giren: 2610, tamamlayan: 1180 },
  { adim: "kimlik-dogrulama", giren: 1180, tamamlayan: 1044 },
  { adim: "onay", giren: 1044, tamamlayan: 1002 },
];

// 2. Nitel kaynak: 12 gozlem oturumunda kodlanmis olaylar.
// Her kayit bir katilimcinin bir adimda yasadigi bir sorunu bildirir.
const KODLAR = [
  { oturum: "K01", adim: "odunc-formu", kod: "sube-secimi-anlasilmadi" },
  { oturum: "K02", adim: "odunc-formu", kod: "sube-secimi-anlasilmadi" },
  { oturum: "K03", adim: "odunc-formu", kod: "sube-secimi-anlasilmadi" },
  { oturum: "K05", adim: "odunc-formu", kod: "sube-secimi-anlasilmadi" },
  { oturum: "K07", adim: "odunc-formu", kod: "sube-secimi-anlasilmadi" },
  { oturum: "K02", adim: "odunc-formu", kod: "tarih-bicimi-reddedildi" },
  { oturum: "K06", adim: "odunc-formu", kod: "tarih-bicimi-reddedildi" },
  { oturum: "K09", adim: "odunc-formu", kod: "tarih-bicimi-reddedildi" },
  { oturum: "K04", adim: "arama-sonucu", kod: "suzgec-sonucu-bosaldi" },
  { oturum: "K08", adim: "arama-sonucu", kod: "suzgec-sonucu-bosaldi" },
  { oturum: "K10", adim: "arama-sonucu", kod: "siralama-beklenmedik" },
  { oturum: "K11", adim: "kayit-ayrintisi", kod: "raf-kodu-anlasilmadi" },
  { oturum: "K12", adim: "kimlik-dogrulama", kod: "kod-gelmedi-beklendi" },
];
const OTURUM_SAYISI = 12;

// 3. Nicel taraf: adim basina terk orani ve mutlak kayip.
const nicel = HUNI.map((h) => ({
  adim: h.adim,
  terkOrani: (h.giren - h.tamamlayan) / h.giren,
  kayip: h.giren - h.tamamlayan,
}));

console.log("adim                  giren  tamamlayan   terk orani   mutlak kayip");
for (const h of HUNI) {
  const n = nicel.find((x) => x.adim === h.adim);
  console.log(
    h.adim.padEnd(20) + String(h.giren).padStart(7) + String(h.tamamlayan).padStart(12) +
      (100 * n.terkOrani).toFixed(1).padStart(12) + "%" + String(n.kayip).padStart(14)
  );
}

// 4. Nitel taraf: adim basina kod cesitliligi ve kodun gorüldügü katilimci sayisi.
const kodOzeti = new Map();
for (const k of KODLAR) {
  const anahtar = k.adim + "|" + k.kod;
  if (!kodOzeti.has(anahtar)) kodOzeti.set(anahtar, new Set());
  kodOzeti.get(anahtar).add(k.oturum);
}
console.log("\nadim                  kod                        katilimci  orani");
for (const [anahtar, oturumlar] of [...kodOzeti].sort((a, b) => b[1].size - a[1].size)) {
  const [adim, kod] = anahtar.split("|");
  console.log(
    adim.padEnd(20) + kod.padEnd(28) + String(oturumlar.size).padStart(6) +
      ("  " + (100 * oturumlar.size / OTURUM_SAYISI).toFixed(0) + "%").padStart(9)
  );
}

// 5. Iki kaynagin siralamasi yan yana.
const nicelSira = [...nicel].sort((a, b) => b.kayip - a.kayip).map((x) => x.adim);
const nitelSayim = new Map(HUNI.map((h) => [h.adim, 0]));
for (const k of KODLAR) nitelSayim.set(k.adim, nitelSayim.get(k.adim) + 1);
const nitelSira = [...nitelSayim].sort((a, b) => b[1] - a[1]).map(([adim]) => adim);

console.log("\nadim                  nicel sira  nitel sira  fark  gozlem sayisi");
let uyusan = 0;
for (const h of HUNI) {
  const n = nicelSira.indexOf(h.adim) + 1;
  const q = nitelSira.indexOf(h.adim) + 1;
  if (n === q) uyusan++;
  console.log(
    h.adim.padEnd(20) + String(n).padStart(10) + String(q).padStart(12) +
      String(n - q).padStart(6) + String(nitelSayim.get(h.adim)).padStart(15)
  );
}
console.log(`ayni siraya dusen adim: ${uyusan} / ${HUNI.length}`);

// 6. Kapsam: en buyuk kaybin ne kadari kodlanmis bir nedene baglanabiliyor?
const enBuyuk = [...nicel].sort((a, b) => b.kayip - a.kayip)[0];
const oAdimKodlari = [...kodOzeti].filter(([a]) => a.startsWith(enBuyuk.adim + "|"));
const kodlananKatilimci = new Set(KODLAR.filter((k) => k.adim === enBuyuk.adim).map((k) => k.oturum));
console.log(
  `\nen buyuk kayip: ${enBuyuk.adim} (${enBuyuk.kayip} oturum, %${(100 * enBuyuk.terkOrani).toFixed(1)})`
);
console.log(`  o adimda kodlanmis ayri neden: ${oAdimKodlari.length}`);
console.log(`  sorunu yasayan katilimci: ${kodlananKatilimci.size} / ${OTURUM_SAYISI}`);

// 7. Iki kaynagin ayristigi adimlar: siralamalar ortusmuyorsa neden?
console.log("\niki kaynagin ayristigi adimlar");
for (const h of HUNI) {
  const n = nicelSira.indexOf(h.adim) + 1, q = nitelSira.indexOf(h.adim) + 1;
  if (n === q) continue;
  const olcum = nicel.find((x) => x.adim === h.adim);
  const katilimci = new Set(KODLAR.filter((k) => k.adim === h.adim).map((k) => k.oturum)).size;
  console.log(
    `  ${h.adim.padEnd(18)} nicel ${n}. / nitel ${q}.  ` +
      `terk %${(100 * olcum.terkOrani).toFixed(1)}, kayip ${olcum.kayip}, ` +
      `gozlemde ${katilimci}/${OTURUM_SAYISI} katilimci`
  );
}

// 8. Nitel sayidan oran uretmenin siniri: 12 oturumluk kumede guven araligi.
function oranAraligi(basari, n) {
  const z = 1.96, p = basari / n;
  const payda = 1 + (z * z) / n;
  const merkez = (p + (z * z) / (2 * n)) / payda;
  const yayilim = (z * Math.sqrt((p * (1 - p)) / n + (z * z) / (4 * n * n))) / payda;
  return [merkez - yayilim, merkez + yayilim];
}
console.log("\nnitel orani nicel gibi okumanin siniri (12 oturum)");
for (const [anahtar, oturumlar] of kodOzeti) {
  if (oturumlar.size < 3) continue;
  const [alt, ust] = oranAraligi(oturumlar.size, OTURUM_SAYISI);
  const [adim, kod] = anahtar.split("|");
  console.log(
    `  ${kod.padEnd(28)} ${oturumlar.size}/12 = %${(100 * oturumlar.size / OTURUM_SAYISI).toFixed(0)}` +
      `   %95 aralik: %${(100 * alt).toFixed(0)} - %${(100 * ust).toFixed(0)}`
  );
}
```

```
adim                  giren  tamamlayan   terk orani   mutlak kayip
arama-sonucu           4820        3140        34.9%          1680
kayit-ayrintisi        3140        2610        16.9%           530
odunc-formu            2610        1180        54.8%          1430
kimlik-dogrulama       1180        1044        11.5%           136
onay                   1044        1002         4.0%            42

adim                  kod                        katilimci  orani
odunc-formu         sube-secimi-anlasilmadi          5      42%
odunc-formu         tarih-bicimi-reddedildi          3      25%
arama-sonucu        suzgec-sonucu-bosaldi            2      17%
arama-sonucu        siralama-beklenmedik             1       8%
kayit-ayrintisi     raf-kodu-anlasilmadi             1       8%
kimlik-dogrulama    kod-gelmedi-beklendi             1       8%

adim                  nicel sira  nitel sira  fark  gozlem sayisi
arama-sonucu                 1           2    -1              3
kayit-ayrintisi              3           3     0              1
odunc-formu                  2           1     1              8
kimlik-dogrulama             4           4     0              1
onay                         5           5     0              0
ayni siraya dusen adim: 3 / 5

en buyuk kayip: arama-sonucu (1680 oturum, %34.9)
  o adimda kodlanmis ayri neden: 2
  sorunu yasayan katilimci: 3 / 12

iki kaynagin ayristigi adimlar
  arama-sonucu       nicel 1. / nitel 2.  terk %34.9, kayip 1680, gozlemde 3/12 katilimci
  odunc-formu        nicel 2. / nitel 1.  terk %54.8, kayip 1430, gozlemde 7/12 katilimci

nitel orani nicel gibi okumanin siniri (12 oturum)
  sube-secimi-anlasilmadi      5/12 = %42   %95 aralik: %19 - %68
  tarih-bicimi-reddedildi      3/12 = %25   %95 aralik: %9 - %53
```

#### Sıralamalar Örtüşmediğinde

Çıktının üçüncü bölümü iki sıralamayı yan yana koyuyor: beş adımın üçü aynı sıraya düşüyor,
ikisi yer değiştiriyor. Bu iki adım dersin asıl konusudur.

Arama sonucu ekranı **mutlak kayıpta birinci**: bin altı yüz seksen oturum orada düşüyor.
Ama gözlemde yalnızca üç katılımcı orada bir sorun yaşadı. Ödünç formu ise mutlak kayıpta
ikinci, gözlemde birinci: yedi katılımcı orada takıldı ve iki ayrı neden kodlandı.

Bu ayrışmanın iki açıklaması vardır ve ikisi de veriyle sınanabilir. Birincisi, arama sonucu
ekranındaki düşüşün bir **sorun olmayabileceğidir**: tarama yapan bir kullanıcının sonuç
listesinden çıkması beklenen bir davranıştır — huni bunu terk olarak sayar, ama görev
başarısızlığı değildir. İkincisi, gözlem çalışmasının o adımda **görev tanımı gereği** kısa
kalmasıdır: katılımcıya aranacak kitap verildiyse arama zorluğu hiç oluşmaz.

Hangi açıklamanın doğru olduğuna bu tablo karar veremez. Verebildiği şey soruyu
daraltmaktır: arama sonucu ekranı için görev tanımı serbest bırakılmış yeni bir gözlem
turu gerekir. Nicel ve nitel verinin birleştirilmesi bir sonuç üretmez; **bir sonraki
çalışmanın konusunu** üretir.

#### Kapsam: Kaybın Ne Kadarı Açıklanabiliyor

Dördüncü bölüm en büyük kaybı ve o adımda kodlanmış nedenleri sayıyor. Arama sonucunda iki
ayrı neden kodlanmış ve bunlar on iki katılımcının üçünde görülmüş. Bu sayı bir kapsam
göstergesidir: kaybın büyüklüğü ile onu açıklayan gözlemin gücü arasındaki mesafeyi ölçer.

Mesafe büyükse iki yanlış karar yolu açılır. Birincisi, az sayıda gözlemden çıkan nedeni bütün
kayba genellemektir — üç katılımcının bildirdiği iki ayrı sorun, bin altı yüz seksen oturumun
nedeni sayılır. İkincisi, gözlemi hiç kullanmayıp yalnız sayıya bakmaktır; o zaman da düzeltilecek
şey belirsiz kalır. Doğru okuma, kapsamın kendisini raporlamaktır: "bu adımdaki kaybın
açıklanabilen bölümü üç katılımcının bildirdiği iki nedenle sınırlıdır."

#### Nitel Oranı Nicel Gibi Okumak

Son bölüm sık yapılan bir hatayı sayıyla gösteriyor. On iki oturumda beş katılımcının
yaşadığı sorun için "kullanıcıların yüzde kırk ikisi" demek, örneklem büyüklüğünü gizler.
Aynı gözlemin yüzde doksan beş güven aralığı yüzde on dokuz ile yüzde altmış sekiz
arasındadır. Bu genişlikte bir aralık, bir tasarım kararını gerekçelendirebilir ama bir
öncelik sırasını tek başına belirleyemez.

Kural şudur: nitel çalışma **sorunun varlığını ve biçimini** bildirir, yaygınlığını
bildirmez. Yaygınlık sorusu alan verisiyle ya da sorunun bir ölçüte dönüştürüldüğü bir
ölçümle yanıtlanır. Beş katılımcının şube seçimini anlamaması, o alanın yeniden
tasarlanması için yeterli gerekçedir; "kullanıcıların yüzde kırk ikisi" cümlesi ise
yazılmamalıdır.

#### İki Kaynak Birbirini Yalanladığında

Bir adımda terk oranı düşük ama gözlemde birden çok sorun kodlanmışsa, ya sorun görevi
tamamlamayı engellemiyordur ya da alan verisi o adımı yanlış ölçüyordur. Tersi durumda —
terk yüksek, gözlem yok — ya gözlem görevleri o yolu hiç kullanmıyordur ya da düşüş bir
başarısızlık değildir.

Her iki durumda da izlenecek sıra aynıdır: önce ölçümün kendisi denetlenir (adım tanımı,
olay kaydının tetiklendiği an, oturum tanımı), sonra görev tanımı denetlenir, en son
tasarım değiştirilir. Ölçüm hatası düzeltilmeden yapılan tasarım değişikliği, sonucu
yorumlanamaz hâle getirir.

#### Özet

- Nicel ve nitel kayıtlar kişi düzeyinde değil **adım düzeyinde** birleştirilir; gözlem
  katılımcısıyla alan verisindeki oturum aynı kişi değildir.
- İki kaynağın sıralaması örtüşmediğinde tablo bir sonuç değil bir soru üretir: beş adımın
  ikisi yer değiştiriyor ve her ikisinin de veriyle sınanabilir iki açıklaması var.
- Kapsam raporlanır: en büyük kaybı açıklayan gözlem on iki katılımcının üçünden geliyor;
  bu mesafe hem aşırı genellemeyi hem de gözlemi yok saymayı engeller.
- Nitel çalışma sorunun varlığını ve biçimini bildirir, yaygınlığını bildirmez: 5/12
  gözlemin güven aralığı yüzde on dokuz ile altmış sekiz arasındadır.
- İki kaynak çeliştiğinde sıra ölçümü denetlemek, görev tanımını denetlemek ve en son
  tasarımı değiştirmektir.

#### Kurs Kapanışı

Bu kurs kullanıcıyı tasarımın girdisi hâline getirmenin zincirini kurdu. Araştırma ve
Tanımlama konusu yöntemin seçimini katılımcı onayı ve veri sınırlarıyla birlikte ele aldı,
profilleri gerçek veriye bağladı ve problem tanımını çözümden önce yazmayı kural yaptı.
Bilgi Mimarisi ve Akış konusu yapıyı içerikten türetti, gezinme modellerini derinlik ve
genişlik ödünleşimiyle hesapladı ve kullanılabilirlik testini küçük örneklemin ne
söyleyebildiği sınırıyla kurdu. Davranış Tasarımı konusu kararın nasıl verildiğini
modelledi ve her mekanizmayı tek bir ölçüte bağladı: kullanıcı bilseydi de aynı seçimi
yapacaksa karar meşrudur, kararın gücü kullanıcının bilgisizliğinden geliyorsa karanlık
kalıptır. Ölçme konusu ise bu kararların sonucunu görev başarımı, süre ve hata oranıyla
raporlamayı, huniyi okumayı, deneyi doğru kurmayı ve bu dersteki gibi iki kaynağı
birleştirmeyi öğretti.

Buraya kadar her karar tek tek doğrulandı. Bir sonraki soru ölçeğe aittir: aynı kararların
onlarca ekranda, birden çok ekipte ve zaman içinde tutarlı kalması nasıl sağlanır?
Bir sonraki kurs, **Tasarım Sistemleri**, bu soruyu ele alır. Tasarım dilini belirteçlere
çevirir, bileşen kataloğunu belge ve sürüm disipliniyle yönetir, sistemin benimsenmesini
ölçer ve yönetişimini kurar. Bu kursta verilen kararlar orada birer sözleşmeye dönüşür.

