← Ana sayfa

Yazılım Kalite Güvencesi ve Testi · Ön hazırlık

Python 101: ilk satırdan listelere

Bu derste yazacağımız kodlar için gereken Python'un tamamı bu sayfada. Her bölümde kısa bir örnek ve çıktısı var. 11. bölümde assert ile ilk testlerimizi yazıyor, sonraki bölümlerde de onları kullanıyoruz. Örnekleri kopyalayıp kendi bilgisayarınızda çalıştırın; okumak yetmez.

Süre: 3–4 saat, bölüm bölümGerekenler: Python 3.10 veya üstü, VS Code
01

Python'u çalıştırmak

10 dakika

Önce Python'un kurulu olduğunu kontrol edin. Terminali açın (Windows'ta VS Code terminali ya da PowerShell):

Terminal
python --version
Python 3.12.x

Windows'ta bu komut Microsoft Store'u açıyorsa ya da hata veriyorsa py --version deneyin; sonraki bütün komutlarda python yerine py yazın. Hiç kurulu değilse python.org adresinden indirin ve kurulumda “Add python.exe to PATH” kutusunu işaretleyin.

İki çalışma şekli

1. Etkileşimli mod. Terminale yalnızca python yazarsanız >>> işareti çıkar. Yazdığınız her satır hemen çalışır. Küçük şeyleri denemek için idealdir. Çıkmak için exit() yazın.

Etkileşimli mod
>>> 2 + 3
5
>>> "merhaba".upper()
'MERHABA'

2. Dosya olarak. VS Code'da merhaba.py adında bir dosya oluşturun, içine yazın, kaydedin ve terminalden çalıştırın. Bu dersteki bütün ödevler böyle çalışacak.

merhaba.py
print("Merhaba, dünya!")
Terminal
python merhaba.py
Merhaba, dünya!
İpucu: Terminal, dosyanın bulunduğu klasörde açık olmalı. VS Code'da Ctrl+` ile açılan terminal zaten proje klasöründe açılır.
02

print ve yorumlar

10 dakika

print ekrana yazar. Virgülle birden fazla şey verirseniz aralarına boşluk koyar. # ile başlayan her şey yorumdur: Python onu okumaz, insanlar okur.

print.py
# Bu bir yorum, çalıştırılmaz
print("Ders:", "Yazılım Testi")
print("Öğrenci sayısı:", 42)
print()                          # boş satır
print("Bitti")
Ders: Yazılım Testi Öğrenci sayısı: 42 Bitti
Yorumu ne zaman yazın? Kodun ne yaptığını değil, neden öyle yapıldığını anlatmak için. # sayacı bir artır gereksizdir; kod zaten bunu söylüyor.
03

Değişkenler ve veri tipleri

15 dakika

Değişken, bir değere verdiğiniz isimdir. = işareti “eşittir” değil, “ata” demektir: sağdaki değeri soldaki isme bağlar.

degiskenler.py
ad = "Ayşe"          # str: metin
yas = 21             # int: tam sayı
ortalama = 78.5      # float: ondalıklı sayı
mezun = False        # bool: True ya da False

print(ad, yas, ortalama, mezun)
print(type(ad), type(yas), type(ortalama), type(mezun))

yas = yas + 1        # değişkenin değeri değişebilir
print(yas)
Ayşe 21 78.5 False <class 'str'> <class 'int'> <class 'float'> <class 'bool'> 22

İsimlendirme kuralları

  • Küçük harf ve alt çizgi kullanın: ogrenci_sayisi, vize_notu
  • Rakamla başlayamaz (2not olmaz), boşluk içeremez
  • Anlamlı olsun: x yerine final_notu. Altı ay sonra okuyacak kişi sizsiniz.
  • Türkçe karakter teknik olarak çalışır ama ı, ş, ğ kullanmamak klavye ve araç sorunlarını önler
04

Sayılarla işlemler

15 dakika

İşlemAnlamıÖrnekSonuç
+ - *Toplama, çıkarma, çarpma7 * 214
/Bölme (sonuç hep float)7 / 23.5
//Tam bölme (aşağı yuvarlar)7 // 23
%Bölümden kalan7 % 21
**Üs alma2 ** 101024
sayilar.py
vize = 60
final = 85
ortalama = vize * 0.4 + final * 0.6
print(ortalama)
print(round(ortalama))       # en yakın tam sayıya yuvarlar
print(10 / 4, 10 // 4, 10 % 4)
75.0 75 2.5 2 2
Dikkat: % çok işe yarar. Bir sayının çift olup olmadığını sayi % 2 == 0 ile, bir yılın 4'e bölünüp bölünmediğini yil % 4 == 0 ile anlarsınız.
05

Metinler (str)

20 dakika

Metinler tek ya da çift tırnak içinde yazılır. En kullanışlı araç f-string'dir: tırnaktan önce f yazıp süslü parantez içine değişken koyarsınız.

metinler.py
ad = "Ayşe"
soyad = "Yılmaz"
not_ = 87.456

tam_ad = ad + " " + soyad             # + ile birleştirme
print(tam_ad)
print(f"{tam_ad} dersten {not_} aldı")  # f-string
print(f"Yuvarlanmış: {not_:.1f}")       # virgülden sonra 1 basamak

print(len(tam_ad))       # karakter sayısı (boşluk dahil)
print(tam_ad.upper())
print(tam_ad.lower())
print(tam_ad[0])         # ilk karakter: sayma 0'dan başlar
print("Ay" in tam_ad)    # içinde geçiyor mu?
Ayşe Yılmaz Ayşe Yılmaz dersten 87.456 aldı Yuvarlanmış: 87.5 11 AYŞE YILMAZ ayşe yılmaz A True
Metin ile sayı toplanamaz. "Not: " + 85 hata verir. Ya f-string kullanın ya da sayıyı str(85) ile metne çevirin.
06

Kullanıcıdan girdi almak

10 dakika

input kullanıcının yazdığını her zaman metin (str) olarak döndürür. Sayı istiyorsanız int() ya da float() ile çevirmeniz gerekir.

girdi.py
ad = input("Adınız: ")
vize = int(input("Vize: "))
final = int(input("Final: "))
print(f"{ad}, ortalamanız {vize * 0.4 + final * 0.6}")
Adınız: Ali Vize: 60 Final: 80 Ali, ortalamanız 72.0
En sık yapılan hata: int() unutulursa "60" + "80" işlemi "6080" verir; çünkü iki metni yan yana ekler. Bu yüzden testlerde tipleri kontrol etmek önemlidir.
07

Karşılaştırma ve mantık

15 dakika

Karşılaştırmaların sonucu her zaman True ya da False'tur.

İşaretAnlamıÖrnekSonuç
==eşit mi?5 == 5True
!=farklı mı?5 != 3True
< >küçük, büyük49 > 50False
<= >=küçük eşit, büyük eşit50 >= 50True
andikisi de doğru mu?True and FalseFalse
oren az biri doğru mu?True or FalseTrue
nottersini alnot TrueFalse
= ile == farklıdır. x = 5 değer atar, x == 5 soru sorar. Koşullarda ve assert'lerde her zaman == kullanılır.
mantik.py
puan = 55
print(puan >= 50)                    # geçti mi?
print(0 <= puan <= 100)              # geçerli aralıkta mı? (zincirleme)
print(puan >= 50 and puan < 70)     # CC aralığında mı?
True True True
08

if, elif, else

20 dakika

Koşula göre farklı kod çalıştırır. Python'da blokları süslü parantez değil girinti (4 boşluk) belirler. Koşul satırı : ile biter.

harf_notu.py
puan = 72

if puan >= 85:
    harf = "AA"
elif puan >= 70:
    harf = "BB"
elif puan >= 50:
    harf = "CC"
else:
    harf = "FF"

print(f"{puan} puan: {harf}")
72 puan: BB

Koşullar yukarıdan aşağı sırayla denenir; ilk doğru olan çalışır, gerisine bakılmaz. Bu yüzden sıra önemlidir: puan >= 50 koşulunu en başa yazsaydınız 90 alan öğrenci de CC alırdı.

Girinti hatası: Blok içindeki satırlar aynı hizada olmalı. Bir satır 3, diğeri 4 boşlukla girintilenirse IndentationError alırsınız. VS Code'da Tab tuşu otomatik 4 boşluk koyar.
09

Döngüler: for ve while

20 dakika

for: belli sayıda tekrar

range(bas, bitis) başlangıcı içerir, bitişi içermez. range(1, 6) 1'den 5'e kadar sayar.

for.py
for i in range(1, 6):
    print(i, "karesi", i * i)

toplam = 0
for sayi in range(1, 101):
    toplam = toplam + sayi
print("1'den 100'e toplam:", toplam)
1 karesi 1 2 karesi 4 3 karesi 9 4 karesi 16 5 karesi 25 1'den 100'e toplam: 5050

while: koşul doğru olduğu sürece

while.py
bakiye = 100
ay = 0
while bakiye < 200:
    bakiye = bakiye * 1.1     # her ay %10 artış
    ay = ay + 1
print(f"{ay} ayda ikiye katlandı")
8 ayda ikiye katlandı
Sonsuz döngü: while'ın koşulu hiç yanlış olmazsa program sonsuza kadar döner. Döngü içinde koşulu değiştiren bir satır olduğundan emin olun. Takılırsanız terminalde Ctrl+C programı durdurur. (Zune müzik çalarlarını donduran hata tam olarak buydu.)
10

Fonksiyonlar

25 dakika

Fonksiyon, bir işe isim vermektir: girdileri (parametreler) alır, bir sonuç döndürür (return). Bu derste test edeceğimiz şeylerin neredeyse hepsi fonksiyon olacak.

fonksiyon.py
def ortalama_hesapla(vize, final):
    return vize * 0.4 + final * 0.6


def gecti_mi(ortalama):
    return ortalama >= 60


ort = ortalama_hesapla(50, 70)
print(ort)
print(gecti_mi(ort))
print(gecti_mi(ortalama_hesapla(80, 30)))
62.0 True False

return ile print aynı şey değil

Bu, yeni başlayanların en sık karıştırdığı konudur ve test yazarken çok önemlidir.

return_print.py
def topla_yaz(a, b):
    print(a + b)          # ekrana yazar, hiçbir şey döndürmez


def topla(a, b):
    return a + b          # sonucu çağırana geri verir


x = topla_yaz(2, 3)
y = topla(2, 3)
print("x =", x)
print("y =", y)
5 x = None y = 5

topla_yaz ekrana 5 yazdı ama sonucu geri vermedi; x'in değeri None (hiçbir şey). Testler fonksiyonun döndürdüğü değeri kontrol eder, ekrana yazdığını değil. Bu yüzden fonksiyonlarınız hesapladığını return ile vermeli, yazdırma işini fonksiyonun dışında yapmalısınız.

11

assert ile test yazmak

25 dakika

assert, “bu ifade doğru olmalı” demektir.

  • İfade doğruysa hiçbir şey olmaz, program bir sonraki satıra geçer.
  • İfade yanlışsa program AssertionError ile durur ve hangi satırda durduğunu söyler.

Test yazmanın en sade hali budur: bir fonksiyonu bilinen bir girdiyle çağırırsınız ve sonucun beklediğiniz değere eşit olduğunu assert ile söylersiniz.

assert_ornek.py
def gecti_mi(ortalama):
    return ortalama >= 60


assert gecti_mi(75) == True       # sıradan bir değer
assert gecti_mi(60) == True       # tam sınır
assert gecti_mi(59) == False      # sınırın bir altı
print("Tüm testler geçti")
Tüm testler geçti

Test başarısız olursa ne görürsünüz?

Diyelim ki biri fonksiyonda >= yerine yanlışlıkla > yazdı:

assert_hata.py
def gecti_mi(ortalama):
    return ortalama > 60          # hata: >= olmalıydı


assert gecti_mi(75) == True
assert gecti_mi(60) == True
assert gecti_mi(59) == False
print("Tüm testler geçti")
Traceback (most recent call last): File "assert_hata.py", line 6, in <module> assert gecti_mi(60) == True AssertionError

Program 6. satırda durdu: 60 puanlık öğrenci geçmesi gerekirken geçemedi. Dikkat edin, 75 ve 59 testleri bu hatayı yakalamazdı; hatayı yalnızca tam sınırdaki 60 testi gösterdi.

Hata mesajı eklemek

Virgülden sonra bir metin yazarsanız, test başarısız olduğunda o metin gösterilir:

Python
assert gecti_mi(60) == True, "60 alan öğrenci geçmeli"
AssertionError: 60 alan öğrenci geçmeli

İyi test nasıl seçilir?

Durumgecti_mi için örnekNeden?
Sıradan75Temel davranış çalışıyor mu?
Tam sınır60Hatalar en çok burada çıkar
Sınırın bir altı59Sınırın öbür tarafı doğru mu?
Uç değerler0, 100Aralığın başı ve sonu
3. haftada aynı testleri pytest ile çalıştıracağız. pytest her testi ayrı ayrı çalıştırır ve raporlar; ama testin içinde yazdığınız şey yine bu assert satırları olacak.
12

Listeler

30 dakika

Liste, birden fazla değeri sırayla tutar. Köşeli parantezle yazılır. Bir sınıfın notları, bir öğrencinin dersleri, bir sepetteki ürünler: hepsi listedir.

liste.py
notlar = [70, 45, 90, 60, 85]

print(notlar[0])        # ilk eleman (sayma 0'dan başlar)
print(notlar[2])        # üçüncü eleman
print(notlar[-1])       # son eleman
print(notlar[1:3])      # 1. ve 2. indeks (3 dahil değil)
print(len(notlar))      # eleman sayısı
70 90 85 [45, 90] 5

Listeyi değiştirmek

liste_degistir.py
dersler = ["Matematik", "Fizik"]
dersler.append("Yazılım Testi")    # sona ekle
print(dersler)

dersler.remove("Fizik")            # değere göre sil
print(dersler)

dersler[0] = "Lineer Cebir"        # bir elemanı değiştir
print(dersler)

print("Fizik" in dersler)          # içinde var mı?
['Matematik', 'Fizik', 'Yazılım Testi'] ['Matematik', 'Yazılım Testi'] ['Lineer Cebir', 'Yazılım Testi'] False

Liste üzerinde dolaşmak

liste_dongu.py
notlar = [70, 45, 90, 60, 85]

gecenler = []
for n in notlar:
    if n >= 60:
        gecenler.append(n)

print("Geçenler:", gecenler)
print("Toplam:", sum(notlar))
print("En düşük:", min(notlar), "En yüksek:", max(notlar))
print("Ortalama:", sum(notlar) / len(notlar))
print("Sıralı:", sorted(notlar))
Geçenler: [70, 90, 60, 85] Toplam: 350 En düşük: 45 En yüksek: 90 Ortalama: 70.0 Sıralı: [45, 60, 70, 85, 90]
Boş liste ve olmayan indeks: notlar[5] beş elemanlı bir listede IndexError verir (son indeks 4'tür). Boş bir listenin ortalamasını sum([]) / len([]) ile almaya çalışırsanız ZeroDivisionError alırsınız. Test yazarken boş listeyi mutlaka deneyin.
13

Hepsi bir arada: sınıf not analizi

20 dakika

Şimdiye kadar gördüğümüz her şey tek bir dosyada: fonksiyonlar, if, döngü, liste ve her fonksiyon için testler. Bu dersteki ödevleriniz de tam olarak bu düzende olacak.

not_analizi.py
GECME_NOTU = 60


def ortalama(notlar):
    if len(notlar) == 0:
        return 0
    return sum(notlar) / len(notlar)


def gecen_sayisi(notlar):
    sayac = 0
    for n in notlar:
        if n >= GECME_NOTU:
            sayac = sayac + 1
    return sayac


def harf_notu(puan):
    if puan >= 85:
        return "AA"
    elif puan >= 70:
        return "BB"
    elif puan >= 60:
        return "CC"
    else:
        return "FF"


# --- Testler ---
assert ortalama([60, 80]) == 70
assert ortalama([100]) == 100
assert ortalama([]) == 0                  # boş sınıf

assert gecen_sayisi([70, 45, 90]) == 2
assert gecen_sayisi([60]) == 1            # tam sınır
assert gecen_sayisi([59]) == 0
assert gecen_sayisi([]) == 0

assert harf_notu(85) == "AA"
assert harf_notu(84) == "BB"
assert harf_notu(60) == "CC"
assert harf_notu(59) == "FF"
print("Tüm testler geçti")

# --- Programın kendisi ---
sinif = [70, 45, 90, 60, 85, 52]
print(f"Ortalama: {ortalama(sinif):.1f}")
print(f"Geçen: {gecen_sayisi(sinif)} / {len(sinif)}")
for n in sinif:
    print(n, harf_notu(n))
Tüm testler geçti Ortalama: 67.0 Geçen: 4 / 6 70 BB 45 FF 90 AA 60 CC 85 AA 52 FF
Deneyin: harf_notu fonksiyonunda puan >= 85 satırını puan > 85 yapıp dosyayı tekrar çalıştırın. Hangi test kırıldı? Neden yalnızca o?
14

Sık karşılaşılan hatalar

Başvuru bölümü

Hata mesajını okumayı öğrenmek, programlamanın yarısıdır. Mesajın son satırı hatanın türünü, bir üstündeki satırlar ise nerede olduğunu söyler.

SyntaxError: expected ':'

if, for, while, def satırlarının sonuna iki nokta koymayı unuttunuz: if puan >= 50:

IndentationError: expected an indented block

: ile biten satırın altındaki satır girintili değil. Blok içindeki her satırın başında 4 boşluk olmalı.

NameError: name 'ortalam' is not defined

Tanımlanmamış bir isim kullandınız. Çoğunlukla yazım hatasıdır (ortalama yerine ortalam) ya da değişkeni kullanmadan önce tanımlamamışsınızdır.

TypeError: can only concatenate str (not "int") to str

Metin ile sayıyı + ile birleştirmeye çalıştınız: "Not: " + 85. f-string kullanın: f"Not: {85}". Ya da input'tan gelen değeri int() ile çevirmeyi unuttunuz.

ValueError: invalid literal for int() with base 10: 'abc'

int() sayıya çevrilemeyen bir metin aldı. Kullanıcı sayı yerine harf yazmış olabilir.

IndexError: list index out of range

Listede olmayan bir indekse eriştiniz. 5 elemanlı listenin son indeksi 4'tür. Boş listede liste[0] bile bu hatayı verir.

ZeroDivisionError: division by zero

Sıfıra böldünüz. En sık sebebi boş listenin ortalamasını almaktır: sum(x) / len(x), x boşken. Bölmeden önce if len(x) == 0 kontrolü yapın.

AssertionError

Bu bir Python hatası değil, testinizin çalıştığının kanıtı: bir assert satırı yanlış çıktı. Mesajın üstündeki satır hangi testin başarısız olduğunu gösterir. Ya kodunuzda bir hata var ya da testteki beklenen değer yanlış; ikisini de kontrol edin.

15

Alıştırmalar

Her biri 10–20 dakika

Her alıştırmada fonksiyonu siz yazacaksınız. Altındaki assert satırlarını olduğu gibi dosyanıza kopyalayın; hepsi geçene kadar fonksiyonunuzu düzeltin. Çözüme bakmadan önce en az bir kez deneyin.

1. Çift mi?

Bir sayının çift olup olmadığını döndüren cift_mi(sayi) fonksiyonunu yazın.

testler
assert cift_mi(4) == True
assert cift_mi(7) == False
assert cift_mi(0) == True
assert cift_mi(-2) == True
Çözümü göster
cozum
def cift_mi(sayi):
    return sayi % 2 == 0


assert cift_mi(4) == True
assert cift_mi(7) == False
assert cift_mi(0) == True
assert cift_mi(-2) == True

2. Artık yıl

4'e bölünen yıllar artık yıldır; ama 100'e bölünenler değildir; ama 400'e de bölünenler yine artık yıldır. artik_yil(yil) fonksiyonunu yazın.

testler
assert artik_yil(2024) == True
assert artik_yil(2023) == False
assert artik_yil(1900) == False
assert artik_yil(2000) == True
Çözümü göster
cozum
def artik_yil(yil):
    if yil % 400 == 0:
        return True
    if yil % 100 == 0:
        return False
    return yil % 4 == 0


assert artik_yil(2024) == True
assert artik_yil(2023) == False
assert artik_yil(1900) == False
assert artik_yil(2000) == True

3. Sesli harf sayısı

Bir metindeki sesli harfleri (a, e, ı, i, o, ö, u, ü) sayan sesli_sayisi(metin) fonksiyonunu yazın. Büyük harfler de sayılmalı.

testler
assert sesli_sayisi("merhaba") == 3
assert sesli_sayisi("") == 0
assert sesli_sayisi("xyz") == 0
assert sesli_sayisi("OKUL") == 2
Çözümü göster
cozum
def sesli_sayisi(metin):
    sesliler = "aeıioöuüAEIİOÖUÜ"
    sayac = 0
    for harf in metin:
        if harf in sesliler:
            sayac = sayac + 1
    return sayac


assert sesli_sayisi("merhaba") == 3
assert sesli_sayisi("") == 0
assert sesli_sayisi("xyz") == 0
assert sesli_sayisi("OKUL") == 2

4. En büyük ikinci not

ikinci_en_buyuk(notlar) listedeki en büyük ikinci farklı değeri döndürsün. Listede iki farklı değer yoksa None döndürsün. (max ve sorted kullanabilirsiniz.)

testler
assert ikinci_en_buyuk([70, 90, 85]) == 85
assert ikinci_en_buyuk([90, 90, 80]) == 80
assert ikinci_en_buyuk([50]) == None
assert ikinci_en_buyuk([]) == None
Çözümü göster
cozum
def ikinci_en_buyuk(notlar):
    farkli = []
    for n in notlar:
        if n not in farkli:
            farkli.append(n)
    if len(farkli) < 2:
        return None
    return sorted(farkli)[-2]


assert ikinci_en_buyuk([70, 90, 85]) == 85
assert ikinci_en_buyuk([90, 90, 80]) == 80
assert ikinci_en_buyuk([50]) == None
assert ikinci_en_buyuk([]) == None

İkinci testi ([90, 90, 80]) neden eklediğimizi düşünün: sorted(notlar)[-2] gibi kısa bir çözüm ilk testi geçer ama bu testte 90 döndürür.

5. Kendi testlerinizi yazın

Aşağıdaki fonksiyon bir ürünün indirimli fiyatını hesaplıyor. İndirim oranı 0 ile 50 arasında olmalı; bu aralığın dışındaki oranlarda fiyat değişmemeli. Fonksiyonu çalıştırmadan önce en az 6 assert yazın: sıradan değer, sınırlar (0 ve 50), sınırın dışı (-1 ve 51). Sonra çalıştırın. Fonksiyonda bir hata var; testleriniz onu buluyor mu?

indirim.py
def indirimli_fiyat(fiyat, oran):
    if oran >= 0 and oran < 50:
        return fiyat * (100 - oran) / 100
    return fiyat
İpucu

Şartname “0 ile 50 arasında” diyor; yani 0 ve 50 dahil. Koşul ifadesi aynı şeyi mi söylüyor? indirimli_fiyat(200, 50) kaç döndürmeli, kaç döndürüyor? 10 ya da 30 gibi sıradan değerlerle yazılmış testler bu hatayı bulamaz; hatayı yalnızca tam sınırdaki test gösterir.

Bitirdiniz mi? Alıştırma dosyalarınızı kalite-lab deponuza ekleyip her biri için ayrı bir commit yapın. Commit mesajı ne yaptığınızı söylesin: “cift_mi fonksiyonu ve testleri eklendi”.