# Generating Functions and Classes from Scratch

> Source: https://sukruyusufkaya.com/en/learn/claude-ustaligi/kod-uretimi-sifirdan
> Updated: 2026-05-13T11:38:00.971Z
> Category: Claude Ustalığı
> Module: 4. Coding with Claude
**TLDR:** Workflow for producing production-ready functions/classes from a clear spec with Claude: signature, edge cases, tests, docs.

> **Bu derste**
>
> Bir gereksinimden 'çalışan + test edilmiş + belgelenmiş' kod üretmek için Claude'la 4 adımlı bir akış.

# Spec → Kod Akışı

Claude'a "şunu yap" demek yerine **spec yazarak** kod isteyin. İyi spec şunları içerir:

- **Tip imzası** (TypeScript / Python type hint).
- **Davranış kuralları** (girdi-çıktı eşleşmeleri, edge case'ler).
- **Performans / bellek beklentisi** (varsa).
- **Hata davranışı** (raise / return / null?).
- **Bağımlılık / dış efekt yasağı**.
- **Test örnekleri** (ideal: 2-3 'happy path' + 2-3 edge).

```text
# Spec şablonu

## Fonksiyon imzası
def normalize_phone(raw: str, default_country: str = "TR") -> str | None: ...

## Davranış
- Türkiye numaralarını "+90 5xx xxx xx xx" formatına çevir.
- Boşluk, parantez, tire ve "+" işaretlerini at.
- 10 haneli "5xx..." numaralara "+90" ekle.
- 11 haneli "0..." başlayan numaralarda "0"ı at, başına "+90" koy.
- Geçersiz numara için None döndür (raise etme).

## Edge cases
- Boş string → None
- Yalnızca harf içerme → None
- "+90 (555) 123-45-67" → "+90 555 123 45 67"
- "905551234567"      → "+90 555 123 45 67"

## Performans
- Pure function, dış erişim yok.
- 100 ms altı, regex kullanılabilir.
```

## 4 Adımlı Akış

**Sıralama egzersizi:**
- `1) Spec'i yaz, Claude'a 'eksik bilgi varsa sor' de`
- `2) Önce testleri Claude'a yazdır (TDD)`
- `3) Spec + testlerle implementasyon iste`
- `4) Refactor iste — okunabilirlik + docstring`

```python
# Üretim seviyesi spec'in çıktısı — Claude'la üretildi, lokal test
import re
from typing import Optional

def normalize_phone(raw: str, default_country: str = "TR") -> Optional[str]:
    if not raw or not isinstance(raw, str):
        return None
    digits = re.sub(r"[^0-9]", "", raw)
    if default_country != "TR":
        return None  # bu fonksiyon yalnızca TR
    if len(digits) == 10 and digits.startswith("5"):
        digits = "90" + digits
    elif len(digits) == 11 and digits.startswith("0"):
        digits = "90" + digits[1:]
    elif len(digits) == 12 and digits.startswith("90"):
        pass
    else:
        return None
    return f"+{digits[:2]} {digits[2:5]} {digits[5:8]} {digits[8:10]} {digits[10:]}"

# Hızlı testler
testler = [
    ("+90 (555) 123-45-67", "+90 555 123 45 67"),
    ("905551234567",        "+90 555 123 45 67"),
    ("05551234567",         "+90 555 123 45 67"),
    ("",                    None),
    ("hello",               None),
]
for inp, exp in testler:
    got = normalize_phone(inp)
    print(f"{inp!r:25} → {got!r:25} {'OK' if got == exp else 'FAIL'}")
```

### TDD ile çalışmanın faydası

Claude testleri implementasyondan önce yazdığında:

- **Spec netleşir.** Yazılırken "bu ne dönsün?" sorularını sen kendine sorarsın.
- **Implementasyon, testlere uyacak şekilde** üretilir.
- **Refactor güvenli olur.** Testler yeşil kalırsa Claude'un yaptığı değişiklik sürpriz çıkarmaz.

### Tip imzası şart mı?

Tip imzası belirsizliği büyük ölçüde kaldırır. `def f(x): ...` yerine `def f(x: list[str]) -> dict[str, int]: ...` yazmak Claude'a bağlamı bedavaya verir.

### Var olan kod tabanına kod ürettiriyorsan

Mevcut style guide / convention'ı prompt'a ekle. "Bu projede async/await kullanılır", "tüm hata logları structured logger'a gider", "import sıralaması isort black uyumlu" gibi.

Daha güçlüsü: **iki örnek dosya** ekleyip "bu dosyalardakiyle tutarlı stil bekliyorum" demek.

**Boşluk doldurma egzersizi (text):**
```text
İyi bir kod üretim akışında ilk adım net bir _____ yazmaktır. TDD'de testler implementasyondan _____ yazılır. Tip imzası belirsizliği büyük ölçüde _____.
```

> ✋ Kontrol noktası: `q-401-mc1`