Python 3
Python 3
18.02.2016
NDEKLER
1 Bu Kitap Hakknda
1.1 Bu Kitab Nereden ndirebilirim? .
1.2 Bu Kitaptan Nasl Yararlanabilirim?
1.3 Nereden Yardm Alabilirim? . . . .
1.4 Projeye Nasl Yardmc Olabilirim? .
1.5 Kullanm Koullar . . . . . . . . . .
.
.
.
.
.
1
1
1
2
2
3
4
4
16
29
30
32
35
4 Programlamaya Giri
4.1 Betikler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Yol (Path ) Kavram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
41
48
5 Python Hakknda
5.1 Python Nedir? . . . . . . . . . . . . . . . . .
5.2 Neden Programlama renmek steyeyim?
5.3 Neden Python? . . . . . . . . . . . . . . . .
5.4 Python Nasl Telaffuz Edilir? . . . . . . . . .
5.5 Platform Destei . . . . . . . . . . . . . . .
5.6 Farkl Python Srmleri . . . . . . . . . . .
5.7 Hangi Seriyi renmeliyim? . . . . . . . . .
.
.
.
.
.
.
.
55
55
55
56
57
57
57
58
59
59
65
66
67
67
72
74
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7.4
74
8 Etkileimli Python
75
8.1 Pythonn Etkileimli Kabuu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.2 Etkileimli Kabukta lk Admlar . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.3 Etkileimli Kabuun Hafzas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
9 print() Fonksiyonu
9.1 Nedir, Ne e Yarar? . . . . . . . . . .
9.2 Nasl Kullanlr? . . . . . . . . . . . .
9.3 Bir Fonksiyon Olarak print() . . . . .
9.4 print() Fonksiyonunun Parametreleri
9.5 Birka Pratik Bilgi . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
101
101
102
106
107
117
10 Ka Dizileri
10.1 Ters Taksim (\) . . . . . . . .
10.2 Satr Ba (\n) . . . . . . . .
10.3 Sekme (\t) . . . . . . . . . .
10.4 Zil Sesi (\a) . . . . . . . . . .
10.5 Ayn Satr Ba (\r) . . . . . .
10.6 Dey Sekme (\v) . . . . . .
10.7 mle Kaydrma (\b) . . . . .
10.8 Kk Unicode (\u) . . . . .
10.9 Byk Unicode (\U) . . . . .
10.10 Uzun Ad (\N) . . . . . . . . .
10.11 Onaltl Karakter (\x) . . . .
10.12 Etkisizletirme (r) . . . . . .
10.13 Sayfa Ba (\f) . . . . . . . .
10.14 Ka Dizilerine Toplu Bak
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
125
127
129
132
133
134
135
135
136
137
138
139
140
142
143
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
160
160
162
162
164
164
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
211
211
217
218
226
229
230
233
18 Dngler (Loops)
18.1 while Dngs . . .
18.2 for Dngs . . . .
18.3 lgili Aralar . . . .
18.4 rnek Uygulamalar
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
244
245
252
258
265
19 Hata Yakalama
19.1 Hata Trleri . . . . . . . .
19.2 try... except... . . . . . . .
19.3 try... except... as... . . . .
19.4 try... except... else... . . .
19.5 try... except... nally... . .
19.6 raise . . . . . . . . . . . .
19.7 Btn Hatalar Yakalamak
19.8 rnek Uygulama . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
277
278
280
283
284
286
286
287
288
20 Karakter Dizileri
20.1 Karakter Dizilerinin elerine Erimek . . . .
20.2 Karakter Dizilerini Dilimlemek . . . . . . . . .
20.3 Karakter Dizilerini Ters evirmek . . . . . . .
20.4 Karakter Dizilerini Alfabe Srasna Dizmek . .
20.5 Karakter Dizileri zerinde Deiiklik Yapmak .
20.6 nemli Fonksiyon . . . . . . . . . . . . . .
20.7 Notlar . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
290
291
298
300
302
304
308
314
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
316
316
318
324
327
329
330
331
333
333
335
338
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
iii
22.4 casefold() . . . . . . . .
22.5 strip(), lstrip(), rstrip() .
22.6 join() . . . . . . . . . .
22.7 count() . . . . . . . . .
22.8 index(), rindex() . . . .
22.9 nd, rnd() . . . . . . .
22.10 center() . . . . . . . . .
22.11 rjust(), ljust() . . . . . .
22.12 zll() . . . . . . . . . .
22.13 partition(), rpartition()
22.14 encode() . . . . . . . .
22.15 expandtabs() . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
339
339
342
344
348
351
352
353
354
355
356
356
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
357
357
368
369
369
370
370
370
371
371
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
449
449
450
452
454
455
458
28 Saylar
460
28.1 Saylarn Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
28.2 Aritmetik Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
29 Temel Dosya lemleri
29.1 Dosya Oluturmak . . . . . .
29.2 Dosyaya Yazmak . . . . . . . .
29.3 Dosya Okumak . . . . . . . .
29.4 Dosyalar Otomatik Kapatma
iv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
468
468
469
471
473
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
483
483
483
484
484
485
486
486
496
496
498
500
.
.
.
.
503
503
506
513
522
.
.
.
.
.
.
.
527
527
529
530
531
531
533
534
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
35 Szlkler
35.1 Szlk Tanmlamak . . . . . . . . . . . . . . . .
35.2 Szlk elerine Erimek . . . . . . . . . . . .
35.3 Szlklerin Yaps . . . . . . . . . . . . . . . . .
35.4 Szlklere e Eklemek . . . . . . . . . . . . .
35.5 Szlk eleri zerinde Deiiklik Yapmak . . .
35.6 Szlk reteleri (Dictionary Comprehensions )
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
536
537
538
542
545
548
548
36 Szlklerin Metotlar
36.1 keys() . . . . . . .
36.2 values() . . . . . .
36.3 items() . . . . . .
36.4 get() . . . . . . . .
36.5 clear() . . . . . . .
36.6 copy() . . . . . . .
36.7 fromkeys() . . . .
36.8 pop() . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
550
550
551
552
553
554
555
556
557
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
577
577
581
585
588
592
601
603
607
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
612
612
613
614
615
616
617
618
618
618
621
622
622
623
623
623
624
624
624
625
626
627
627
627
627
628
631
632
632
632
632
633
634
634
39.34 id() . . . .
39.35 input() . .
39.36 format() .
39.37 lter() . . .
39.38 hash() . . .
39.39 isinstance()
39.40 len() . . . .
39.41 map() . . .
39.42 max() . . .
39.43 min() . . .
39.44 open() . .
39.45 pow() . . .
39.46 print() . . .
39.47 quit() . . .
39.48 range() . .
39.49 reversed()
39.50 sorted() . .
39.51 slice() . . .
39.52 sum() . . .
39.53 type() . . .
39.54 zip() . . . .
39.55 vars() . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
635
636
636
636
639
639
640
640
641
643
643
647
648
648
649
651
651
657
658
659
659
660
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
679
679
681
682
690
698
699
702
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
712
712
713
714
722
723
725
731
731
737
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
744
744
749
752
761
.
.
.
.
.
.
.
.
.
vii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
765
765
765
767
777
778
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
802
802
804
806
808
814
817
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
820
820
821
826
828
831
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
835
835
836
838
841
50 Dzenli fadeler
50.1 Dzenli fadelerin Metotlar . . . . . . . . . . . . . . . . . . .
50.2 Metakarakterler . . . . . . . . . . . . . . . . . . . . . . . . . .
50.3 Eleme Nesnelerinin Metotlar . . . . . . . . . . . . . . . . .
50.4 zel Diziler . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50.5 Dzenli fadelerin Derlenmesi . . . . . . . . . . . . . . . . . .
50.6 Dzenli fadelerle Metin/Karakter Dizisi Deitirme lemleri
50.7 Sonu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
850
851
858
874
876
878
880
884
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
885
885
885
886
887
888
890
viii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
890
891
892
893
894
895
896
897
898
903
904
909
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
911
911
929
941
945
956
53 Katkda Bulunanlar
53.1 Barbaros Akkurt . . .
53.2 ebnem Duyar . . . .
53.3 Onur Eker . . . . . .
53.4 Emre Erzgn . . . .
53.5 Tayfun Yaar . . . . .
53.6 Metin Hrn . . . . .
53.7 Ahmet ztekin . . . .
53.8 Mesut diz . . . . . .
53.9 Levent Civa . . . . . .
53.10 Frat Ekinci . . . . . .
53.11 Talha Kesler . . . . .
53.12 mer Gk . . . . . .
53.13 Yunus Emre Bulut . .
53.14 Erhan Paaolu . . .
53.15 Cemre Efe Karaka .
53.16 Salim Yldrm . . . .
53.17 aatay Genlik . . . .
53.18 Valeh Asadl . . . . .
53.19 Halit Turan Arcan . .
53.20 Levent Gler . . . . .
53.21 Yaar Celep . . . . .
53.22 Uur Uyar . . . . . .
53.23 Serdar alar . . . .
53.24 Ahmet Onur Yldrm
53.25 Anl lginolu . . . . .
53.26 Hseyin Ula Yeltrk
53.27 Nuri Acar . . . . . . .
53.28 Azat Frat imen . . .
53.29 Aykut Karda . . . . .
53.30 Sezer Bozkr . . . . .
53.31 Alican Uzunhan . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
961
961
961
961
962
962
962
963
963
963
963
963
964
964
964
964
964
965
965
965
965
966
966
966
966
967
967
967
968
968
968
968
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
ix
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
969
969
969
969
969
970
970
970
970
970
970
BLM 1
Bu Kitap Hakknda
Elinizdeki kitap, Python programlama dili iin kapsaml bir Trke kaynak oluturma
projesi olan [Link] bir rndr. Bu kitabn amac, herhangi bir sebeple Python
programlama diline ilgi duyan, bu programlama dilini renmek isteyen kiilere bu dili
olabildiince hzl, ayrntl ve kolay bir ekilde retmektir.
Bu kitabn hedef kitlesi, programlamay hi bilmeyen kiilerdir. Bu sebeple, bu kitapta ders
konularn olabildiince ayrntl ve basitletirilmi bir ekilde ele almaya altk. Ancak
eer gemiten gelen bir programlama deneyiminiz varsa, stelik programlamaya ilikin
kavramlara da ainaysanz, bu belgelerin yerine, Python programlama diline ait resmi
klavuzun1 , yine [Link] projesinin bir rn olan Trke evirisini2 takip etmeyi tercih
edebilirsiniz. Fakat reneceiniz ilk programlama dili Python ise, resmi klavuzu anlamak
epey zor gelecektir.
gmmek yerine, bol bol rnek kod yazmaya alrsanz, rendiiniz eyler zihninizde daha
kolay yer edecektir. Birincisi bu.
kincisi, kimse sizden bu kitaptaki her ayrnty ezberlemenizi beklemiyor. Maharet, bir
konuya ilikin btn ayrntlar aklda tutabilmekte deildir. yi bir programc, bir konuya dair
nasl aratrma yapacan ve kaynaklardan nasl faydalanacan bilir. Bir yazlm gelitirici
aday olarak sizin de renmeniz gereken ey, grdnz btn konular en ince ayrntsna
kadar ezberlemeye kalkmaktan ziyade, o konuya ilikin ilk aamada kir sahibi olmaya
almaktr. Pythonda ilerledike, zaten belli alanlara ilgi duyacak, kendinizi o alanlarda
gelitirmeye alacaksnz. Elbette ok uratnz konulara ilikin ayrntlar da daha kolay
aklnzda kalacaktr. stelik bir projeye ilikin gerekliliklerin sizi ynlendirmesiyle, belli
konularda daha ayrntl aratrma yapma frsat da bulacaksnz.
ncs, bir konuyu alrken yeterince anlayamadnz hissederseniz, ltfen dudanz
bzp bir duvar kesine kvrlarak kendi kendinizi ylgnla drmeyin. Eer bir konuyu
anlamadysanz, okuyup gein. Okuyup gemek iinize sinmiyorsa, aada belirttiimiz
ekilde yardm isteyin.
BLM 2
Biraz sonra Python programlama diliyle ilgili ilk almalarmz yapmaya balayacaz. Ama
herhangi bir programlama faaliyetine girimeden nce mutlaka biliyor olmamz gereken baz
eyler var. rnein, programlama renmek isteyen bir kii her eyden nce, program
yazmay tasarlad iletim sisteminde komut satrnn nasl kullanlacana dair temel bilgileri
edinmi olmaldr. Zira btn programlama dillerinde olduu gibi, Pythonda da komut
satr en byk yardmcmz olacak. Bu kitapta Python programlama dilinin temellerini
komut satr zerinde alarak reneceiz. zellikle yazacamz ilk programlar komut
satrnda alacak. O yzden, hi deilse bu kitaptan yararlanabilmek iin, kullandnz
iletim sisteminin komut satrna aina olmalsnz. Ayrca srf bu kitaptan yararlanabilmek
iin deil, btn programclk maceranz boyunca pek ok farkl sebepten, komut satr
zerinde almaya ihtiya duyacaksnz. te bundan tr, en azndan bu kitab rahatlkla
takip etmenizi salayacak kadar komut satr bilgisini bu blmde edinmenizi salamaya
alacaz.
Bu blmde, Python ile programlama maceramza balamadan nce komut satr hakknda
bilmemiz gerekenleri GNU/Linux ve Microsoft Windows iletim sistemleri iin ayr ayr ele
alacaz. Dilerseniz nce GNU/Linuxtan balayalm.
2.1 GNU/Linux
GNU/Linux iletim sisteminde komut satrna ilikin temel bilgilere halihazrda sahip olup
olmadnz anlamak iin aadaki nermelerin sizin anzdan doru olup olmadn kendi
kendinize sorgulayabilirsiniz:
1. Kullandm iletim sisteminde komut satrna nasl ulaacam biliyorum.
2. Komut satrn atktan sonra, o anda hangi dizin altnda bulunduumu anlayabilirim.
3. Mevcut alma dizini iindeki btn dosya ve dizinleri listeleyebilirim.
4. Komut satr araclyla dizinler arasnda dolaabilirim.
5. Masastnde bulunan bir dosyay, komut satrn kullanarak /usr/bin dizini iine
kopyalayabilirim, tayabilirim veya bu dosyay silebilirim.
6. Bir dosya silmek ile dizin silmenin birbirinden farkl eyler olduunu ve birbirinden farkl
ilemler uygulamak gerektiini biliyorum.
7. echo $HOME komutunun ne ie yaradn, bu komuttaki echo ve $HOME ifadelerinin ne
anlama geldiini gayet iyi biliyorum.
2.1. GNU/Linux
pwd
Bu ktda sekiz dizin, iki de dosya gryoruz. GNU/Linuxta dizin ve dosyalar komut ekrannda
farkl renklerle gsterilir. Bu sayede dizin ve dosyalar birbirinden rahatlkla ayrt edebilirsiniz.
cd Desktop
Bu komut bizi /home/istihza dizinine geri gtrecektir. Dikkat ederseniz yukardaki komut
bizi bir st dizine gtryor. Bu komutu tekrar verirseniz yine bir st dizine, yani /home
dizinine gidersiniz.
imdi ekranda /home ibaresi grnrken u komutu vererek masastne ulamaya aln:
cd Desktop
Grdnz gibi, bu defa bu komut bizi masastne gtrmek yerine bir hata mesaj verdi.
nk o anda bulunduumuz konumda artk Desktop bir alt dizin deil. Bu durumu teyit
etmek iin yine ls komutu yardmyla dizin ieriini kontrol edebilirsiniz. Grdnz gibi,
bu dizin ieriini gsteren ktda Desktop ad grnmyor. Eer aldnz ktda Desktop
yoksa, elbette cd Desktop komutu sizi masastne gtrmeyecektir. Byle bir durumda
masastne ulamak iin yle bir komut vermemiz gerekir:
2.1. GNU/Linux
cd istihza/Desktop
Burada [Link] dosyasnn yolunu, o anda iinde bulunduumuz dizine gre tarif
ettiimize dikkat edin. Bir dosya veya dizinin tek bir mutlak yolu ve o anda iinde bulunulan
konuma bal olarak birden fazla greceli yolu vardr. Dolaysyla bir dosya veya dizine, o
dosya veya dizinin greceli yolunu belirterek ulamak istediinizde, o anda hangi konumda
bulunduunuzu bilmiyorsanz, muhtemelen ilgili dosyaya veya dizine ulaamazsnz.
Byle bir ey yapabilmek iin, kullanclarnzn masastne giden yolu tespit edebilmeniz
lazm. Ama burada yle bir problem var: Bildiiniz gibi herkesin masastne giden yol ayn
deildir. Bir bilgisayardaki masastn bulabilmek iin, o bilgisayar kullanan kiinin kullanc
adn da biliyor olmanz lazm. nk masastnn bulunduu dizin kullanc adna bal
olarak farkl olacaktr.
Mesela /home/istihza/Desktop veya /home/mahmut/Desktop
Hatta iletim sisteminin dilinin Trke veya ngilizce olmasna gre de masastnn yolu
farkl olabilir. Mesela /home/ceren/Masast...
Peki biz bunca farkllkla kar karyayken, masastne giden yolu salkl bir ekilde nasl
tespit edeceiz?
te byle bir durumda imdadmza evre deikenleri (veya ortam deikenleri) denen
birtakm aralar yetiecek. Peki nedir bu evre deikenleri denen ey?
evre deikenleri, kullandmz iletim sisteminde belli deerlerin atand birtakm
isimlerdir. Bu tanm yeterince ak olmayabilir. O yzden isterseniz evre deikenlerini bir
rnekle anlatmaya alalm.
Mesela komut satrnda u komutu verelim:
echo $HOME
2.1. GNU/Linux
gsterdi. Ama neyse ki iletim sistemleri bize evre deikenleri gibi bir kolaylk sunuyor.
Bu deikenleri kullanarak, hangi konumda olursak olalm rahatlkla masastne ulaabiliriz:
cd $HOME/Desktop
Bunun dnda, ~ iareti de kullanc dizininin adn tutar. rnein, komut satrnda u komutu
verin:
echo ~
Bylece evre deikeni kavramn da anlatm ve bu esnada nemli bir evre deikenini
de incelemi olduk. Elbette evre deikenleri yukarda gsterdiimiz tek bir rnekten
ibaret deildir. Sisteme ve o sistemi kullanan kiiye ilikin pek ok nemli deeri iinde
barndran baka evre deikenleri de bulunur. Kullandnz iletim sisteminde hangi evre
deikenlerinin bulunduunu renmek iin u komutu verebilirsiniz:
set
10
.adobe/
.aptitude/
.cache/
.compiz-1/
.config/
.dbus/
Desktop/
Documents/
Downloads/
.dropbox/
Dropbox/
.fontconfig/
.gconf/
.gegl-0.0/
.gimp-2.6/
.gnome2/
.gstreamer-0.10/
.gvfs/
.icons/
lang/
.local/
.macromedia/
.mission-control/
.mozilla/
.mplayer/
Music/
Pictures/
.pki/
Public/
.pulse/
.shotwell/
Templates/
.themes/
.thumbnails/
.thunderbird/
Ubuntu One/
Videos/
Not: Yukardaki kt Ubuntu iletim sisteminden. Sizin kullandnz iletim sisteminin kts
elbette daha farkl olacaktr.
Not: Burada banda . iareti olanlar gizli, olmayanlar ise grnr dizinlerdir.
imdi ayn konumda cd D yazp yine iki kez Tab tuuna basn. yle bir kt alacaksnz:
Desktop/
Grdnz gibi, ad D har ile balayan dizinleri listeledik. Tab tuunun bu kod tamamlama
zellii sayesinde, ulamak istediiniz dizin adnn tamamn yazmak zorunda kalmadan,
sadece ilk birka harni yazp Tab tuuna basarak o dizine rahatlkla ulaabilirsiniz. rnein
cd De yazp iki kez Tab tuuna basarak (eer bir alt dizinde ilk hareri De olan baka bir dizin
yoksa) dorudan Desktop dizinine ulaabilirsiniz.
Bu arada, elbette Tab tuuna basldnda yalnzca dizin adlar tamamlanmaz. Ayn zamanda
bu ekilde dosya adlarn da tamamlayabilirsiniz. cd komutu yalnzca dizin adlaryla
birlikte kullanlabildii iin bu komuttan sonra Tab tuuna basldnda yalnzca dizin adlar
tamamlanacaktr. Ama mesela eer echo komutunu yazdktan sonra bir boluk brakp Tab
tuuna basarsanz dizinlerle birlikte dosyalarn da tamamlandn grrsnz.
veya:
/home/istihza/Desktop/[Link]
2.1. GNU/Linux
11
Ayn ekilde, sistem gncelleme gibi hassas bir ilemi yerine getirebilmek iin de root
haklarna sahip olmanz gerekir:
sudo apt-get update
sudo apt-get upgrade
Banda sudo olan bir komutu veya su komutunu verdiimizde iletim sistemimiz bize root
parolasn sorar.
Uyar: Root parolas girilirken, gvenlik gereince parolay ekranda grmezsiniz; siz yine
de doru bir ekilde parolay girip ENTER dmesine basn.
Baka baz GNU/Linux datmlar ise, komutlarn bana sudo getirilmesi yerine, nce su ile
root olunmasn, sonra ilgili komutun verilmesini zorunlu tutar. Buna gre nce su ile ynetici
haklarn alrz:
su
veya:
apt-get update
apt-get upgrade
Parolamz doru bir ekilde girdiimizde root yetkilerini elimize alm oluruz. Bylece
yukardaki hassas komutlar altrabilmeye hak kazanrz. Root parolasna sahip olmayan
sradan bir kullanc GNU/Linuxta yalnzca kendi ev (home) dizinine mdahale edebilir.
GNU/Linux datmlarnda yetkisiz bir kullanc ancak ev dizini iindeki dosyalara mdahale
edebilir; bir dosyay, rnein $HOME dizininden /usr/bin dizini iine kopyalamak isterse root
(yani ynetici) haklarn almas gerekir.
Sradan kullanc olarak yetkimiz olmayan konumlara dosya yneticileri araclyla grak
olarak erimenin baz yntemleri olsa da en kestirme yol kopyalama, tama ve silme gibi
ilemleri komut satr zerinden halletmektir. Bu tr dosyalara mdahale ederken komut
satrn kullanmak ilerinizi epey hzlandracaktr. te biz de ilerinizi kolayca yapmanz
salamak iin bu blmde dosya kopyalama, tama ve silme gibi dosya ve dizin ilemlerinin
komut satr araclyla nasl yaplacan inceleyeceiz.
Dosya Kopyalama
Bir dosyay baka bir konuma kopyalamak iin cp adl bir komuttan yararlanyoruz. Bu komut
yle kullanlyor:
cp zgn_konumdaki_dosya hedef_konumdaki_dosya
Elbette, daha nce de sylediimiz gibi, /usr/bin dizinine bir dosya kopyalayabilmek iin root
haklarna sahip olmalsnz. Dolaysyla yukardaki komutlar, balarna sudo getirerek (veya
nce su komutuyla root haklarn alarak) yazmalsnz:
sudo cp $HOME/Desktop/[Link] /usr/bin/[Link]
Eer bir dizinin tamamn baka bir konuma kopyalamak istiyorsanz, yukardaki komutlar -rf
parametresi ile altrmanz gerekir. Yani:
2.1. GNU/Linux
13
veya:
sudo cp -rf zgn_dizin hedef_dizin_adresi
Dosya Silme
Bir dosyay silmek iin rm adl bir komuttan yararlanyoruz. rnein masastnde bulunan
[Link] adl dosyay silmek iin u komutu veriyoruz:
rm $HOME/Desktop/[Link]
Elbette eer sileceimiz dosya ev dizini dndaysa bu komutu root yetkileri ile altrmamz
gerekir:
sudo rm /usr/bin/[Link]
rm komutu yukardaki ekilde ancak dosyalar silmek iin kullanlabilir. Eer silmek istediiniz
ey bir dosya deil de dizin ise o zaman rm komutunu -rf parametresi ile birlikte altrmamz
gerekir:
rm -rf $HOME/silinecek_dizin
Dosya Tama
Bir dosyay bir yerden baka bir yere tamak iin mv adl bir komuttan yararlanacaz:
mv zgn_konumdaki_dosya hedef_konumdaki_dosya
rnein masastnde bulunan [Link] adl bir dosyay /usr/bin dizinine tamak iin
yle bir komut yazyoruz:
sudo mv $HOME/Desktop/[Link] /usr/bin/
Bu komut masastndeki [Link] dosyasn silip /usr/bin/ dizini altnda [Link] adl
baka bir dosya oluturacak, yani dosyay masastnden /usr/bin dizinine tam olacaktr.
Eer [Link] dosyasn farkl bir adla tamak isterseniz yukardaki komutu yle
yazabilirsiniz:
sudo mv $HOME/Desktop/[Link] /usr/bin/yeni_ad
14
Dosya Balama
Eer bir dosyay baka bir konuma kopyalamak yerine, o dosyaya baka bir konumdan ksa
yol oluturmak isterseniz ilgili dosyay ilgili konuma balamay tercih edebilirsiniz. Mesela
/usr/local/bin/[Link] adl dosyay /usr/bin/ konumuna balamak, yani bir bakma ksa
yol oluturmak isterseniz ln komutundan yararlanabilirsiniz:
ln -s /usr/local/bin/[Link] /usr/bin/program
15
veya:
ls --all
Peki bir komutun ne tr yeteneklere sahip olduunu veya ne ie yaradn nasl reneceiz?
Elbette bunun iin nternet zerinde bulunan kaynaklar tarayabilirsiniz. Ama ilk bavuru
kaynanz yine komut satr olmaldr.
Herhangi bir komut hakknda ayrntl bilgi almak iin genellikle help, parametresi kullanlr.
Mesela:
cp --help
Bu komutu verdiimizde, olduka ayrntl bir kullanm klavuzu ile karlarz. Burada cp
komutu hakknda renmek istediiniz her eyi bulabilirsiniz.
help parametresi dnda ayrca man veya info adl zel bir komutu kullanarak da eitli
klavuzlara ulaabilirsiniz. rnein:
man cd
veya:
info mv
Bu ekilde sayfalarca klavuza ulaabilirsiniz. Eer uzun bir klavuzu yarda kesip kmak
isterseniz klavyedeki q tuuna basabilirsiniz.
Bylece bu kitaptan yararlanabilmek iin GNU/Linuxta komut satrna dair bilmemiz
gerekenleri renmi olduk. imdi de Windowsta komut satr hakknda neleri bilmemiz
gerektiinden sz edeceiz. Eer Windows kullanmyorsanz, aadaki blm atlayp bir
sonraki konuya geebilirsiniz.
16
Bu temel bilgilere halihazrda sahip olup olmadnz anlamak iin aadaki nermelerin
sizin anzdan doru olup olmadn kendi kendinize sorgulayabilirsiniz:
1. Kullandm iletim sisteminde komut satrna nasl ulaacam biliyorum.
2. Komut satrn atktan sonra, o anda hangi dizin altnda bulunduumu anlayabilirim.
3. Mevcut alma dizini iindeki btn dosya ve dizinleri listeleyebilirim.
4. Komut satr araclyla dizinler arasnda dolaabilirim.
5. Masastnde bulunan bir dosyay, komut satrn kullanarak C:\Users dizini iine
kopyalayabilirim, tayabilirim veya bu dosyay silebilirim.
6. Bir dosya silmek ile dizin silmenin birbirinden farkl eyler olduunu ve birbirinden farkl
ilemler uygulamak gerektiini biliyorum.
7. echo %USERPROFILE% komutunun ne ie yaradn, bu komuttaki echo ve %USERPROFILE%
ifadelerinin ne anlama geldiini gayet iyi biliyorum.
8. access denied ifadesinin ne anlama geldiini biliyorum. Bu hataya bakarak, sorunun
nereden kaynaklandn tahmin edebilir, zmn ne olduunu kestirebilirim.
9. Bir program ynetici olarak nasl altrabileceimi biliyorum.
Eer yukardaki nermelerin tamamna doru cevabn verebiliyorsanz bu blm hzlca
gzden geirip yolunuza devam edebilirsiniz. Ama eer komut satr konusunda bilginiz yoksa
veya yetersizse, stelik yukardaki nermelere de olumlu cevap veremiyorsanz bu blm
iyice sindirmeden ltfen bir sonraki blme gemeyin. Bu blm hakkyla tamamlamanz,
kitaptan salkl bir ekilde yararlanabilmeniz asndan byk nem tayor.
17
Komut satrnda C:\Users\istihza> ibaresi grnrken bu komutu verirseniz una benzer bir
kt alrsnz:
27.06.2011
17.11.2011
27.09.2011
28.09.2010
31.03.2011
02.11.2009
12:31
10:09
15:35
12:13
14:49
11:19
<DIR>
<DIR>
<DIR>
<DIR>
16 Dosya
22 Dizin
Belgeler
Desktop
183 [Link]
251 [Link]
Start Menu
Sk Kullanlanlar
13.376.408 bayt
[Link] bayt bo
Grdnz gibi, dir komutu o anda iinde bulunduunuz dizinde yer alan dosya ve
klasrleri listeliyor.
18
Yukardaki ktda, sol tarafnda <DIR> ibaresi tayan eler birer dizindir. Eer sol tarafta
herhangi bir ibare yoksa o e bir dosyadr. rnein yukardaki ktda Belgeler, Desktop,
Start Menu ve Sk Kullanlanlar birer dizinken, [Link] ve [Link] birer dosyadr.
19
Bu komut bizi C:\Users\istihza dizinine geri gtrecektir. Dikkat ederseniz yukardaki komut
bizi bir st dizine gtryor. Bu komutu tekrar verirseniz yine bir st dizine, yani C:\Users
dizinine gidersiniz.
imdi ekranda C:\Users ibaresi grnrken u komutu vererek masastne ulamaya aln:
cd Desktop
Grdnz gibi, bu defa bu komut bizi masastne gtrmek yerine bir hata mesaj verdi.
nk o anda bulunduumuz konumda artk Desktop bir alt dizin deil. Bu durumu teyit
etmek iin yine dir komutu yardmyla dizin ieriini kontrol edebilirsiniz. Grdnz gibi,
bu dizin ieriini gsteren ktda Desktop ad grnmyor. Eer aldnz ktda Desktop
yoksa, elbette cd Desktop komutu sizi masastne gtrmeyecektir. Byle bir durumda
masastne ulamak iin yle bir komut vermemiz gerekir:
cd istihza\Desktop
20
C:\Users\Firat\Desktop\[Link]
Grdnz gibi, burada [Link] dosyasnn adresini kk dizinden, yani C:\ dizininden
itibaren eksiksiz bir ekilde belirttik. O anda bilgisayarda hangi dizin altnda bulunuyor
olursanz olun, [Link] nin mutlak yolunu kullanarak bu dosyaya ulaabilirsiniz.
Bir dosya ve dizinin greceli (veya bal) yolu ise, o dosya veya dizinin, o anda iinde bulunulan
dizine gre tarif edilen konumudur. Mesela o anda C:\Users dizini altnda bulunuyorsak,
masastndeki [Link] adl dosyann greceli yolu udur:
firat\Desktop\[Link]
Burada [Link] dosyasnn yolunu, o anda iinde bulunduumuz dizine gre tarif
ettiimize dikkat edin. Bir dosya veya dizinin tek bir mutlak yolu ve o anda iinde bulunulan
konuma bal olarak birden fazla greceli yolu vardr. Dolaysyla bir dosya veya dizine, o
dosya veya dizinin greceli yolunu belirterek ulamak istediinizde, o anda hangi konumda
bulunduunuzu bilmiyorsanz, muhtemelen ilgili dosyaya veya dizine ulaamazsnz.
21
Bylece evre deikeni kavramn da anlatm ve bu esnada nemli bir evre deikenini
de incelemi olduk. Elbette evre deikenleri yukarda gsterdiimiz tek bir rnekten
ibaret deildir. Sisteme ve o sistemi kullanan kiiye ilikin pek ok nemli deeri iinde
barndran baka evre deikenleri de bulunur. Kullandnz iletim sisteminde hangi evre
deikenlerinin bulunduunu renmek iin u komutu verebilirsiniz:
set
22
konuyu bir kenara brakp, komut satrnn kullanmna ilikin nemli baka bir konudan sz
edelim.
Ancak bu ters taksim iareti (\ ) yalnzca Windowsta alr. Bu iareti GNU/Linux dizinlerini
ayrmak iin kullanamayz. GNU/Linuxta dizinleri birbirinden ayrmak iin dz taksim (/ )
iaretini kullanyoruz.
Dz taksim iareti ou durumda Windowsta da alr. Dolaysyla yazdnz programlarn
birden fazla platform zerinde almasn istiyorsanz, her iki iletim sistemi iin de ters
taksim yerine dz taksim iaretini kullanmanz daha mantkl olacaktr.
23
C:\Windows gibi, kendi kullanc adnn dnda kalan dizinler altna herhangi bir dosya
kopyalayamaz, buradan herhangi bir dosya silemez ya da burada yeni bir dosya oluturamaz.
Birazdan ynetici haklarndan ve bu haklarn nasl alnacandan daha ayrntl olarak sz
edeceiz. Ama bundan nce, kullanc yetkilerini daha iyi anlayabilmemizi salayacak baz
somut bilgileri edinmemiz gerekiyor. Bu bilgileri edinmeden kullanc yetkilerini anlatmaya
alrsak, anlattmz eyler havada kalacaktr.
24
veya:
erase dosya_ad
Bu komutlar kullanarak bir dizini silmeye altnzda, silmeye altnz dizinin iindeki
dosyalar silinecektir.
Eer bir dizini iindeki dosyalarla birlikte tamamen silmek isterseniz rmdir adl baka bir
komutu kullanmanz gerekiyor:
25
rmdir /s /q dizin_ad
Burada rmdir komutunu /s ve /q parametreleri ile birlikte kullandmza dikkat edin. Eer
/s parametresini kullanmazsak, bu komut ii dolu dizinleri silmeyecektir. /q parametresi ise
silme ilemi srasnda emin misiniz? sorusunun sorulmasn engeller.
Dosya izinleriyle ilgili sylediimiz eyler burada da geerlidir.
Dosya Tama
Bir dosyay bir yerden baka bir yere tamak iin move adl bir komuttan yararlanacaz:
move zgn_konumdaki_dosya hedef_konumdaki_dosya
rnein masastnde bulunan [Link] adl bir dosyay Belgelerim dizinine tamak iin
yle bir komut yazyoruz:
move %USERPROFILE%\Desktop\[Link] %USERPROFILE%\Belgelerim
xcopy
extended copy - geniletilmi, gelitirilmi kopyalama. Daha dar kapsaml bir
kopyalama komutu olan copyye atfen bu isim verilmitir.
del
delete - sil
erase
erase - sil
rmdir
remove directory - dizini sil
/s
subdirectories - alt dizinlerin de kapsanacan belirtir
/q
quiet - lemin sessiz kipte, yani kt verilmeden yrtleceini belirtir
move
move - ta
Bu komut, eer mevcut dizin altnda gizli dosyalar varsa onlar da listeleyecektir.
Peki bir komutun ne tr yeteneklere sahip olduunu veya ne ie yaradn nasl reneceiz?
Elbette bunun iin nternet zerinde bulunan kaynaklar tarayabilirsiniz. Ama ilk bavuru
kaynanz yine komut satr olmaldr.
Bir komut hakknda yardm alabilmek iin /? parametresini kullanabilirsiniz. Mesela:
dir /?
Ayrca bir komuta ilikin yardm dosyalarna ulamak iin help adl bir komutu da
kullanabilirsiniz:
help dir
Bu ekilde dir komutuna ilikin olduka ayrntl bir klavuza eriebilirsiniz. Tamamlanmas
uzun sren bir klavuzu yarda kesmek iin q tuunu kullanabilirsiniz.
Bylece ok nemli bir konuyu geride brakm olduk. Buraya gelene kadar komut satrna
ilikin epey ey rendiniz. Bylece en azndan bu kitab takip etmenizi salayacak temel
komut satr bilgilerini edinmi oldunuz. Bu kitaptan yararlanabilmek iin komut satrna
ilikin olarak yukarda anlattklarmz bilmeniz yeterli olacaktr. Ancak eer yetkin bir
27
28
BLM 3
29
Yukarda anlattmz durum sayesinde, mesela basit bir program yazmak istediimizde,
bunun iin nce bilgisayar, sonra ekirdei, ardndan iletim sistemini, son olarak da
programlama dilini icat etmek zorunda kalmyoruz. Sadece yazacamz program en
verimli ekilde hayata geirmemizi salayacak bir programlama dili seiyoruz ve onun
zerinden ilerliyoruz. Ayn ekilde, amacmz bir programlama dili gelitirmekse, nce
bilgisayar, sonra ekirdei, ardndan da iletim sistemini sfrdan gelitirmiyoruz. Burada da,
gelitireceimiz programlama dilini hangi iletim sistemi veya sistemleri zerinde alacak
ekilde tasarlayacamz dnerek yola koyuluyoruz.
Burada derece derece ilerleyen katmanl bir yap ile kar karya olduumuza dikkat edin.
Esasnda bu yap etrafmzda grdmz her eyde vardr. Biz herhangi bir ey yapmak
istediimizde, ncelikle bizden nce yaplanlara bakarz. Yapmak istediimiz eyin temeli
hazrsa, o temeli bir de biz icat etmeye kalkmayz. Mesela elektrikli bir alet reteceksek,
bunun iin ihtiyacmz olan elektrii duvardaki prizin ucuna kadar getirecek olan sistemi
kendimiz sfrdan kurmaya almayz. Bunun yerine, halihazrda prizin ucuna getirilmi olan
elektrii kullanr, biz asl yapmak istediimiz ie odaklanrz. Esasnda insan teki canllardan
ayran en nemli zellik de budur zaten: Yani kendinden ncekilerin ina ettii bilgileri temel
alarak, bunlarn zerine yeni bilgi ina edebilme kabiliyeti.
Dolaysyla, halihazrda yaplm bir eyi sfrdan tekrar yapmak, ya da baka bir deyile
tekerlei yeniden icat etmek, u durum hari iyi bir kir deildir:
1. Tekerlein nasl altn renmek istiyorsunuzdur.
2. Tekerlein mevcut hali sizi tatmin etmiyordur ve daha iyisini yapabileceinizi
dnyorsunuzdur.
3. Patent kstlamalar nedeniyle tekerlei kullanamyorsunuzdur, o yzden zgn
tekerlein patentini ihlal etmeyecek ekilde tekerlei yeniden yapmanz gerekiyordur.
Bunlarn dndaki gerekeler, mesela tekerlein bize ait olmamas, tek vasf yerli olmas olan,
bunun dnda hibir meziyeti olmayan bir tekerlek icat etmemiz iin makul bir neden deildir.
31
nsanlar genellikle komut satr arayzn, grak kullanc arayz ve doal kullanc
arayzne kyasla ilkel bir yntem olarak grr. Her ne kadar, zellikle son kullanc ad
verilen genel halk, arlkl olarak grak kullanc arayzlerine veya doal kullanc arayzlerine
yneliyor olsa da, zellikle programclar asndan komut satr ve dolaysyla komutlar hl
vazgeilmezdir. Peki ama neden?
Yukarda verdiimiz bilet makinesi rnei zerinden konuacak olursak, komut satr arayz,
bilet makinesiyle dorudan muhatap olmaya benzer. Grak kullanc arayzleri ise bilet
makinesiyle sizin aranzdaki bileti gibidir. letim sistemiyle dorudan komutlar araclyla
iletiim kurmak, menler ve simgeler yoluyla iletiim kurmaya kyasla ok daha hzl ve
gvenilirdir. Ayrca menlerin ve simgelerin yeri ve ilevi sk sk deiiklie urarken, komutlar
genellikle yllarca deimeden kalr. Birine bilgisayarda bir ey yaptrmaya alrken, falanca
komutu gir, demek, nce u menye gir, sonra u dmeye bas, demekten ok daha pratik
bir yntemdir. Dahas, yazdnz bir programda bir grevi gerekletirmek iin, yani bir
ilevi programatik olarak yerine getirebilmek iin menleri veya dmeleri kullanamazsnz,
bunun iin mutlaka komutlar kullanmanz gerekir.
32
33
bir deiiklik yapamazsnz. yle ki, GNU/Linuxun zgr ve ak kaynakl olmas, size bu
iletim sisteminin damarlarnda akan kan bile deitirme imkan salar...
GNU/Linux ve Windows iletim sistemleri arasndaki, herkesi ilgilendiren nemli bir fark
da program kurma mantna ilikindir. letim sistemlerini yeni yeni tanyan kimselerin,
zellikle de GNU/Linuxa heves eden Windows kullanclarnn sklkla yapt hata, nternet
zerinde bulduklar her program tm iletim sistemlerine kurabileceklerini zannetmeleridir.
Ancak iletim sistemlerinin alma mant birbirlerinden tamamen farkl olduu iin, bir
iletim sisteminde yazlm kurmak iin kullandnz yntemi ve aralar baka bir iletim
sisteminde dorudan kullanamazsnz. Mesela nternet zerinde bulduunuz herhangi bir
programn .exe uzantl kurulum dosyasn alp rastgele hem Windowsa hem de GNU/Linuxa
kuramazsnz. (Bugn Wine adl bir uyumluluk katman yardmyla Windows uygulamalarn
GNU/Linuxta altrmak mmkn olsa da, bu ekilde altrlan bir Windows uygulamasnn
GNU/Linux zerindeki performans tatmin edici olmayabilir.)
GNU/Linux iletim sistemlerinde yazlm kurmak iin iki yntem bulunur. lk ynteme
gre, herhangi bir yazlmn kaynak kodlarn, gelitiricisinin datt yerden alp kendiniz
derleyebilirsiniz. Bu yntem, derleyeceiniz programn karmaklna bal olarak ok kolay
olabilecei gibi ok zor da olabilir. Bir program kaynaktan derleyebilmek iin, o programn
ihtiya duyduu ilave programlar da sizin temin etmeniz gerekir. Bir program, derlenebilmek
iin onlarca ilave programn (yani bamlln) halihazrda kurulu olmasn gerektiriyor
olabilir. stelik, kurmak istediiniz bir programn ihtiya duyduu bir programn kendisi de
baka programlara ihtiya duyuyor olabilir. Dahas, derlemeniz gereken bamllklarn ihtiya
duyduu baka bamllklarn srmleri de bir noktada birbiriyle uyumsuzluk gstermeye
balayabilir ve kendinizi bir anda bamllk cehennemi (dependency hell ) ad verilen bir
durumun iinde bulabilirsiniz. te o zaman bu cehennemden kurtulmak; kan, gzya ve ter
dkmenizi gerektirebilir...
GNU/Linuxta program kurmann ikinci ve makul yntemi ise, kullandnz datmn
paket ynetim sistemini kullanmaktr. GNU/Linux dnyasnda, Debian tabanl datmlarn
kulland DEB paket sistemi ve RedHat tabanl datmlarn kulland RPM paket sistemi
olmak zere iki byk paket ynetim sistemi bulunur. Bu paket ynetim sistemleri sayesinde
yazlmlar nternet zerindeki rastgele adreslerden deil, tpk Androiddeki Google Play ve
iOStaki Apple Store gibi merkezi bir yerden indirilir. ou GNU/Linux datmnn, paket
deposu ad verilen, kendi yazlm merkezi bulunur. te GNU/Linux yazlmlar da tek bir
tklamayla (veya tek bir komutla) bu depolardan indirilip kurulur. Bylece bir yazlmn ihtiya
duyduu bamllklar dert etmeden ve ilgili programn sisteminizde dzgn alacandan
emin olarak program gnl rahatlyla kurabilirsiniz.
Windowsta ise yazlmlar genellikle EXE (veya MSI) ad verilen bir biimde bulunur. Piyasada
bulunan masast ve dizst sistemlerinin byk bir ounluunda Windows iletim sistemi
kurulu olduu iin, program gelitiricileri genellikle yazlmlarn EXE olarak datr ve
dolaysyla herhangi bir yazlmn Windowsa uyumlu srmn bulmak, GNU/Linuxa uyumlu
srmn bulmaktan ok daha kolaydr.
Yazlmlarn merkezi bir yerden indirilebilmesi, gvenlik asndan nemli bir avantaj salar.
nk bu ekilde, iletim sistemine kurulan yazlmlar, iletim sistemini gelitiren ekibin
denetiminde olmaktadr. Dolaysyla GNU/Linux datmlarnda yllardr uygulanan bu sistem,
artk Microsoft Store gibi giriimler araclyla Microsoft rmasnn rnlerinde de ksmen
de olsa uygulanmaya allmaktadr.
u anda piyasada arlkl olarak farkl Windows srm bulunur: Windows 7, Windows
8 ve Windows 10. Bu kitaptaki Windows bilgileri genellikle Windows 7 ve Windows 10a
dayanacaktr. Ancak Windows 8 kullanclarnn da bu kitaptan yararlanamamas iin hibir
34
sebep yok. Python programlama dilinin 3.5 ve zeri srmleri Windows XPye kurulamad
iin, Windows XP kullanclar bu kitaptan yararlanamayacak.
35
Grdnz gibi, 2 saysn ifade etmemizi salayacak zel bir simge olmad iin baa
dndk ve tpk onlu sistemde olduu gibi, basamak artrarak simgeleri birbiriyle birletirdik.
Devam edelim:
0, 1, 10, 11, 100, 101, 110, 111, 1000
Burada 8e kadar saym olduk. Yalnz zihniniz tamamen onlu sisteme alkn olduu iin, bu
saylar takip etmekte zorlanabilirsiniz. Eer bu saylar telaffuz ederken sfr, bir, on, on
bir, yz diye deil de, sfr, bir, bir sfr, bir bir, bir sfr sfr eklinde telaffuz ederseniz
ikili sistemdeki saylar daha kolay kavrayabilirsiniz.
Peki bu ikili sistemin bilgisayarlarla alakas nedir?
Bildiiniz gibi, temelde bilgisayar dediimiz ey, zerinden elektrik akm geen birtakm
devrelerden ibarettir. Elektriksel adan bir devrede ya elektrik vardr ya da elektrik yoktur.
te bu ikili durumu temsil etmenin en mantkl yolu, ikili say sistemini kullanmaktr. Buna
gre, eer bir devrede elektrik akm varsa o devrenin deeri matematiksel olarak 1 says
ile ifade edilir. Ama eer o devrede elektrik akm yoksa, o devrenin deerini 0 says ile
ifade ederiz. Szn z, ikili (binary) sayma sistemini bilgisayarlarda kullanmamzn nedeni,
bir devredeki elektrik varln ve yokluunu birbirinden ayrt edebilmenin ve bu iki durumu
matematiksel olarak ifade etmenin en makul ynteminin bu olmasdr. Eer bir elektrik
devresi on farkl durumda bulunabiliyor olsayd, o zaman da makul yol onlu say sistemini
kullanmak olurdu. Ama iki farkl durumda (ak veya kapal) bulunabiliyor olduu iin, makul
yol ikili say sistemini kullanmaktr.
Bu arada, tamamen elektriksel sistemler olan bilgisayarlar iin herhangi bir say sisteminin
hibir ey ifade etmediine zellikle dikkatinizi ekmek isterim. Yani bir bilgisayar devresinde
gerekleen olay tamamen elektrikseldir, saysal deil. Bir bilgisayar devresi asndan tek
gereklik, bir transistrn ak veya kapal durumda olmasdr. Biz insanlar bu durumu
kafamzda somutlatrabilmek iin, saysal olarak temsil etme ihtiyac duyarz. Bu sebepten
de, transistrn ak olduu duruma 1, kapal olduu duruma 0 deriz. Yani esasnda ikili say
sistemi bilgisayar iin deil, biz insanlar iin bir eyler ifade eder.
Yukarda anlattmz eyleri somutlatrmak iin yle bir rnek verelim:
nnzde, yan yana dizilmi sekiz adet ampul olduunu hayal edin:
O O O O O O O O
Buradan elde ettiimiz say 10000000. Yalnz bu say ikili (binary) sisteme ait bir saydr. Bunu
daha aina olduumuz onlu sisteme evirirsek elde edeceimiz say 128 olacaktr.
Not: Bir sayy baka bir say sistemine evirmek iin nternet zerinde bulabileceiniz say
taban dntrclerini kullanabilirsiniz.
te ikili sayma sistemindeki bu 0 ve 1lerin her birine bir bit ad verilir. Yukardaki rnee
bakacak olursak, 10000000 says 8 bitlik bir saydr. nk burada 8 adet bit yan yana
gelmitir. Eer bu bitlerin 32 tanesini yan yana getirecek olursanz 32 bitlik bir say elde
36
edersiniz. Bunlarn 64 tanesi ise 64 bitlik bir say meydana getirir. Grdnz gibi, iin
mant son derece basit.
Peki size yle bir soru soraym: Acaba ikili sayma sisteminde 8 bitlik en byk say ka
olabilir?
Bunu cevaplamadan nce u soruyu cevaplayn:
Acaba 8 haneli en byk onlu say katr?
Bunun cevabn verebilmek iin, onlu say sistemindeki en byk tek say olan 9u
kullanabileceimizi biliyorsunuz:
999999999
8 haneli en byk onlu say budur. Eer buna bir say daha eklerseniz 9 haneye km
olursunuz.
te bu yntemi ikili say sisteminde de kullanacaz. Yani 8 bitlik en byk ikili sayy
bulabilmek iin, ikili say sisteminin en byk tek says olan 1i kullanacaz:
11111111
Demek ki 8 bitlik en byk say buymu. Eer yukardaki 1lerin yanna bir say daha eklersek
9 bitlik bir say elde etmi oluruz.
Bu sayy onlu sisteme evirirsek 255 saysn elde ederiz.
Gelin btn bu anlattklarmz iin gerek hayattan bir rnek verelim.
IP adreslerinin neye benzediini hepimiz biliyoruz. Mesela u bir IP adresidir:
[Link]
8 bitlik en byk ikili saynn onlu sistemdeki karlnn 255 olduunu biliyorsunuz.
Dolaysyla bir IP adresi en fazla yle olabilir:
[Link]
Hibir blokta 255ten byk bir say kullanamazsnz, nk bu bloklarn her biri 8 bit olacak
ekilde tasarlanmtr.
Grdnz gibi, burada her biri 8 bitten oluan toplam 4 blok var. Yani elimizdeki toplam
bit says 32. Peki 32 bitlik en byk say katr?
Hemen bakalm:
11111111111111111111111111111111
37
Burada 32 tane 1 var. Bu sayy onlu sisteme evirirsek 4294967295 saysn elde ederiz.
Bu demek oluyor ki, IPv4 sistemine gre, toplamda sadece [Link] adet IP adresi
retilebilir. Ancak teknolojinin ve nternetin gnmzdeki byme hz dnldnde bu
saynn yeterli olmayaca aikar. Bu sorunu zmek iin, 32 bit yerine 128 bitlik bir sistemin
kullanld IPv6ya geilmesi iin almalar sryor...
Baka bir rnek daha verelim...
Bildiiniz gibi, Google rmas, YouTube sitesindeki videolarn ka kez izlendiini takip etmek
iin ilgili videonun yannda bir saya gsteriyor. Bu saya 32 bitlik olduu iin en fazla
[Link] saysna kadar kabilir. Ancak burada yle bir durum var: Google rmas,
sayac tasarlarken, bir videonun izlenme says asla eksiye dmeyecek olsa bile, kendi
kodlama ilkeleri gereince1 , bu 32 bitlik saynn yarsn eksi saylara, br yarsn da art
saylara ayrm. Dolaysyla [Link] saysnn yars eksi saylara gittiinden tr,
YouTube zerinde bulunan bir videonun ka kez izlendiini takip edebilmek iin elimizde,
sfr da sayarsak toplam [Link] adet say kalm olacaktr.
2015 yl iinde PSY adl arkcnn Gangnam Style adl arksnn izlenme says bu pozitif say
limitini geride braknca, saya eksi saylara gemi ve bylece PSYnin videosunun izlenme
says eksilerde dolamaya balamtr. Dolaysyla Google rmas, 32 bitlik bu sayac tekrar
tasarlayp 64 bitlik bir saya haline getirdi. Bylece sitedeki videolar iin yeni izlenme limiti
[Link].709.551.615 olmu oldu.
Bu arada, YouTube sayacnn tam say tasarm ile IPv4n tam say tasarmnn birbirinden
farkl olduuna dikkat etmenizi istiyorum. Google rmas, 32 bit aralna hem eksi hem
de art saylar yerletirdii iin, videolarn izlenme saysnn takibinde 32 bit aralna isabet
eden [Link] adet saynn yalnzca yarsn kullanabiliyor. Zira videolarn izlenme says
asla eksiye dmeyecei iin, 32 bit aralndaki eksi saylar atl durumdadr. IPv4 sisteminde
ise, IP adreslerinin gsteriminde eksi saylara ihtiya olmayacandan tr, 32 bit aralnn
tamam yalnzca art saylara ayrlm, eksi saylara yer verilmemitir. Bu da, [Link]
adet saynn tamamnn IP adresleri iin kullanlabilmesine olanak tanmtr.
Szn z, bir yazlmn veya donanmn 32 bit olmas demek, o yazlm veya donanmn en
fazla 232 bit, yani sfr says ile birlikte [Link] adet bit zerinde ilem yapabilmesi
demektir. Ayn ekilde bir yazlm ya da donanmn 64 bit olmas demek, o yazlm ya da
donanmn 264 bit, yani sfr says ile birlikte [Link].709.551.616 adet bit zerinde
ilem yapabilmesi demektir.
Dolaysyla bilgisayarnzn ilemcisinin 32 bit veya 64 bit olmas, bu ilemcinin ka tane bit
zerinde ilem yapabileceini belirler. lemcinizin bit durumunun somut bir neticesini,
bilgisayarnzn kullanabilecei bellek miktarnda grebilirsiniz.
Buna gre, 32 bitlik bir ilemci en fazla 4 GB bellek kullanabilir. Yani:
4294967296 / (1024 x 1024) = 4096 MB = 4GB
64 bitlik bir ilemci ise en fazla 17 milyon terabayt civar bellek kullanabilir. Yani:
18446744073709551616 / (1024 x 1024) = 17592186044416 MB = ~ 17 milyon TB
Ancak burada yle bir durum var: Bellek denince sadece RAMi anlamayn; yukardaki
deerlere, RAM ile birlikte ekran kart bellei ve PCI bellei de dahildir. Dolaysyla eer
32 bitlik bir ilemciniz varsa, bilgisayarnza en fazla 3 GB civar RAM takabilirsiniz. letim
sisteminiz bunun tesini gremez. letim sisteminizin bunun tesini grebilmesi iin, hem
ilemcinizin hem de iletim sisteminizin 64 bitlik olmas gerekir.
1
38
64 bitlik ilemciler iin verdiimiz 17 milyon terabayt limiti de teoriktir. Yani teorik
olarak yaklak 17 milyon terabayt RAM kullanabilecek olsak da, pratikte ilemcinin
mimari kstlamalar ve bilgisayar kasasnn ziksel kstlamalar bu teorik limite ulamamz
engelleyecektir.
Yukarda szn ettiimiz neticelerinden tr, sahip olduumuz ilemci ile ilgili olarak
bilmemiz gereken en nemli eylerden biri, o ilemcinin 32 bit mi yoksa 64 bit mi olduudur.
Zira ilemcimizin 32 bit veya 64 bit oluu bu ilemcinin destekleyecei bellek miktarn ve
iletim sistemi mimarisini dorudan etkileyecektir.
Eer ilemcimiz 64 bit ise, bu ilemci zerine hem 32 bitlik hem de 64 bitlik iletim sistemlerini
kurabiliriz. Ama eer ilemcimiz 32 bit ise, bu ilemci yalnzca 32 bitlik iletim sistemlerini
destekleyebilecektir. Ayrca eer ilemcimiz 32 bit ise, bu sistem zerine 3 GBden fazla RAM
ykleyemeyeceiz demektir.
Peki acaba ilemcimizin mimarisini, yani 32 bit mi yoksa 64 bit mi olduunu nereden
anlayacaz?
Eer siz bir GNU/Linux kullancsysanz, ilemci (CPU) mimarisini sorgulamak iin lscpu
komutunu kullanabilirsiniz. Bu komut una benzer bir kt verir:
Architecture:
CPU op-mode(s):
Byte Order:
CPU(s):
Vendor ID:
CPU family:
Model:
Stepping:
CPU MHz:
BogoMIPS:
Hypervisor vendor:
Virtualization type:
i686
32-bit
Little Endian
12
Genu
6
45
7
2000.000
4000.00
VMware
full
Burada ikinci satrda grdnz CPU op-mode(s) ifadesinin karsndaki 32-bit deeri,
ilemcinizin 32 bit olduunu gsteriyor. Eer o satr yle olsayd:
CPU op-mode(s):
32-bit, 64-bit
Bu durumda ilemcinizin hem 32 bit, hem de 64 bit mimariyi desteklediini, yani 64 bit
olduunu anlayacaktk.
Yukardaki kt, ilemci mimarisi dnda, bize iletim sistemimizin mimarisi hakknda da bilgi
veriyor. lk satrda grdnz Architecture (mimari) ifadesinin karsndaki deere bakarak
iletim sisteminizin 32 bit mi, yoksa 64 bit mi olduunu anlayabilirsiniz. Burada grdnz
i386, i486, i586 veya i686 deerleri iletim sistemi mimarinizin 32 bit olduunu gsterir.
Eer burada x86_64 deerini grseydik, o zaman da iletim sistemimizin 64 bit olduunu
anlayacaktk.
Bunun dnda u komutlar da iletim sisteminizin mimarisi hakknda bilgi verecektir (bu
komutlarn hepsi her sistemde almayabilir):
1. getconf LONG_BIT
2. arch
3. uname -m
4. dpkg --print-architecture
3.3. 32 bit ve 64 bit Ne Demek?
39
Gelelim Windowsa...
Windowsta iletim sistemi mimarisini renmenin en kolay yolu wmic komutunu
kullanmaktr:
wmic os get osarchitecture
Bu komutun ktsnda, iletim sisteminizin mimarisi 32-bit veya 64-bit olarak aka
belirtilecektir.
Ayrca Windowsta alternatif olarak masastndeki Bilgisayar simgesine sa tklayp
zellikler mens iindeki Sistem ksmna da bakabilirsiniz.
Windowsta ilemci mimarisini renmek iin ise evre deikenlerinden biri olan
PROCESSOR_IDENTIFIER veya PROCESSOR_ARCHITECTURE kullanlabilir:
echo %PROCESSOR_IDENTIFIER%
veya:
echo %PROCESSOR_ARCHITECTURE%
Bunun dnda, wmic komutunu kullanarak da ilemci mimarisi hakknda bilgi edinebilirsiniz:
wmic cpu get caption
Bylece iletim sistemleri, ilemciler, mimariler ve say sistemleri konusunda temel bilgileri
edinmi olduk. Bu bilgileri de cebimize koyarak bir sonraki blme doru kararllkla
ilerleyebiliriz.
Dipnotlar:
40
BLM 4
Programlamaya Giri
4.1 Betikler
Geen blmde komut satr araclyla komutlar tek tek nasl altracamz renmitik.
Ancak komut satrna yazlan kodlarn tek seferlik olduunu, bunlarn herhangi bir
kalclnn olmadn farketmisinizdir. Komut satrna yazdmz kodlar herhangi bir
yere kaydetmediimiz iin, komut satrn kapattmz anda bu komutlar silinip gidecektir.
Kodlarmzn kalcln salamak ve bunlar bakalaryla paylaabilmek iin bunlar bir
dosyaya kaydetmemiz gerekiyor.
Ksa bir grevi hzlca yerine getirmek istediimizde, ilgili kodlar komut satr zerinde
altrmak, birka farkl menye girmekten veya birka dmeye tklamaktan daha makul bir
yntemdir. Ancak bazen, zellikle bilgisayardaki gnlk ilerimizi gerekletirmek iin, belli
komutlar art arda iletme ihtiyac duyarz. Byle bir durumda, kodlar tek tek komut satrnda
elle altrmak yerine, rutin bir ekilde tekrar ettiimiz ileri bir dosya iine alt alta yazp bu
dosyay altrmak daha pratik olacaktr. rnein her defasnda alt yedi tane komutu tek
tek elle vermek yerine bunlar bir dosyaya yazp kaydederseniz, daha sonra yalnzca kodlar
ieren bu dosyay altrmanz yeterli olacaktr. Ayrca, biraz nce de bahsettiimiz gibi,
komut satrna yazdnz kodlar tek seferliktir. Eer bunlar kalc hale getirip bakalaryla
paylaabilmek istiyorsanz, bunlar bir dosyaya kaydetmeniz gerekir.
te iinde birtakm kodlar barndran ve altrlabilme zelliine sahip bu tr zel dosyalara
betik (script ) ad verilir. Aslnda betik dediimiz dosyalar da birer programdr. Ancak
genellikle betik ile program arasnda kapsam ynnden ayrm yaplr. Bu ayrma gre,
betikler, programlara gre daha dar kapsaml aralardr. Betikler genellikle dosyalar saa
sola tama, bu dosyalar iinde baz deiiklikler yapma, nternetten birtakm dosyalar
indirme ve kurma gibi kstl ileri yerine getirmek iin kullanlrken, programlar ise daha geni
apl projeleri gerekletirmede kullanlr. Betikler zellikle otomatikletirmek istediimiz
41
basit, sral iler iin biilmi kaftandr. Programlar ise, oyunlar, web siteleri ve mobil
uygulamalar gibi daha karmak ve kapsaml programlar meydana getirmeye uygundur.
Bu blmde ele alacamz konular GNU/Linux ve Windows balklar altnda ayr ayr
inceleyeceiz. ncelikle GNU/Linuxtan balayalm.
4.1.1 GNU/Linux
Metin Dzenleyici
Kodlarmz kaydedebilmek iin, elbette iine yaz yazabilmemizi salayacak zel bir programa
ihtiyacmz olacak.
Eer KDE masast ortamn kullanyorsanz Kwrite adl bir metin dzenleyiciyi
kullanabilirsiniz. Kwritea ulamak iin ALT+F2 tularna birlikte basp, alan pencereye
Kwrite yazdktan sonra ENTER dmesine basabilirsiniz.
GNOME veya UNITY masast ortamn kullananlar ise Gedit adl bir metin dzenleyiciyi
kullanacak. Bu metin dzenleyiciye ulamak iin ALT+F2 ile alan pencerede Gedit komutunu
verebilirsiniz.
imdi metin dzenleyicinizi nasl ap kapatacanz iyice renin. Bundan sonra metin
dzenleyiciniz sizin en iyi dostunuz olacak.
Kabuk Betikleri
GNU/Linuxta almak zere yazlan betiklere kabuk betii (shell script ) ad verilir.
Basit bir kabuk betii (shell script ) oluturmak iin metin dzenleyicimizi ap u satr
yazyoruz:
echo merhaba zalim dnya
GNU/Linuxta kabuk betikleri sh adl bir program araclyla altrlr. te burada da ilk
satrn amac, betiimizi altracak olan sh adl bu programn iletim sisteminde hangi
konumda olduunu belirtmektir. Demek ki sh program /bin dizini iinde bulunuyormu.
Esasnda kabuk betikleri, bu satr belirtmeseniz de byk ihtimalle dzgn alacaktr. Yine
de bu satr aka belirtmek her zaman iyi bir kirdir ve srprizlerle karlamanz nler.
Bu betii yazp deneme adyla kaydedelim ve kaydettiimiz konuma gelip u komutu verelim:
./deneme
42
Bu komutu bu ekilde verdiinizde, deneme adl dosya iin, sistemdeki herkese altrma
yetkisi vermi oluyorsunuz. Yani iletim sisteminizde oturum aan herkes deneme adl bu
program altrabilecektir. Eer yukardaki komutu u ekilde verirseniz dosyay yalnzca
dosyann sahibi, yani siz, altrabilirsiniz:
chmod u+x deneme
chmod -x deneme
Eer echo $PATH komutunun ktsnda grnen dizinler iinde tesadfen deneme adl
baka bir dosya varsa, yukardaki komutu ./ iaretleri olmadan verdiinizde kendi yazdnz
4.1. Betikler
43
program dosyas deil, o dosya alacaktr. O yzden, o anda iinde bulunduumuz dizinde
yer alan program dosyalarn altrrken ./ iaretlerini kullanmaya dikkat ediyoruz.
Not: $PATH adl evre deikeninden ilerleyen sayfalarda daha ayrntl bir ekilde sz
edeceiz.
GNU/Linuxta kabuk betiklerinin nasl altn temel olarak rendiimize gre, basit bir
kabuk betii yazarak rendiklerimizi test edebiliriz:
#!/bin/sh
echo
echo
echo
wget
Burada ilk olarak art arda echo satr gryoruz. Bu satrlarn grevi, yaplacak ileri ifade
eden cmleleri ekrana kt olarak vermek. ncelikle Python klavuzunun indirilmekte olduu
bilgisini veriyoruz:
echo Python klavuzu indiriliyor
Burada $pwd adl evre deikenini kullandmza dikkat edin. Bu kodlar altran kiinin
sisteminde $pwd deikeninin deeri neyse, betik alrken o dizinin adresi kt olarak
verilecektir.
Betii altran kiiye baz bilgiler verdikten sonra, GNU/Linux datmlarnda bulunan wget
adl bir program kullanarak [Link] adresinde
bulunan dosyay o anda iinde bulunduumuz dizine, yani mevcut alma dizinine
indiriyoruz.
Daha sonra, bu betii altran kiiyi, indirilen dosyann isminin deitirilmekte olduu
konusunda bilgilendiriyoruz:
echo ndirilen dosyann ismi deitiriliyor
44
#!/bin/sh
wget [Link]
mv [Link] python_kilavuzu.pdf
4.1.2 Windows
Metin Dzenleyici
Kodlarmz kaydedebilmek iin, elbette iine yaz yazabilmemizi salayacak zel bir programa
ihtiyacmz olacak.
Bunun iin balang olarak, btn Windows srmlerinde kurulu olan Notepad adl yazlm
kullanabilirsiniz. Notepade balat mensnde ulaabileceiniz gibi, komut satrnda notepad
komutunu altrarak da ulaabilirsiniz.
imdi metin dzenleyicinizi nasl ap kapatacanz iyice renin. Bundan sonra metin
dzenleyiciniz sizin en iyi dostunuz olacak.
Toplu Betikleri
Diyelim ki bilgisayarnzn sabit diskinde yer amak iin ara sra geici dosyalar silmek
istiyorsunuz. Windowsta geici dosyalar %TEMP% adl evre deikeninin gsterdii dizin
iinde bulunur. Burada biriken dosyalar rahatlkla silebilirsiniz.
Bu geici dosyalar ortadan kaldrmak iin dorudan bu klasrlerin iine gidip bunlar
SHIFT+DELETE tu bileimi yardmyla silebilirsiniz. Ya da komut satrnda srasyla u
komutlar iletebilirsiniz:
del /f /s /q %TEMP%
rmdir /s /q %TEMP%
Burada del komutu %TEMP% dizini iindeki btn klasr ve alt klasrlerin iini boaltr.
Bu komuta verdiimiz /f parametresi salt okunur dosyalarn da silinmesini salarken, /s
parametresi alt dizinlerde bulunan dosyalarn da silinmesini salar. Burada grdmz
/q parametresinin grevi ise silme srasnda iletim sisteminin sorabilecei onay sorularn
susturmaktr.
del komutunun ardndan kullandmz rmdir komutu ise bu bo klasr ve alt klasrleri hzl
bir ekilde ortadan kaldrr. /s ve /q parametrelerinin grevi ise, srasyla, ii dolu dizinleri de
silmek ve silerken emin misiniz? diye sorulmasn engellemektir.
Aslnda rmdir /s /q %TEMP% komutu tek bana da kullanlabilir. Bu ekilde dizinleri iindeki
dosyalarla birlikte silmi olursunuz. Ancak ilgin bir ekilde, bu iki komut art arda verildiinde,
rmdir /s /q %TEMP% komutunun tek bana verilmesine kyasla, silme ilemi kat daha hzl
gereklemektedir.
Eer yukardaki komutlar dzenli olarak kullanacaksanz, her defasnda bu iki satr tek
tek altrmak bir sre sonra skc bir hal almaya balayabilir. Bunun gibi, birden fazla
satrdan oluan kodlarnz tek tek elle vermek yerine, bunlar bir dosya iine kaydedip
altrabilirsiniz. te bu tr toplu ileri yerine getiren zel betiklere Windowsta toplu i
betii (batch script ) ad verilir.
4.1. Betikler
45
Gelin isterseniz toplu i betiklerinin nasl altn anlamak iin basit bir rnek verelim.
imdi komut satrnda notepad komutunu vererek Notepad adl metin dzenleyiciyi balatn.
Alan bo dosyaya unlar yazn:
echo merhaba zalim dnya
Bu dosyay [Link] adyla ve kodlama (encoding ) ANSI olacak ekilde kaydedin. Dosyay
kaydettiiniz konumda bir komut satr balatn ve u komutu verin:
[Link]
Grdnz gibi, betik iine yazdmz echo komutununun kendisi de ktda grnyor.
Bunu engellemek ve daha temiz bir kt almak iin betiimizin bana su satr ekleyeceiz:
@echo off
Burada, @echo off satrn yazarak, echo zelliini kapattk. Bylece betiimiz komutun
kendisini kt olarak vermeyecek.
imdi bu betii tekrar altralm. Grdnz gibi, bu defa daha temiz bir kt aldk. Ancak
burada bir baka sorun daha var: Merhaba zalim dnya ifadesi iinde geen Trke karakter,
yani har ktda dzgn grnmyor. Bu durum btn Trke karakterler iin geerlidir.
Mesela yukardaki betii yle yazalm:
@echo off
echo
46
Bu komut, mevcut komut satr oturumunun dil kodlamasn cp1254 olarak ayarlayacaktr.
cp1254 numaral bu dil kodlamas Trke karakterleri gsterebilmektedir.
Btn bu ilemleri yaptktan sonra betiinizi tekrar altrn.
olmalsnz:
Eer isterseniz, yukarda verdiimiz chcp 1254 komutunu da betiimize dahil edebiliriz:
@echo off
chcp 1254
echo merhaba zalim dnya
Grdnz gibi, burada Etkin kod sayfas: 1254 diye fazladan bir satr daha var. Bu satr,
chcp 1254 komutundan geliyor. Bunu engellemek iin betiimizi yle yazyoruz:
@echo off
chcp 1254 > nul
echo merhaba zalim dnya
Burada grdmz > nul ifadesi, yapt ilemin sonucunu raporlayan chcp gibi komutlar
susturmak iin kullanlr. Bu ifade ile, normalde ktlarn komutun verildii ortama gnderen
chcp komutuna, ktlarn hibir yere gnderme mesaj vermi oluyoruz. Eer bu komutun
ktsn, mesela [Link] adl bir dosyaya ynlendirmek istersek o ifadeyi yle yazabiliriz:
chcp 1254 > [Link]
Bu ekilde, betiinizle ayn dizin iinde [Link] adl bir dosya daha oluacaktr. Bu dosyann
iini ap baktnzda chcp 1254 komutunun ktsn orada greceksiniz.
Bir betik dosyasnn neye benzediini ve temel olarak nasl hazrlanacan rendiimize
gre, bu blmn banda bahsettiimiz u kodlar ieren bir toplu i betii yazabiliriz:
del /f /s /q %TEMP%
rmdir /s /q %TEMP%
Bu dosyay [Link] adyla ve kodlama ANSI olacak ekilde kaydedip normal bir ekilde
altrabiliriz. Burada, iinde Trke karakter geen herhangi bir ifade kullanmadmz iin,
chcp 1254 komutunu iletmediimize dikkat edin. nk bu betikte buna gerek yok.
4.1. Betikler
47
Windows iletim sisteminde ise ayn ilev iin komut satrnda u komutu veriyoruz:
echo %PATH%
te bu kt bize yol deikeni (ngilizcede path variable ) dediimiz eyi gsteriyor. letim
sistemimiz, bir program armak istediimizde, yani komut satrnda programn adn yazp
Enter tuuna bastmzda ncelikle yukarda ad verilen dizinlerin iini kontrol edecektir.
Eer ardmz programn altrlabilir dosyas bu dizinlerden herhangi birinin iinde ise
o program ismiyle arabiliyoruz.
GNU/Linux iletim sisteminde bir programn yolunun ne olduunu bulmak iin which adl
bir sistem komutundan yararlanabiliriz. rnein Gedit programnn yolunu bulmak iin u
komutu verelim:
which gedit
48
Bu komut /usr/bin/gedit ktsn verecektir. Hemen yukarda echo $PATH komutunun ktsn
kontrol ediyoruz ve gryoruz ki /usr/bin/ dizini yol deikenleri arasnda var. Dolaysyla,
Gedit program yol stndedir, diyoruz. Zaten Gedit programnn yol stnde olmas
sayesinde, konsolda sadece gedit komutunu vererek Gedit programn altrabiliyoruz.
Bu arada elbette which gedit komutunun dzgn kt verebilmesi iin Gedit adl programn
sisteminizde kurulu olmas gerekiyor. Bu program genellikle GNOME ve UNITY masast
ortamlarnn kurulu olduu GNU/Linux datmlarnda bulunur. Eer KDE adl masast
ortamn kullanyorsanz Gedit adl program sizde kurulu olmayabilir. Eer yleyse siz
Gedit yerine, sisteminizde kurulu olduundan emin olduunuz baka bir programn adn
verebilirsiniz. Mesela kwrite veya kate.
Gelelim Windowsa...
Windowsta, which komutu yerine where adl komutu kullanabiliriz:
where [Link]
Yol zerinde bulunmayan bir program altrmak iin o programn tam yol adresini
kendimiz yazmalyz. Program yol stnde bulunmad iin iletim sistemimiz bu programn
altrlabilir dosyasnn nerede olduunu bulamyor. Bu yzden programn nerede olduunu
iletim sistemimize bizim sylememiz gerekiyor. Mesela [Link] yol stnde olmad
iin iletim sistemimizin bu program srf ismiyle altrmas mmkn deil. letim
sistemimizin bu program bulabilmesi iin, bu programn tam yolunu elle bizim girmemiz
gerekiyor:
"C:\Program Files\Windows Media Player\[Link]"
49
Ayn ekilde GNU/Linux iletim sistemlerinde /etc dizini de yol zerinde olmad iin mesela
bu dizinde yer alan fstab dosyasn dorudan adyla aramayz. Bu yzden, bu dosyay
amamz gereken durumlarda, dosyann bulunduu konumun tam adresini yazmamz lazm.
rnein /etc/fstab adl dosyay Gedit programyla amay deneyelim:
gedit fstab
Bu komut, o anda bulunduunuz dizin iinde fstab adl bo bir dosya oluturacaktr. Bizim
amaya altmz asl fstab dosyas yol zerinde bulunmad iin bu dosyay sadece adn
kullanarak aamayz. Bu dosyay aabilmek iin dosyann konumunu eksiksiz bir biimde
yazmamz lazm:
gedit /etc/fstab
50
Bu ekranda Gelimi sekmesinin iinde Ortam Deikenleri adl bir dme greceksiniz. Bu
dmeye tkladnzda ise karnza yle bir pencere alacak:
51
Bu pencerede Sistem Deikenleri bal altnda birtakm eleri barndran bir liste
greceksiniz. O listede Path adl girdiyi bulun. Path girdisine ift tkladnzda yle bir
pencere ile karlaacaksnz:
Daha nce
wmplayer
Grdnz gibi, artk bu komut bize bir hata mesaj vermek yerine, doru bir ekilde
Windows Media Player adl program altryor. te bunun sebebi, bizim Windows Media
Player programn barndran dizini yola eklemi olmamzdr. Bu sayede biz wmplayer
komutunu verdiimizde iletim sistemimiz ilgili program nerede aramas gerektiini biliyor.
sterseniz echo %PATH% komutunu verip C:\Program Files\Windows Media Player adl dizinin
gerekten yola eklenip eklenmediini kontrol edebilirsiniz.
Bu arada, yol deikeni zerinde yaptnz herhangi bir deiikliin etkinleebilmesi iin
ak olan btn MS-DOS komut pencerelerini kapatmanz gerekir. Komut penceresini tekrar
atnzda, yaptnz deiiklikler etkinleecektir.
Gelelim GNU/Linux kullanclarnn durumuna...
Bildiiniz gibi, GNU/Linux iletim sistemlerinde yol dizinlerini listelemek iin yle bir komut
kullanyoruz:
echo $PATH
Grdnz gibi, nasl Windows iletim sistemlerinde yol dizinleri birbirinden ; iareti
ile ayrlyorsa, GNU/Linux datmlarnda da yol dizinleri birbirinden : iareti ile ayrlyor.
Dolaysyla GNU/Linux iletim sistemlerinde herhangi bir dizini yola eklemek iin yle bir
komut kullanyoruz:
PATH=$PATH:/yola/eklemek/istediimiz/dizin
Bu komuttaki $PATH ksm, yola yeni dizini eklerken halihazrdaki dizinlerin de silinmemesini
salyor. Eer yukardaki komutu yle verecek olursanz:
PATH=/yola/eklemek/istediimiz/dizin
Yol zerinde nceden varolan btn dizinler silinip, tek girdi olarak yeni eklediiniz dizin
grnecektir. Byle bir durumda da sisteminizde pek ok programn artk almadn
grrsnz. O yzden bu komutu verirken dikkatli olun.
Btn bu bilgiler nda, mesela Desktop (Masast) dizinini yola eklemek iin yle bir
komut yazabiliriz:
PATH=$PATH:$HOME/Desktop
Bu ekilde masast dizinini yola eklemi olduk. Yeni eklediimiz dizini, halihazrda YOL
zerinde bulunan dizinlerden : iareti ile ayrdmza dikkat edin.
sterseniz echo $PATH komutuyla masastnzn yol stnde grnp grnmediini
kontrol edebilirsiniz. Bu sayede artk masastnde bulunan altrlabilir dosyalar da kendi
adlaryla arlabilecekler. Ancak masastn yola eklediinizde, masastnz hep yol
stnde kalmayacak, mevcut konsol oturumu kapatlnca her ey yine eski haline dnecektir.
Eer herhangi bir dizini kalc olarak yola eklemek isterseniz, .prole (veya kullandnz
datma gre .bash_prole ya da .bashrc ) dosyanzda deiiklik yapmanz gerekir. Mesela
masastn yola eklemek iin $HOME/.prole dosyanzn en sonuna u satr eklemelisiniz:
53
export PATH=$PATH:$HOME/Desktop
Ancak GNU/Linuxta genel yaklamnz yola kalc olarak dizin eklemek deil, ya bir dizini
yola geici olarak eklemek, ya programnz mevcut yol dizinlerinden biri iine kopyalamak,
ya da programmza yol dizinlerinden birisi iinden sembolik ba vermek olmaldr. Yani
mesela masastnde bir programnz varsa, masastn yola eklemek yerine, programnz
yol dizinlerinden biri iine (mesela /usr/bin ) kopyalamak ya da o konumda bir sembolik ba
oluturmak daha akllca olacaktr.
Hatrlarsanz geen blmde altrma yetkisi konusundan sz ederken deneme adl bir
kabuk betii yazmtk. Masastne kaydettiimiz bu betii altrabilmek iin de ./deneme
gibi bir komut kullanmtk. Bu komutu verirken bataki ./ iaretlerini kullanmazsak
programmz hata veriyordu.
te bu blmde rendiklerimiz sayesinde programmzn neden hata verip almadn
artk daha iyi anlyor olmalsnz. Dediimiz gibi, deneme gibi bir komut verdiimizde
iletim sistemimiz echo $PATH ktsnda grnen yol dizinlerinin iine bakp, bu dizinlerin
herhangi birinin iinde deneme adl bir program olup olmadn kontrol edecektir. Eer siz
kendiniz eklemediyseniz, iletim sisteminizde masast ntanml olarak yola ekli deildir. O
yzden deneme komutunu verdiinizde iletim sisteminiz masastne bakmaz. te iletim
sisteminin deneme adl program baka yerde deil de masastnde aramasn salamak iin
komutun bana ./ iaretlerini yerletiriyoruz...
Tpk daha nce rendiimiz %USERPROFILE% (veya $HOME ) adl evre deikeni gibi,
%PATH% (veya $PATH ) de ok nemli evre deikenlerinden biri olduu iin yol kavramyla
bundan sonra da yeterince har neir olacaz. Ayrca birka blm sonra gerek Python
programlar yazmaya baladmzda, u anda belki de kafanzda mulak kalm baz eyler
iyiden iyiye yerine oturmu olacak. O yzden imdilik konuyu daha fazla uzatmadan burada
noktalyoruz ve nemli bir konuya daha geiyoruz.
54
BLM 5
Python Hakknda
Eer yaamnzn bir dneminde herhangi bir programlama dili ile az veya ok ilgilendiyseniz,
Python adn duymu olabilirsiniz. nceden bir programlama dili deneyiminiz hi olmamsa
dahi, Python adnn bir yerlerden kulanza alnm olma ihtimali bir hayli yksek. Bu
satrlar okuyor olduunuza gre, Python adn en az bir kez duymu olduunuzu ve bu eye
kar iinizde hi deilse bir merak uyandn varsayabiliriz.
Peki, en kt ihtimalle kulak dolgunluunuz olduunu varsaydmz bu ey hakknda acaba
neler biliyorsunuz?
te biz bu ilk blmde, fazla teknik ayrntya kamadan, Python hakknda ksa ksa bilgiler
vererek Pythonn ne olduunu ve bununla neler yapabileceinizi anlatmaya alacaz.
55
siliyorsunuzdur. Bu ilemlerin ne kadar vakit alc ve skc olduunu dnn. Eer bir
programlama dili biliyor olsaydnz, btn bu ilemleri sizin yerinize bu programlama dili
hallediyor olabilirdi.
te Python programlama dili byle bir durumda devreye girer. Her gn saatler boyunca
uratnz ilerinizi, yalnzca birka satr Python kodu yardmyla birka saniye iinde
tamamlayabilirsiniz.
Ya da yle bir durum dnn: altnz i yerinde PDF belgeleriyle bolca har neir
oluyor olabilirsiniz. Belki de yzlerce sayfalk kaeli ve imzal belgeyi PDF haline getirmeniz
gerekiyordur. stelik sizden bu belgeleri mmkn olduunca tek para halinde PDFlemeniz
isteniyor olabilir. Ama o yzlerce sayfay taraycdan geirirken iin tam ortasnda bir aksilik
oluyor, makine arzalanyor ve belki de ister istemez belgeniz blnyordur.
te Python programlama dili byle bir durumda da devreye girer. Eer Python programlama
dilini renirseniz, nternette saatlerce cretsiz PDF birletirme program aramak veya
profesyonel yazlmlara onlarca dolar para vermek yerine, belgelerinizi birletirip iinizi
grecek program kendiniz yazabilirsiniz.
Elbette Pythonla yapabilecekleriniz yukarda verdiimiz basit rneklerle snrl deildir.
Python kullanarak masast programlama, oyun programlama, tanabilir cihaz
programlama, web programlama ve a programlama gibi pek ok alanda almalar
yrtebilirsiniz.
56
57
Python programlama dili 1990 ylndan bu yana gelitirilen bir dil. Bu sre iinde pek ok
Python program yazld ve insanlarn kullanmna sunuldu. u anda piyasada Pythonn 2.x
serisinden bir srmle yazlm pek ok program bulunuyor. 3.x serisi ise ancak son yllarda
yaygnlk kazanmaya balad.
Not: Biz bu kitapta kolaylk olsun diye Pythonn 3.x serisini Python3; 2.x serisini ise Python2
olarak adlandracaz.
Python3, Python2ye gre hem ok daha gldr, hem de Python2nin hatalarndan
arndrlmtr. Python3teki byk deiikliklerden tr, Python2 ile yazlm bir program
Python3 altnda almayacaktr. Ayn durum bunun tersi iin de geerlidir. Yani Python3
kullanarak yazdnz bir program Python2 altnda almaz.
Dediimiz gibi, piyasada Python2 ile yazlm ok sayda program var. te bu sebeple Python
gelitiricileri uzun bir sre daha Python2yi gelitirmeye devam edecek. Elbette gelitiriciler
bir yandan da Python3 zerinde almay ve bu yeni seriyi gelitirmeyi srdrecek.
Farkl Python serilerinin var olmasndan tr, Python ile program yazarken hangi seriye
ait srmlerden birini kullandnz bilmeniz, yazacanz programn kaderi asndan byk
nem tar.
58
BLM 6
Bu blme gelene kadar, herhangi bir programlama faaliyetine girimeden nce halihazrda
biliyor olmamz gereken her eyi rendik. Artk Python ile program yazabilmemizin nnde
tek bir engel kald. te biz bu blmde Python ile program yazmamzn nndeki son engel
olan kurulumdan sz edeceiz.
Dediimiz gibi, Python ile program yazabilmemiz iin bu programlama dilinin
bilgisayarmzda kurulu olmas gerekiyor. Bu programlama dilini kurmanzn gerekip
gerekmedii, kullandnz iletim sistemine baldr. Biz burada hem GNU/Linux hem de
Windows kullanclarnn durumunu srasyla ve ayr ayr inceleyeceiz. Dilerseniz ncelikle
GNU/Linux kullanclarnn durumuna bakalm:
Not: Bu kitap boyunca baz konularn GNU/Linux ve Windows kullanclar iin ayr ayr
anlatldn greceksiniz. Ancak konular bu ekilde ayrlm da olsa, ben size her ikisini
de okumanz tavsiye ederim. nk bu blmlerde her iki kullanc grubunun da ilgisini
ekebilecek bilgilere rastlayacaksnz. Ayrca bu blmler farkl kullanc gruplarna hitap
ediyor olsa da, aslnda bu blmlerin birbirini tamamlayc nitelikte olduunu greceksiniz.
59
Eer bu komuttan Python 2.x.y eklinde bir kt alyorsanz, yani x ve yden nceki ksm 2 ile
balyorsa sisteminizde Python2 kuruludur.
Ancak python -V komutundan Python 2.x.y eklinde bir kt almanz sisteminizde sadece
Python2nin kurulu olduunu gstermez. Sisteminizde Python2 ile birlikte Python3 de
halihazrda kurulu olabilir. rnein Ubuntu GNU/Linuxun 12.10 srmnden itibaren hem
Python2, hem de Python3 sistemde kurulu vaziyettedir.
Kullandnz GNU/Linux datmnda durumun ne olduunu denetlemek iin yukardaki
komutu bir de python3 -V eklinde altrmay deneyebilirsiniz. Eer bu komut size bir hata
mesaj yerine bir srm numaras veriyorsa sisteminizde Python3 de kuruludur.
Sisteminizdeki Python srmlerine ilikin daha kesin bir rapor iin ise u komutu
kullanabilirsiniz:
ls -g {,/usr{,/local}}/bin | grep python
Buradan aldnz kty inceleyerek de sisteminizde birden fazla Python srmnn kurulu
olup olmadn grebilirsiniz. [Bununla ilgili bir tartma iin bkz. [Link]
Eer Python2 ile birlikte Python3 de kuruluysa yukardaki komut una benzer bir kt verir
(kt, fazla yer kaplamamas iin krplmtr):
dh_python2
dh_python3
pdb2.7 -> ../lib/python2.7/[Link]
pdb3.2 -> ../lib/python3.2/[Link]
py3versions -> ../share/python3/[Link]
python -> python2.7
python2 -> python2.7
python2.7
python3 -> python3.2
python3.2 -> python3.2mu
python3.2mu
python3mu -> python3.2mu
pyversions -> ../share/python/[Link]
ktda iki farkl Python srmne ait kaytlarn olmas sistemde iki farkl Python srmnn
kurulu olduunu doruluyor. Bu ktya gre, bu komutun verildii sistemde Pythonn 2.7 ve
3.2 srmleri zaten kurulu.
Ayrca kullandnz GNU/Linux datmnda whereis python gibi bir komut vererek de
sistemde kurulu Python srmleri hakknda bilgi edinebilirsiniz.
Eer sisteminizde Python3 kuruluysa ve siz de kurulu olan Python3 srmnden
memnunsanz herhangi bir ey yapmanza gerek yok. Farkl bir Python srm kurmaya
almadan yolunuza devam edebilirsiniz.
60
orada python kelimesini kullanarak bir arama yapmanz neririm. rnein Ubuntu
GNU/Linux datmnn paket depolarnda Python3 var. Dolaysyla Ubuntu kullanclar, eer
sistemlerinde zaten kurulu deilse (ki muhtemelen kuruludur), bu paketi Ubuntu Yazlm
Merkezi araclyla veya dorudan u komutla kurabilir:
sudo apt-get install python3
61
Not:
Farkl GNU/Linux datmlarnda, Python3 kaynaktan derleme ileminden nce
halihazrda kurulu olmas gereken paketlerin listesi iin [Link] adresindeki
tabloyu inceleyebilirsiniz.
Yukardaki programlar kurduktan sonra [Link] adresine
gidiyoruz. Bu adreste, zerinde [Link] yazan balantya tklayarak sktrlm
kurulum dosyasn bilgisayarmza indiriyoruz.
Daha sonra bu sktrlm dosyay ayoruz. Alan klasrn iine girip, orada ilk olarak u
komutu veriyoruz:
./configure
Burada aslnda ./configure komutu ile oluan Makele adl dosyay make adl bir program
araclyla altrm oluyoruz. make bir sistem komutudur. Bu komutu yukardaki gibi
parametresiz olarak altrdmzda make komutu, o anda iinde bulunduumuz dizinde
bir Makele dosyas arar ve eer byle bir dosya varsa onu altrr. Eer bir nceki
admda altrdmz ./configure komutu baarsz olduysa, dizinde bir Makele dosyas
olumayaca iin yukardaki make komutu da almayacaktr. O yzden derleme ilemi
srasnda verdiimiz komutlarn ktlarn takip edip, bir sonraki aamaya gemeden nce
komutun dzgn sonlanp sonlanmadndan emin olmamz gerekiyor.
make komutunun yapt i, Python programlama dilinin sisteminize kurulmas esnasnda
sistemin eitli yerlerine kopyalanacak olan dosyalar ina edip oluturmaktr. Bu komutun
tamamlanmas, kullandnz bilgisayarn kapasitesine bal olarak biraz uzun srebilir.
Baz sistemlerde make komutunun sonunda yle bir hata mesajyla karlaabilirsiniz:
Undefined reference to '_PyFaulthandler_Init'
hatayla
karlarsanz
[Link]
adresindeki
nerimizi
make komutu tamamlandktan sonra, komut ktsnn son satrlarna doru yle bir uyar
mesaj da grebilirsiniz:
62
Burada Python, sistemimizde baz paketlerin eksik olduu konusunda bizi uyaryor. Uyar
mesajnda bir veya daha fazla paketin eksik olduunu grebilirsiniz. Eer yleyse, eksik
olduu bildirilen btn paketleri kurmamz gerekiyor.
Gerekli paketi ya da paketleri kurduktan sonra make komutunu tekrar altryoruz. Endie
etmeyin, make komutunu ikinci kez verdiimizde komutun tamamlanmas birincisi kadar uzun
srmez. Eer bu komutu ikinci kez altrdnzda yukardaki uyar mesaj kaybolduysa u
komutla yolunuza devam edebilirsiniz:
sudo make altinstall
Daha nce kaynaktan program derlemi olan GNU/Linux kullanclarnn eli, make
komutundan sonra make install komutunu vermeye gitmi olabilir. Ama burada bizim make
install yerine make altinstall komutunu kullandmza dikkat edin. make altinstall
komutu, Python kurulurken klasr ve dosyalara srm numarasnn da eklenmesini salar.
Bylece yeni kurduunuz Python, sistemdeki eski Python3 srmn silip zerine yazmam
olur ve iki farkl srm yan yana varolabilir. Eer make altinstall yerine make install
komutunu verirseniz sisteminizde zaten varolan eski bir Python3 srmne ait dosya ve
dizinlerin zerine yazp silerek o srm kullanlamaz hale getirebilirsiniz. Bu da sistemde
beklenmedik problemlerin ortaya kmasna yol aabilir. Bu nemli ayrnty kesinlikle gzden
karmamalsnz.
Ayrca bkz.:
Python3n
kaynaktan
kurulumu
ile
ilgili
[Link]
bir
tartma
iin
bkz.
Derleme aamalarnn hibirinde herhangi bir hata mesaj almadysanz kurulum baaryla
gereklemi ve sisteminize Python programlama dilinin 3.x srm kurulmu demektir.
Yetkisiz Kullanc Olarak Kurulum
Elbette sudo make altinstall komutunu verip Python kurabilmek iin root haklarna sahip
olmanz gerekiyor. Ama eer kullandnz sistemde bu haklara sahip deilseniz Python bu
ekilde kuramazsnz. Kstl haklara sahip olduunuz bir sistemde Python ancak kendi ev
dizininize ($HOME) kurabilirsiniz.
Eer Python yetkisiz kullanc olarak kuracaksanz, ncelikle yukarda bahsettiimiz Python
bamllklarnn sisteminizde kurulu olup olmadn kontrol etmeniz lazm. Kullandnz
sistemde herhangi bir Python srm halihazrda kuruluysa, bu bamllklar da muhtemelen
zaten kuruludur.
Ama deilse, bunlar kurmas iin ya sistem yneticisine ricada
bulunacaksnz, ya da bu bamllklar da tek tek kendi ev dizininize kuracaksnz. Eer sistem
yneticisini bu bamllklar kurmaya ikna edemezseniz, internet zerinden bulabileceiniz
bilgiler yardmyla bu bamllklar tek tek elle kendiniz kurabilirsiniz. Ancak bu ilemin epey
zaman alacan ve sre srasnda pek ok baka bamllkla da karlacanz syleyebilirim.
O yzden ne yapp edip sistem yneticisini bamllklar kurmaya ikna etmenizi tavsiye
ederim... Tabii sistem yneticisini bu bamllklar kurmaya ikna edebilirseniz, istediiniz
Python srmn de kurmaya ikna edebileceinizi dnebiliriz! Ama biz burada sizin
Python kendinizin kuracan varsayarak yolumuza devam edelim.
63
Python yetkisiz olarak kurmak, root haklaryla kurmaya ok benzer. Aralarnda yalnzca
bir-iki ufak fark vardr. Mesela Python yetkisiz kullanc olarak kurarken, ./configure
komutunu u ekilde vermeniz gerekiyor:
./configure --prefix=$HOME/python
Python root haklaryla kurduunuzda Python /usr dizini altna kurulacaktr. Ancak siz
yetkisiz kullanc olduunuz iin /usr dizinine herhangi bir ey kuramazsnz. te bu yzden,
congure betiine verdiimiz prex parametresi yardmyla Python, yazma yetkimiz olan
bir dizine kuruyoruz. Mesela yukardaki komut Pythonn /usr dizinine deil, ev dizininiz iinde
python adl bir klasre kurulmasn salayacaktr. Elbette siz python yerine farkl bir dizin
ad da belirleyebilirsiniz. Burada nemli olan nokta, prex parametresine vereceiniz dizin
adnn, sizin yazmaya yetkili olduunuz bir dizin olmasdr.
Bu komutu altrdktan sonra make komutunu normal bir ekilde veriyoruz. Bunun ardndan
da make install (veya duruma gre make altinstall) komutuyla Python ev dizinimize
kuruyoruz. Burada make install komutunu sudosuz kullandmza dikkat edin. nk,
dediimiz gibi, siz yetkili kullanc olmadnz iin sudo komutunu kullanamazsnz.
Python bu ekilde ev dizininiz altnda bir klasre kurduunuzda Python ile ilgili btn
dosyalarn bu klasr iinde yer aldn greceksiniz. Bu klasr dikkatlice inceleyip neyin
nerede olduuna ainalk kazanmaya aln. Eer mmknse root haklar ile kurulmu bir
Python srmn inceleyerek, dosyalarn iki farkl kurulum trnde nerelere kopyalandn
karlatrn.
Bylece Python programlama dilini bilgisayarmza nasl kuracamz renmi olduk.
Ama bu noktada bir uyar yapmadan gemeyelim: Python zellikle baz GNU/Linux
datmlarnda pek ok sistem aracyla sk skya balantldr. Yani Python, kullandnz
datmn belkemii durumunda olabilir. Bu yzden Python kaynaktan derlemek baz
riskler tayabilir. Eer yukarda anlatld ekilde, kaynaktan Python derleyecekseniz, kar
karya olduunuz risklerin farknda olmalsnz. Ayrca GNU/Linux zerinde kaynaktan
program derlemek konusunda tecrbeli deilseniz ve eer yukardaki aklamalar size kafa
kartrc geliyorsa, mesela Ben bu komutlar nereye yazacam? diye bir soru geiyorsa
aklnzdan, kesinlikle datmnzla birlikte gelen Python srmn kullanmalsnz. Python
srmlerini baa ba takip ettii iin, ben size Ubuntu GNU/Linuxu denemenizi nerebilirim.
Ubuntunun depolarnda Pythonn en yeni srmlerini rahatlkla bulabilirsiniz. Ubuntunun
resmi sitesine [Link] adresinden, yerel Trkiye sitesine ise [Link]
adresinden ulaabilirsiniz. Eer u anda kullandnz GNU/Linux datmndan vazgemek
istemiyorsanz, sabit diskinizden kk bir blm ayrp bu blme sadece Python
almalarnz iin Ubuntu datmn da kurmay tercih edebilirsiniz.
Yalnz kk bir uyar daha yapalm. Kaynaktan kurulum ile ilgili bu sylediklerimizden,
Pythonn GNU/Linuxa kesinlikle kaynaktan derlenerek kurulmamas gerektii anlam
kmamal. Yukardaki uyarlarn amac, kullancnn Python kaynaktan derlerken sadece
biraz daha dikkatli olmas gerektiini hatrlatmaktr. rnein bu satrlarn yazar, kulland
Ubuntu sisteminde Python3 kaynaktan derleyerek kullanmay tercih ediyor ve herhangi bir
problem yaamyor.
Bu nemli uyarlar da yaptmza gre gnl rahatlyla yolumuza devam edebiliriz.
Kurduumuz yeni Python nasl altracamz biraz sonra greceiz. Ama nce Windows
kullanclarnn Python3 nasl kuracaklarna bakalm.
64
O yzden Windows
65
66
BLM 7
Bir nceki blmde, Python farkl platformlara nasl kuracamz btn ayrntlaryla
anlattk. Bu blmde ise kurduumuz bu Python programn hem GNU/Linuxta hem de
Windowsta nasl altracamz greceiz. ncelikle GNU/Linux kullanclarnn Python
nasl altracana bakalm.
Ancak daha nce de dediimiz gibi, 16.02.2016 tarihi itibariyle pek ok GNU/Linux
datmnda ntanml olarak Python2 kuruludur. Dolaysyla python komutunu verdiinizde
alan srm muhtemelen Python2 olacaktr. Bu yzden sistemimizde ntanml olarak
hangi srmn kurulu olduuna ve python komutunun hangi srm balattna ok dikkat
etmelisiniz.
Yine daha nce de sylediimiz gibi, sisteminizde hem Python2 hem de Python3 zaten
kurulu durumda olabilir. O yzden yukardaki komutu bir de python3 eklinde vermeyi
deneyebilirsiniz.
rnein Ubuntu GNU/Linux datmnn 12.10 srmnden itibaren python komutu
Python2yi; python3 komutu ise Python3 altryor.
69
Bu komut iki farkl Python srmnn kurulu olduu sistemlerde una benzer bir kt verir
(kt krplmtr):
dh_python2
dh_python3
pdb2.7 -> ../lib/python2.7/[Link]
pdb3.2 -> ../lib/python3.2/[Link]
py3versions -> ../share/python3/[Link]
python -> python2.7
python2 -> python2.7
python2.7
python3 -> python3.2
python3.2 -> python3.2mu
python3.2mu
python3mu -> python3.2mu
pyversions -> ../share/python/[Link]
Yatk harerle gsterdiimiz ksmlara dikkat edin. Grdnz gibi python ve python2
komutlar bu sistemde Pythonn 2.7 srmn altryor. python3 komutu ise Pythonn 3.2
srmn... Dolaysyla yukardaki kty aldmz bir sistemde kendi kurduumuz Python
srmlerine python, python2 veya python3 gibi isimler vermekten kanmalyz.
Szn z, bir GNU/Linux kullancs olarak sistemdeki ntanml hibir Python srmn
silmemeli, ntanml srme ulaan komutlar deitirmemelisiniz. Eer mesela sisteminizde
python3 komutu halihazrda bir Python srmn altryorsa, siz yeni kurduunuz Python
srmne ulamak iin ntanml adla akmayacak baka bir komut ad kullann. Yani
rnein sisteminizde python3 komutu Pythonn 3.2 srmn altryorsa, siz yeni
kurduunuz srm altrmak iin py3 gibi bir sembolik ba oluturun. Brakn ntanml
komut (python, python3 vb.) ntanml Python srmn altrmaya devam etsin.
Asla unutmayn. Siz bir programc aday olarak, program yazacanz iletim sistemini enine
boyuna tanmakla ykmlsnz. Dolaysyla iletim sisteminizi kararsz hale getirecek
davranlar bilmeli, bu davranlardan kanmal, yanl bir ilem yaptnzda da nasl geri
dneceinizi bilmelisiniz. Hele ki bir program kaynaktan derlemeye karar vermiseniz...
Bu ciddi uyary da yaptmza gre gnl rahatlyla yolumuza devam edebiliriz.
nce u komutla
cd $HOME/python/bin
70
Elbette eer sizin sisteminizdeki dosyann ad .bash_prole veya .bashrc ise yukardaki
komutu ona gre deitirmelisiniz.
5. Daha sonra $HOME/python/bin/python 3.5 adl dosyaya $HOME/python/bin/ dizini
altndan mesela py3 gibi bir sembolik ba verin:
ln -s $HOME/python/bin/python3.5 $HOME/python/bin/py3
6. Bilgisayarnz yeniden balatn.
7. Artk hangi konumda bulunursanz bulunun, u komutu vererek Python3 balatabilirsiniz:
py3
71
yaygn. Eer hem Python2 ile yazlm programlar altrmak, hem de Python3 ile gelitirme
yapmak istiyorsanz, sisteminizde hem Python2yi hem de Python3 ayn anda bulundurmay
tercih edebilirsiniz. Peki bunu nasl yapacaksnz?
En bata da sylediimiz gibi, hemen hemen btn GNU/Linux datmlarnda Python2 kurulu
olarak gelir. Dolaysyla eer sisteminize ek olarak Python3 de kurduysanz (kaynaktan
veya paket deposundan), baka herhangi bir ey yapmanza gerek yok. Yukarda anlattmz
ynergeleri takip ettiyseniz, konsolda python komutu verdiinizde Python2 alacak, python3
(veya py3) komutunu verdiinizde ise Python3 alacaktr.
Ama eer sisteminizde Python2 bile kurulu deilse, ki bu ok ok dk bir ihtimaldir,
Python2yi paket yneticiniz yardmyla sisteminize kurabilirsiniz. u anda piyasada olup da
paket deposunda Python bulundurmayan GNU/Linux datm pek azdr.
GNU/Linuxta Python nasl altracamz ve farkl Python srmlerini bir arada nasl
kullanacamz rendiimize gre, Windows kullanclarnn durumuna bakabiliriz.
72
yapmak istiyorsanz, sisteminizde hem Python2yi hem de Python3 ayn anda bulundurmay
tercih edebilirsiniz. Peki bunu nasl yapacaksnz?
Windowsta bu ilemi yapmak ok kolaydr. [Link]/download adresine giderek farkl
Python srmlerini bilgisayarnza indirebilir ve bunlar bilgisayarnza normal bir ekilde
kurabilirsiniz. Bu ekilde sisteminize istediiniz sayda farkl Python srm kurabilirsiniz.
Peki bu farkl srmlere nasl ulaacaksnz?
Python, bilgisayarmzdaki farkl Python srmlerini altrabilmemiz iin bize py adl zel
bir program sunar.
Not: Py program yalnzca Windowsa zgdr. GNU/Linuxta byle bir program bulunmaz.
Py programn altrmak iin, daha nce gsterdiimiz ekilde sistem komut satrna
ulayoruz ve orada u komutu veriyoruz:
py
Eer sisteminizde birden fazla Python2 veya birden fazla Python3 srm kurulu ise, ana ve
alt srm numaralarn belirterek istediiniz srme ulaabilirsiniz:
py -2.6
py -2.7
py -3.4
py -3.5
Bu arada dikkat ettiyseniz, Python programlarn balatabilmek iin hem python hem de py
komutunu kullanma imkanna sahibiz. Eer sisteminizde tek bir Python srm kurulu ise,
Python balatmak iin python komutunu kullanmak isteyebilir, farkl srmlerin bir arada
bulunduu durumlarda ise py ile bu farkl srmlere tek tek erimek isteyebilirsiniz.
Bylece Pythonla ilgili en temel bilgileri edinmi olduk. Bu blmde rendiklerimiz
sayesinde Python programlama dilini bilgisayarmza kurabiliyor ve bu programlama dilini
baaryla altrabiliyoruz.
73
BLM 8
Etkileimli Python
ara olarak karmza kar. Bu ortam, zellikle Pythona yeni balayanlarn bu programlama
diline ainalk kazanmasn salamas asndan da bulunmaz bir aratr. Biz de bu blmde
etkileimli kabuk zerinde baz almalar yaparak, Pythona alma turlar atacaz.
Bu arada, geen blmde sylediimiz gibi, bu ortamn sistem komut satr adn verdiimiz
ortamdan farkl olduunu aklmzdan karmyoruz. O zaman da dediimiz gibi, sistem komut
satrnda sistem komutlar, Python komut satrnda (yani etkileimli kabukta) ise Python
komutlar verilir. Mesela echo %PATH%, cd Desktop, dir ve ls birer sistem komutudur. Eer
bu komutlar etkileimli kabukta vermeye kalkrsanz, bunlar birer Python komutu olmad
iin, Python size bir hata mesaj gsterecektir. Mesela Pythonn etkileimli kabuunda cd
Desktop komutunu verirseniz yle bir hata alrsnz:
>>> cd Desktop
File "<stdin>", line 1
cd Desktop
^
SyntaxError: invalid syntax
76
Bu arada yukardaki kodlar iinde grnen >>> iaretini siz yazmayacaksnz. Bu iareti
etkileimli kabuun grnmn temsil etmek iin yerletirdik oraya. Siz Merhaba Zalim
Dnya! satrn yazdktan sonra doruca Enter dmesine basacaksnz.
Bu komutu yazp Enter tuuna bastmzda yle bir kt alm olmalyz:
'Merhaba Zalim Dnya!'
77
yukarda rneini verdiimiz Merhaba Zalim Dnya! adl karakter dizisi de bir veri tipidir.
Pythonda karakter dizileri dnda baka veri tipleri de bulunur. Biraz sonra baka veri
tiplerini de inceleyeceiz.
Dikkat ederseniz Merhaba Zalim Dnya! adl karakter dizisini trnak iinde gsterdik. Bu da
ok nemli bir bilgidir. Eer bu cmleyi trnak iine almazsak programmz hata verecektir:
>>> Merhaba Zalim Dnya!
File "<stdin>", line 1
Merhaba Zalim Dnya!
^
SyntaxError: invalid syntax
Zaten trnak iaretleri, karakter dizilerinin ayrt edici zelliidir. yle ki, Pythonda trnak
iinde gsterdiiniz her ey bir karakter dizisidir. rnein u bir karakter dizisidir:
>>> "a"
Grdnz gibi, trnak iinde gsterilen tek karakterlik bir e de Pythonda karakter dizisi
snfna giriyor.
Mesela u, ii bo bir karakter dizisidir:
>>> ""
Bu ikisi arasndaki farka dikkat ediyoruz: Pythonda bo karakter dizisi ve bir adet boluktan
oluan karakter dizisi birbirlerinden farkl iki kavramdr. Adndan da anlalaca gibi, bo
karakter dizileri ilerinde hibir karakter (baka bir deyile e) barndrmayan karakter
dizileridir. Bir (veya daha fazla) boluktan oluan karakter dizileri ise ilerinde boluk karakteri
barndran karakter dizileridir. Yani bu karakter dizilerinden biri bo, teki ise doludur. Ama
neticede her ikisi de karakter dizisidir. u anda olduka anlamsz bir konu zerinde vakit
kaybediyormuuz hissine kaplm olabilirsiniz, ama emin olun, Python programlama diline
yeni balayanlarn nemli tkezleme noktalarndan biridir bu sylediimiz ey...
Dilerseniz biz karakter dizilerine elimizin almas iin birka rnek verelim:
>>> "Elma"
'Elma'
>>> "Guido Van Rossum"
'Guido Van Rossum'
>>> "Python programlama dili"
'Python programlama dili'
>>> "mnhbgfgh"
'mnhbgfgh'
>>> "$5&"
78
'$5&'
>>> ""
''
>>> " "
' '
>>> " "
' '
Yukardaki rneklerin hepsi birer karakter dizisidir. Dikkat ettiyseniz yukardaki karakter
dizilerinin hepsinin ortak zellii trnak iinde gsteriliyor olmasdr. Dediimiz gibi, trnak
iaretleri karakter dizilerinin ayrt edici zelliidir.
Peki bir verinin karakter dizisi olup olmadndan nasl emin olabilirsiniz?
Eer herhangi bir verinin karakter dizisi olup olmad konusunda tereddtnz varsa, type()
adl bir fonksiyondan yararlanarak o verinin tipini sorgulayabilirsiniz. Bu fonksiyonu yle
kullanyoruz:
>>> type("Elma")
<class 'str'>
79
Grdnz gibi, bu iki karakter dizisi, arada boluk olmadan birbiriyle bititirildi. Araya
boluk eklemek iin birka farkl yntemden yararlanabilirsiniz:
>>> "Frat" + " " + "zgl"
'Frat zgl'
Burada iki karakter dizisi arasna bir adet boluk karakteri yerletirdik. Ayn etkiyi u ekilde
de elde edebilirsiniz:
>>> "Frat" + " zgl"
Burada da zgl karakter dizisinin bana bir adet boluk yerletirerek istediimiz kty elde
ettik.
Bu arada, karakter dizilerini birletirmek iin mutlaka + iareti kullanmak zorunda deilsiniz.
Siz + iaretini kullanmasanz da Python sizin karakter dizilerini birletirmek istediinizi
anlayacak kadar zekidir:
>>> "www" "." "google" "." "com"
'[Link]'
ok uzak...'
Grdnz gibi, ok basit paralar bir araya getirerek karmak ktlar elde edebiliyoruz.
Mesela son rnekte uzak adl karakter dizisine nce 5 adet boluk karakteri (" " * 5),
ardndan da ok uzak... adl karakter dizisini ekleyerek istediimiz kty aldk.
Burada + ve * adl iki yeni ara gryoruz. Bunlar aslnda saylarla birlikte kullanlan birer
aritmetik iletir. Normalde + ileci toplama ilemleri iin, * ileci ise arpma ilemleri iin
80
81
2.5
>>> 10 - 3
7
Grevi
toplama
karma
arpma
blme
Yukardaki rneklerde bir ey dikkatinizi ekmi olmal: Karakter dizilerini tanmlarken trnak
iaretlerini kullandk. Ancak saylarda trnak iareti yok. Daha nce de dediimiz gibi, trnak
iaretleri karakter dizilerinin ayrt edici zelliidir. Pythonda trnak iinde gsterdiiniz her
ey bir karakter dizisidir. Mesela u rneklere bakalm:
>>> 34657
34657
Bu ise bir karakter dizisidir. Dilerseniz biraz nce rendiimiz type() fonksiyonu yardmyla
bu verilerin tipini sorgulayalm:
>>> type(34657)
<class 'int'>
Buradaki int ifadesi ngilizce integer , yani tamsay kelimesinin ksaltmasdr. Demek ki
34657 says bir tamsay imi. Bir de una bakalm:
>>> type("34657")
<class 'str'>
Grdnz gibi, 34657 saysn trnak iine aldmzda bu say artk say olma zelliini
yitiriyor ve bir karakter dizisi oluyor. u anda bu ok nemsiz bir ayrntym gibi gelebilir
size, ama aslnda son derece nemli bir konudur bu. Bu durumun etkilerini u rneklerde
grebilirsiniz:
>>> 23 + 65
88
82
Burada ise Python iki karakter dizisini yan yana yazmakla yetindi; yani bunlar birletirdi.
Python asndan 23 ve 23 birbirinden farkldr. 23 bir karakter dizisi iken, 23 bir saydr.
Ayn ey 65 ve 65 iin de geerlidir. Yani Python asndan 65 ile Merhaba Zalim Dnya!
arasnda hi bir fark yoktur. Bunlarn ikisi de karakter dizisi snfna girer. Ancak 65 ile 65
birbirinden farkldr. 65 bir say iken, 65 bir karakter dizisidir.
Bu bilgi, zellikle aritmetik ilemlerde byk nem tar. Bunu dilerseniz u rnekler zerinde
gsterelim:
>>> 45 + "45"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Grdnz gibi, yukardaki kodlar hata veriyor. Bunun sebebi bir say (45 ) ile bir karakter
dizisini (45 ) birbiriyle toplamaya almamzdr. Asla unutmayn, aritmetik ilemler ancak
saylar arasnda yaplr. Karakter dizileri ile herhangi bir aritmetik ilem yaplamaz.
Bir de una bakalm:
>>> 45 + 45
90
Bu kodlar ise dzgn alr. nk burada iki sayy aritmetik ileme soktuk ve baarl olduk.
Son olarak u rnei verelim:
>>> "45" + "45"
'4545'
Burada + ilecinin toplama anlamna gelmediine dikkat edin. Bu ile burada iki karakter
dizisini birletirme grevi stleniyor. Yani yukardaki rnein u rnekten hibir fark yoktur:
>>> "istihza." + "com"
'[Link]'
Burada * ileci bir karakter dizisi (w ) ve bir say (3 ) arasnda ilem yapt iin, karakter
dizisini, ilgili say kadar tekrarlyor. Yani w karakter dizisini 3 kez tekrarlyor.
83
Burada ise * ileci iki adet say arasnda ilem yapt iin bu deerleri birbiriyle aritmetik
olarak arpyor ve 75 deerini elde etmemizi salyor.
Grdnz gibi, o anda elimizde bulunan verilerin tipini bilmek gerekten de byk nem
tayor. nk eer elimizdeki verilerin tipini bilmezsek nasl sonular elde edeceimizi de
kestiremeyiz.
Bylece karakter dizileri ile saylar arasndaki fark renmi olduk. Bu bilgiler size
nemsizmi gibi gelebilir, ama aslnda karakter dizileri ile saylar arasndaki fark anlamak,
Python programlama dilinin nemli bir blmn renmi olmak demektir. leride
yazacanz en karmak programlarda bile, bazen programnzn almamasnn (veya daha
kts yanl almasnn) nedeninin karakter dizileri ile saylar birbirine kartrmanz
olduunu greceksiniz.
O yzden burada rendiiniz hibir bilgi krntsn batan
savmamanz (ve sabrszlk ya da acelecilik etmemenizi) tavsiye ederim.
8.2.3 Deikenler
imdi yle bir durum dnn: Diyelim ki sisteme kayt iin kullanc ad ve parola
belirlenmesini isteyen bir program yazyorsunuz. Yazacanz bu programda, belirlenebilecek
kullanc ad ve parolann toplam uzunluu 40 karakteri gemeyecek.
Bu program yazarken ilk aamada yapmanz gereken ey, kullancnn belirledii kullanc ad
ve parolann uzunluunu tek tek denetlemek olmal.
Mesela kullanc yle bir kullanc ad belirlemi olsun:
firat_ozgul_1980
te bizim ncelikle kullancdan gelen bu verilerin teker teker uzunluunu biliyor olmamz
lazm, ki bu verilerin toplam 40 karakter snrn ap amadn denetleyebilelim.
Peki bu verilerin uzunluunu nasl leceiz? Elbette bunun iin verilerdeki hareri elle
tek tek saymayacaz. Bunun yerine, Python programlama dilinin bize sunduu bir arac
kullanacaz. Peki nedir bu ara?
Hatrlarsanz birka sayfa nce type() adl bir fonksiyondan sz etmitik. Bu fonksiyonun
grevi bir verinin hangi tipte olduunu bize bildirmekti. te tpk type() gibi, Pythonda
len() adl baka bir fonksiyon daha bulunur. Bu fonksiyonun grevi ise karakter dizilerinin
(ve ileride greceimiz gibi, baka veri tiplerinin) uzunluunu lmektir. Yani bu fonksiyonu
kullanarak bir karakter dizisinin toplam ka karakterden olutuunu renebiliriz.
Biz henz kullancdan nasl veri alacamz bilmiyoruz. Ama imdilik unu syleyebiliriz:
Pythonda kullancdan herhangi bir veri aldmzda, bu veri bize bir karakter dizisi olarak
gelecektir. Yani kullancdan yukardaki kullanc ad ve parolay aldmz varsayarsak, bu
veriler bize u ekilde gelir:
84
"firat_ozgul_1980"
ve:
"rT%65#$hGfUY56123"
Grdnz gibi, elde ettiimiz veriler trnak iinde yer alyor. Yani bunlar birer karakter
dizisi. imdi gelin yukarda bahsettiimiz len() fonksiyonunu kullanarak bu karakter
dizilerinin uzunluunu lelim.
Dediimiz gibi, len() de tpk type() gibi bir fonksiyondur. Dolaysyla len() fonksiyonunun
kullanm type() fonksiyonunun kullanmna ok benzer. Nasl type() fonksiyonu bize,
kendisine verdiimiz parametrelerin tipini sylyorsa, len() fonksiyonu da kendisine
verdiimiz parametrelerin uzunluunu syler.
Dikkatlice bakn:
>>> len("firat_ozgul_1980")
16
>>> len("rT%65#$hGfUY56123")
17
len() fonksiyonunun bize say deerli bir veri gndermesi sayesinde bu fonksiyondan elde
ettiimiz deerleri birbiriyle toplayabiliyoruz:
>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")
33
Eer len() fonksiyonu bize say deil de mesela karakter dizisi verseydi, bu fonksiyondan elde
ettiimiz deerleri yukardaki gibi dorudan birbiriyle aritmetik olarak toplayamazdk. yle
bir durumda, bu iki veriyi birbiriyle toplamaya altmzda, + ileci 16 ve 17 deerlerini
birbiriyle toplamak yerine bu deerleri birbiriyle birletirerek bize 1617 gibi bir sonu
verecekti.
Her zaman sylediimiz gibi, Pythonda veri tipi kavramn ok iyi anlamak ve o anda elimizde
bulunan bir verinin hangi tipte olduunu bilmek ok nemlidir. Aksi halde programlarmzda
8.2. Etkileimli Kabukta lk Admlar
85
Bu kodlar, istediimiz eyi gayet gzel yerine getiriyor. Ama sizce de yukardaki kodlarda ok
rahatsz edici bir durum yok mu?
Dikkat ederseniz, yukardaki rneklerde kullandmz verileri, program iinde her
ihtiya duyduumuzda tekrar tekrar yazdk.
Bylece ayn program iinde iki kez
rat_ozgul_1980 ; iki kez de rT%65#$hGfUY56123 yazmak zorunda kaldk. Halbuki bu
verileri programlarmzn iinde her ihtiya duyduumuzda tekrar tekrar yazmak yerine bir
deikene atasak ve gerektiinde o deikeni kullansak ok daha iyi olmaz m? Herhalde
olur...
Peki nedir bu deiken dediimiz ey?
Pythonda bir program iinde deerlere verilen isimlere deiken denir. Hemen bir rnek
verelim:
>>> n = 5
Burada 5 saysn bir deikene atadk. Deikenimiz ise n. Ayrca 5 saysn bir deikene
atamak iin = iaretinden yararlandmza da ok dikkat edin. Buradan, = iaretinin Python
programlama dilinde deer atama ilemleri iin kullanld sonucunu karyoruz.
n = 5 gibi bir komut yardmyla 5 deerini n adl deikene atamamz sayesinde artk ne
zaman 5 saysna ihtiya duysak bu n deikenini armamz yeterli olacaktr:
>>> n
5
>>> n * 10
50
>>> n / 2
2.5
86
otomatik olarak yerine koyabiliyor. Yani n = 5 komutuyla n adl bir deiken tanmladktan
sonra, artk ne zaman 5 saysna ihtiya duysak n deikenini armamz yeterli olacaktr.
Python o 5 deerini otomatik olarak yerine koyar.
imdi de pi adl baka bir deiken tanmlayalm:
>>> pi = 3.14
Grdnz gibi, deerleri her defasnda tekrar yazmak yerine bunlar bir deikene atayp,
gereken yerde bu deikeni kullanmak ok daha pratik bir yntem.
Ayn eyi programmz iin de yapabiliriz:
>>> kullanc_ad = "firat_ozgul_1980"
>>> parola = "rT%65#$hGfUY56123"
= iaretini kullanarak ilgili deerlere artk birer ad verdiimiz, yani bu deerleri birer
deikene atadmz iin, bu deerleri kullanmamz gereken yerlerde deerlerin kendisini
uzun uzun yazmak yerine, belirlediimiz deiken adlarn kullanabiliriz. Mesela:
>>> len(kullanc_ad)
16
>>> len(parola)
17
>>> len(kullanc_ad) + len(parola)
33
>>> k_ad_uzunluu = len(kullanc_ad)
>>> type(k_ad_uzunluu)
<class 'int'>
87
4. Deiken adlar iinde Trke karakterler kullanabilirsiniz. Ancak ileride beklenmedik uyum
sorunlar kmas ihtimaline kar deiken adlarnda Trke karakter kullanmaktan kanmak
isteyebilirsiniz.
5. Aadaki kelimeleri deiken ad olarak kullanamazsnz:
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class',
'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for',
'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not',
'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
Bunlar Pythonda zel anlam ifade eden kelimelerdir. Etkileimli kabuk zaten bu kelimeleri
deiken ad olarak kullanmanza izin vermez. rnein:
>>> elif = "ho kz"
File "<stdin>", line 1
elif = "ho kz"
^
SyntaxError: invalid syntax
>>> as = "kare"
File "<stdin>", line 1
as = "kare"
^
SyntaxError: invalid syntax
>>> False = 45
File "<stdin>", line 1
SyntaxError: assignment to keyword
Ama ilerde greceimiz gibi, programlarnz bir dosyaya yazarken bu kelimeleri deiken ad
olarak kullanmaya alrsanz programnz tespit etmesi ok g hatalar retecektir.
Bu arada elbette yukardaki listeyi bir rpda ezberlemeniz beklenmiyor sizden. Python
programlama dilini rendike zel kelimeleri bir bakta tanyabilecek duruma geleceksiniz.
Ayrca eer isterseniz u komutlar vererek, istediiniz her an yukardaki listeye ulaabilirsiniz:
>>> import keyword
>>> [Link]
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class',
'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for',
'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not',
'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
88
Bu soru karsnda listedeki kelimeleri tek tek elle saymaya kalkan arkadalarma
teesserimi iletiyorum... Bu tr iler iin hangi arac kullanabileceimizi artk ok iyi biliyor
olmalsnz:
>>> len([Link])
33
Bu rnekte type adnda bir deiken tanmladk. imdi mesela elma kelimesinin tipini
denetlemek iin type() fonksiyonunu kullanmaya alalm:
>>> type("elma")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Grdnz gibi, artk type() fonksiyonu almyor. nk siz type kelimesini bir deiken
ad olarak kullanarak, type() fonksiyonunu kullanlamaz hale getirdiniz.
Bu durumdan kurtulmak iin etkileimli kabuu kapatp tekrar aabilirsiniz. Ya da eer
etkileimli kabuu kapatmak istemiyorsanz u komut yardmyla type deikenini ortadan
kaldrmay da tercih edebilirsiniz:
>>> del type
Bylece, (tahmin edebileceiniz gibi delete (silmek) kelimesinin ksaltmas olan) del
komutuyla type deikenini silmi oldunuz. Artk type kelimesi yine type() fonksiyonunu
aracak:
>>> type("elma")
<class 'str'>
89
Ya da yle:
>>> kullancAd = "istihza"
8.
Deiken adlar belirlerken, deiken adnn, deikenin deerini olabildiince
betimlemesine dikkat etmemiz kodlarmzn okunaklln artracaktr. rnein:
>>> personel_says = 45
Yukardaki, tanmlad deere uygun bir deiken addr. u ise kurallara uygun bir deiken
ad olsa da yeterince betimleyici deildir:
>>> say = 45
90
Grdnz gibi, burada da 22 saysna ihtiya duyduk. Aslnda deerleri bu ekilde her
defasnda tekrar tekrar elle girmek hem hata yapma riskini artrd, hem de bize fazladan
i kard iin tercih edilmeyen bir yntemdir. Bunun yerine, 22 saysna bir isim verip,
gereken yerlerde bu ismi kullanmak daha mantkl olacaktr. Yani tpk kullanc ve parola
rneinde olduu gibi, burada da verileri ncelikle bir deikene atamak ok daha akllca bir
itir:
>>>
>>>
>>>
>>>
gn = 22
gidi_creti = 1.5
dn_creti = 1.4
gn * (gidi_creti + dn_creti)
63.8
Btn deerleri birer deikene atadmz iin, artk bu deikenleri istediimiz yerde
kullanabiliriz. Mesela ylda toplam ka gn altmz bulmak istersek, ilgili deeri elle
91
Eer bu ekilde deiken atamak yerine, deerleri gerektii her yerde elle yazsaydk, bu
deerlerde herhangi bir deiiklik yapmamz gerektiinde program iinde geen ilgili btn
deerleri bulup tek tek deitirmemiz gerekecekti:
>>> 23 * (1.6 + 1.5)
71.3
>>> 23 * 12
276
Deiken kavram u anda gznze pek anlaml grnmemi olabilir. Ama programlarmz
ilerde dosyaya kaydettiimiz zaman bu deikenler ok daha kullanl aralar olarak
karmza kacaktr.
Dilerseniz bir rnek daha yaparak yukardaki bilgilerin kafamza iyice yerlemesiniz
salayalm. Mesela bir dairenin alann (yaklak olarak) hesaplayan bir program yazalm.
ncelikle ap adl bir deiken tanmlayarak dairenin apn belirleyelim:
>>> ap = 16
92
Bylece bir dairenin alann yaklak olarak hesaplam olduk. Dilerseniz programmz bir de
derli toplu olarak grelim:
>>>
>>>
>>>
>>>
>>>
ap = 16
yarap = ap / 2
pi = 3.14159
alan = pi * (yarap * yarap)
alan
201.06176
Bu kodlar tek kullanmlktr. Eer yukardaki rnekte mesela dairenin apn deitirmeniz
gerekirse, iki yerde elle deiiklik yapmanz gerekir. Ama deikenleri kullandmzda sadece
ap deikeninin deerini deitirmeniz yeterli olacaktr. Ayrca deiken kullanmadnzda,
ilgili deeri program boyunca aklnzda tutmanz gerekir. rnein ap deikenini kullanmak
yerine, gereken her yerde 16 deerini kullanacaksanz, bu 16 deerini srekli aklnzda
tutmanz lazm. Ama bu deeri en bata bir deikene atarsanz, 16 deerini kullanmanz
gereken yerlerde, aklda tutmas daha kolay bir ifade olan ap ismini kullanabilirsiniz.
Bu arada yeri gelmiken sizi yeni bir ilele daha tantralm. imdiye kadar Pythonda
toplama (+ ), karma (-), arpma (* ), blme (/ ) ve deer atama (= ) ilelerini grdk. Ama
yukarda verdiimiz son rnek, baka bir ile daha renmemizi gerektiriyor...
Yukardaki u rnee tekrar bakalm:
alan = pi * (yarap * yarap)
Burada yarap deikeninin karesini alabilmek iin bu deeri kendisiyle arptk. Aslnda
gayet mantkl ve makul bir yntem. Kare bulmak iin deeri kendisiyle arpyoruz. Eer
bir saynn kpn bulmak isteseydik o sayy kez kendisiyle arpacaktk:
>>> 3 * 3 * 3
27
Peki ya bir saynn mesela beinci kuvvetini hesaplamak istersek ne yapacaz? O sayy be
kez kendisiyle mi arpacaz? Bu ne kadar vasat bir yntem, deil mi?
Elbette bir saynn herhangi bir kuvvetini hesaplamak iin o sayy kendisiyle kuvvetince
arpmayacaz. Pythonda bu tr kuvvet hesaplamalar iin ayr bir ile (ve fonksiyon)
bulunur.
ncelikle kuvvet hesaplarn yapmamz salayan ileten sz edelim.
Pythonda ** adl bir ile bulunur. Bu ilecin grevi bir saynn kuvvetini hesaplamamz
salamaktr. rnein bir saynn 2. kuvvetini, ya da baka bir deyile karesini hesaplamak
istersek yle bir kod yazabiliriz:
>>> 12 ** 2
144
93
Bu ileci herhangi bir saynn herhangi bir kuvvetini hesaplamak iin kullanabiliriz elbette.
Mesela 23 saysnn kpn (yani 3. kuvvetini) hesaplayalm:
>>> 23 ** 3
12167
Ayn ileten, bir saynn karekkn hesaplamak iin de yararlanabilirsiniz. Neticede bir
saynn 0.5 inci kuvveti, o saynn karekkdr:
>>> 144 ** 0.5
12.0
Grdnz gibi, kuvvet hesaplama ilemleri iin bu ile son derece kullanl bir ara
vazifesi gryor. Ama eer istersek ayn i iin zel bir fonksiyondan da yararlanabiliriz. Bu
fonksiyonun ad pow().
Peki bu fonksiyonu nasl kullanacaz?
Daha nce rendiimiz type() ve len() fonksiyonlarn nasl kullanyorsak pow() fonksiyonu
da ayn ekilde kullanacaz.
type() ve len() fonksiyonlarn birtakm parametreler ile birlikte kullanyorduk hatrlarsanz.
Ayn ekilde pow() fonksiyonu da birtakm parametreler alr.
Daha nce rendiimiz fonksiyonlar tek bir parametre ile birlikte kullanmtk. pow()
fonksiyonu ise toplam farkl parametre alr. Ama genellikle bu fonksiyon yalnzca iki
parametre ile kullanlr.
Bu fonksiyonu yle kullanyoruz:
>>> pow(12, 2)
144
>>> pow(23, 3)
12167
>>> pow(144, 0.5)
12.0
Grdnz gibi, pow() fonksiyonunun ilk parametresi asl sayy, ikinci parametresi ise bu
saynn hangi kuvvetini hesaplamak istediimizi gsteriyor.
Bu arada, fonksiyonun parantezleri iinde belirttiimiz parametreleri birbirinden virgl ile
ayrdmz gzden karmayn.
Dediimiz gibi, pow() fonksiyonu, pek kullanlmayan nc bir parametre daha alr. Bu
fonksiyonun nc parametresi yle kullanlr. Dikkatlice bakn:
94
>>> pow(16, 2, 2)
0
Demek ki, 11 saysnn 3. kuvveti olan 1331 says 4 e blndnde, blme ileminden kalan
say 3 imi...
Dediimiz gibi, pow() fonksiyonu genellikle sadece iki parametre ile kullanlr.
parametrenin kullanm alan olduka dardr.
nc
imdi size yle bir soru sormama izin verin: Acaba ayn deere sahip iki deikeni nasl
tanmlayabiliriz? Yani mesela deeri 4 says olan iki farkl deikeni nasl belirleyeceiz?
Aklnza yle bir zm gelmi olabilir:
>>> a = 4
>>> b = 4
Bylece ikisi de 4 deerine sahip a ve b adl iki farkl deiken tanmlam olduk. Bu tamamen
geerli bir yntemdir. Ancak Pythonda bu ilemi yapmann daha kolay bir yolu var. Bakalm:
>>> a = b = 4
Bu kodlar bir ncekiyle tamamen ayn ilevi grr. Yani her iki kod da 4 deerine sahip a ve
b deikenleri tanmlamamz salar:
>>> a
4
>>> b
4
Bu bilgiyi kullanarak mesela bir yl iindeki her bir ayn ektii gn saysn ay adlarna
atayabilirsiniz:
8.2. Etkileimli Kabukta lk Admlar
95
Bylece bir rpda deeri 31 olan yedi adet deiken, deeri 30 olan drt adet deiken,
deeri 28 olan bir adet deiken tanmlam olduk. Bu deikenlerin deerine nasl
ulaacanz biliyorsunuz:
>>> ocak
31
>>> haziran
30
>>> ubat
28
>>> mays
31
>>> ekim
31
>>> eyll
30
Eer Pythonn ayn anda birden fazla deikene tek bir deer atama zellii olmasayd
yukardaki kodlar yle yazmamz gerekirdi:
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
ocak = 31
ubat = 28
mart = 31
nisan = 30
mays = 31
haziran = 30
temmuz = 31
austos = 31
eyll = 30
ekim = 31
kasm = 30
aralk = 31
Bu deikenleri nasl bir program iinde kullanacanz tamamen sizin hayal gcnze kalm.
Mesela bu deikenleri kullanarak aylara gre doalgaz faturasn hesaplayan bir program
yazabiliriz.
Hemen son gelen doalgaz faturasn (rn. Mart ay) elimize alp inceliyoruz ve bu faturadan
u verileri elde ediyoruz:
Mart ay doalgaz faturasna gre sayatan llen hacim 346 m3 . Demek ki bir ayda toplam
346 m3 doalgaz harcamz.
Fatura tutar 273.87 TL imi. Yani 346 m3 doalgaz tketmenin bedeli 273.87 TL. Buna gre
96
deikenlerimizi tanmlayalm:
>>> aylk_sarfiyat = 346
>>> fatura_tutar = 273.87
Demek ki doalgazn m3 yat (vergilerle birlikte yaklak) 0.79 TLye karlk geliyormu.
Bu noktada gnlk ortalama doalgaz saryatmz da hesaplamamz gerekiyor:
>>> gnlk_sarfiyat = aylk_sarfiyat / mart
>>> gnlk_sarfiyat
11.161290322580646
Diyelim ki, iyerinizdeki personelin unvanlarn tuttuunuz bir veritaban var elinizde. Bu
veritabannda una benzer ilikiler tanml:
>>> osman = "Aratrma Gelitirme Mdr"
>>> mehmet = "Proje Sorumlusu"
97
Gelin isterseniz
>>> osman
'Proje Sorumlusu
>>> mehmet
'Aratrma Gelitirme Mdr'
Grdnz gibi, osman deikeninin deerini mehmet e; mehmet deikeninin deerini ise
osman a baaryla verebilmiiz.
Yukardaki yntem Pythonn teki diller zerinde nemli bir stnldr.
Baka
programlama dillerinde bu ilemi yapmak iin geici bir deiken tanmlamanz gerekir. Yani
mesela:
>>> osman = "Aratrma Gelitirme Mdr"
>>> mehmet = "Proje Sorumlusu"
Elimizdeki deerler bunlar. Biz imdi Osmann deerini Mehmete; Mehmetin deerini ise
Osmana aktaracaz. Bunun iin ncelikle bir geici deiken tanmlamalyz:
>>> geici = "Proje Sorumlusu"
Bu sayede Proje Sorumlusu deerini yedeklemi olduk. Bu ilem sayesinde, takas srasnda
bu deeri kaybetmeyeceiz.
imdi Osmann deerini Mehmete aktaralm:
>>> mehmet = osman
Grdnz gibi, mehmet = osman kodunu kullanarak mehmet deikeninin deerini osman
deikeninin deeriyle deitirdiimiz iin Proje Sorumlusu deeri ortadan kayboldu. Ama
biz nceden bu deeri geici adl deikene atadmz iin bu deeri kaybetmemi olduk.
imdi Osmana geici deikeni iinde tuttuumuz Proje Sorumlusu deerini verebiliriz:
>>> osman = geici
Bylece istediimiz takas ilemini gerekletirmi olduk. Son durumu kontrol edelim:
>>> osman
98
'Proje Sorumlusu
>>> mehmet
'Aratrma Gelitirme Mdr'
Basit bir ilem iin ne kadar byk bir zaman kayb, deil mi? Ama dediimiz gibi, Pythonda
bu ekilde geici bir deiken atamakla uramamza hi gerek yok. Sadece u forml
kullanarak deikenlerin deerini takas edebiliriz:
a, b = b, a
Bylece deikenler konusunu da olduka ayrntl bir ekilde incelemi olduk. Ayrca bu
esnada len() ve pow() adl iki yeni fonksiyon ile ** adl bir ile de rendik.
Hazr laf gemiken, len() fonksiyonunun baz kstlamalarndan sz edelim. Dediimiz
gibi, bu fonksiyonu kullanarak karakter dizileri iinde toplam ka adet karakter bulunduunu
hesaplayabiliyoruz. rnein:
>>> kelime = "muvaffakiyet"
>>> len(kelime)
12
Grdnz gibi, len() fonksiyonu, u ana kadar rendiimiz veri tipleri arasnda yalnzca
karakter dizileri ile birlikte kullanlabiliyor. Bu fonksiyonu saylarla birlikte kullanamyoruz.
Bu blmn banda, o anda elimizde bulunan bir verinin tipini bilmemizin ok nemli
olduunu ve Pythonda bir verinin tipinin, o veri ile neler yapp neler yapamayacanz
belirlediini sylediimizi hatrlyorsunuz, deil mi? te len() fonksiyonu bu duruma ok
gzel bir rnektir.
len() fonksiyonu saylarla birlikte kullanlamaz. Dolaysyla eer elinizdeki verinin bir say
olduunu bilmezseniz, bu sayy len() fonksiyonu ile birlikte kullanmaya alabilir ve bu
ekilde programnzn hata vererek kmesine yol aabilirsiniz.
Ayrca daha nce de sylediimiz gibi, len() fonksiyonunu doru kullanabilmek iin, bu
fonksiyonun bize say deerli bir kt verdiini de bilmemiz gerekir.
len() fonksiyonu ile ilgili bu durumu da bir kenara not ettikten sonra yolumuza kaldmz
yerden devam edelim.
99
Bu zellikten eitli
>>> _ + 15
56715
Burada _ komutunun deeri bir nceki ilemin sonucu olan 56715 deeri olduu iin,
_ komutuna 15 eklediimizde 56715 deerini elde ediyoruz. _ komutunun deerini tekrar
kontrol edelim:
>>> _
56715
Bu iaret yle ok sk kullanlan bir ara deildir, ama zaman zaman iinizi epey kolaylatrr.
Yalnz, unutmamamz gereken ey, bu zelliin sadece etkileimli kabuk ortamnda geerli
olmasdr. _ komutunun etkileimli kabuk ortam dnda herhangi bir geerlilii yoktur.
Aslnda burada sylenecek daha ok ey var. Ama biz imdilik bunlar sonraki konulara
brakacaz. Zira bu blmdeki amacmz size konularn her ayrntsn vermekten ziyade,
Pythona snmanz salamaktr.
100
BLM 9
print() Fonksiyonu
Geen blmde bir yandan Pythonn etkileimli kabuunu yakndan tanyp bu vesileyle baz
nemli fonksiyon ve aralar renirken, br yandan bu rendiklerimizi kullanarak rnek
programlar yazdk. Grdnz gibi, azck bir bilgiyle dahi az ok ie yarar programlar
yazmak mmkn olabiliyor. Daha yararl programlar yazabilmek iin henz renmemiz
gereken pek ok ey var. te bu blmde, daha yararl programlar yazmamz salayacak
ok nemli bir aratan sz edeceiz. neminden dolay ayrntl bir ekilde anlatacamz bu
aracn ad print() fonksiyonu.
Elbette bu blmde sadece print() fonksiyonundan bahsetmeyeceiz. Bu blmde print()
fonksiyonunun yansra Pythondaki baz nemli temel konular da ele alacaz. Mesela bu
blmde Pythondaki karakter dizilerine ve saylara ilikin ok nemli bilgiler vereceiz. Ayrca
print() fonksiyonu vesilesiyle Pythondaki fonksiyon konusuna da salam bir giri yapm,
bu kavram ile ilgili ilk bilgilerimizi alm olacaz. Szn z, bu blm bizim iin, deyim
yerindeyse, tam anlamyla bir dnm noktas olacak.
O halde isterseniz laf daha fazla uzatmadan ie print() fonksiyonunun ne olduu ve ne ie
yaradn anlatarak balayalm.
Etkileimli kabuk da, ekrana yazdmz bu karakter dizisi ve sayy dorudan bize kt
olarak verdi. Ancak ilerde Python kodlarmz bir dosyaya kaydedip altrdmzda da
greceiniz gibi, Pythonn ekrana kt verebilmesi iin yukardaki kullanm yeterli deildir.
Yani yukardaki kullanm yalnzca etkileimli kabukta alr. Bu kodlar bir dosyaya kaydedip
altrmak istediimizde hibir kt alamayz. Pythonda yazdmz eylerin ekrana kt
olarak verilebilmesi iin print() adl zel bir fonksiyondan yararlanmamz gerekir.
O halde gelin bu print() fonksiyonunun ne ie yaradn ve nasl kullanldn anlamaya
alalm:
101
print() de tpk daha nce grdmz type(), len() ve pow() gibi bir fonksiyondur.
Fonksiyonlar ilerde daha ayrntl bir ekilde inceleyeceimizi sylemitik hatrlarsanz. O
yzden fonksiyon kelimesine taklarak, burada anlattmz eylerin kafanz kartrmasna,
moralinizi bozmasna izin vermeyin.
print() fonksiyonunun grevi ekrana kt vermemizi salamaktr. Hemen bununla ilgili bir
rnek verelim:
>>> print("Python programlama dili")
Python programlama dili
Bildiiniz gibi burada grdmz Python programlama dili bir karakter dizisidir. te
print() fonksiyonunun grevi bu karakter dizisini ekrana kt olarak vermektir. Peki
bu karakter dizisini print() fonksiyonu olmadan yazdmzda da ekrana kt vermi
olmuyor muyuz? Aslnda olmuyoruz. Dediimiz gibi, ilerde programlarmz dosyalara
kaydedip altrdmzda, banda print() olmayan ifadelerin ktda grnmediine ahit
olacaksnz.
Daha nce de dediimiz gibi, etkileimli kabuk bir test ortam olmas asndan rahat bir
ortamdr. Bu sebeple bu ortamda ekrana kt verebilmek iin print() fonksiyonunu
kullanmak zorunda deilsiniz. Yani banda print() olsa da olmasa da etkileimli kabuk
ekrana yazdrmak istediiniz eyi yazdrr. Ama iyi bir alkanlk olmas asndan, ekrana
herhangi bir ey yazdracanzda ben size print() fonksiyonunu kullanmanz tavsiye
ederim.
print() son derece gl bir fonksiyondur. Gelin isterseniz bu gl ve faydal fonksiyonu
derin derin incelemeye koyulalm.
Bu arada, hem imdi verdiimiz, hem de daha nce yazdmz rneklerde bir ey dikkatinizi
ekmi olmal. imdiye kadar verdiimiz rneklerde karakter dizilerini hep ift trnakla
gsterdik. Ama aslnda tek seeneimiz ift trnak deildir. Python bize farkl trnak
seenei sunar:
102
1. Tek trnak ( )
2. ift trnak ( )
3. trnak ( )
Dolaysyla yukardaki rnei farkl ekilde yazabiliriz:
>>> print('Python programlama dili')
Python programlama dili
>>> print("Python programlama dili")
Python programlama dili
>>> print("""Python programlama dili""")
Python programlama dili
Bunun sebebi, cmle iinde geen piton kelimesinin de ift trnaklar iinde gsterilmi
olmasdr. Cmlenin, yani karakter dizisinin kendisi de ift trnak iinde gsterildii iin
Python, karakter dizisini balatan ve bitiren trnaklarn hangisi olduunu ayrt edemiyor.
Yukardaki cmleyi en kolay u ekilde ekrana yazdrabiliriz:
>>> print('Python programlama dilinin ad "piton" ylanndan gelmez')
Python programlama dilinin ad "piton" ylanndan gelmez
Burada karakter dizisini tek trnak iine aldk. Karakter dizisi iinde geen piton kelimesi
ift trnak iinde olduu iin, karakter dizisini balatp bitiren trnaklarla piton kelimesindeki
trnaklarn birbirine karmas gibi bir durum sz konusu deildir.
Bir de yle bir rnek verelim: Diyelim ki aadaki gibi bir kt elde etmek istiyoruz:
stanbul'un 5 gnlk hava durumu tahmini
Eer bu karakter dizisini tek trnak iaretleri iinde belirtirseniz Python size bir hata mesaj
gsterecektir:
103
Bu hatann sebebi stanbulun kelimesi iinde geen kesme iaretidir. Tpk bir nceki
rnekte olduu gibi, Python karakter dizisini balatan ve bitiren trnaklarn hangisi olduunu
kestiremiyor.
Python, karakter dizisinin en bandaki tek trnak iaretinin ardndan
stanbulun kelimesi iindeki kesme iaretini grnce karakter dizisinin burada sona erdiini
zannediyor. Ancak karakter dizisini soldan saa doru okumaya devam edince bir yerlerde
bir terslik olduunu dnyor ve bize bir hata mesaj gstermekten baka aresi kalmyor.
Yukardaki karakter dizisini en kolay yle tanmlayabiliriz:
>>> print("stanbul'un 5 gnlk hava durumu tahmini")
stanbul'un 5 gnlk hava durumu tahmini
Burada da, karakter dizisi iinde geen kesme iaretine taklmamak iin karakter dizimizi ift
trnak iaretleri iine alyoruz.
Yukardaki karakter dizilerini dzgn bir ekilde kt verebilmek iin trnak iaretlerinden
de yararlanabiliriz:
>>> print("""Python programlama dilinin ad "piton" ylanndan gelmez""")
Python programlama dilinin ad "piton" ylanndan gelmez
>>> print("""stanbul'un 5 gnlk hava durumu tahmini""")
stanbul'un 5 gnlk hava durumu tahmini
104
Byle bir kt verebilmek iin eer tek veya ift trnak kullanmaya kalkrsanz epey eziyet
ekersiniz. Bu tr bir kt vermenin en kolay yolu trnaklar kullanmaktr:
>>>
...
...
...
...
...
...
...
...
...
print("""
[H]=========HARMAN========[-][o][x]
|
|
|
Programa Hogeldiniz!
|
|
Srm 0.8
|
|
Devam etmek iin herhangi
|
|
bir dmeye basn.
|
|
|
|=================================|
""")
Burada baz eyler dikkatinizi ekmi olmal. Grdnz gibi, trnakl yap teki trnak
tiplerine gre biraz farkl davranyor. imdi u rnee bakn:
>>> print("""Game Over!
...
Buraya ok dikkatli bakn. Karakter dizisine trnakla baladktan sonra, kapan trnan
koymadan Enter tuuna bastmzda >>> iareti ... iaretine dnt. Python bu ekilde
bize, yazmaya devam et! demi oluyor. Biz de buna uyarak yazmaya devam edelim:
>>> print("""Game Over!
... Insert Coin!""")
Game Over!
Insert Coin!
Kapan trna koyulmadan Enter tuuna basldnda >>> iaretinin ... iaretine dnmesi
trnaa zg bir durumdur. Eer ayn eyi tek veya ift trnaklarla yapmaya alrsanz
programnz hata verir:
>>> print("Game Over!
File "<stdin>", line 1
print("Game Over!
^
SyntaxError: EOL while scanning string literal
...veya:
>>> print('Game Over!
File "<stdin>", line 1
print("Game Over!
^
SyntaxError: EOL while scanning string literal
trnak iaretlerinin trnak kapanmadan Enter tuuna basldnda hata vermeme zellii
sayesinde, bu trnak tipi zellikle birden fazla satra yaylm karakter dizilerinin gsterilmesi
iin birebirdir.
Gelin isterseniz trnak kullanmna ilikin bir rnek daha verelim:
>>> print("""Python programlama dili Guido Van Rossum
... adl Hollandal bir programc tarafndan 90l
105
...
...
...
...
...
Elbette eer istersek bu metni nce bir deikene atamay da tercih edebiliriz:
>>>
...
...
...
...
...
...
>>>
Siz yukardaki kty tek veya ift trnak kullanarak nasl ekrana yazdrabileceinizi
dnedurun, biz nemli bir konuya gei yapalm!
Burada print() bir fonksiyon, Aramak istediiniz kelimeyi yazn: adl karakter dizisi ise bu
fonksiyonun parametresidir. Daha nce len() adl baka bir fonksiyon daha renmitik
hatrlarsanz. Onu da yle kullanyorduk:
>>> len("elma")
Burada da len() bir fonksiyon, elma adl karakter dizisi ise bu fonksiyonun parametresidir.
Aslnda biim olarak print() ve len() fonksiyonlarnn birbirinden hibir fark olmadn
106
gryorsunuz.
Daha nce sylediimiz ve bu rneklerden de anladmz gibi, bir fonksiyonun parantezleri
iinde belirtilen elere parametre ad veriliyor.
Mesela aadaki rnekte print()
fonksiyonunu tek bir parametre ile kullanyoruz:
>>> print('En az 8 haneli bir parola belirleyin.')
print() fonksiyonu, tpk pow() fonksiyonu gibi, birden fazla parametre alabilir:
>>> print('Frat', 'zgl')
Frat zgl
Bu rnekte bizim iin karlacak ok dersler var. Bir defa burada print() fonksiyonunu iki
farkl parametre ile birlikte kullandk. Bunlardan ilki Frat adl bir karakter dizisi, ikincisi ise
zgl adl baka bir karakter dizisi. Pythonn bu iki karakter dizisini nasl birletirdiine dikkat
edin. print() fonksiyonu bu iki karakter dizisini kt olarak verirken aralarna da birer boluk
yerletirdi. Ayrca, geen derste de vurguladmz gibi, parametrelerin birbirinden virgl ile
ayrldn da gzden karmyoruz.
Gelin bununla ilgili bir iki rnek daha verelim elimizin almas iin:
>>> print("Python", "Programlama", "Dili")
Python Programlama Dili
>>> print('Frat', 'zgl', 'Adana', 1980)
Frat zgl Adana 1980
Bu arada dikkatinizi nemli bir noktaya ekmek istiyorum. Yukardaki rneklerde bazen tek
trnak, bazen de ift trnak kullandk. Daha nce de sylediimiz gibi, hangi trnak tipini
kullandmz nemli deildir. Python hangi trnak tipini kullandmzdan ziyade, trnak
kullanmnda tutarl olup olmadmzla ilgilenir. Yani Python iin nemli olan, karakter
dizisini hangi trnakla balatmsak, o trnakla bitirmemizdir. Yani u tip kullanmlar geerli
deildir:
>>> print("karakter dizisi')
>>> print('karakter dizisi")
Karakter dizisini tanmlamaya balarken kullandmz trnak tipi ile karakter dizisini
tanmlamay bitirirken kullandmz trnak tipi birbirinden farkl olduu iin bu iki kullanm
da hata verecektir.
107
9.4.1 sep
print() fonksiyonu ile ilgili olarak yukarda verdiimiz rnekleri incelediimizde, bu
fonksiyonun kendine zg bir davran ekli olduunu gryoruz. Mesela bir nceki blmde
verdiimiz u rnee bakalm:
>>> print('Frat', 'zgl')
Frat zgl
Burada print() fonksiyonunu iki farkl parametre ile birlikte kullandk. Bu fonksiyon,
kendisine verdiimiz bu parametreleri belli bir dzene gre birbiriyle birletirdi. Bu dzen
gereince print(), kendisine verilen parametreleri birletirirken, parametreler arasna bir
boluk yerletiriyor. Bunu daha net grmek iin yle bir rnek daha verelim:
>>> print("Python", "PHP", "C++", "C", "Erlang")
Python PHP C++ C Erlang
Ya da boluk karakteri yerine daha farkl bir karakter kullanmak istiyor da olabiliriz. Peki byle
bir durumda ne yapmamz gerekir?
te bu noktada baz zel aralardan yararlanarak print() fonksiyonunun ntanml davran
kalplar zerinde deiiklikler yapabiliriz.
Peki nedir print() fonksiyonunu zelletirmemizi salayacak bu aralar?
Hatrlarsanz, Pythonda fonksiyonlarn parantezleri iindeki deerlere parametre ad
verildiini sylemitik. Mesela print() fonksiyonunu bir ya da daha fazla parametre ile
birlikte kullanabileceimizi biliyoruz:
>>> print("Mehmet", "z", "stanbul", "amlca", 156, "/", 45)
Mehmet z stanbul amlca 156 / 45
print() fonksiyonu iinde istediimiz sayda karakter dizisi ve/veya say deerli parametre
kullanabiliriz.
Fonksiyonlarn bir de daha zel grnml parametreleri vardr.
Mesela print()
fonksiyonunun sep adl zel bir parametresi bulunur. Bu parametre print() fonksiyonunda
grnmese bile her zaman oradadr. Yani diyelim ki yle bir kod yazdk:
>>> print("[Link] "www.", "google.", "com")
Burada herhangi bir sep parametresi grmyoruz. Ancak Python yukardaki kodu aslnda
yle alglar:
108
Grdnz gibi, karakter dizilerini baaryla birletirip, geerli bir internet adresi elde ettik.
Burada yaptmz ey aslnda ok basit. Sadece sep parametresinin bir adet boluk karakteri
olan ntanml deerini silip, yerine bo bir karakter dizisi deerini yazdk. Bu iki kavramn
birbirinden farkl olduunu sylediimizi hatrlyorsunuz, deil mi?
Gelin bir rnek daha yapalm:
>>> print("T", "C", sep=".")
T.C
imdi bu trky
Burada bir terslik olduu ak! Karakter dizileri birbirlerine skk dzende birletirildi.
Bunlarn arasnda birer boluk olsa tabii daha iyi olurdu.
Ancak biliyorsunuz sep
9.4. print() Fonksiyonunun Parametreleri
109
Burada da, mumdur adl karakter dizisinin banda ve sonunda birer boluk brakmak
yerine, gerekli boluklar + iareti yardmyla bu karakter dizisine birletirdik. Hatta istersek +
ilecini kullanmak zorunda olmadmz dahi biliyorsunuz:
>>> print("bir", "iki", "", "drt", "on drt", sep=" " "mumdur" " ")
Ama grdnz gibi bir problemimiz daha var. Trknn szleri u ekilde olmalyd:
bir mumdur iki mumdur mumdur drt mumdur on drt mumdur
Ama sondaki mumdur kelimesi yukardaki ktda yok. Normal olan da bu aslnda. sep
parametresi, karakter dizilerinin arasna bir deer yerletirir. Karakter dizilerinin son tarafyla
ilgilenmez. Bu i iin print() fonksiyonu baka bir parametreye sahiptir.
Bu arada, yukardaki rneklerde hep karakter dizilerini kullanm olmamz sizi yanltmasn.
sep parametresi yalnzca karakter dizilerinin deil saylarn arasna da istediiniz bir deerin
yerletirilmesini salayabilir. Mesela:
>>> print(1, 2, 3, 4, 5, sep="-")
1-2-3-4-5
Ancak sep parametresine deer olarak yalnzca karakter dizilerini ve None adl zel bir
szc verebiliriz. (None szcnden ileride sz edeceiz):
>>> print(1, 2, 3, 4, 5, sep=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sep must be None or a string, not int
110
Eer amacnz parametreleri birbirine bititirmekse, yani sep parametresinin ntanml deeri
olan boluk karakterini ortadan kaldrmaksa, sep parametresine bo bir karakter dizisi
vermeniz gerektiini biliyorsunuz:
>>> print('a', 'b', sep='')
ab
9.4.2 end
Bir nceki blmde yle bir laf etmitik:
print() fonksiyonun sep adl zel bir parametresi bulunur.
print() fonksiyonunda grnmese bile her zaman oradadr.
Bu parametre
Ayn bu ekilde, print() fonksiyonunun end adl zel bir parametresi daha bulunur. Tpk
sep parametresi gibi, end parametresi de print() fonksiyonunda grnmese bile her zaman
oradadr.
Bildiiniz gibi, sep parametresi print() fonksiyonuna verilen parametreler birletirilirken
araya hangi karakterin gireceini belirliyordu. end parametresi ise bu parametrelerin sonuna
neyin geleceini belirler.
print() fonksiyonu ntanml olarak, parametrelerin sonuna satr ba karakteri ekler. Peki
bu satr ba karakteri (veya yeni satr karakteri) denen ey de ne oluyor?
Dilerseniz bunu bir rnek zerinde grelim.
yle bir kodumuz olsun:
>>> print("Pardus ve Ubuntu birer GNU/Linux datmdr.")
Bu kodu yazp Enter tuuna bastmz anda print() fonksiyonu iki farkl ilem gerekletirir:
1. ncelikle karakter dizisini ekrana yazdrr.
2. Ardndan bir alt satra geip bize >>> iaretini gsterir.
te bu ikinci ilem, karakter dizisinin sonunda bir adet satr ba karakteri olmasndan,
daha dorusu print() fonksiyonunun, satr ba karakterini karakter dizisinin sonuna
eklemesinden kaynaklanr. Bu aklama biraz kafa kartrc gelmi olabilir. O halde biraz
daha aklayalm. u rnee bakn:
>>> print("Pardus\nUbuntu")
Pardus
Ubuntu
Burada Pardus ve Ubuntu karakter dizilerinin tam ortasnda ok zel bir karakter dizisi
daha gryorsunuz. Bu karakter dizisi udur: \n. te bu zel karakter dizisine satr ba
karakteri (newline ) ad verilir. Bu karakterin grevi, karakter dizisini, bulunduu noktadan
blp, karakter dizisinin geri kalann bir alt satra geirmektir. Zaten ktda da bu ilevi
yerine getirdiini gryorsunuz. Karakter dizisi Pardus ksmndan sonra ikiye blnyor ve
bu karakter dizisinin geri kalan ksm olan Ubuntu karakter dizisi bir alt satra yazdrlyor.
Bunu daha iyi anlamak iin bir rnek daha verelim:
9.4. print() Fonksiyonunun Parametreleri
111
Peki size bir soru soraym: Acaba yukardaki kodlar daha verimli bir ekilde nasl yazabiliriz?
Evet, doru tahmin ettiniz... Tabii ki sep parametresini kullanarak:
>>> print("birinci satr", "ikinci satr", "nc satr", sep="\n")
birinci satr
ikinci satr
nc satr
Burada yaptmz ey ok basit. sep parametresinin deerini \n, yani yeni satr karakteri
(veya satr ba karakteri) olarak deitirdik. Bylece karakter dizileri arasna birer \n karakteri
yerletirerek her bir karakter dizisinin farkl satra yazdrlmasn saladk.
te end parametresinin ntanml deeri de bu \n karakteridir ve bu parametre print()
fonksiyonunda grnmese bile her zaman oradadr.
Yani diyelim ki yle bir kod yazdk:
>>> print("Bugn gnlerden Sal")
Burada herhangi bir end parametresi grmyoruz. Ancak Python yukardaki kodu aslnda
yle alglar:
>>> print("Bugn gnlerden Sal", end="\n")
Biraz nce de dediimiz gibi, bu kodu yazp Enter tuuna bastmz anda print() fonksiyonu
iki farkl ilem gerekletirir:
1. ncelikle karakter dizisini ekrana yazdrr.
2. Ardndan bir alt satra geip bize >>> iaretini gsterir.
Bunun ne demek olduunu anlamak iin end parametresinin deerini deitirmemiz yeterli
olacaktr:
>>> print("Bugn gnlerden Sal", end=".")
Bugn gnlerden Sal.>>>
Grdnz gibi, end parametresinin ntanml deeri olan \n karakterini silip yerine .
(nokta) iareti koyduumuz iin, komutu yazp Enter tuuna bastmzda print() fonksiyonu
satr bana gemedi. Yeni satra geebilmek iin Enter tuuna kendimiz basmalyz. Elbette,
eer yukardaki kodlar yle yazarsanz, print() fonksiyonu hem karakter dizisinin sonuna
nokta ekleyecek, hem de satr bana geecektir:
>>> print("Bugn gnlerden Sal", end=".\n")
Bugn gnlerden Sal.
112
Not: Burada kodlarmzn saa doru irkin bir ekilde uzamasn engellemek iin on drt
karakter dizisini yazp virgl koyduktan sonra Enter tuuna basarak bir alt satra getik.
Bir alt satra getiimizde >>> iaretinin ... iaretine dntne dikkat edin. Pythonda
doru kod yazmak kadar, yazdmz kodlarn dzgn grnmesi de nemlidir. O yzden
yazdmz her bir kod satrnn mmkn olduunca 79 karakteri gememesini salamalyz.
Eer yazdnz bir satr 79 karakteri ayorsa, aan ksm yukarda gsterdiimiz ekilde alt
satra alabilirsiniz.
end parametresi de, tpk sep parametresi gibi, her zaman ismiyle birlikte kullanlmas
gereken bir parametredir. Yani eer end parametresinin ismini belirtmeden sadece deerini
kullanmaya alrsak Python ne yapmaya altmz anlayamaz.
Yine tpk sep parametresi gibi, end parametresinin deeri de sadece bir karakter dizisi veya
None olabilir:
>>> print(1, 2, 3, 4, 5, end=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: end must be None or a string, not int
Eer amacnz yeni satra geilmesini engellemekse, yani end parametresinin ntanml
deeri olan \n ka dizisini ortadan kaldrmaksa, end parametresine bo bir karakter dizisi
vermelisiniz:
>>> print('a', 'b', end='')
a b>>>
9.4.3 le
Not: Burada henz renmediimiz baz eyler greceksiniz. Hi endie etmeyin. Bunlar
ilerde btn ayrntlaryla reneceiz. imdilik konu hakknda biraz olsun kir sahibi
olmanz salayabilirsek kendimizi baarl sayacaz.
print() fonksiyonunun sep ve end dnda nc bir zel parametresi daha bulunur. Bu
parametrenin ad le dr. Grevi ise, print() fonksiyonuna verilen karakter dizisi ve/veya
saylarn, yani parametrelerin nereye yazlacan belirtmektir.
Bu parametrenin ntanml deeri [Link] tur. Peki bu ne anlama geliyor? [Link],
standart kt konumu anlamna gelir. Peki standart kt konumu ne demek?
113
Standart kt konumu; bir programn, rettii ktlar verdii yerdir. Aslnda bu kavramn ne
demek olduu adndan da anlalyor:
standart kt konumu = ktlarn standart olarak verildii konum.
Mesela Python ntanml olarak, rettii ktlar ekrana verir. Eer o anda etkileimli kabukta
alyorsanz, Python rettii ktlar etkileimli kabuk zerinde gsterir. Eer yazdnz
bir program komut satrnda altryorsanz, retilen ktlar komut satrnda grnr.
Dolaysyla Pythonn standart kt konumu etkileimli kabuk veya komut satrdr. Yani
print() fonksiyonu yardmyla bastnz ktlar etkileimli kabukta ya da komut satrnda
grnecektir.
imdi bu konuyu daha iyi anlayabilmek iin birka rnek yapalm.
Normal artlar altnda print() fonksiyonunun ktsn etkileimli kabukta grrz:
>>> print("Ben Python, Monty Python!")
Ben Python, Monty Python!
Ama eer istersek print() fonksiyonunun, ktlarn ekrana deil, bir dosyaya yazdrmasn
da salayabiliriz. Mesela biz imdi print() fonksiyonunun [Link] adl bir dosyaya kt
vermesini salayalm.
Bunun iin srasyla u kodlar yazalm:
>>> dosya = open("[Link]", "w")
>>> print("Ben Python, Monty Python!", file=dosya)
>>> [Link]()
Herhangi bir kt almadnz, deil mi? Evet. nk yazdmz bu kodlar sayesinde print()
fonksiyonu, ktlarn [Link] adl bir dosyaya yazdrd.
Gelin isterseniz yukardaki kodlar satr satr inceleyelim:
1. ncelikle [Link] adl bir dosya oluturduk ve bu dosyay dosya adl bir deikene
atadk. Burada kullandmz open() fonksiyonuna ok taklmayn. Bunu birka blm sonra
inceleyeceiz. Biz imdilik bu ekilde dosya oluturulduunu bilelim yeter. Bu arada open
fonksiyonunun da biim olarak type(), len(), pow() ve print() fonksiyonlarna ne kadar
benzediine dikkat edin. Grdnz gibi open() fonksiyonu da tpk type(), len(), pow()
ve print() fonksiyonlar gibi birtakm parametreler alyor. Bu fonksiyonun ilk parametresi
[Link] adl bir karakter dizisi. te bu karakter dizisi bizim oluturmak istediimiz
dosyann adn gsteriyor. kinci parametre ise w adl baka bir karakter dizisi. Bu da
[Link] dosyasnn yazma kipinde (modunda) alacan gsteriyor. Ama dediim gibi,
siz imdilik bu ayrntlara fazla taklmayn. lerleyen derslerde, bu konular adnz bilir gibi
bileceinizden emin olabilirsiniz.
2. Oluturduumuz bu [Link] adl dosya, o anda bulunduunuz dizin iinde oluacaktr.
Bu dizinin hangisi olduunu renmek iin u komutlar verebilirsiniz:
>>> import os
>>> [Link]()
114
3. Ardndan da normal bir ekilde print() fonksiyonumuzu altrdk. Ama grdnz gibi
print() fonksiyonu bize herhangi bir kt vermedi. nk, daha nce de sylediimiz gibi,
print() fonksiyonunu biz ekrana deil, dosyaya kt verecek ekilde ayarladk. Bu ilemi, le
adl bir parametreye, biraz nce tanmladmz dosya deikenini yazarak yaptk.
4. Son komut yardmyla da, yaptmz deiikliklerin dosyada grnebilmesi iin ilk bata
atmz dosyay kapatyoruz.
imdi [Link] adl dosyay an. Biraz nce print() fonksiyonuyla yazdrdmz Ben
Python, Monty Python! karakter dizisinin dosyaya ilenmi olduunu greceksiniz.
Bylece print() fonksiyonunun standart kt konumunu deitirmi olduk. Yani print()
fonksiyonunun le adl parametresine farkl bir deer vererek, print() fonksiyonunun
etkileimli kabua deil dosyaya yazmasn saladk.
Tpk sep ve end parametreleri gibi, le parametresi de, siz grmeseniz bile her zaman
print() fonksiyonunun iinde vardr. Yani diyelim ki yle bir komut verdik:
>>> print("Tahir olmak da ayp deil", "Zhre olmak da")
Yani kendisine parametre olarak verilen deerleri ekrana yazdrrken srasyla u ilemleri
gerekletirir:
1. Parametrelerin arasna birer boluk koyar (sep=" "),
2. Ekrana yazdrma ilemi bittikten sonra parametrelerin sonuna satr ba karakteri ekler
(end="\n")
3. Bu kty standart kt konumuna gnderir (file=[Link]).
te biz burada le parametresinin deeri olan standart kt konumuna baka bir deer
vererek bu konumu deitiriyoruz.
Gelin isterseniz bununla ilgili bir rnek daha yapalm. Mesela kiisel bilgilerimizi bir dosyaya
kaydedelim. ncelikle bilgileri kaydedeceimiz dosyay oluturalm:
>>> f = open("kiisel_bilgiler.txt", "w")
imiz bittiinde dosyay kapatmay unutmuyoruz. Bylece btn bilgiler dosyaya yazlm
oluyor:
>>> [Link]()
115
En bata da sylediim gibi, bu blmde henz renmediimiz baz eylerle karlatk. Eer
yukarda verilen rnekleri anlamakta zorlandysanz hi endie etmenize gerek yok. Birka
blm sonra burada anlattmz eyler size ocuk oyunca gibi gelecek...
9.4.4 ush
imdiye kadar print() fonksiyonunun sep, end ve le adl zel birtakm parametreleri
olduunu rendik. print() fonksiyonunun bunlarn dnda baka bir zel parametresi daha
bulunur. Bu parametrenin ad ush. te imdi biz print() fonksiyonunun bu ush adl
parametresinden sz edeceiz.
Bildiiniz gibi, print() gibi bir komut verdiimizde Python, yazdrmak istediimiz bilgiyi
standart kt konumuna gnderir. Ancak Pythonda baz ilemler standart kt konumuna
gnderilmeden nce bir sre tamponda bekletilir ve daha sonra bekleyen bu ilemler topluca
standart kt konumuna gnderilir. Peki ilk bata ok karmakm gibi grnen bu ifade ne
anlama geliyor?
Aslnda siz bu olguya hi yabanc deilsiniz. le parametresini anlatrken verdiimiz u rnei
tekrar ele alalm:
>>> f = open("kiisel_bilgiler.txt", "w")
Bu komutla kiisel_bilgiler.txt adl bir dosyay yazma kipinde atk. imdi bu dosyaya baz
bilgiler ekleyelim:
>>> print("Frat zgl", file=f)
Bu komutla kiisel_bilgiler.txt adl dosyaya Frat zgl diye bir satr eklemi olduk.
imdi bilgisayarnzda oluan bu kiisel_bilgiler.txt dosyasn an. Grdnz gibi dosyada
hibir bilgi yok. Dosya u anda bo grnyor. Halbuki biz biraz nce bu dosyaya Frat zgl
diye bir satr eklemitik, deil mi?
Python bizim bu dosyaya eklemek istediimiz satr tampona kaydetti. Dosyaya yazma
ilemleri sona erdiinde ise Python, tamponda bekleyen btn bilgileri standart kt
konumuna (yani bizim durumumuzda f adl deikenin tuttuu kiisel_bilgiler.txt adl
dosyaya) boaltacak.
Dosyaya baka bilgiler de yazalm:
>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)
Dosyaya yazacamz eyler bu kadar. Artk yazma ileminin sona erdiini Pythona bildirmek
iin u komutu veriyoruz:
>>> [Link]()
Bylece dosyamz kapatm olduk. imdi kiisel_bilgiler.txt adl dosyaya ift tklayarak
dosyay tekrar an. Orada Frat zgl, Adana ve Ubuntu satrlarn greceksiniz.
Grdnz gibi, gerekten de Python dosyaya yazdrmak istediimiz btn verileri nce
tamponda bekletti, daha sonra dosya kapatlnca tamponda bekleyen btn verileri dosyaya
boaltt. te ush parametresi ile, bahsettiimiz bu boaltma ilemini kontrol edebilirsiniz.
imdi dikkatlice inceleyin:
116
Grdnz gibi, burada ush adl yeni bir parametre kullandk. Bu parametreye verdiimiz
deer True. imdi dosyaya ift tklayarak dosyay an. Grdnz gibi, henz dosyay
kapatmadmz halde bilgiler dosyaya yazld. Bu durum, tahmin edebileceiniz gibi, ush
parametresine True deeri vermemiz sayesindedir. Bu parametre iki deer alabilir: True ve
False. Bu parametrenin ntanml deeri False tur. Yani eer biz bu parametreye herhangi
bir deer belirtmezsek Python bu parametrenin deerini False olarak kabul edecek ve
bilgilerin dosyaya yazlmas iin dosyann kapatlmasn bekleyecektir. Ancak bu parametreye
True deerini verdiimizde ise veriler tamponda bekletilmeksizin standart kt konumuna
gnderilecektir.
Yazdnz bir programda, yapmak istediiniz iin niteliine gre, bir dosyaya yazmak
istediiniz bilgilerin bir sre tamponda bekletilmesini veya hi bekletilmeden dorudan
dosyaya yazlmasn isteyebilirsiniz. htiyacnza bal olarak da ush parametresinin deerini
True veya False olarak belirleyebilirsiniz.
Yukardaki, gerekten de doru bir zmdr. Ancak bu soruyu zmenin ok daha basit bir
yolu var. imdi dikkatle bakn:
>>> print(*"Linux", sep=".")
L.i.n.u.x
117
dizisinin her bir esini paralarna ayrarak, bunlar tek tek print() fonksiyonuna yolluyor.
Yani sanki print() fonksiyonunu yle yazmz gibi oluyor:
>>> print("G", "a", "l", "a", "t", "a", "s", "a", "r", "a", "y")
G a l a t a s a r a y
Dediimiz gibi, bir fonksiyona parametre olarak verdiimiz bir karakter dizisinin bana
eklediimiz yldz iareti, bu karakter dizisini tek tek elerine ayrp, bu eleri yine tek tek ve
sanki her bir e ayr bir parametreymi gibi o fonksiyona gnderdii iin doal olarak yldz
iaretini ancak, birden fazla parametre alabilen fonksiyonlara uygulayabiliriz.
rnein len() fonksiyonu sadece tek bir parametre alabilir:
>>> len("Galatasaray")
11
Hata mesajnda da sylendii gibi, len() fonksiyonu yalnzca tek bir parametre alabilirken,
biz 3 parametre vermeye almz...
Dolaysyla yldzl parametreleri len() fonksiyonuna uygulayamayz:
>>> len(*"Galatasaray")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: len() takes exactly one argument (11 given)
Bir parametrenin bana yldz eklediimizde, o parametreyi oluturan btn eler tek tek
fonksiyona gnderildii iin, sanki len() fonksiyonuna 1 deil de, 11 ayr parametre vermiiz
gibi bir sonu ortaya kyor.
Yldzl parametreleri bir fonksiyona uygulayabilmemiz iin o fonksiyonun birden fazla
parametre alabilmesinin yansra, yapsnn da yldzl parametre almaya uygun olmas
gerekir. Mesela open(), type() ve biraz nce bahsettiimiz len() fonksiyonlarnn yaps
yldzl parametre almaya uygun deildir. Dolaysyla yldzl parametreleri her fonksiyonla
birlikte kullanamayz, ama print() fonksiyonu yldzl parametreler iin son derece uygun bir
fonksiyondur:
>>> print(*"Galatasaray")
G a l a t a s a r a y
>>> print(*"TBMM", sep=".")
T.B.M.M
>>> print(*"abcdefgh", sep="/")
118
a/b/c//d/e/f/g//h
Dolaysyla, yldz iareti sayesinde Galatasaray adl karakter dizisinin her bir esinin
arasna bir adet boluk karakteri yerletiriliyor. Bir sonraki TBMM karakter dizisinde ise, sep
parametresinin deerini nokta iareti olarak deitirdiimiz iin TBMM karakter dizisinin
her bir esinin arasna bir adet nokta iareti yerletiriliyor. Ayn ekilde abcdefgh
karakter dizisinin her bir esini tek tek print() fonksiyonuna yollayarak, sep parametresine
verdiimiz / iareti yardmyla her enin arasna bu / iaretini yerletirebiliyoruz.
Yldzl parametrelerle ilgili tek kstlama, bunlarn saylarla birlikte kullanlamayacak
olmasdr:
>>> print(*2345)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print() argument after * must be a sequence, not int
nk yldzl parametreler ancak ve ancak dizi zellii tayan veri tipleriyle birlikte
kullanlabilir. Mesela karakter dizileri bu trden bir veri tipidir. lerde dizi zellii tayan ve
bu sayede yldzl parametrelerle birlikte kullanlabilecek baka veri tiplerini de reneceiz.
Yukarda verdiimiz rnekler bize yldzl parametrelerin son derece kullanl aralar
olduunu gsteriyor. leride de bu parametrelerden bol bol yararlanacaz. Biz imdi bu
konuyu burada kapatp baka bir eyden sz edelim.
f = open("[Link]", "w")
print("Frat zgl", file=f)
print("Adana", file=f)
print("Ubuntu", file=f)
[Link]()
119
Grdnz gibi, her defasnda le parametresine f deerini vererek iimizi hallettik. Ama
bunu yapmann daha pratik bir yntemi var. Dilerseniz yazdnz programn tm ileyii
boyunca ktlar baka bir konuma ynlendirebilirsiniz. Bunun iin hem imdiye kadar
rendiimiz, hem de henz renmediimiz baz bilgileri kullanacaz.
lk nce yle bir kod yazalm:
>>> import sys
Bu kod yardmyla sys adl zel bir modl programmza dahil etmi, yani ie aktarm olduk.
Peki modl nedir, ie aktarmak ne demek?
Aslnda biz bu modl ve ie aktarma kavramlarna hi de yabanc deiliz. nceki derslerde,
pek zerinde durmam da olsak, biz Pythondaki birka modlle zaten tanmtk. Mesela
os adl bir modl iindeki getcwd() adl bir fonksiyonu kullanarak, o anda hangi dizinde
bulunduumuzu renebilmitik:
>>> import os
>>> [Link]()
Ayn ekilde keyword adl baka bir modl iindeki kwlist adl deikeni kullanarak, hangi
kelimelerin Pythonda deiken ad olarak kullanlamayacan da listeleyebilmitik:
>>> import keyword
>>> [Link]
te imdi de, os ve keyword modllerine ek olarak sys adl bir modlden sz ediyoruz.
Gelin isterseniz teki modlleri imdilik bir kenara brakp, bu sys denen modle dikkatimizi
verelim.
Dediimiz gibi, sys modl iinde pek ok nemli deiken ve fonksiyon bulunur. Ancak bir
modl iindeki deiken ve fonksiyonlar kullanabilmek iin o modl ncelikle programmza
dahil etmemiz, yani ie aktarmamz gerekiyor. Bunu import komutuyla yapyoruz:
>>> import sys
Bu ktdaki name=<stdout> ksmna dikkat edin. Bu ifadeye birazdan geri dneceiz. Biz
imdi baka bir eyden sz edelim.
Hatrlarsanz etkileimli kabuu nasl kapatabileceimizi anlatrken, etkileimli kabuktan
kmann bir yolunun da u komutlar vermek olduunu sylemitik:
>>> import sys; [Link]()
120
Dedik ya, sys modl iinde pek ok deiken ve fonksiyon bulunur. Nasl stdout sys modl
iindeki deikenlerden biri ise, exit() de sys modl iinde bulunan fonksiyonlardan biridir.
Biz modller konusunu ilerleyen derslerde ayrntl bir ekilde inceleyeceiz.
modllere ilikin olarak yalnzca unlar bilelim yeter:
imdilik
1. Pythonda modller import komutu ile ie aktarlr. rnein sys adl modl ie aktarmak
iin import sys komutunu veriyoruz.
2. Modller iinde pek ok faydal deiken ve fonksiyon bulunur. te bir modl ie
aktardmzda, o modl iindeki bu deiken ve fonksiyonlar kullanma imkan elde ederiz.
3.
sys modl iindeki deikenlere bir rnek stdout ; fonksiyonlara rnek
ise exit() fonksiyonudur.
Bir modl iindeki bu deiken ve fonksiyonlara
modl_ad.deiken_ya_da_fonksiyon formln kullanarak eriebiliriz. rnein:
>>> [Link]
>>> [Link]()
4. Hatrlarsanz bundan nce de, open() fonksiyonu ile dosya oluturmay anlatrken,
oluturulan dosyann hangi dizinde olduunu bulabilmek amacyla, o anda iinde
bulunduumuz dizini tespit edebilmek iin u kodlar kullanmtk:
>>> import os
>>> [Link]()
Burada da os adl baka bir modl gryoruz. te os da tpk sys gibi bir modldr ve tpk
sys modlnde olduu gibi, os modlnn de iinde pek ok yararl deiken ve fonksiyon
bulunur. getcwd() adl fonksiyon da os modl iinde yer alan ve o anda hangi dizin altnda
bulunduumuzu gsteren bir fonksiyondur. Elbette, yine tpk sys modlnde olduu gibi,
os modl iindeki bu yararl deiken ve fonksiyonlar kullanabilmek iin de ncelikle bu os
modln ie aktarmamz, yani programmza dahil etmemiz gerekiyor. os modln import
komutu araclyla uygun bir ekilde ie aktardktan sonra, modl iinde yer alan getcwd()
adl fonksiyona yine modl_ad.fonksiyon formln kullanarak eriebiliyoruz.
Modllere ilikin imdilik bu kadar bilgi yeter. Modlleri bir kenara brakp yolumuza devam
edelim...
Eer [Link]() komutunu verip etkileimli kabuktan ktysanz, etkileimli kabua tekrar
girin ve sys modln yeniden ie aktarn:
>>> import sys
Not: Bir modl ayn etkileimli kabuk oturumu iinde bir kez ie aktarmak yeterlidir. Bir
modl bir kez ie aktardktan sonra, o oturum sresince bu modl iindeki deiken ve
fonksiyonlar kullanmaya devam edebilirsiniz. Ama tabii ki etkileimli kabuu kapatp tekrar
atktan sonra, bir modl kullanabilmek iin o modl tekrar ie aktarmanz gerekir.
imdi u kodu yazn:
>>> f = open("[Link]", "w")
121
Bu kodun anlamn biliyorsunuz. Burada [Link] adl bir dosyay yazma kipinde am
olduk. Tahmin edebileceiniz gibi, ktlarmz ekran yerine bu dosyaya ynlendireceiz.
imdi de yle bir kod yazalm:
>>> [Link] = f
Bildiiniz gibi, [Link] deeri Pythonn ktlar hangi konuma vereceini belirliyor. te
biz burada [Link] un deerini biraz nce oluturduumuz f adl dosya ile deitiriyoruz.
Bylece Python btn ktlar f deikeni iinde belirttiimiz [Link] adl dosyaya
gnderiyor.
Bu andan sonra yazacanz her ey [Link] adl dosyaya gidecektir:
>>> print("deneme metni", flush=True)
Elbette bu komuttan herhangi bir kt almadnz. ktnn ne olduunu grmek iin [Link]
adl dosyay an. Orada u satr greceksiniz:
<_io.TextIOWrapper name='[Link]' mode='w' encoding='cp1254'>
122
Peki standart kt konumunu, etkileimli kabuktan kmadan veya program kapatmadan eski
haline dndrmenin bir yolu var m? Elbette var. Dikkatlice bakn:
>>>
>>>
>>>
>>>
>>>
>>>
import sys
f = open("[Link]", "w")
[Link], f = f, [Link]
print("deneme", flush=True)
f, [Link] = [Link], f
print("deneme")
deneme
import sys
f = open("[Link]", "w")
zgn_stdout = [Link]
[Link] = f
print("deneme", flush=True)
[Link] = zgn_stdout
print("deneme")
deneme
Bylece stdout deeri eski haline dnm oluyor ve bundan sonra yazdrdmz her ey
yeniden ekrana baslmaya balyor.
...ve bylece uzun bir blm daha geride braktk. Bu blmde hem print() fonksiyonunu
btn ayrntlaryla incelemi olduk, hem de Python programlama diline dair baka ok
123
124
BLM 10
Ka Dizileri
Pythonda karakter dizilerini tanmlayabilmek iin tek, ift veya trnak iaretlerinden
faydalandmz geen blmde renmitik. Python bir verinin karakter dizisi olup
olmadna bu trnak iaretlerine bakarak karar verdii iin, tek, ift ve trnak iaretleri
Python asndan zel bir nem tayor. Zira Pythonn gznde bir balang trna ile biti
trna arasnda yer alan her ey bir karakter dizisidir.
rnein ilk olarak bir iareti koyup ardndan elma eklinde devam ettiinizde, Python ilk
trna grdkten sonra karakter dizisini tanmlayabilmek iin ikinci bir trnak iareti aramaya
balar. Siz elma eklinde kodunuzu tamamladnzda ise Python bellekte elma adl bir
karakter dizisi oluturur.
Bu noktada size yle bir soru sormama izin verin: Acaba trnak iaretleri herhangi bir metin
iinde ka farkl amala kullanlabilir?
sterseniz bu sorunun cevabn rnekler zerinde vermeye alalm:
Ahmet, Bugn sinemaya gidiyorum, dedi.
Burada trnak iaretlerini, bir bakasnn szlerini aktarmak iin kullandk.
book kelimesi Trkede kitap anlamna gelir.
Burada ise trnak iaretlerini baz kelimeleri vurgulamak iin kullandk.
Bir de una bakalm:
Yarn Adanaya gidiyorum.
Burada da trnak iaretini, ekim eki olan -(y)a ile zel isim olan Adana kelimesini birbirinden
ayrmak iin kesme iareti grevinde kullandk.
imdi yukarda verdiimiz ilk cmleyi bir karakter dizisi olarak tanmlamaya alalm:
>>> 'Ahmet, "Bugn sinemaya gidiyorum," dedi.'
Burada karakter dizisini tanmlamaya tek trnak iareti ile baladk. Bylece Python bu
karakter dizisini tanmlama ilemini bitirebilmek iin ikinci bir tek trnak iareti daha aramaya
koyuldu ve arad tek trnak iaretini cmlenin sonunda bularak, karakter dizisini dzgn bir
ekilde oluturabildi.
Dediimiz gibi, Pythonn gznde trnak iaretleri bir karakter dizisini baka veri tiplerinden
ayrt etmeye yarayan bir lttr. Ama biz insanlar, yukarda verdiimiz rnek cmlelerden
de greceiniz gibi, programlama dillerinden farkl olarak, trnak iaretlerini bir metin iinde
daha farkl amalar iin de kullanabiliyoruz.
125
te burada Pythonn karlar ile bizim karlarmz birbiriyle att. Python karakter
dizisini balatan ilk ift trnak iaretini grdkten sonra, karakter dizisini tanmlama ilemini
bitirebilmek iin ikinci bir trnak iareti daha aramaya koyuldu. Bu aray srasnda da Bugn
kelimesinin bandaki ift trnak iaretini grd ve karakter dizisinin u olduunu zannetti:
>>> "Ahmet, "
Buraya kadar bir sorun yok. Bu karakter dizisi Pythonn szdizimi kurallarna uygun.
Karakter dizisi bu ekilde tanmlandktan sonra Python cmlenin geri kalann okumaya
devam ediyor ve herhangi bir trnak iareti ile balamayan ve kendisinden nce gelen eden
herhangi bir virgl iareti ile ayrlmam Bugn kelimesini gryor. Eer bir kelime trnak
iareti ile balamyorsa bu kelime ya bir deikendir ya da saydr. Ama Bugn kelimesi
ne bir deiken, ne de bir say olduu, stelik nceki eden de virglle ayrlmad iin
Pythonn hata vermekten baka aresi kalmyor. nk biz burada Bugn kelimesinin
ba tarafndaki ift trnak iaretini karakter dizisi tanmlamak iin deil, bakasnn szlerini
aktarmak amacyla kullandk. Ancak elbette bir programlama dili bizim amacmzn ne
olduunu kestiremez ve hata mesajn suratmza yaptrr:
File "<stdin>", line 1
"Ahmet, "Bugn sinemaya gidiyorum," dedi."
^
SyntaxError: invalid syntax
... veya:
>>> """Ahmet, "Bugn sinemaya gidiyorum," dedi."""
Bylece karakter dizisini balatan iaret Bugn sinemaya gidiyorum, cmlesinin bandaki ve
sonundaki iaretlerden farkl olduu iin, Python okuma esnasnda bu cmleye taklmaz ve
doru bir ekilde, karakter dizisini kapatan trnak iaretini bulabilir.
Bu yntem tamamen geerli ve mantkldr. Ama eer istersek, ayn karakter dizisini ift
trnakla tanmlayp, yine de hata almay engelleyebiliriz. Peki ama nasl?
te burada ka dizileri ad verilen birtakm aralardan faydalanacaz.
Peki nedir bu ka dizisi denen ey?
Ka dizileri, Pythonda zel anlam tayan iaret veya karakterleri, sahip olduklar bu zel
anlam dnda bir amala kullanmamz salayan birtakm aralardr. Mesela yukarda da
rneklerini verdiimiz gibi, trnak iaretleri Python asndan zel anlam tayan iaretlerdir.
Normalde Python bu iaretleri karakter dizilerini tanmlamak iin kullanr. Ama eer siz
mesela bir metin iinde bu trnak iaretlerini farkl bir amala kullanacaksanz Python bu
durumdan haberdar etmeniz gerekiyor. te ka dizileri, Python byle bir durumdan
haberdar etmemize yarayan aralardr.
126
Pythonda pek ok ka dizisi bulunur. Biz burada bu ka dizilerini tek tek inceleyeceiz. O
halde hemen ie koyulalm.
Burada da cmle iinde ift trnak iaretlerini kullandmz halde, \ iaretleri sayesinde
karakter dizilerini yine ift trnakla tanmlayabildik.
Bir de u rnee bakalm:
>>> print("Python programlama dilinin ad \"piton\" ylanndan gelmez")
Btn bu rneklerde, karakter dizisini hem ift trnakla tanmlayp hem de karakter
dizisi iinde ift trnak iaretlerini kullandmz halde, herhangi bir hata almadmz
gryorsunuz. Yukardaki kodlarda hata almamz nleyen eyin \ iareti olduu belli. Ama
dilerseniz bu iaretin, hata almamz nasl nlediini anlatmadan nce son bir rnek daha
verelim.
Hatrlarsanz nceki sayfalarda yle bir karakter dizisi ile karlamtk:
>>> print('stanbul'un 5 gnlk hava durumu tahmini')
File "<stdin>", line 1
print('stanbul'un 5 gnlk hava durumu tahmini')
^
SyntaxError: invalid syntax
Burada da stanbulun kelimesi iinde geen trnak iareti nedeniyle karakter dizisini tek
trnak kullanarak tanmlayamyorduk. Bu karakter dizisini hatasz bir ekilde tanmlayabilmek
iin ya ift trnak ya da trnak kullanmamz gerekiyordu:
>>> print("stanbul'un 5 gnlk hava durumu tahmini")
stanbul'un 5 gnlk hava durumu tahmini
127
... veya:
>>> print("""stanbul'un 5 gnlk hava durumu tahmini""")
stanbul'un 5 gnlk hava durumu tahmini
Tpk nceki rneklerde olduu gibi, yukardaki karakter dizisini de aslnda tek trnakla
tanmlayp hata olumasn nleyebiliriz. Hemen grelim:
>>> print('stanbul\'un 5 gnlk hava durumu tahmini')
stanbul'un 5 gnlk hava durumu tahmini
Tpk bir nceki rnekte olduu gibi, burada da Python karakter dizisini soldan saa doru
okumaya balyor, karakter dizisini balatan ift trnak iaretini gryor ve bunun zerine
Python karakter dizisini bitirecek olan ift trnak iaretini aramaya koyuluyor.
Karakter dizisini soldan saa doru okuduu srada, karakter dizisi iinde geen piton
kelimesini gryor. Eer burada bir nlem almazsak Python bu kelimenin bandaki ift trnak
iaretini, karakter dizisini sona erdiren trnak olarak alglar ve durum aslnda byle olmad
iin de hata verir.
Bu hatay nlemek iin piton kelimesinin bandaki ift trnan soluna bir adet \ iareti
yerletirerek Pythona, Aradn trnak bu deil! mesaj veriyoruz. Yani bir bakma, \ adl
ka dizisi kendisini trnak iaretine siper edip Pythonn bu trna grmesine mani oluyor...
Bunun zerine Python bu ift trnak iaretini grmezden gelerek, soldan saa doru okumaya
devam eder ve yol zerinde piton kelimesinin sonundaki ift trnak iaretini grr. Eer
burada da bir nlem almazsak Python yine bir hata verecektir.
Tpk biraz nce yaptmz gibi, bu trnak iaretinin de soluna bir adet \ iareti yerletirerek
Pythona, Aradn trnak bu da deil. Sen yine okumaya devam et! mesaj veriyoruz.
128
Bu mesaj alan Python karakter dizisini soldan saa doru okumaya devam ediyor ve sonunda
karakter dizisini bitiren ift trnak iaretini bularak bize hatasz bir kt veriyor.
Bylece \ iareti zerinden hem ka dizilerinin ne olduunu renmi, hem de bu ka
dizisinin nasl kullanlacana dair rnekler vermi olduk. Ancak \ ka dizisinin yetenekleri
yukardakilerle snrl deildir. Bu ka dizisini, uzun karakter dizilerini blmek iin de
kullanabiliriz. imdi u rnei dikkatlice inceleyin:
>>> print("Python 1990 ylnda Guido Van Rossum \
... tarafndan gelitirilmeye balanm, olduka \
... gl ve yetenekli bir programlama dilidir.")
Python 1990 ylnda Guido Van Rossum tarafndan gelitirilmeye
balanm, olduka gl ve yetenekli bir programlama dilidir.
Normal artlar altnda, bir karakter dizisini tanmlamaya tek veya ift trnakla balamsak,
karakter dizisinin kapan trnan koymadan Enter tuuna bastmzda Python bize bir hata
mesaj gsterir:
>>> print("Python 1990 ylnda Guido Van Rossum
File "<stdin>", line 1
print("Python 1990 ylnda Guido Van Rossum
SyntaxError: EOL while scanning string literal
te \ ka dizisi bizim burada olas bir hatadan kamamz salar. Eer Enter tuuna
basmadan nce bu iareti kullanrsak Python tpk trnak iaretlerinde ahit olduumuz
gibi, hata vermeden bir alt satra geecektir. Bu srada, yani \ ka dizisini koyup Enter tuuna
bastmzda >>> iaretinin ... iaretine dntn gryorsunuz. Bu iaretin, Pythonn
bize verdii bir Yazmaya devam et! mesaj olduunu biliyorsunuz.
Grdnz gibi, \n adl ka dizisi, bir alt satra geilmesini salyor. te aslnda \n ka
dizisi de, \ ile n harnin birlemesinden olumu bir ka dizisidir. Burada \ iaretinin
grevi, n harnin zel bir anlam kazanmasn salamaktr. \ iareti ile n har birletiinde
satr ba karakteri denen zel bir karakter dizisi ortaya karyor.
10.2. Satr Ba (\n)
129
Gelin bu ka dizisi ile ilgili bir rnek verelim. imdi u kodlar dikkatlice inceleyin:
>>> balk = "Trkiye'de zgr Yazlmn Gemii"
>>> print(balk, "\n", "-"*len(balk), sep="")
Trkiye'de zgr Yazlmn Gemii
----------------------------------
Burada, balk adl deikenin tuttuu Trkiyede zgr Yazlmn Gemii adl karakter
dizisinin altn izdik.
Dikkat ederseniz, baln altna koyduumuz izgiler baln
uzunluunu amyor. Yazdmz program, baln uzunluu kadar izgiyi baln altna
ekliyor. Bu programda balk ne olursa olsun, programmz izgi uzunluunu kendisi
ayarlayacaktr. rnein:
>>> balk = "Python Programlama Dili"
>>> print(balk, "\n", "-"*len(balk), sep="")
Python Programlama Dili
---------------------->>> balk = "Alveri Listesi"
>>> print(balk, "\n", "-"*len(balk), sep="")
Alveri Listesi
-----------------
Burada ncelikle balk adl deikeni print() fonksiyonunun parantezleri iine yazdk.
Bylece balk deikeninin deeri ekrana yazdrlacak.
print() fonksiyonunun ikinci parametresinin \n adl ka dizisi olduunu gryoruz. Bu
ka dizisini eklememiz sayesinde Python ilk parametreyi kt olarak verdikten sonra bir alt
satra geiyor. Bu parametrenin tam olarak ne ie yaradn anlamak iin, yukardaki satr
bir de o parametre olmadan altrmay deneyebilirsiniz:
>>> print(balk, "-"*len(balk), sep="")
Alveri Listesi-----------------
print() fonksiyonunun
"-"*len(balk).
nc
parametresinin
ise
olduunu
gryoruz:
te balk deikeninin altna gerekli sayda izgiyi izen kodlar bunlardr. Burada len()
fonksiyonunu nasl kullandmza ok dikkat edin. Bu kod sayesinde balk deikeninin
uzunluu (len(balk)) saysnca - iaretini ekrana kt olarak verebiliyoruz.
Yukardaki kodlarda print() fonksiyonunun son parametresi ise sep=. Peki bu ne ie
yaryor? Her zaman olduu gibi, bu kod parasnn ne ie yaradn anlamak iin program
bir de o kodlar olmadan altrmay deneyebilirsiniz:
>>> print(balk, "\n", "-"*len(balk))
Alveri Listesi
-----------------
130
Grdnz gibi, balk deikeninin tam altna gelmesi gereken izgi iaretleri saa kaym.
Bunun nedeni sep parametresinin ntanml deerinin bir adet boluk karakteri olmasdr.
sep parametresinin ntanml deeri nedeniyle izgilerin ba tarafna bir adet boluk
karakteri ekleniyor ktda. O yzden bu izgiler saa kaym grnyor. te biz yukardaki
kodlarda sep parametresinin ntanml deerini deitirip, boluk karakteri yerine bo bir
karakter dizisi yerletiriyoruz. Bylece izgiler ktda saa kaymyor.
Satr ba karakteri, programlama maceramz srasnda en ok kullanacamz ka
dizilerinden biri ve hatta belki de birincisidir. O yzden bu ka dizisini ok iyi renmenizi
tavsiye ederim.
Ayrca bu ka dizisini (ve tabii teki ka dizilerini) tanyp renmeniz, yazacanz
programlarn selameti asndan da byk nem tar. Eer bir karakter dizisi iinde
geen ka dizilerini ayrt edemezseniz Python size hi beklemediiniz ktlar verebilir.
Hatta yazdnz programlar ka dizilerini tanmyor olmanzdan tr bir anda hata verip
kebilir. Peki ama nasl?
imdi u rnee dikkatlice bakn:
Diyelim ki bilgisayarnzn C:\ dizinindeki nisan adl bir klasrn iinde yer alan [Link]
adl bir dosyay yazdnz bir program iinde kullanmanz gerekiyor. Mesela bu dosyay, tam
adresiyle birlikte kullanclarnza gstermek istiyorsunuz.
lk denememizi yapalm:
>>> print("C:\nisan\[Link]")
131
Tabii tutarllk asndan karakter dizisi iindeki btn ters taksim iaretlerini iftlemek
mantkl olacaktr:
>>> open("C:\\nisan\\masraflar")
Bunun dnda, bu rnek iin, dizin adlarn ters taksim yerine dz taksim iaretiyle ayrmay
tercih edebilirsiniz:
>>> open("C:/nisan/masraflar")
Dediimiz gibi, nc (ve aslnda daha kullanl olan) yntemi biraz sonra inceleyeceiz. Biz
imdilik ka dizilerini anlatmaya devam edelim.
Burada \t adl ka dizisi, abc ifadesinden sonra sanki Tab (sekme) tuuna baslm gibi bir
etki oluturarak def ifadesini saa doru itiyor. Bir de u rnee bakalm:
>>> print("bir", "iki", "", sep="\t")
bir
iki
132
Grdnz gibi, parametreler arasnda belli aralkta bir boluk brakmak istediimizde \t
adl ka dizisinden yararlanabiliyoruz.
Tpk \n ka dizisinde olduu gibi, karakter dizilerinde \t ka dizisinin varlna kar da
uyank olmalyz:
>>> open("C:\nisan\masraflar\toplam_masraf.txt")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'C:\nisan\\masraflar\toplam_masraf.txt'
Burada da \n ile yaadmz soruna benzer bir durum var. Biz toplam_masraf.txt adl
bir dosyaya atfta bulunmaya alyoruz, ama Python bu ifadenin bandaki t harnin,
kendisinden nce gelen \ iareti ile birlemesinden tr, bunu \t ka dizisi olarak alglyor
ve ona gre davranyor.
Belki yukardaki kodlar yle yazarsak durumu anlamak daha kolay olabilir:
>>> print("C:\nisan\masraflar\toplam_masraf.txt")
C:
isan\masraflar
oplam_masraf.txt
Grdnz gibi, Python \n ka dizisini grd noktada alt satrn bana geiyor ve \t ka
dizisini grd noktada da nceki ve sonraki eler arasnda bir sekme boluu brakyor.
Bu durumu engellemek iin ne yapmanz gerektiini biliyorsunuz: Ya ters taksim iaretlerini
iftleyeceksiniz:
>>> print("C:\\nisan\\masraflar\\toplam_masraf.txt")
Daha nce de sylediimiz gibi, nc ve daha pratik olan yolu biraz sonra greceiz.
imdilik sadece biraz sabr...
133
Bu ekilde !bip! sesi 10 kez tekrar edilecektir. Ancak bu ka dizisi ounlukla sadece
Windows zerinde alacaktr. Bu ka dizisinin GNU/Linux zerinde alma garantisi
yoktur. Hatta bu ka dizisi btn Windows sistemlerinde dahi almayabilir. Dolaysyla
bu ka dizisinin ilevine bel balamak pek mantkl bir i deildir.
Tpk \n ve \t ka dizilerinde olduu gibi bu ka dizisinin varlna kar da uyank olmalyz.
Burada da mesela C:\aylar gibi bir dizin ad tanmlamaya alrken aslnda \a ka dizisini
oluturuyor olabilirsiniz farknda olmadan.
Burada olan ey u: Normal artlar altnda, print() fonksiyonu iine yazdmz bir karakter
dizisindeki btn karakterler soldan saa doru tek tek ekrana yazdrlr:
>>> print("Merhaba Zalim Dnya!")
Merhaba Zalim Dnya!
Ancak eer karakter dizisinin herhangi bir yerine \r adl ka dizisini yerletirirsek, bu ka
dizisinin bulunduu konumdan itibaren ayn satrn bana dnlecek ve \r ka dizisinden
sonra gelen btn karakterler satr bandaki karakterlerin zerine yazacaktr. u rnek daha
aklayc olabilir:
>>> print("Merhaba\rDnya")
Dnyaba
Burada, Merhaba karakter dizisi ekrana yazdrldktan sonra \r ka dizisinin etkisiyle satr
bana dnlyor ve bu ka dizisinden sonra gelen Dnya karakter dizisi Merhaba
karakter dizisinin zerine yazyor. Tabii Dnya karakter dizisi iinde 5 karakter, Merhaba
karakter dizisi iinde ise 7 karakter olduu iin, Merhaba karakter dizisinin son iki karakteri
(ba ) darda kalyor. Bylece ortaya Dnyaba gibi bir ey kyor.
nceki ka dizilerinde olduu gibi, bu ka dizisini de farknda olmadan karakter dizisi
iinde kullanrsanz beklemediiniz ktlar alrsnz:
>>> print("C:\lke\trkiye\iller\rize\[Link]")
izelke
[Link]
rkiye\iller
134
Grdnz gibi, \b ka dizisinin etkisiyle imle bir karakter sola kayd iin, com
kelimesinin son har silindi ve bunun yerine \b ka dizisinden sonra gelen .uk karakterleri
yerletirildi. Dolaysyla biz de u kty aldk:
[Link]
Biz bu eleri birbirine bititirmek iin yle bir yol izleyebileceimizi biliyoruz:
>>> print('istihza', '.', 'com', sep='')
[Link]
Grdnz gibi, \b ka dizisi, . ve com parametrelerinden nce imleci birer karakter sola
kaydrd iin, parametreler arasndaki boluk karakterleri ortadan kalkt.
10.6. Dey Sekme (\v)
135
Burada \b ka dizisini st ste birka kez kullanarak imleci birka karakter sola kaydrdk ve
sn harerini hz harerinin zerine bindirdik. Bylece istihza kelimesi istisna kelimesine
dnm oldu...
Daha fazla uzatmadan, bu ka dizisinin Pythonda ok nadir kullanld bilgisini vererek
yolumuza devam edelim...
Belki sada solda UNICODE diye bir ey duymusunuzdur. Eer imdiye kadar byle bir
ey duymadysanz veya duyduysanz bile ne olduunu bilmiyorsanz hi ziyan yok. Birka
blm sonra bunun ne anlama geldiini btn ayrntlaryla anlatacaz. Biz imdilik sadece
unu bilelim: UNICODE, karakterlerin, harerin, saylarn ve bilgisayar ekrannda grdmz
teki btn iaretlerin her biri iin tek ve benzersiz bir numarann tanmland bir sistemdir.
Bu sistemde, kod konumu (code point ) ad verilen bu numaralar zel bir ekilde gsterilir.
rnein har UNICODE sisteminde u ekilde temsil edilir:
u+0131
Python programlama dilinde ise, yukardaki kod konumu dzeni yle gsterilir:
\\u0131
Grdnz gibi, Python UNICODE sistemindeki her bir kod konumunu gsterebilmek iin,
nce \u eklinde bir ka dizisi tanmlyor, ardndan UNICODE sisteminde + iaretinden sonra
gelen sayy bu ka dizisinin hemen sana ekliyor. Gelin kendi kendimize birka deneme
almas yapalm:
>>> '\u0130'
''
136
>>> '\u0070'
'p'
>>> "\ufdsf"
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 0-4: truncated \uXXXX escape
Grdnz gibi, eer \u ka dizisinden sonra doru bir kod konumu belirtmezsek Python
bize bir hata mesaj gsteriyor...
Bu hata mesajnn, biraz nce print("Dosya konumu: C:\users\zeynep\gizli\[Link]")
kodunu yazdktan sonra aldmz hata ile ayn olduuna dikkat edin. Tpk \ufdsf rneinde
olduu gibi, \users ifadesi de varolan bir UNICODE kod konumuna karlk gelmedii iin,
Pythonn hata vermekten baka aresi kalmyor.
Biz bu rnekte users kelimesini kullanmaya alyoruz, ama u harnden hemen nce gelen
\ ka dizisi nedeniyle, hi farknda olmadan Python asndan nemli bir karakter dizisi (\u )
meydana getirmi oluyoruz. O yzden, byle can skc hatalarla karlamamak iin olas
ka dizilerine kar her zaman uyank olmamz gerekiyor.
Pek biz bu ka dizisi yznden, yazdmz programlarda
C:\users\zeynep\gizli\[Link]) gibi bir kt veremeyecek miyiz?
Dosya
konumu:
Verebileceimizi, ama bunun bir yolu yordam olduunu biliyorsunuz. Biz yine de tekrar
edelim:
>>> print("Dosya konumu: C:\\users\\zeynep\\gizli\\[Link]")
Dosya konumu: C:\users\zeynep\gizli\[Link]
Grdnz gibi, karakter dizisi iinde geen btn \ iaretlerini iftleyerek sorunumuzu
zdk. Buradaki gibi bir sorunla karlamamak iin, dizin adlarn ayrrken ters taksim
iareti yerine dz taksim iaretini kullanmay da tercih edebilirsiniz:
>>> print("Dosya konumu: C:/users/zeynep/gizli/[Link]")
Biraz sonra bu sorunu halletmenin nc ve daha kolay bir ynteminden daha sz edeceiz.
Ama biz imdilik bu ka dizisini bir kenara brakp baka bir ka dizisini incelemeye geelim.
137
Eer ayn kod konumunu U adl ka dizisi ile gstermek istersek yle bir ey yazmamz
gerekir:
>>> '\U00000131'
Grdnz gibi, burada \U ka dizisinden sonra gelen ksm toplam 8 haneli bir saydan
oluuyor. u ka dizisinde ise bu ksm toplam 4 haneli bir say olarak yazyorduk. te \u
ka dizisi ile U ka dizisi arasndaki fark budur. u ka dizisi hakknda sylediimiz teki
her ey U ka dizisi iin de geerlidir.
Bir karakterin UNICODE sistemindeki uzun adn renmek iin unicodedata adl bir
modlden yararlanabilirsiniz:
>>> import unicodedata
>>> [Link]('a')
LATIN SMALL LETTER A
>>> [Link]('')
LATIN CAPITAL LETTER S WITH CEDILLA
Bu arada, daha nce de sylediimiz gibi, bu modl kavramna imdilik taklmayn. lerde
modlleri ayrntl olarak inceleyeceiz. imdilik unicodedata denen eyin, (tpk daha nce
rneklerini grdmz os, sys ve keyword gibi) bir modl olduunu ve bu modl iindeki
name adl bir fonksiyonu kullanarak, parantez iinde belirttiimiz herhangi bir karakterin
UNICODE sistemindeki uzun adn elde edebileceimizi bilelim yeter.
te \N ka dizisi bu uzun isimleri, Python programlarmzda kullanma imkan verir bize.
Bu ka dizisini, karakterlerin UNICODE sistemindeki uzun adlar ile birlikte kullanarak asl
karakterleri elde edebiliriz. Dikkatlice bakn:
>>> print("\N{LATIN SMALL LETTER A}")
a
>>> print("\N{LATIN CAPITAL LETTER S WITH CEDILLA}")
>>> print("\Nisan")
File "<stdin>", line 1
138
Grdnz gibi, herhangi bir karl olmayan bir uzun ad belirttiimizde Python bize
bir hata mesaj gsteriyor. nk Python \N ka dizisinin hemen ardndan { iaretinin
getirilmesini ve sonra da UNICODE sistemi dahilinde geerli bir uzun ad belirtilmesini
bekliyor. Yukardaki rnekte \N ka dizisinden sonra { iareti yok. Zaten \N ka dizisinin
hemen ardndan gelen isan ifadesi de doru bir uzun ada iaret etmiyor. Dolaysyla da
Pythonn bize hata mesaj gstermekten baka aresi kalmyor...
\u, \U ve \N ka dizileri, UNICODE sistemi ile ilgili almalar yapmak isteyen programclar
iin Python programlama dilinin sunduu faydal aralardan yalnzca birkadr. Ancak bu
aralarn sizin iinize yaramayacan asla dnmeyin. Zira \u, \U ve \N ka dizileri ile ilgili
yukardaki durum hi beklemediiniz bir anda sizi de vurabilir. nk bu ka dizilerinin
oluturduu risk hi de yle nadir karlalacak bir sorun deildir.
Bildiiniz gibi Windows 7de kullancnn dosyalarn ieren dizin ad C:\Users\kullanc_ad
eklinde gsteriliyor.
Dolaysyla Windows kullananlar UNICODE ka dizilerinden
kaynaklanan bu tuzaa her an debilir. Ya da eer adnz u veya n har ile balyorsa yine
bu tuzaa dme ihtimaliniz epey yksek olacak, C:\Users\umut veya C:\Users\Nihat gibi bir
dizin ad belirtirken ok dikkatli olmanz gerekecektir. Zira zellikle dosyalar zerinde ilem
yaparken, bu tr dizin adlarn sk sk kullanmak durumunda kalacaksnz. Bu yzden, alelade
bir kelime yazdnz zannederken hi farknda olmadan bir ka dizisi tanmlyor olma
ihtimalini her zaman gz nnde bulundurmal ve buna uygun nlemleri alm olmalsnz.
Onaltl sayma sistemindeki 41 says A harne karlk gelir. Eer hangi karakterlerin
hangi saylara karlk geldiini merak ediyorsanz [Link] adresindeki tabloyu
inceleyebilirsiniz. Bu tabloda hex stunu altnda gsterilen saylar onaltl saylar olup,
symbol stununda gsterilen karakterlere karlk gelirler. rnein hex stunundaki
4E says symbol stunundaki N harne karlk gelir. Bu durumu Pythonla da teyit
edebilirsiniz:
>>>"\x4E"
N
139
>>> print("C:\Users\Aye\xp_dosyalar")
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 2-4: truncated \UXXXXXXXX escape
Grdnz gibi, Python \x ifadesinden sonra onaltl bir say belirtmenizi bekliyor.
Halbuki biz burada \x ifadesini xp_dosyalar adl dizini gsterebilmek iin kullanmtk.
Ama grne gre yanllkla Python iin zel bir anlam ifade eden bir karakter dizisi
oluturmuuz...
Bildiimiz yoldan bu kty vermeye alrsak neler olacan adnz gibi biliyorsunuz:
>>> print("Kurulum dizini: C:\aylar\nisan\toplam masraf")
Kurulum dizini: C:ylar
isan
oplam masraf
Not: Eer Windows zerinde alyorsanz bu komutu verdikten sonra bir !bip! sesi de
duymu olabilirsiniz...
Python tabii ki, karakter dizisi iinde geen \aylar, \nisan, ve \toplam masraf ifadelerinin
ilk karakterlerini yanl anlad! \a, \n ve \t gibi ifadeler Pythonn gznde birer ka dizisi.
Dolaysyla Python \a karakterlerini grnce bir !bip! sesi karyor, \n karakterlerini grnce
satr bana geiyor ve \t karakterlerini grnce de Tab tuuna baslm gibi bir tepki veriyor.
Sonu olarak da yukardaki gibi bir kt retiyor.
Daha nce bu durumu yle bir kod yazarak engellemitik:
>>> print("Kurulum dizini: C:\\aylar\\nisan\\toplam masraf")
Kurulum dizini: C:\aylar\nisan\toplam masraf
Burada, \ iaretlerinin her birini iftleyerek sorunun stesinden geldik. Yukardaki yntem
doru ve kabul grm bir zmdr. Ama bu sorunun stesinden gelmenin ok daha basit
ve pratik bir yolu var. Bakalm:
>>> print(r"Kurulum dizini: C:\aylar\nisan\toplam masraf")
Kurulum dizini: C:\aylar\nisan\toplam masraf
140
Grdnz gibi, karakter dizisinin ba ksmnn d tarafna bir adet r har yerletirerek
sorunun stesinden geliyoruz. Bu ka dizisinin, kullanm asndan teki ka dizilerinden
farkl olduuna dikkat edin. teki ka dizileri karakter dizisinin iinde yer alrken, bu ka
dizisi karakter dizisinin dna yerletiriliyor.
Bu ka dizisinin tam olarak nasl ilediini grmek iin dilerseniz bir rnek daha verelim:
>>> print("Ka dizileri: \, \n, \t, \a, \\, r")
Ka dizileri: \,
,
, , \, r
Burada da Python bizim yapmak istediimiz eyi anlayamad ve karakter dizisi iinde geen
ka dizilerini dorudan ekrana yazdrmak yerine bu ka dizilerinin ilevlerini yerine
getirmesine izin verdi. Tpk biraz nceki rnekte olduu gibi, istersek ka dizilerini
iftleyerek bu sorunu aabiliriz:
>>> print("Ka dizileri: \\, \\n, \\t, \\a, \\\, r")
Ka dizileri: \, \n, \t, \a, \\, r
Grdnz gibi, karakter dizisinin bana getirdiimiz r ka dizisi, karakter dizisi iinde
geen ka dizilerinin ilevlerini yerine getirmesine engel olarak, istediimiz kty elde
etmemizi salyor.
Bu arada bu ka dizisini, daha nce rendiimiz \r adl ka dizisi ile kartrmamaya dikkat
ediyoruz.
Pythondaki btn ka dizilerinden sz ettiimize gre, konuyu kapatmadan nce nemli bir
ayrntdan sz edelim.
Pythonda karakter dizilerinin sonunda sadece ift sayda \ iareti bulunabilir. Tek sayda
\ iareti kullanldnda karakter dizisini bitiren trnak iareti etkisizleecei iin akma
sorunu ortaya kar. Bu etkisizlemeyi, karakter dizisinin bana koyduunuz r ka dizisi
de engelleyemez. Yani:
>>> print("Ka dizisi: \")
Bu ekilde bir tanmlama yaptmzda Python bize bir hata mesaj gsterir. nk kapan
trnann hemen ncesine yerletirdiimiz \ ka dizisi, Pythonn karakter dizisini kapatan
trnak iaretini grmezden gelmesine yol aarak bu trna etkisizletiriyor. Bylece sanki
karakter dizisini tanmlarken kapan trnan hi yazmamz gibi bir sonu ortaya kyor:
>>> print("Ka dizisi: \")
File "<stdin>", line 1
print("Ka dizisi: \")
^
SyntaxError: EOL while scanning string literal
141
^
SyntaxError: EOL while scanning string literal
Byle bir durumla ilk kez karlatnzda bunun Python programlama dilinden kaynaklanan
bir hata olduunu dnebilirsiniz, ancak bu durum Pythonn resmi internet sitesinde Ska
Sorulan Sorular blmne alnacak kadar nemli bir tasarm tercihidir: [Link]
imdi bu kodlarla oluturduunuz [Link] adl dosyay LibreOce veya Microsoft Word
gibi bir programla an. deneme satrlarnn iki farkl sayfaya yazdrldn greceksiniz. Bu
arada, eer Microsoft Word dosyay aarken bir hata mesaj gsterirse, o hata mesajna birka
kez tamam diyerek hata penceresini kapatn. Dosya normal bir ekilde alacaktr.
Dediimiz gibi, bu ka dizisi artk pek kullanlmyor. Ama yine de bu ka dizisine kar
da uyank olmalsnz. nk bu ka dizisi de beklemediiniz ktlar almanza yol aabilir.
Mesela u rnee bir bakalm:
>>> "\frat"
'\x0crat'
Grdnz gibi, siz aslnda \frat yazmak isterken, Python bu kelimenin ba tarafndaki \f
karakter dizisini bir ka dizisi olarak deerlendirip ona gre bir kt verdi.
142
Anlam
Karakter dizisi iinde tek trnak iaretini kullanabilmemizi salar.
Karakter dizisi iinde ift trnak iaretini kullanabilmemizi salar.
Karakter dizisi iinde \ iaretini kullanabilmemizi salar.
Yeni bir satra gememizi salar.
Karakterler arasnda sekme boluu brakmamz salar.
UNICODE kod konumlarn gsterebilmemizi salar.
UNICODE kod konumlarn gsterebilmemizi salar.
Karakterleri UNICODE adlarna gre kullanabilmemizi salar.
Onaltl sistemdeki bir saynn karakter karln gsterebilmemizi salar.
Destekleyen sistemlerde, kasa hoparlrnden bir bip sesi verilmesini
salar.
Ayn satrn bana dnlmesini salar.
Destekleyen sistemlerde dey sekme oluturulmasn salar.
Kendisinden nce gelen karakterin silinmesini salar.
Yeni bir sayfaya geilmesini salar.
Karakter dizisi iinde ka dizilerini kullanabilmemizi salar.
143
BLM 11
Bu noktaya kadar btn ilerimizi Pythonn etkileimli kabuu zerinden hallettik. Her ne
kadar etkileimli kabuk son derece kullanl bir ortam da olsa, bizim asl alma alanmz
deildir. Daha nce de dediimiz gibi, etkileimli kabuu genellikle ufak tefek Python kodlarn
test etmek iin kullanacaz. Ama asl programlarmz tabii ki etkileimli kabua deil,
program dosyasna yazacaz.
Ne dedik? zellikle kk kod paralar yazp bunlar denemek iin etkileimli kabuk
mkemmel bir ortamdr. Ancak kodlar oalp bymeye balaynca bu ortam yetersiz
gelmeye balayacaktr. stelik tabii ki yazdnz kodlar bir yere kaydedip saklamak
isteyeceksiniz. te burada metin dzenleyiciler devreye girecek.
Python kodlarn yazmak iin istediiniz herhangi bir metin dzenleyiciyi kullanabilirsiniz.
Hatta Notepad bile olur. Ancak Python kodlarn ayrt edip renklendirebilen bir metin
dzenleyici ile yola kmak her bakmdan hayatnz kolaylatracaktr.
Not: Python kodlarnz yazmak iin Microsoft Word veya [Link] OOWriter gibi,
belgeleri ikili (binary ) dzende kaydeden programlar uygun deildir. Kullanacanz metin
dzenleyici, belgelerinizi dz metin (plain text ) biiminde kaydedebilmeli.
Biz bu blmde farkl iletim sistemlerinde, metin dzenleyici kullanlarak Python
programlarnn nasl yazlacan ve bunlarn nasl altrlacan tek tek inceleyeceiz.
Daha nce de sylediimiz gibi, hangi iletim sistemini kullanyor olursanz olun, hem
Windows hem de GNU/Linux bal altnda yazlanlar okumalsnz.
Dilerseniz nce GNU/Linux ile balayalm:
11.1 GNU/Linux
Eer kullandnz sistem GNU/Linuxta Unity veya GNOME masast ortam ise balang
dzeyi iin Gedit adl metin dzenleyici yeterli olacaktr.
Eer kullandnz sistem GNU/Linuxta KDE masast ortam ise Kwrite veya Kate adl metin
dzenleyicilerden herhangi birini kullanabilirsiniz. u aamada kullanm kolayl ve sadelii
nedeniyle Kwrite nerilebilir.
e yeni bir Gedit belgesi aarak balayalm. Yeni bir Gedit belgesi amann en kolay yolu
Alt+F2 tularna bastktan sonra kan ekranda:
144
gedit
Eer bu kt yerine bir hata mesaj alyorsanz bunun birka farkl sebebi olabilir:
1. Kodlarda yazm hatas yapm olabilirsiniz. Bu ihtimali bertaraf etmek iin yukardaki
kodlarla kendi yazdnz kodlar dikkatlice karlatrn.
2. Kodlarnz kaydettiiniz [Link] adl dosyann adn yanl yazm olabilirsiniz.
Dolaysyla python3 [Link] komutu, var olmayan bir dosyaya atfta bulunuyor
olabilir.
3. python3 [Link] komutunu verdiiniz dizin konumu ile [Link] dosyasnn
bulunduu dizin konumu birbirinden farkl olabilir. Yani siz [Link] dosyasn
masastne kaydetmisinizdir, ama python3 [Link] komutunu yanllkla baka
bir dizin altnda veriyor olabilirsiniz. Bu ihtimali ortadan kaldrmak iin, nceki derslerde
rendiimiz yntemleri kullanarak hangi dizin altnda bulunduunuzu kontrol edin.
O anda iinde bulunduunuz dizinin ieriini listeleyerek, [Link] dosyasnn
orada grnp grnmediini kontrol edebilirsiniz. Eer program dosyanz bu listede
grnmyorsa, elbette python3 [Link] komutu almayacaktr.
11.1. GNU/Linux
145
11.2 Windows
Daha nce de sylediimiz gibi, Python kodlarmz yazmak iin istediimiz bir metin
dzenleyiciyi kullanabiliriz. Hatta Notepadi bile kullansak olur. Ancak Notepadden biraz
daha gelimi bir metin dzenleyici ile balamak iinizi kolaylatracaktr.
Python programlama dilini renmeye yeni balayan Windows kullanclar iin en uygun
metin dzenleyici IDLEdr. Balat > Tm Programlar > Python 3.5 > IDLE (Python GUI) yolunu
takip ederek IDLEa ulaabilirsiniz.
IDLE atnzda yle bir ekranla karlaacaksnz:
Aslnda bu ekran size bir yerlerden tandk geliyor olmal. Dikkat ederseniz beyaz ekrann en
sonunda bordo renkli bir >>> iareti var. Evet, tahmin ettiiniz gibi, buras aslnda Pythonn
etkileimli kabuudur. Yani o siyah etkileimli kabuk ekrannda ne yapabilirseniz burada da
ayn eyi yapabilirsiniz. Dilerseniz kendi kendinize baz denemeler yapn. Ama u anda biz
IDLEn bu zelliini deil, metin dzenleyici olma zelliini kullanacaz. O yzden yolumuza
devam ediyoruz.
146
Not:
Dediimiz gibi, yukarda grnen ekran aslnda Pythonn etkileimli kabuudur.
Dolaysyla biraz sonra gstereceimiz kodlar buraya yazmayacaz. Python programlama
diline yeni balayanlarn en sk yapt hatalardan biri de, kaydetmek istedikleri kodlar
yukarda grnen ekrana yazmaya almalardr.
Unutmayn, Pythonn etkileimli
kabuunda ne yapabiliyorsanz, IDLE atnzda ilk karnza kan ekranda da onu
yapabilirsiniz.
Pythonn etkileimli kabuunda yazdnz kodlar etkileimli kabuu
kapattnzda nasl kayboluyorsa, yukardaki ekrana yazdnz kodlar da IDLE kapattnzda
kaybolur...
Bir nceki ekranda sol st kede File [Dosya] mens gryorsunuz. Oraya tklayn ve men
iindeki New Window [Yeni Pencere] dmesine basn. yle bir ekranla karlaacaksnz:
Bu noktadan sonra yapmamz gereken ey dosyamz kaydetmek olacak. Bunun iin File >
Save as yolunu takip ederek programmz masastne [Link] adyla kaydediyoruz.
u anda programmz yazdk ve kaydettik. Artk programmz altrabiliriz. Bunun iin
IDLEda Run > Run Module yolunu takip etmeniz veya ksaca F5 tuuna basmanz yeterli
olacaktr. Bu iki yntemden birini kullanarak programnz altrdnzda yle bir kt elde
edeceksiniz:
02.01.2012 Pazartesi leden sonra bulualm.
11.2. Windows
147
BLM 12
12.1 GNU/Linux
Elimizde yle bir program olduunu dnelim:
kartvizit = """
stihza Anonim irketi
Frat zgl
Tel: 0212 123 23 23
Faks: 0212 123 23 24
[Link]: kistihza@[Link]"""
print(kartvizit)
148
kartvizit = """
stihza Anonim irketi
Frat zgl
Tel: 0212 123 23 23
Faks: 0212 123 23 24
[Link]: kistihza@[Link]"""
print(kartvizit)
Not: chmod komutunun bir Python komutu olmadn biliyorsunuz. Bu komut bir sistem
komutudur. Dolaysyla Pythonn etkileimli kabuunda deil, iletim sisteminin komut
satrnda altrlr.
Program dosyasn altrabilmemiz iin gereken yetkileri elimize aldk. Ama yapmamz
gereken birka ilem daha var.
ncelikle program dosyamz aarak ilk satra u ibareyi ekleyelim:
#!/usr/bin/python3
Son olarak da programmz echo $PATH ktsnda grnen dizinlerden herhangi birinin iine
kopyalayalm. Mesela /usr/bin dizini bu i iin en uygun yerdir:
sudo cp kartvizit /usr/bin/kartvizit
12.1. GNU/Linux
149
Bylece iletim sistemimiz Python /usr/bin dizini altnda arayacak ve yazdmz program
Pythonla altrmas gerektiini anlayacaktr.
Ancak baz GNU/Linux sistemlerinde, Pythonn nasl kurulduuna bal olarak Pythonn
altrlabilir dosyas baka bir dizinin iinde de olabilir. Mesela eer Python programlama
dilini yetkisiz kullanc olarak ev dizininin altndaki python adl bir dizin iine kurduysak,
altrlabilir dosya $HOME/python/bin/ dizini altnda olacaktr. Bu durumda, altrlabilir
dosya /usr/bin altnda bulunamayaca iin, sistemimiz yazdmz program altramaz.
Pythonn altrlabilir dosyasnn her sistemde ayn dizin altnda bulunmama ihtimalinden
tr yukardaki gibi sabit bir dizin ad vermek iyi bir kir olmayabilir.
Bu tr
sistem farkllklarna kar nlem olarak GNU/Linux sistemlerindeki env adl bir betikten
yararlanabiliriz. /usr/bin dizini altnda bulunduunu varsayabileceimiz bu env betii,
YOL dizinlerini tek tek tarayarak, Pythonn hangi YOL dizini iinde olduunu bulabilir.
Bylece yazdmz bir programn, Pythonn /usr/bin dizini haricinde bir konuma kurulduu
sistemlerde altrlmas konusunda endie etmemize gerek kalmaz.
Bunun iin
programmzn en bana eklediimiz satr yle yazyoruz:
#/usr/bin/env python3
lk satr bu ekilde yazmamz sayesinde Python YOL iinde nereye kurulmu olursa olsun
kolaylkla tespit edilebilecektir.
Uzun lafn ksas, #!/usr/bin/python3 yazdmzda sisteme u emri vermi oluyoruz:
Python /usr/bin dizini iinde ara! #!/usr/bin/env python3 yazdmzda ise u emri:
150
Byle bir hata almamak iin, o satr #!/usr/bin/env python3 eklinde yazmaya zen
gsteriyoruz. Bylece Python YOL iindeki dizinler arasnda nereye kurulmu olursa olsun
iletim sistemimiz Python tespit edebiliyor.
Bu noktada size yle bir soru sormama izin verin: Acaba Pythonn python3 adyla deil de,
mesela python 35 (veya py3) adyla kurulu olduu sistemlerde #!/usr/bin/env python3 satr
grevini yerine getirebilir mi?
Elbette getiremez...
nk bu satr yardmyla biz sistemde python3 adl bir dosya aratyoruz aslnda. Ama
eer sistemde Python3 altran dosyann ad python3 deil de, mesela py3 ise tabii ki
o satr bir ie yaramayacaktr. Programmzn byle bir sistemde alabilmesi iin bu satrn
#!/usr/bin/env python3.5 eklinde yazlmas gerekir.
Bu manzara karsnda aklnza yle bir soru gelmi olabilir:
GNU/Linux sistemlerinde Python3 altrmann standart ve tek bir yolu yok.
nk Python3 altran dosyann ad farkl datmlarda farkl ada sahip
olabiliyor. Byle bir durumda ben yazdm bir Python programnn btn
GNU/Linux datmlarnda alabileceinden nasl emin olacam?
Bu sorunun cevab, Emin olamazsnz, olacaktr...
GNU/Linuxta sadece Python iin deil baka programlama dilleriyle yazlm programlar iin
de ayn sorun geerlidir. nk GNU/Linux datmlar arasnda bir uyumluluktan bahsetmek
mmkn deil. Sistem farkllklarndan tr, bir GNU/Linux datmnda alan bir program
baka bir GNU/Linux datmnda almayabilir.
GNU/Linux iletim sistemine ynelik programlar yazan bir Python programcs olarak sizin
sorumluluunuz programnz yazp bitirmekten ibarettir. Bu programn herhangi bir
GNU/Linux datmnda alabilmesi o datmn gelitiricilerinin sorumluluu altndadr.
Yani mesela siz kendiniz Ubuntu datmn kullanyorsanz programlarnz Ubuntuyu temel
alarak yazarsnz. Burada sizin sorumluluunuz, yazdnz programn Ubuntu altnda
almasn salamaktan ibarettir. Ayn programn mesela Pardus altnda alabilmesi
Pardusa uygun paket yazan gelitiricilerin grevidir. Tabii ki siz isterseniz programnz iin
hem Ubuntu paketini (DEB ), hem de Pardus paketini (PISI ) ayr ayr hazrlayabilirsiniz. Ama
elbette btn datmlara uygun paketleri tek tek hazrlamanz mmkn deil.
Ayrca programlarnzn kaynak kodlarn yaymlarken, programn nasl altrlacana ilikin
ayrntl aklamalar README yada BENOKU adl bir dosya iine yazabilirsiniz. Bylece
farkl datmlarn kullanclar, yazdnz program kendi datmlarnda nasl altrmalar
gerektii konusunda bir kir sahibi olabilir. Kullanclar, yazdnz aklamalardan yola
karak programnz altrabilirse ne l! Ama eer altramazsa, bu dorudan sizin
sorununuz deil. Byle bir durumda zaten GNU/Linux kullanclar da sizi sulamayacak,
kendi kullandklar datmn gelitiricilerinden sizin yazdnz program iin paket isteinde
bulunacaktr.
12.1. GNU/Linux
151
Veya eer isterseniz, daha nce gsterdiimiz yntemleri uygulayarak, program yalnzca
ismiyle de altrabilirsiniz.
GNU/Linux datmlarnda, yalnzca komut arayzne sahip bir program ift tklayarak
altrmann nndeki bir baka engel, btn GNU/Linux datmlarnn, simge zerine ift
tklamaya ayn tepkiyi vermemesidir. Ama teorik olarak, GNU/Linuxta komut satr zerinde
alabilen bir programn dosyas zerine ift tklayarak altrabilmek iin u yolu takip
edebilirsiniz:
ncelikle programmzn ilk satrna, programmz hangi Python srm ile altrmak
istediimizi belirten u kodu ekliyoruz:
#!/usr/bin/env python3
152
[Link]: kistihza@[Link]"""
print(kartvizit)
input()
Artk program dosyas zerine ift tklayarak programmz altrmay deneyebiliriz. Ama
dediimiz gibi, farkl GNU/Linux datmlarnda ift tklama ilemi farkl yantlar verebilir. O
yzden komut satr uygulamalarn ift tklayarak balatmak pek tercih edilen bir yntem
deildir.
GNU/Linux iletim sistemi altnda bir Python programn altrmann alternatif yntemlerini
rendiimize gre, ayn ilemi Windows altnda nasl yapabileceimizi tartmaya geebiliriz.
Bu arada siz GNU/Linux kullanclar da yukarda verdiimiz bilgileri iyice sindirebilmek iin
kendi kendinize rnek programlar yazp bunlar farkl ekillerde altrmay deneyebilirsiniz.
Bu arada, her zaman sylediimiz gibi, yukarda anlatlanlar ezberlemeye almak yerine,
neyi neden yaptmz anlamaya almak ok daha faydal bir i olacaktr. rnein bir
program adyla arabilmek iin btn o ilemleri yaparken nereye varmaya alyoruz?
Amacmz ne? Her bir adm hangi maksada ynelik? Mesela programmza neden altrma
izni veriyoruz? env betii ne ie yarar? Programmzn konumunu neden deitiriyoruz?
Yukarda anlatlanlar okurken kendinize bu tr sorular sorup cevaplamanz, sreci
ezberlemek yerine srecin mantn kavramanz salayacaktr. Unutmayn, buradaki bilgiler
sadece Python programlar iin geerli deildir. Burada sz edilen program altrma
mant, etrafta grdnz btn programlar iin geerlidir. Dolaysyla, eer buradaki
bilgileri hakkyla renirseniz, bir tala iki ku vurmu olursunuz.
12.2 Windows
Bir nceki blmde, yazdmz bir Python programn IDLE zerinden nasl
altrabileceimizi grdk. Eer IDLE adl metin dzenleyiciyi kullanyorsanz, Python
programlarnz altrmak iin muhtemelen ounlukla bu yntemi kullanacaksnz. Ama
elbette bir Python programn altrmann tek yntemi bu deildir. te biz bu blmde,
Windowsta Python programlarn altrmann alternatif yntemlerinden sz edeceiz.
12.2. Windows
153
MS-DOS komut satrna ulatktan sonra, daha nce rendiimiz ekilde, komut satr
zerinden masastne, yani dosyay kaydettiiniz yere gelin. (Bu ilemin nasl yaplacan
hatrladnz varsayyorum.)
Masastne geldikten sonra u komutu vererek programnz altrabilirsiniz:
python program_ad.py
Elbette burada Pythonn etkileimli kabuuna ulamak iin hangi komutu kullanyorsanz
onu kullanacaksnz. Ben sizin Pythonn etkileimli kabuuna ulamak iin python komutunu
kullandnz varsaydm.
Yukardaki gibi python komutunu vermek yerine, ayn ilev iin nceki derslerde rendiimiz
py adl betii de kullanabilirsiniz:
py program_ad.py
py adl betii altrrken, istediiniz Python srmnn almasn temin etmek iin,
yukarda gsterdiimiz ekilde srm numarasn da belirtmenin yansra, yazdnz bir
programn istediiniz Python srm ile almasn salamann bir yolu daha var:
Bunun iin ncelikle bo bir metin dzenleyici ap u kodlar yazn:
#! python3
print("Merhaba Zalim Dnya!")
Programnz normal bir ekilde kt verir. imdi ayn kodlar bir de yle yazn:
#! python2
print("Merhaba Zalim Dnya!")
#! python2
Bu satr ise programmz Pythonn 2.x srmlerinden biri ile altrmamz salyor.
Pythonn 2.x srmlerinde ntanml karakter kodlama biimi ASCII olduundan, Trke
karakterler ieren bir program altrabilmek iin ilave ilemler yapmamz gerekir.
Yukardaki program dosyas bu ilave ilemleri iermedii iin programmz Pythonn 2.x
srmlerinde hata verecektir.
Bu satrlarn oluturduu etkiyi daha net bir ekilde grebilmek iin u kodlar da
kullanabilirsiniz:
#! python3
import sys
print([Link])
12.2. Windows
155
Elbette ben yukardaki kodlar anlatrken, sisteminizde Python3 ile birlikte Python2nin
de kurulu olduunu varsaydm. Eer sisteminizde Python2 kurulu deilse, aldnz hata
mesajnn sebebi, doal olarak, kodlarda Trke karakterlerin bulunmas deil, Python2nin
kurulu olmamas olacaktr...
Grdnz gibi, programlarmzn ilk satrna eklediimiz bu kodlar, programlarmz
altrmak istediimiz srmleri kontrol etmemizi salyor.
Bu satrlar kullanarak,
programlarmzn istediimiz Python srmyle almasn temin edebiliriz.
Hatrlarsanz buna benzer bir satrn GNU/Linux iletim sistemleri iin de geerli olduunu
sylemitik. GNU/Linuxta bu satr yle yazyorduk:
#!/usr/bin/env python3
Tpk bir nceki konuda da anlattmz gibi, programmz hangi Python srmnn
altracan yine program dosyasnn ilk satrna yazacamz #! python3 gibi bir kod
yardmyla kontrol edebiliriz.
Burada hemen yle bir soru akla geliyor: Windowsta mesela Notepad ve Calc gibi
programlar, hi .EXE uzantsn belirtmeden dorudan isimleriyle arabiliyoruz. Yani
rnein MS-DOS komut satrnda notepad komutu verirsek Notepad program, calc komutu
verirsek de Hesap Makinesi program almaya balayacaktr. Ama mesela [Link] adl
programmz altrabilmek iin .PY uzantsn da belirtmemiz gerekti. Peki bu durumun
nedeni nedir?
Windowsta PATHEXT adl bir evre deikeni vardr. Bu deiken, sistemin altrlabilir kabul
ettii uzantlar tutar. MS-DOS ekrannda u komutu verelim:
echo %PATHEXT%
156
Windowsta eer bir program yukarda grlen uzantlardan birine sahipse altrlabilir
olarak kabul edilecektir. Grdnz gibi, EXE de bu uzantlardan biri. Dolaysyla bu uzantya
sahip bir dosyay, uzantsn belirtmeden de arabiliyoruz. Eer isterseniz bu listeye .PY
uzantsn da ekleyebilirsiniz. Bunun iin u ilemleri yapabilirsiniz:
1. Balat > Denetim Masas > Sistem ve Gvenlik > Sistem > Gelimi Sistem Ayarlar
yolunu takip edin.
2. Alan pencerede Gelimi sekmesine tklayn ve Ortam Deikenleri dmesine basn.
3. Sistem Deikenleri blmnde PATHEXT esini bulup buna ift tklayn.
4. En son girdi olan .WSH den sonra ;.PY girdisini ekleyin.
5. TAMAM a basp kn.
Bylece artk .PY uzantl dosyalar da, uzant belirtmeden altrabilirsiniz. Ancak bu
komutun ie yarayabilmesi iin, MS-DOSta o anda programn bulunduu dizin iinde
olmamz gerek. Yani eer programnz Belgeler dizini iinde ise ve siz de MS-DOSta
C:/Users/Kullanici_adi/Desktop dizini altndaysanz bu komut bir ie yaramayacaktr.
Eer yazdnz program konum farketmeksizin her yerden arabilmek istiyorsanz,
programnzn bulunduu dizini daha nce anlattmz ekilde YOLa eklemelisiniz.
Kullandmz iletim sisteminde birden fazla Python srm kurulu olabilir. O yzden,
programmzn hangi Python srmyle almasn istiyorsak ona uygun ekilde bir ilk
satr yazmamz gerekiyor ncelikle. Biz programmz Python3 ile altrmak istediimizi
varsayalm ve ilk satra unu ekleyelim:
#! python3
Bylece Windows, programmz hangi Python srm ile altrmas gerektiini bilecek.
12.2. Windows
157
imdi program bu ekilde kaydedip simgesi zerine ift tkladmzda program penceresi
alacak ve biz Enter dmesine basana kadar da ak kalacaktr.
Burada imdilik
input() fonksiyonunun ne olduuna taklmayn. Birka blm sonra bu fonksiyonu btn
ayrntlaryla inceleyeceiz.
Bu arada, elbette en sona eklediimiz input() satrnn grevini yerine getirebilmesi iin,
ondan nce gelen btn kodlarn doru ve hatasz olmas gerekiyor. Eer bu satrdan
nceki ksmda herhangi bir hata yapmsanz, programn ak hibir zaman input() satrna
ulamayaca iin yine siyah bir komut ekrannn hzla yanp sndn grrsnz. O
yzden programlarnz ift tklayarak altrmadan nce, komut satrnda test ederek hatasz
olduundan emin olmalsnz.
158
Bu komutun kts size hangi dizin adn veriyorsa Python oraya kurulmu demektir. Bu dizin
altndaki Scripts klasrne girin.
Bu konumdayken bir komut satr an ve u komutu verin:
python3 cxfreeze-postinstall
Tabii ben burada sizin Python altrmak iin python3 komutunu kullandnz varsaydm.
Eer Python altrmak iin baka bir komut kullanyorsanz, yukarda o komutun adn
yazmalsnz.
Eer cx_Freeze programn kuramazsanz [Link] adresinden yardm
isteyebilirsiniz.
cx_Freeze Nasl Kullanlr?
cx_Freeze adl program indirip kurduktan sonra, kendi yazdnz Python programnn
bulunduu dizin altnda u komutu verin:
cxfreeze [Link]
Bu komutu verdiinizde dist adl bir dizinin olutuunu greceksiniz. imdi bu dizinin
iine girin. te orada [Link] adl dosya, sizin yazdnz Python programnn .EXE ye
dntrlm hali. Programnz datrken sadece .exe uzantl dosyay deil, dist adl dizini
btn ieriiyle birlikte datacaksnz.
Dizin adn kendiniz sonradan elle deitirebileceiniz gibi, daha .EXE dosyasn olutururken
de deitirebilirsiniz. Bunun iin yukardaki komutu u ekilde verebilirsiniz:
cxfreeze [Link] --install-dir=program_ad
Burada program_ad deerinin yerine, program dizininin adnn ne olmasn istiyorsanz onu
yazacaksnz.
Cxfreeze olduka kapsaml ve ayrntl bir programdr. Elbette yazdnz programlar
karmaklatka, programnz .EXE haline getirmek iin yukardaki gsterdiimiz cxfreeze
komutunu daha farkl parametrelerle altrmanz gerektiini greceksiniz. Biz imdilik sizi
sadece cxfreeze adl bu programn varlndan haberdar etmekle yetiniyoruz. lerde bu
program daha ayrntl bir ekilde inceleyeceiz.
12.2. Windows
159
BLM 13
Bu blmde, Python programlar gelitirirken rahat bir alma ortam elde edebilmek iin
yapmanz gerekenleri sralayacaz. ncelikle Windows kullanclarndan balayalm.
160
161
Artk komut satrn hangi dizin altnda balatmak istiyorsanz o dizine sa tklayn. Menler
arasnda Open in Terminal [Ubirimde a] adl bir seenek greceksiniz. Buna tkladnzda
o dizin altnda bir komut satr penceresi alacaktr.
Eer yazdnz bir program byle bir hata mesaj retiyorsa, ilk olarak metin dzenleyicinizin
kodlama biimi (encoding ) ayarlarn kontrol edin. Metin dzenleyiciler genellikle tercih
edilen kodlama biimini aadaki rnek resimde grld gibi, durum ubuunda srekli
olarak gsterir.
162
Ancak kodlama biimi doru bir ekilde utf-8 olarak ayarlanm metin dzenleyicilerde,
zellikle internet zerinden kod kopyalanp yaptrlmas srasnda bu ayar siz farknda
olmadan deiebilir. Byle bir durumda da program alrken yukarda bahsedilen hatay
alabilirsiniz. Dolaysyla, programnz yazdnz metin dzenleyicinin kodlama ayarlarnn siz
farknda olmadan deime ihtimaline kar uyank olmanz gerekir.
Elbette piyasada yzlerce metin dzenleyici olduu iin yukarda bahsedilen ayarlarn her
metin dzenleyicide nasl yaplacan tek tek gstermemiz mmkn deil. Ancak iyi bir
metin dzenleyicide yukardaki ayarlarn hepsi bulunur. Tek yapmanz gereken, bu ayarlarn,
kullandnz metin dzenleyicide nereden yapldn bulmak. Eer kullandnz metin
dzenleyiciyi ayarlamakta zorlanyorsanz, her zamanki gibi [Link]/forum adresinde
skntnz dile getirebilirsiniz.
Kodlama biimi kavramndan sz etmiken, Pythonla ilgili nemli bir konuya daha deinelim.
En bata da sylediimiz gibi, u anda piyasada Python iki farkl seri halinde gelitiriliyor.
Bunlardan birinin 2.x serisi, brnn de 3.x serisi olduunu biliyoruz. Pythonn 2.x serisinde
Trke karakterlerin gsterimi ile ilgili ok ciddi problemler vard. rnein Pythonn 2.x
serisinde yle bir kod yazamyorduk:
print("Gnaydn irin Baba!")
Bu kodu bir dosyaya kaydedip, Pythonn 2.x serisine ait bir srmle altrmak istediimizde
Python bize yle bir hata mesaj veriyordu:
SyntaxError: Non-ASCII character '\xc3' in file
[Link] on line 1, but no encoding declared;
see [Link] for details
Bunun sebebi, Pythonn 2.x srmlerinde ASCII adl kodlama biiminin kullanlyor olmasdr.
Zaten hata mesajna baktmzda da, Pythonn ASCII olmayan karakterlerin varlndan
ikayet ettiini gryoruz.
Yukardaki kodlarn alabilmesi iin programmza yle bir ekleme yapmamz gerekiyordu:
# -*- coding: utf-8 -*print("Gnaydn irin Baba!")
Buradaki ilk satra dikkat edin. Bu kodlarla yaptmz ey, Pythonn ASCII adl kodlama biimi
yerine UTF-8 adl kodlama biimini kullanmasn salamaktr. ASCII adl kodlama biimi
Trke karakterleri gsteremez, ama UTF-8 adl kodlama biimi Trke karakterleri ok rahat
bir ekilde gsterebilir.
Not:
Kodlama biimlerinden, ileride ayrntl bir ekilde sz edeceiz. O yzden bu
anlattklarmzda eer anlamadnz yerler olursa bunlara taklmanza gerek yok.
Pythonn 3.x serisinin gelii ile birlikte Pythonda ntanml olarak ASCII yerine UTF-8
kodlama biimi kullanlmaya baland. Dolaysyla yazdmz programlara # -*- coding:
utf-8 -*- satrn eklememize gerek kalmad. nk zaten Python UTF-8 kodlama biimini
163
ntanml olarak kendisi kullanyor. Ama eer UTF-8 dnda baka bir kodlama biimine
ihtiya duyarsanz yine bu satrdan yararlanabilirsiniz.
rnein GNU/Linux datmlarnn geleneksel olarak UTF-8 kodlama biimi ile aras
iyidir.
Dolaysyla eer GNU/Linux zerinde Python programlar gelitiriyorsanz bu
satr hi yazmadan bir mr geirebilirsiniz. Ama Windows iletim sistemleri UTF-8 i
desteklemekle birlikte, bu destek GNU/Linuxtaki kadar iyi deildir. Dolaysyla zaman zaman
Windowsta UTF-8 dnda baka bir kodlama biimini kullanmanz gerekebilir. rnein
yazdnz bir programda Trke karakterleri gremiyorsanz, programnzn ilk satrn yle
dzenleyebilirsiniz:
# -*- coding: cp1254 -*-
Burada UTF-8 yerine cp1254 adl kodlama biimini kullanm oluyoruz. Windows iletim
sisteminde cp1254 adl kodlama biimi UTF-8 e kyasla daha fazla desteklenir.
videoyu
Bylece MS-DOS komut satr iin Trke karakterleri gsterebilen bir yaz tipi belirlemi
olduk. Ancak bu, Trke karakterleri dzgn grntlemeye yetmeyebilir. Eer Trke
karakterler hala dzgn grnmyorsa, kullandnz sistemde MS-DOSun dil kodlamas
Trke karakterleri grntlemeye uygun olmayabilir. Trke karakterleri gsterebilen bir
dil kodlamas belirlemek iin komut satrnda u komutu verin:
chcp 1254
CP1254, Trke karakterleri de ieren bir dil kodlamasdr. Bu komutu verdikten sonra artk
Trke karakterleri dzgn grntleyebiliyor olmanz lazm.
nem tayordu. Ancak yukarda pratie ynelik pek bir ey sunamadk. te bu blmde
pratik eksikliimizi biraz olsun kapamaya dnk rnekler yapacaz.
Hatrlarsanz Pythonla tanmamz salayan ilk rneimiz ekrana basit bir Merhaba Zalim
Dnya! cmlesi yazdrmakt. Bu ilk rnei etkileimli kabukta verdiimizi hatrlyorsunuz:
>>> "Merhaba Zalim Dnya!"
imdi de bu dosyay daha nce anlattmz ekilde masastne [Link] adyla kaydedip
programmz altralm.
Ne oldu? Programnz hibir kt vermeden kapand, deil mi?
Hemen hatrlayacanz gibi, print() fonksiyonu iine alnmayan ifadelerin ekrana kt
olarak verilebilmesi sadece etkileimli kabua zg bir durumdur. Programlarmz dosyadan
altrrken, print() fonksiyonu iine alnmayan ifadeler ekranda grnmeyecektir.
Yukardaki rnek bu durumun bir gstergesidir. Dolaysyla yukardaki ifadenin ekrana kt
olarak verilebilmesi iin o kodu yle yazmamz gerekiyor:
print("Merhaba Zalim Dnya!")
Bu olduka basit bir rnekti. imdi biraz daha karmak bir rnek verelim.
Yine hatrlayacanz gibi, nceki blmlerden birinde aylk yol masrafmz hesaplayan bir
program yazmtk.
Orada elimizdeki verilerin unlar olduunu varsaymtk:
1. Cumartesi-Pazar gnleri almyoruz.
2. Dolaysyla ayda 22 gn alyoruz.
3. Evden ie gitmek iin kullandmz vastann creti 1.5 TL
4. ten eve dnmek iin kullandmz vastann creti 1.4 TL
Elimizdeki bu bilgilere gre aylk yol masrafmz hesaplamak iin de yle bir forml
retmitik:
masraf = gn says x (gidi creti + dn creti)
165
print(masraf)
Grdnz gibi, bu kodlar sayesinde kullancya daha ayrntl bilgi vermi olduk. stelik
elde ettiimiz kt daha k grnyor.
Yukardaki kodlarda imdiye kadar renmediimiz hibir ey yok. Yukardaki kodlarn
tamamn anlayabilecek kadar Python bilgimiz var. Bu kodlarda ok basit paralar bir araya
getirerek istediimiz kty nasl elde ettiimizi dikkatlice inceleyin. Mesela elde etmek
istediimiz ktnn grnn gzelletirmek iin iki yerde u satr kullandk:
print("-"*30)
Bylece 30 adet - iaretini yan yana basm olduk. Bu sayede elde ettiimiz kt daha derli
toplu bir grnme kavutu. Ayrca kodlarmz iinde \t adl ka dizisinden de yararlandk.
Bylelikle ekrana baslan ktlar alt alta dzgn bir ekilde hizalanm oldu.
Bu arada, yukardaki kodlar sayesinde deiken kullanmnn ilerimizi ne kadar
kolaylatrdna da birebir tank olduk. Eer deikenler olmasayd yukardaki kodlar yle
yazacaktk:
print("-"*30)
print("allan gn says\t:", 22)
print("ie gidi creti\t:", 1.5)
print("iten dn creti\t:", 1.4)
166
print("-"*30)
print("AYLIK YOL MASRAFI\t:", 22 * (1.5 + 1.4))
Eer gnn birinde mesela allan gn says deiirse yukardaki kodlarn iki farkl yerinde
deiiklik yapmamz gerekecekti. Bu kodlarn ok byk bir programn paras olduunu
dnn. Kodlarn iinde deer arayp bunlar tek tek deitirmeye kalkmann ne kadar
hataya ak bir yntem olduunu tahmin edebilirsiniz. Ama deikenler sayesinde, sadece
tek bir yerde deiiklik yaparak kodlarmz gncel tutabiliriz. Mesela allan gn says 20 ye
dm olsun:
gn = 20
gidi_creti = 1.5
dn_creti = 1.4
masraf = gn * (gidi_creti + dn_creti)
print("-"*30)
print("allan gn says\t:", gn)
print("ie gidi creti\t:", gidi_creti)
print("iten dn creti\t:", dn_creti)
print("-"*30)
print("AYLIK YOL MASRAFI\t:", masraf)
167
BLM 14
=
=
=
=
"Frat"
"zgl"
"Ubuntu"
"stanbul"
print("isim
: ",
"soyisim
: ",
"iletim sistemi: ",
"ehir
: ",
sep="")
isim,
soyisim,
isis,
ehir,
"\n",
"\n",
"\n",
"\n",
lk olarak isim, soyisim, isis ve ehir adnda drt farkl deiken tanmladk. Bu deikenlerin
deeri srasyla Frat, zgl, Ubuntu ve stanbul.
Daha sonra da tanmladmz bu deikenleri belli bir dzen iinde kullanclarmza
gsterdik, yani ekrana yazdrdk. Elbette bu i iin print() fonksiyonunu kullandk. Bildiiniz
gibi, print() birden fazla parametre alabilen bir fonksiyondur. Yani print() fonksiyonunun
parantezleri iine istediimiz sayda e yazabiliriz.
Eer print() fonksiyonunun yukardaki kullanm ilk bakta gznze anlalmaz
grndyse, fonksiyonda geen ve ne ie yaradn anlayamadnz eleri, bir de kartarak
yazmay deneyebilirsiniz bu fonksiyonu.
Pythonla yazlm herhangi bir programn tam olarak nasl ilediini anlamann en iyi
yolu program iindeki kodlarda baz deiiklikler yaparak ortaya kan sonucu incelemektir.
rnein print() fonksiyonunda sep parametresinin deerini bo bir karakter dizisi
yapmamzn nedenini anlamak iin, fonksiyondaki bu sep parametresini kaldrp, program
bir de bu ekilde altrmay deneyebilirsiniz.
Yukardaki rnekte btn eleri tek bir print() fonksiyonu iine yazdk. Ama tabii eer
isterseniz birden fazla print() fonksiyonu da kullanabilirsiniz. yle:
isim
soyisim
isis
ehir
168
=
=
=
=
"Frat"
"zgl"
"Ubuntu"
"stanbul"
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim)
soyisim)
isis)
ehir)
Ancak bu ekilde kod yaps biraz karmak grnyor. Ayrca parantez iindeki eleri yan
yana yazdmz iin, isim:, soyisim:, iletim sistemi: ve ehir: ifadelerini alt alta dzgn bir
ekilde hizalamak da kolay olmayacaktr.
Belki bu basit kodlarda ok fazla dikkati ekmiyordur, ama zellikle byk boyutlu
programlarda kodlarmz hem yap hem de grnt olarak olabildiince anlalr bir hale
getirmek hem kodu okuyan bakalar iin, hem de kendimiz iin byk nem tar.
Unutmayn, bir program yazdktan 5-6 ay sonra geri dnp baktnzda kendi yazdnz
kodlardan siz dahi hibir ey anlamadnz farkedebilirsiniz!
Bir program yazarken kodlarn olabildiince okunakl olmasn salamann bir ka yolu vardr.
Biz bunlardan bazlarn yukarda grdk. Ancak bir program okunakl hale getirmenin en iyi
yolu kodlar iine baz yorum cmleleri ekleyerek kodlar aklamaktr.
te bu blmde, Python programlama dili ile yazdmz kodlara nasl yorum ve aklama
cmleleri ekleyeceimizi inceleyeceiz.
169
=
=
=
=
"Frat"
"zgl"
"Ubuntu" #iletim sistemi
"stanbul"
iaretini koymay
170
=
=
=
=
=
"Frat"
"zgl"
"Ubuntu"
"stanbul"
"T.C"
print("isim
: ", isim,
"soyisim
: ", soyisim,
"iletim sistemi: ", isis,
"ehir
: ", ehir,
#"uyruu
: ", uyruu,
sep="")
"\n",
"\n",
"\n",
"\n",
"\n",
Burada, programa henz eklemek istemediimiz bir zellii, yorum iine alarak imdilik iptal
ediyoruz yani etkisizletiriyoruz (ngilizcede bu yorum iine alma ilemine comment out
deniyor). Python yorum iinde bir kod bile yer alsa o kodlar altrmayacaktr. nk Python
# iareti ile balayan satrlarn ieriini grmez (#!/usr/bin/env python3 ve # -*- coding:
utf-8 -*- satrlar hari).
Peki eklemek istemediimiz zellii yorum iine almaktansa dorudan silsek olmaz m?
Elbette olur. Ama programn daha sonraki bir srmne ilave edeceimiz bir zellii yorum
iine almak yerine silecek olursak, vakti geldiinde o zellii nasl yaptmz hatrlamakta
zorlanabiliriz! Hatta bir sre sonra programmza hangi zellii ekleyeceimizi dahi unutmu
olabiliriz. Hayr, ben hafzama gveniyorum! diyorsanz karar sizin.
Yorum iine alarak iptal ettiiniz bu kodlar programa ekleme vakti geldiinde yapacanz tek
ey, kodlarn bandaki # iaretlerini kaldrmak olacaktr. Hatta baz metin dzenleyiciler
bu ilemi tek bir tua basarak da gerekletirme yeteneine sahiptir. rnein IDLE ile
alyorsanz, yorum iine almak istediiniz kodlar fare ile setikten sonra Alt+3 tularna
basarak ilgili kodlar yorum iine alabilirsiniz. Bu kodlar yorumdan kurtarmak iin ise ilgili
alan setikten sonra Alt+4 tularna basmanz yeterli olacaktr (yorumdan kurtarma ilemine
ngilizcede uncomment diyorlar).
#######################################################
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#
FALANCA v.1
#
#
Yazan: Keramet Su
#
#
Lisans: GPL v2
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#######################################################
isim
= "Frat"
soyisim = "zgl"
171
isis
ehir
= "Ubuntu"
= "stanbul"
print("isim
: ",
"soyisim
: ",
"iletim sistemi: ",
"ehir
: ",
sep="")
isim,
soyisim,
isis,
ehir,
"\n",
"\n",
"\n",
"\n",
Yani ksaca, Pythonun grmesini, altrmasn istemediimiz her eyi yorum iine alabiliriz.
Unutmamamz gereken tek ey, yorumlarn yazdmz programlarn nemli bir paras
olduu ve bunlar mantkl, makul bir ekilde kullanmamz gerektiidir.
172
BLM 15
imdiye kadar Python programlama dili ile ilgili epey bilgi edindik. Ama muhtemelen buraya
kadar rendiklerimiz sizi heyecanlandrmaktan bir hayli uzakt. Zira u ana kadar hep tek
ynl bir programlama faaliyeti yrttk.
Mesela imdiye kadar rendiklerimizi kullanarak ancak yle bir program yazabildik:
isim = "Mbeccel"
print("Merhaba", isim, end="!\n")
173
#!/usr/bin/env python3
kartvizit = """
stihza Anonim irketi
Frat zgl
Tel: 0212 123 23 23
Faks: 0212 123 23 24
[Link]: kistihza@[Link]
"""
print(kartvizit)
Bu program yazp kaydettikten sonra bu programn simgesi zerine ift tkladmzda siyah
bir komut ekrannn ok hzl bir ekilde alp kapandn grrz. Aslnda programmz
alyor, ama programmz yapmas gereken ii yaptktan hemen sonra kapand iin biz
program penceresini grmyoruz.
Programmzn altktan sonra hemen kapanmamasn salamak iin son satra bir input()
fonksiyonu yerletirmemiz gerektiini biliyoruz:
#!/usr/bin/env python3
kartvizit = """
stihza Anonim irketi
Frat zgl
Tel: 0212 123 23 23
Faks: 0212 123 23 24
[Link]: kistihza@[Link]
"""
print(kartvizit)
input()
ya = input("Yanz: ")
print("Demek", ya, "yandasn.")
print("Gen mi yoksa yal m olduuna karar veremedim.")
input() fonksiyonunun ne kadar kullanl bir ara olduu ortada. Bu fonksiyon sayesinde,
imdiye kadar tek sesli bir ekilde yrttmz programclk faaliyetlerimizi ok sesli bir
hale getirebileceiz. Mesela nceki blmlerden birinde yazdmz, daire alan hesaplayan
program hatrlarsnz. O zaman henz dosyalarmz kaydetmeyi ve input() fonksiyonunu
renmediimiz iin o program etkileimli kabukta u ekilde yazmtk:
>>>
>>>
>>>
>>>
>>>
ap = 16
yarap = ap / 2
pi = 3.14159
alan = pi * (yarap * yarap)
alan
201.06176
Ama artk hem dosyalarmz kaydetmeyi biliyoruz, hem de input() fonksiyonunu rendik.
Dolaysyla yukardaki program u ekilde yazabiliriz:
#Kullancdan dairenin apn girmesini istiyoruz.
ap = input("Dairenin ap: ")
#Kullancnn verdii ap bilgisini kullanarak
#yarap hesaplayalm. Buradaki int() fonksiyonunu
#ilk kez gryoruz. Biraz sonra bunu aklayacaz
yarap = int(ap) / 2
#pi saymz sabit
pi = 3.14159
#Yukardaki bilgileri kullanarak artk
#dairenin alann hesaplayabiliriz
alan = pi * (yarap * yarap)
#Son olarak, hesapladmz alan yazdryoruz
print("ap", ap, "cm olan dairenin alan: ", alan, "cm2'dir")
Grdnz gibi, input() fonksiyonunu renmemiz sayesinde artk yava yava ie yarar
programlar yazabiliyoruz.
Ancak burada, daha nce renmediimiz bir fonksiyon dikkatinizi ekmi olmal. Bu
fonksiyonun ad int(). Bu yeni fonksiyon dnda, yukardaki btn kodlar anlayabilecek
kadar Python bilgisine sahibiz.
int() fonksiyonunun ne ie yaradn anlamak iin isterseniz ilgili satr yarap = ap / 2
eklinde yazarak altrmay deneyin bu program.
Dediim gibi, eer o satrdaki int() fonksiyonunu kaldrarak program altrdysanz una
benzer bir hata mesaj alm olmalsnz:
Traceback (most recent call last):
File "[Link]", line 8, in <module>
yarap = ap / 2
TypeError: unsupported operand type(s) for /: 'str' and 'int'
175
Grdnz gibi programmz blme ilemini yapamad. Buradan anlyoruz ki, bu int()
fonksiyonu programmzdaki aritmetik ilemin dzgn bir ekilde yaplabilmesini salyor.
Gelelim bu fonksiyonun bu ilevi nasl yerine getirdiini incelemeye.
Bu kodlar altrdmz zaman, programmz kullancdan bir say girmesini isteyecek, ancak
kullanc bir say girip Enter tuuna bastnda yle bir hata mesajyla karlaacaktr:
Traceback (most recent call last):
File "[Link]", line 5, in <module>
print("Girdiiniz saynn karesi: ", say ** 2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
Hata mesajna baktnzda, TypeError ifadesinden, bunun veri tipine ilikin bir hata
olduunu tahmin edebilirsiniz. Eer ngilizce biliyorsanz yukardaki hata mesajnn anlamn
rahatlkla karabilirsiniz. ngilizce bilmeseniz de en sondaki str ve int kelimeleri size
karakter dizisi ve say adl veri tiplerini hatrlatacaktr. Demek ki ortada veri tiplerini
ilgilendiren bir sorun var...
Peki burada tam olarak neler dnyor?
Hatrlayacaksnz, geen derslerden birinde len() fonksiyonunu anlatrken yle bir ey
sylemitik:
Biz henz kullancdan nasl veri alacamz bilmiyoruz. Ama imdilik unu
syleyebiliriz: Pythonda kullancdan herhangi bir veri aldmzda, bu veri bize
bir karakter dizisi olarak gelecektir.
Gelin isterseniz yukarda anlattmz durumu teyit eden bir program yazalm:
#Kullancdan herhangi bir veri girmesini istiyoruz
say = input("Herhangi bir veri girin: ")
#Kullancnn girdii verinin tipini bir
#deikene atyoruz
tip = type(say)
#Son olarak kullancnn girdii verinin tipini
#ekrana basyoruz.
print("Girdiiniz verinin tipi: ", tip)
176
Bu program altrdmzda ne tr bir veri girersek girelim, girdiimiz verinin tipi str, yani
karakter dizisi olacaktr. Demek ki gerekten de, kullancdan veri almak iin kullandmz
input() fonksiyonu bize her koulda bir karakter dizisi veriyormu.
Geen derslerde yle bir ey daha sylemitik:
Pythonda, o anda elinizde bulunan bir verinin hangi tipte olduunu bilmek son
derece nemlidir. nk bir verinin ait olduu tip, o veriyle neler yapp neler
yapamayacanz belirler.
u anda kar karya olduumuz durum da buna ok gzel bir rnektir. Eer o anda
elimizde bulunan verinin tipini bilmezsek tpk yukarda olduu gibi, o veriyi programmzda
kullanmaya alrken programmz hata verir ve ker.
Her zaman stne basa basa sylediimiz gibi, aritmetik ilemler yalnzca saylarla
yaplr. Karakter dizileri ile herhangi bir aritmetik ilem yaplamaz. Dolaysyla, input()
fonksiyonundan gelen veri bir karakter dizisi olduu iin ve biz de programmzda girilen
saynn karesini hesaplamak amacyla bu fonksiyondan gelen verinin 2. kuvvetini, yani
karesini hesaplamaya altmz iin programmz hata verecektir.
Yukardaki programda neler olup bittiini daha iyi anlayabilmek iin Pythonn etkileimli
kabuunda u ilemleri yapabiliriz:
>>> "23" ** 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
Grdnz gibi, programmzdan aldmz hata ile yukardaki hata tamamen ayn (hata
mesajlarnda bizi ilgilendiren ksm en son satrdr). Tpk burada olduu gibi, hata
veren programda da Ltfen bir say girin: sorusuna rnein 23 cevabn verdiimizde
programmz aslnda "23" ** 2 gibi bir ilem yapmaya alyor. Bir karakter dizisinin
kuvvetini hesaplamak mmkn olmad, kuvvet alma ilemi yalnzca saylarla yaplabilecei
iin de hata vermekten baka aresi kalmyor.
Ancak bazen yle durumlarla karlarsnz ki, programnz hibir hata vermez, ama elde
edilen sonu aslnda tamamen beklentinizin dndadr. Mesela u basit rnei inceleyelim:
say1 = input("Toplama ilemi iin ilk sayy girin: ")
say2 = input("Toplama ilemi iin ikinci sayy girin: ")
print(say1, "+", say2, "=", say1 + say2)
177
input() fonksiyonunun alttan alta neler evirdiini bu rnek yardmyla ok daha iyi
anladnz zannediyorum. Grdnz gibi yukardaki program herhangi bir hata vermedi.
Ama beklediimiz kty da vermedi. Zira biz programmzn iki sayy toplamasn istiyorduk.
O ise kullancnn girdii saylar yan yana yazmakla yetindi. Yani bir aritmetik ilem
yapmak yerine, verileri birbiriyle bititirdi. nk, dediim gibi, input() fonksiyonunun
kullancdan ald ey bir karakter dizisidir. Dolaysyla bu fonksiyon yukardaki gibi bir
durumla karlat zaman karakter dizileri arasnda bir birletirme ilemi gerekletirir. Tpk
ilk derslerimizde etkileimli kabukta verdiimiz u rnekte olduu gibi:
>>> "23" + "23"
2323
Bu son rnekten ayrca unu karyoruz: Yazdnz bir programn herhangi bir hata
vermemesi o programn doru alt anlamna gelmeyebilir. Dolaysyla bu tr durumlara
kar her zaman uyank olmanzda fayda var.
Peki yukardaki gibi durumlarla karlamamak iin ne yapacaz?
te bu noktada devreye tip dntrc adn verdiimiz birtakm fonksiyonlar girecek.
15.2.1 int()
Dediimiz gibi, input() fonksiyonundan gelen veri her zaman bir karakter dizisidir.
Dolaysyla bu fonksiyondan gelen veriyle herhangi bir aritmetik ilem yapabilmek iin
ncelikle bu veriyi bir sayya dntrmemiz gerekir. Bu dntrme ilemi iin int()
adl zel bir dntrc fonksiyondan yararlanacaz. Gelin isterseniz Pythonn etkileimli
kabuunda bu fonksiyonla bir ka deneme yaparak bu fonksiyonun ne ie yaradn ve nasl
kullanldn anlamaya alalm. Zira etkileimli kabuk bu tr deneme ilemleri iin biilmi
kaftandr:
178
Burada ncelikle 23 adl bir karakter dizisi tanmladk. Ardndan da int() fonksiyonunu
kullanarak bu karakter dizisini bir tamsayya (integer ) dntrdk.
sminden de
anlayacanz gibi int() fonksiyonu ngilizce integer (tamsay) kelimesinin ksaltmasdr ve
bu fonksiyonun grevi bir veriyi tamsayya dntrmektir.
Ancak burada dikkat etmemiz gereken bir ey var.
Herhangi bir verinin sayya
dntrlebilmesi iin o verinin say deerli bir veri olmas gerekir. rnein 23, say deerli
bir karakter dizisidir. Ama mesela elma say deerli bir karakter dizisi deildir. Bu yzden
elma karakter dizisi sayya dntrlemez:
>>> karakter_dizisi = "elma"
>>> say = int(karakter_dizisi)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'elma'
Grdnz gibi, say deerli olmayan bir veriyi sayya dntrmeye altrdmzda
Python bize bir hata mesaj gsteriyor. Yazdmz programlarda bu duruma zellikle dikkat
etmemiz gerekiyor.
imdi bu blmn banda yazdmz ve hata veren programmza dnelim yine:
say = input("Ltfen bir say girin: ")
print("Girdiiniz saynn karesi: ", say ** 2)
Bu kodlarn beklediimiz kty vermeyeceini biliyoruz. Ama eer bu kodlar yle yazarsak
iler deiir:
v1 = input("Toplama ilemi iin ilk sayy girin: ")
v2 = input("Toplama ilemi iin ikinci sayy girin: ")
179
15.2.2 str()
Pythondaki tip dntrcleri elbette sadece int() fonksiyonuyla snrl deildir.
Grdnz gibi, int() fonksiyonu say deerli verileri (mesela karakter dizilerini) tam
sayya dntryor. Bunun bir de tersi mmkndr. Yani karakter dizisi olmayan verileri
karakter dizisine dntrmemiz de mmkndr. Bu ilem iin str() adl baka bir tip
dntrcden yararlanyoruz:
>>> say = 23
>>> kardiz = str(say)
>>> print(kardiz)
23
>>> print(type(kardiz))
<class 'str'>
Grdnz gibi, bir tam say olan 23 str() adl bir fonksiyondan yararlanarak karakter
dizisi olan 23 ifadesine dntrdk. Son satrda da, elde ettiimiz eyin bir karakter dizisi
olduundan emin olmak iin type() fonksiyonunu kullanarak verinin tipini denetledik.
Yukardaki rneklerden grdmz gibi, aritmetik ilemler yapmak istediimizde karakter
dizilerini sayya evirmemiz gerekiyor. Peki acaba hangi durumlarda bunun tersini yapmamz,
yani saylar karakter dizilerine evirmemiz gerekir? Python bilginiz ve tecrbeniz arttka
bunlarn hangi durumlar olduunu kendiniz de greceksiniz. Mesela biz daha imdiden,
saylar karakter dizisine evirmemiz gereken bir durumla karlatk. Hatrlarsanz, len()
fonksiyonunu anlatrken, bu fonksiyonun saylarla birlikte kullanlamayacan sylemitik:
>>> len(12343423432)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
180
Bildiiniz gibi, len() fonksiyonu, u ana kadar rendiimiz veri tipleri iinde sadece karakter
dizileri zerinde ilem yapabiliyor. Biz de bu yzden, saymzn ka haneli olduunu
renebilmek iin, ncelikle bu sayy bir karakter dizisine eviriyoruz. Daha sonra da elde
ettiimiz bu karakter dizisini len() fonksiyonuna parametre olarak veriyoruz. Bylece saynn
ka haneli olduu bilgisini elde etmi oluyoruz.
Bu arada elbette yukardaki ilemi tek satrda da halledebilirsiniz:
>>> len(str(12343423432))
11
15.2.3 oat()
Hatrlarsanz ilk blmlerde saylardan sz ederken tamsaylarn (integer ) dnda kayan
noktal saylarn (oat ) da olduundan sz etmitik. te eer bir tamsayy veya say
deerli bir karakter dizisini kayan noktal sayya dntrmek istersek float() adl baka
bir dntrcden yararlanacaz:
>>> a = 23
>>> type(a)
<class 'int'>
>>> float(a)
23.0
Grdnz gibi, 23 tamsays, float() fonksiyonu sayesinde 23.0 a yani bir kayan noktal
sayya dnt.
Ayn eyi, say deerli karakter dizileri zerine uygulamak da mmkndr:
>>> b = "23"
>>> type(b)
<class 'str'>
>>> float(b)
23.0
15.2.4 complex()
Saylardan sz ederken, eer matematikle ok fazla ili dl deilseniz pek
karlamayacanz, karmak say adl bir say trnden de bahsetmitik. Karmak
saylar Pythonda complex ifadesiyle gsteriliyor. Mesela unun bir karmak say olduunu
biliyoruz:
181
>>> 12+0j
Kontrol edelim:
>>> type(12+0j)
<class 'complex'>
te eer herhangi bir sayy karmak sayya dntrmeniz gerekirse complex() adl bir
fonksiyondan yararlanabilirsiniz. rnein:
>>> complex(15)
(15+0j)
Bu say bir tamsaydr. ngilizce olarak ifade etmek gerekirse, integer. Bunun bir tamsay
olduunu u ekilde teyit edebileceimizi gayet iyi biliyorsunuz:
>>> type(a)
<class 'int'>
Burada aldmz <class int> kts, bize a deikeninin tuttuu saynn bir tamsay olduunu
sylyor. int ifadesi, integer (tamsay) kelimesinin ksaltmasdr.
Bir de u sayya bakalm:
>>> b = 34.5
>>> type(b)
<class 'float'>
Bu kt ise bize 34.5 saysnn bir kayan noktal say olduunu sylyor. oat kelimesi Floats
veya Floating Point Number ifadesinin ksaltmasdr. Yani kayan noktal say demektir.
Bu arada, bu type() adl fonksiyonu sadece saylara deil,
uygulayabileceimizi biliyorsunuz. Mesela bir rnek vermek gerekirse:
baka eylere de
Grdnz gibi, type() fonksiyonu bize meyve adl deikenin deerinin bir str yani string
yani karakter dizisi olduunu bildirdi.
Bu veri tipleri arasnda, baz zel fonksiyonlar kullanarak dntrme ilemi yapabileceimizi
rendik. Mesela:
>>> say = 45
say adl deikenin tuttuu verinin deeri bir tamsaydr. Biz bu tamsayy kayan noktal
sayya dntrmek istiyoruz. Yapacamz ilem ok basit:
182
>>> float(say)
45.0
Grdnz gibi, 45 adl tamsayy, 45.0 adl bir kayan noktal sayya dntrdk. imdi
type(45.0) komutu bize <class oat> ktsn verecektir.
Eer kayan noktal bir sayy tamsayya evirmek istersek u komutu veriyoruz. Mesela kayan
noktal saymz, 56.5 olsun:
>>> int(56.5)
56
Yukardaki deeri trnak iinde belirttiimiz iin bu deer bir karakter dizisidir. imdi bunu bir
tamsayya evireceiz:
>>> int(nesne)
45
Hatta bir sayy karakter dizisine de evirebiliriz. Bunun iin string (karakter dizisi) kelimesinin
ksaltmas olan str ifadesini kullanacaz:
>>> s = 6547
>>> str(s)
'6547'
Yalnz unu unutmayn: Bir karakter dizisinin sayya dntrlebilmesi iin o karakter
dizisinin say deerli olmas lazm. Yani 45 deerini sayya dntrebiliriz. nk 45
deeri, trnaklardan tr bir karakter dizisi de olsa, neticede say deerli bir karakter
dizisidir. Ama mesela elma karakter dizisi byle deildir. Dolaysyla, yle bir maceraya
girimek bizi hsrana uratacaktr:
15.2. Tip Dnmleri
183
Grdnz gibi, Python byle bir ilem denemesi karsnda hata veriyor...
Bu blmde pek ok yeni ey rendik. Bu blmn en nemli getirisi input() fonksiyonunu
renmemiz oldu. Bu fonksiyon sayesinde kullancyla iletiim kurmay baardk. Artk
kullancdan veri alp, bu verileri programlarmz iinde ileyebiliyoruz.
Yine bu blmde dikkatinizi ektiimiz baka bir konu da saylar ve karakter dizileri arasndaki
ilikiydi. input() fonksiyonuyla elde edilen ktnn bir karakter dizisi olduunu rendik.
Bildiimiz gibi, aritmetik ilemler ancak saylar arasnda yaplabilir. Dolaysyla input()
fonksiyonuyla gelen karakter dizisini bir sayyla arpmaya kalkarsak hata alyoruz. Burada
yapmamz gereken ey, elimizdeki verileri dntrmek. Yani input() fonksiyonundan gelen
karakter dizisini bir sayyla arpmak istiyorsak, ncelikle aldmz karakter dizisini sayya
dntrmemiz gerekiyor. Dntrme ilemleri iin kullandmz fonksiyonlar unlard:
int() Say deerli bir karakter dizisini veya kayan noktal sayy tamsayya
(integer ) evirir.
float() Say deerli bir karakter dizisini veya tamsayy kayan noktal sayya
(oat ) evirir.
str() Bir tamsay veya kayan noktal sayy karakter dizisine (string ) evirir.
complex() Herhangi bir sayy veya say deerli karakter dizisini karmak sayya
(complex ) evirir.
Ayrca bu blmde rendiklerimiz, yle nemli bir tespitte bulunmamza da olanak tand:
Her tamsay ve/veya kayan noktal say bir karakter dizisine dntrlebilir. Ama
her karakter dizisi tamsayya ve/veya kayan noktal sayya dntrlemez.
rnein, 5654 gibi bir tamsayy veya 543.34 gibi bir kayan noktal sayy str() fonksiyonu
yardmyla karakter dizisine dntrebiliriz:
>>> str(5654)
>>> str(543.34)
5654 veya 543.34 gibi bir karakter dizisini int() veya float() fonksiyonu yardmyla
tamsayya ya da kayan noktal sayya da dntrebiliriz:
>>> int("5654")
>>> int("543.34")
>>> float("5654")
>>> float("543.34")
Ama elma gibi bir karakter dizisini ne int() ne de float() fonksiyonuyla tamsayya veya
kayan noktal sayya dntrebiliriz! nk elma verisi say deerli deildir.
Bu blm kapatmadan nce, dilerseniz imdiye kadar rendiklerimizi de ieren rnek bir
program yazalm. Bu program, Python maceramz asndan bize yeni kaplar da aacak.
184
Burada yine bilmediimiz bir fonksiyonla daha karlatk. Bu fonksiyonun ad eval(). Biraz
sonra eval() fonksiyonunu derinlemesine inceleyeceiz. Ama bu fonksiyonu anlatmaya
gemeden nce dilerseniz yukardaki kodlar biraz didikleyelim.
lk satrlarn ne ie yaradn zaten biliyorsunuz. Bir yl iindeki btn aylarn ka gn ektiini
gsteren deikenlerimizi tanmladk. Burada her bir deikeni tek tek tanmlamak yerine
deikenleri topluca tanmladmza dikkat edin. steseydik tabii ki yukardaki kodlar yle
de yazabilirdik:
#Her bir ayn ka gn ektiini tanmlyoruz
ocak
= 31
ubat
= 28
mart
= 31
nisan
= 30
mays
= 31
haziran = 30
temmuz = 31
austos = 31
eyll
= 30
ekim
= 31
kasm
= 30
aralk = 31
#Doalgazn vergiler dahil m3 fiyat
birimFiyat = 0.79
185
Ama tabii ki, deikenleri tek tek tanmlamak yerine topluca tanmlamak, daha az kod
yazmanz salamasnn yansra, programnzn alma performans asndan da daha iyidir.
Yani deikenleri bu ekilde tanmladnzda programnz daha hzl alr.
Programmz incelemeye devam edelim...
Deikenleri tanmladktan sonra doalgazn vergiler dahil yaklak birim yatn da bir
deiken olarak tanmladk. 0.79 deerini zaten birka blm nce hesaplayp bulduumuz
iin, ayn ilemleri tekrar programmza eklememize gerek yok. Dorudan nihai deeri
programmza yazsak yeter...
Birim yat belirledikten sonra kullancya aylk doalgaz saryatn soruyoruz. Kullancnn bu
deeri m3 olarak girmesini bekliyoruz. Elbette bu veriyi kullancdan alabilmek iin input()
fonksiyonunu kullanyoruz.
Daha sonra kullancya hangi aya ait doalgaz faturasn demek istediini soruyoruz. Bu
bilgi, bir sonraki satrda gnlk doalgaz saryatn hesaplarken iimize yarayacak. nk
kullancnn girdii ayn ektii gn saysna bal olarak gnlk saryat deiecektir. Gnlk
saryat hesaplamak iin aylk saryat, ilgili ayn ektii gn saysna blyoruz. Bu arada
bir nceki satrda dnem deikenini eval() adl bir fonksiyonla birlikte kullandmz
gryorsunuz. Bunu biraz sonra inceleyeceiz. O yzden bu satrlar atlayp son satra
gelelim.
Son satrda print() fonksiyonunu kullanarak, kullancdan aldmz verileri dzgn bir
ekilde kendisine gsteriyoruz. Programmz kullancya gnlk doalgaz saryatn ve
ay sonunda karlaaca tahmini fatura tutarn bildiriyor. print() fonksiyonu iinde
kullandmz ka dizilerine zellikle dikkatinizi ekmek istiyorum. Burada dzgn bir kt
elde etmek iin \t ve \n adl ka dizilerinden nasl yararlandmz gryorsunuz. Bu ka
dizilerinin buradaki ilevini tam olarak anlayabilmek iin, bu kodlar bir de bu ka dizileri
olmadan yazmay deneyebilirsiniz.
Bu bilgileri, nemlerinden tr aklmzda tutmaya alalm. Buraya kadar anlatlan konular
hakknda zihnimizde belirsizlikler varsa veya baz noktalar tam olarak kavrayamadysak,
imdiye kadar rendiimiz konular tekrar gzden geirmemiz bizim iin epey faydal
olacaktr. Zira bundan sonraki blmlerde, yeni bilgilerin yansra, buraya kadar rendiimiz
eyleri de youn bir ekilde pratie dkeceiz. Bundan sonraki konular takip edebilmemiz
186
asndan, buraya kadar verdiimiz temel bilgileri iyice sindirmi olmak iimizi bir hayli
kolaylatracaktr.
toplama
karma
arpma
blme
ngilizcede evaluate diye bir kelime bulunur. Bu kelime, deerlendirmeye tabi tutmak, ileme
sokmak, ilemek gibi anlamlar tar. te eval() fonksiyonundaki eval kelimesi bu evaluate
kelimesinin ksaltmasdr. Yani bu fonksiyonun grevi, kendisine verilen karakter dizilerini
deerlendirmeye tabi tutmak ya da ilemektir. Peki bu tam olarak ne anlama geliyor?
Aslnda yukardaki rnek program altrdmzda bu sorunun yantn kendi kendimize
verebiliyoruz. Bu program altrarak, leminiz: ifadesinden sonra, rnein, 45 * 76
yazp Enter tuuna basarsak programmz bize 3420 kts verecektir. Yani programmz
hesap makinesi ilevini yerine getirip 45 says ile 76 saysn arpacaktr. Dolaysyla,
yukardaki program kullanarak her trl aritmetik ilemi yapabilirsiniz. Hatta bu program,
son derece karmak aritmetik ilemlerin yaplmasna dahi msaade eder.
Peki programmz bu ilevi nasl yerine getiriyor?
geelim.
187
Daha sonra kullancdan alacamz komutlar veri adl bir deikene atadk. Tabii ki
kullancyla iletiimi her zaman olduu gibi input() fonksiyonu yardmyla salyoruz.
Ardndan, kullancdan gelen veriyi eval() fonksiyonu yardmyla deerlendirmeye tabi
tutuyoruz. Yani kullancnn girdii komutlar ileme sokuyoruz. rnein, kullanc 46 / 2
gibi bir veri girdiyse, biz eval() fonksiyonu yardmyla bu 46 / 2 komutunu iletiyoruz. Bu
ilemin sonucunu da hesap adl baka bir deiken iinde depoluyoruz.
Eer burada eval() fonksiyonunu kullanmazsak, programmz, kullancnn girdii 45 * 76
komutunu hibir ileme sokmadan dmdz ekrana basacaktr. Yani:
print("""
Basit bir hesap makinesi uygulamas.
leler:
+
*
/
toplama
karma
arpma
blme
Not: Buradaki None deerini grmezden gelin. Bunu fonksiyonlar konusunu anlatrken
inceleyeceiz.
Grdnz gibi, yazdmz program, kullancnn girdii Python komutunun iletilmesine
sebep oldu. Bu noktada, Eee, ne olmu! demi olabilirsiniz. Gelin bir de una bakalm. imdi
program tekrar altrp u cevab verin:
188
open("[Link]", "w")
Bu cevap, bilgisayarnzda [Link] adl bir dosya oluturulmasna sebep oldu. Belki
farkndasnz, belki farknda deilsiniz, ama aslnda u anda kendi yazdnz program
sizin kontrolnzden tamamen kt. Siz aslnda bir hesap makinesi program yazmtnz.
Ama eval() fonksiyonu nedeniyle kullancya rastgele Python komutlarn altrma imkan
verdiiniz iin programnz sadece aritmetik ilemleri hesaplamak iin kullanlmayabilir. Byle
bir durumda kt niyetli (ve bilgili) bir kullanc size ok byk zarar verebilir. Mesela
kullancnn, yukardaki programa yle bir cevap verdiini dnn:
__import__("os").system("dir")
Burada anlamadnz eyleri imdilik bir kenara brakp, bu komutun sonularna odaklann.
Grdnz gibi, yukardaki programa bu cevab vererek mevcut dizin altndaki btn
dosyalar listeleyebildik. Yani programmz bir anda amacn at. Artk bu aamadan sonra
bu program eytani bir amaca ynelik olarak kullanmak tamamen program kullanan kiiye
kalm... Bu programn, bir web sunucusu zerinde alan bir uygulama olduunu ve
bu program kullananlarn yukardaki gibi masumane bir ekilde dizin iindeki dosyalar
listeleyen bir komut yerine, dizin iindeki dosyalar ve hatta sabit disk zerindeki her eyi
silen bir komut yazdn dnn... Yanl yazlm bir program yznden btn verilerinizi
kaybetmeniz iten bile deildir. (Bahsettiim o, btn sabit diski silen komutu kendi
sisteminizde vermemeniz gerektiini sylememe gerek yok, deil mi?)
Eer SQL Injection kavramn biliyorsanz, yukardaki kodlarn yol at gvenlik an gayet
iyi anlam olmalsnz. Zaten internet zerinde yaygn bir ekilde kullanlan ve web sitelerini
hedef alan SQL Injection tarz saldrlar da ayn mantk zerinden gerekletiriliyor. SQL
Injection metoduyla bir web sitesine saldran cracker lar, o web sitesini programlayan kiinin
(ounlukla farknda olmadan) kullancya verdii rastgele SQL komutu iletme yetkisini
ktye kullanarak gizli ve zel bilgileri ele geirebiliyorlar. rnein SQL Injection metodu
kullanlarak, bir web sitesine ait veritabannn ierii tamamen silinebilir. Ayn ekilde,
yukardaki eval() fonksiyonu da kullanclarnza rastgele Python komutlarn altrma
yetkisi verdii iin kt niyetli bir kullancnn programnza szmasna yol aabilecek
potansiyele sahiptir.
Peki eval() fonksiyonunu asla kullanmayacak myz? Elbette kullanacaz. Bu fonksiyonun
kullanmn gerektiren durumlarla da karlaabilirsiniz. Ama unu asla aklnzdan karmayn:
eval() fonksiyonu her ne kadar son derece yetenekli ve gl bir ara da olsa yanl ellerde
ykc sonular dourabilir. Program yazarken, eer eval() kullanmanz gerektiren bir
durumla kar karya olduunuzu dnyorsanz, bir kez daha dnn. eval() ile elde
edeceiniz etkiyi muhtemelen baka ve ok daha iyi yntemlerle de elde edebilirsiniz. stelik
performans asndan eval() pek iyi bir tercih deildir, nk bu fonksiyon (ou durumda
farketmeseniz de) aslnda yava alr. O yzden, eval() fonksiyonunu kullanacanz zaman,
bunun art ve eksilerini ok iyi tartn: Bu fonksiyonu kullanmak size ne kazandryor, ne
kaybettiriyor?
Ayrca eval() fonksiyonu kullanlaca zaman, kullancdan gelen veri bu fonksiyona
parametre olarak verilmeden nce sk bir kontrolden geirilir. Yani kullancnn girdii veri
eval() araclyla dorudan deerlendirmeye tabi tutulmaz. Araya bir kontrol mekanizmas
yerletirilir. rnein, yukardaki hesap makinesi programnda kullancnn girecei verileri
sadece saylar ve ilelerle snrlandrabilirsiniz. Yani kullancnzn, izin verilen deerler harici
bir deer girmesini engelleyebilirsiniz. Bu durumu somutlatrmak iin yle bir diyagram
izebiliriz:
189
Burada ise, veri eval() fonksiyonuna ulamadan nce kontrolden geiriliyor. Eer veri
ancak kontrol aamasndan geerse eval() fonksiyona ulaabilecek ve oradan da kt olarak
verilebilecektir. Bylece kullancdan gelen komutlar szme imkanna sahip oluyoruz.
Grdnz gibi, Python eval() gibi bir fonksiyon yardmyla karakter dizileri iinde
geen Python kodlarn ayklayp bunlar altrabiliyor. Bu sayede, mesela bize input()
fonksiyonu araclyla gelen bir karakter dizisi iindeki Python kodlarn iletme imkanna
sahip olabiliyoruz. Bu zellik, dikkatli kullanldnda, ilerinizi epey kolaylatrabilir.
Pythonda eval() fonksiyonuna ok benzeyen exec() adl baka bir fonksiyon daha bulunur.
eval() ile yapamadmz baz eyleri exec() ile yapabiliriz. Bu fonksiyon yardmyla, karakter
dizileri iindeki ok kapsaml Python kodlarn iletebilirsiniz.
rnein eval() fonksiyonu bir karakter dizisi iindeki deiken tanmlama ilemini yerine
getiremez. Yani eval() ile yle bir ey yapamazsnz:
>>> eval("a = 45")
190
d1 = """
Python'da ekrana kt verebilmek iin print() adl bir
fonksiyondan yararlanyoruz. Bu fonksiyonu yle kullanabilirsiniz:
>>> print("Merhaba Dnya")
imdi de ayn kodu siz yazn!
>>> """
girdi = input(d1)
exec(girdi)
d2 = """
Grdnz gibi print() fonksiyonu, kendisine
parametre olarak verilen deerleri ekrana basyor.
Bylece ilk dersimizi tamamlam olduk. imdi bir
sonraki dersimize geebiliriz."""
print(d2)
Burada exec() ile yaptmz ii eval() ile de yapabiliriz. Ama mesela eer bir sonraki
derste Pythonda deikenler konusunu retecekseniz, eval() yerine exec() fonksiyonunu
kullanmak durumunda kalabilirsiniz.
eval() fonksiyonunu anlatrken gvenlik ile ilgili olarak sylediimiz her ey exec()
fonksiyonu iin de geerlidir. Dolaysyla bu iki fonksiyonu ok dikkatli bir ekilde kullanmanz
ve bu fonksiyonlarn dourduu gvenlik ann bilincinde olmanz gerekiyor.
Henz Python bilgilerimiz ok kstl olduu iin eval() ve exec() fonksiyonlarn btn
ayrntlaryla inceleyemiyoruz. Ama bilgimiz arttka bu fonksiyonlarn ne kadar gl (ve
tehlikeli) aralar olduunu siz de greceksiniz.
191
Burada belli ki adres ubuuna [Link] diye bir URL yazmz, ama byle bir internet adresi
olmad iin, kullandmz internet taraycs bize yle bir mesaj vermi:
Hata! Google Chrome [Link] sitesini bulamad
Grdnz gibi, hata mesajlarnda deien tek yer, aradmz sitenin adresi. Yani internet
taraycmz bu hata iin yle bir taslaa sahip:
Hata! Google Chrome ... sitesini bulamad
Burada ... ile gsterdiimiz yere, bulunamayan URL yerletiriliyor. Peki byle bir eyi Python
programlama dili ile nasl yapabiliriz?
ok basit:
#ncelikle kullancdan bir internet adresi girmesini istiyoruz
url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")
#imdi de bu adresin bulunamad konusunda kullancy bilgilendiriyoruz
print("Hata! Google Chrome", url, "sitesini bulamad")
Grdnz gibi, imdiye kadar rendiimiz bilgileri kullanarak byle bir program rahatlkla
yazabiliyoruz.
Peki ya biz kullancnn girdii internet adresini mesela trnak iinde gstermek istersek ne
olacak? Yani rnein yle bir kt vermek istersek:
Hata! Google Chrome '[Link]' sitesini bulamad
Burada, + iaretlerini kullanarak, kullancnn girdii adresin sana ve soluna birer trnak
iaretini nasl yerletirdiimize dikkat edin.
Grdnz gibi bu yntem ie yaryor, ama ortaya kan karakter dizisi de olduka karmak
grnyor. te bu tr karakter dizisi biimlendirme ilemleri iin Python bize ok faydal bir
ara sunuyor. Bu aracn ad format().
Bu arac yle kullanyoruz:
#ncelikle kullancdan bir internet adresi girmesini istiyoruz
url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")
#imdi de bu adresin bulunamad konusunda kullancy bilgilendiriyoruz
print("Hata! Google Chrome {} sitesini bulamad".format(url))
Burada taslak metni dorudan format() metoduna parametre olarak vermeden nce bir
deikene atadk. Bylece bu metni daha kolay bir ekilde kullanabildik.
Bu rneklerin, format() denen arac anlamak konusunda size epey kir verdiini
zannediyorum. Ama isterseniz bu aracn ne olduunu ve nasl altn daha ayrntl olarak
incelemeye gemeden nce baka bir rnek daha verelim.
Varsayalm ki kullancdan ald bilgiler dorultusunda, zel bir konu zerine dileke
oluturan bir program yazmak istiyorsunuz.
Dileke taslamz u ekilde olsun:
tarih:
T.C.
... NVERSTES
... Fakltesi Dekanlna
193
Amacnz bu dilekedeki boluklara gelmesi gereken bilgileri kullancdan alp, eksiksiz bir
dileke ortaya karmak.
Kullancdan bilgi alma ksm kolay. input() fonksiyonunu kullanarak gerekli bilgileri
kullancdan alabileceimizi biliyorsunuz:
tarih
niversite
faklte
blm
renci_no
retim_yl
yaryl
ad
soyad
tc_kimlik_no
adres
tel
ekler
=
=
=
=
=
=
=
=
=
=
=
=
=
input("tarih: ")
input("niversite ad: ")
input("faklte ad: ")
input("blm ad: ")
input("renci no. :")
input("retim yl: ")
input("yaryl: ")
input("rencinin ad: ")
input("rencinin soyad: ")
input("TC Kimlik no. :")
input("adres: ")
input("telefon: ")
input("ekler: ")
Bilgileri kullancdan aldk. Peki ama bu bilgileri dileke tasla iindeki boluklara nasl
yerletireceiz?
u ana kadar rendiimiz print() fonksiyonunu ve \t ve \n gibi ka dizilerini kullanarak
istediiniz kty elde etmeyi deneyebilirsiniz. Ama denediinizde siz de greceksiniz ki,
bu tr yntemleri kullanarak yukardaki dileke taslan doldurmak inanlmaz zor ve vakit
alc olacaktr. Halbuki bunlarn hibirine gerek yok. nk Python bize bu tr durumlarda
kullanlmak zere ok pratik bir ara sunuyor. imdi ok dikkatlice inceleyin u kodlar:
dileke = """
tarih: {}
T.C.
{} NVERSTES
{} Fakltesi Dekanlna
Faklteniz {} Blm {} numaral rencisiyim. Ekte sunduum belgede
belirtilen mazeretim gereince {} Eitim-retim Yl {}.
yarylnda renime ara izni (kayt dondurma) istiyorum.
Bilgilerinizi ve gereini arz ederim.
194
mza
Ad
: {}
Soyad
: {}
T.C. Kimlik No. : {}
Adres
: {}
Tel.
: {}
Ekler
: {}
"""
tarih
niversite
faklte
blm
renci_no
retim_yl
yaryl
ad
soyad
tc_kimlik_no
adres
tel
ekler
=
=
=
=
=
=
=
=
=
=
=
=
=
input("tarih: ")
input("niversite ad: ")
input("faklte ad: ")
input("blm ad: ")
input("renci no. :")
input("retim yl: ")
input("yaryl: ")
input("rencinin ad: ")
input("rencinin soyad: ")
input("TC Kimlik no. :")
input("adres: ")
input("telefon: ")
input("ekler: ")
195
Grdnz gibi, {} iareti karakter dizisi iinde URLnin gelecei yeri tutuyor. Bu {} iaretinin
yerine neyin geleceini format() metodunun parantezleri iinde belirtiyoruz. Dikkatlice
bakn:
print("Hata! Google Chrome {} sitesini bulamad".format(url))
Burada hata metnini ieren karakter dizisini dorudan format() metoduna balamak yerine,
bunu bir deikene atayp, format() metodunu bu deikene baladk.
Bunun dnda u rnekleri de vermitik:
>>> metin = "{} ve {} iyi bir ikilidir"
>>> [Link]("Python", "Django")
'Python ve Django iyi bir ikilidir
>>> metin = "{} {}'yi seviyor!"
>>> [Link]("Ali", "Aye")
'Ali Aye'yi seviyor!'
>>> metin = "{} {} yanda bir {}dur"
>>> [Link]("Ahmet", "18", "futbolcu")
'Ahmet 18 yanda bir futbolcudur'
Burada da, grdz gibi, ncelikle bir karakter dizisi tanmlyoruz. Bu karakter dizisi
iindeki deiken deerleri ise {} iaretleri ile gsteriyoruz. Daha sonra format() metodunu
alp bu karakter dizisine balyoruz. Karakter dizisi iindeki {} iaretleri ile gsterdiimiz
yerlere gelecek deerleri de format() metodunun parantezleri iinde gsteriyoruz. Yalnz
burada una dikkat etmemiz lazm: Karakter dizisi iinde ka tane {} iareti varsa, format()
metodunun parantezleri iinde de o sayda deer olmas gerekiyor.
Bu yapnn, yazdmz programlarda iimizi ne kadar kolaylatracan tahmin edebilirsiniz.
Ksa karakter dizilerinde pek belli olmayabilir, ama zellikle ok uzun ve boluklu karakter
dizilerini biimlendirirken format() metodunun hayat kurtardna kendiniz de ahit
olacaksnz.
lerleyen derslerimizde format() metodunu ve karakter dizisi biimlendirme konusunu ok
daha ayrntl bir ekilde inceleyeceiz. Ancak yukarda verdiimiz bilgiler format() metodunu
verimli bir ekilde kullanabilmenizi salamaya yetecek dzeydedir.
196
BLM 16
Koullu Durumlar
Artk Python programlama dilinde belli bir noktaya geldik saylr. Ama eer farkettiyseniz,
yine de elimizi kolumuzu balayan, istediimiz eyleri yapmamza engel olan bir eyler var.
te bu blmde, Python programlama dilinde hareket alanmz bir hayli geniletecek aralar
tanyacaz.
Aslnda sadece bu blmde deil, bu blm takip eden her blmde, hareket alanmz
kstlayan duvarlar tek tek yktmza ahit olacaksnz. zellikle bu blmde inceleyeceimiz
koullu durumlar konusu, tabir yerindeyse, Pythonda boyut atlamamz salayacak.
O halde hi vakit kaybetmeden yola koyulalm...
imdiye kadar rendiimiz Python bilgilerini kullanarak yle bir program yazabileceimizi
biliyorsunuz:
ya = 15
print("""Programa hogeldiniz!
Programmz kullanabilmek iin en az
13 yanda olmalsnz.""")
print("Yanz: ", ya)
Burada yaptmz ey ok basit. ncelikle, deeri 15 olan, ya adl bir deiken tanmladk.
Daha sonra, programmz altran kullanclar iin bir hogeldin mesaj hazrladk. Son
olarak da ya deikeninin deerini ekrana yazdrdk.
Bu programn zellii tek sesli bir uygulama olmasdr. Yani bu programda kullancyla
herhangi bir etkileim yok. Burada btn deerleri/deikenleri programc olarak kendimiz
belirliyoruz. Bu programn ne kadar yavan olduunu herhalde sylemeye gerek yok.
Ancak yine nceki derslerde rendiimiz input() fonksiyonu yardmyla yukardaki
programn zerindeki yavanl bir nebze de olsa atabilir, bu program rahatlkla ok sesli
bir hale getirebilir, yani kullancyla etkileim iine girebiliriz.
Yukardaki tek sesli uygulamay, input() fonksiyonunu kullanarak ok sesli bir hale nasl
getireceimizi gayet iyi bildiinize eminim:
print("""Programa hogeldiniz!
Programmz kullanabilmek iin en az
13 yanda olmalsnz.""")
197
Tpk bir nceki uygulamada olduu gibi, burada da yaptmz ey ok basit. lk rnekte
ya deikeninin deerini kendimiz elle yazmtk. kinci rnekte ise bu ya deikenini
kullancdan alyoruz ve tpk ilk rnekte olduu gibi, bu deikenin deerini ekrana
yazdryoruz.
Bu arada, yukardaki uygulamada yer verdiimiz \n ve \t adl ka dizileri de artk sizin
iin olduka tandk. \n ka dizisi yardmyla bir alt satra getiimizi, \t adl ka dizisi
yardmyla da bir sekmelik boluk braktmz biliyorsunuz.
Grdnz gibi, u ana kadar rendiklerimizle ancak kullancdan gelen ya bilgisini
ekrana yazdrabiliyoruz. rendiimiz input() fonksiyonu bize kullancdan bilgi alma imkan
salyor. Ama kullancdan gelen bu bilgiyi imdilik ancak olduu gibi kullanabiliyoruz. Yani
mesela yukardaki rnei dikkate alarak konuacak olursak, kullancnn ya eer 13n
zerindeyse onu programa kabul edecek, yok eer 13 yan altndaysa da programdan
atacak bir mekanizma retemiyoruz. Yapabildiimiz tek ey, kullancnn girdii veriyi ekrana
yazdrmak.
Yukarda verdiimiz rneklerle nereye varmaya altmz az ok tahmin etmisinizdir.
Dikkat ederseniz yukarda szn ettiimiz ey koullu bir durum. Yani aslnda yapmak
istediimiz ey, kullancnn yan denetleyip, onun programa kabul edilmesini 13 yandan
byk olma kouluna balamak.
sterseniz tam olarak neden bahsettiimizi anlayabilmek iin, birka vaka rnei verelim.
Diyelim ki Googlen Gmail hizmeti araclyla bir [Link] hesab aldnz. Bu hesaba gireceiniz
zaman Gmail size bir kullanc ad ve parola sorar. Siz de kendinize ait kullanc adn ve
parolay sayfadaki kutucuklara yazarsnz. Eer yazdnz kullanc ad ve parola doruysa
hesabnza eriebilirsiniz. Ama eer kullanc adnz ve parolanz doru deilse hesabnza
eriemezsiniz. Yani [Link] hesabnza erimeniz, kullanc ad ve parolay doru girme
kouluna baldr.
Ya da u vaka rneini dnelim: Diyelim ki Pardusta komut satr araclyla gncelleme
ilemi yapacaksnz. sudo pisi up komutunu verdiiniz zaman gncellemelerin listesi size
bildirilecek, bu gncellemeleri yapmak isteyip istemediiniz sorulacaktr. Eer evet cevab
verirseniz gncelleme ilemi balar. Ama eer hayr cevab verirseniz gncelleme ilemi
balamaz. Yani gncelleme ileminin balamas kullancnn evet cevab vermesi kouluna
baldr.
te bu blmde biz bu tr koullu durumlardan sz edeceiz.
198
16.1.1 if
Python programlama dilinde koullu durumlar belirtmek iin adet deyimden
yararlanyoruz:
if
elif
else
sterseniz nce if deyimi ile balayalm...
Eer daha nceden herhangi bir programlama dilini az da olsa kurcalama frsatnz olduysa,
bir programlama dilinde if deyimlerinin ne ie yaradn az ok biliyorsunuzdur. Daha
nceden hi programclk deneyiminiz olmamsa da ziyan yok. Zira bu blmde if
deyimlerinin ne ie yaradn ve nerelerde kullanldn enine boyuna tartacaz.
ngilizce bir kelime olan if , Trkede eer anlamna gelir. Anlamndan da karabileceimiz
gibi, bu kelime bir koul bildiriyor. Yani eer bir ey falanca ise... ya da eer bir ey lanca
ise... gibi... te biz Pythonda bir koula balamak istediimiz durumlar if deyimi araclyla
gstereceiz.
Gelin isterseniz bu deyimi nasl kullanacamza dair ufack bir rnek vererek ie balayalm:
ncelikle elimizde yle bir deiken olsun:
n = 255
Yukarda verdiimiz deikenin deerinin bir karakter dizisi deil, aksine bir say olduunu
gryoruz. imdi bu deikenin deerini sorgulayalm:
if n > 10:
Anlam
byktr
kktr
byk eittir
kk eittir
eittir
eit deildir
Grdnz gibi hibiri bize yabanc gelecek gibi deil. Yalnzca en sondaki eittir (== ) ve
eit deildir (!= ) iaretleri biraz deiik gelmi olabilir. Burada eittir iaretinin = olmadna
dikkat edin. Pythonda = iaretini deer atama ilemleri iin kullanyoruz. == iaretini ise iki
adet deerin birbirine eit olup olmadn denetlemek iin... Mesela:
>>> a = 26
Burada deeri 26 olan a adl bir deiken belirledik. Yani a deikenine deer olarak 26
saysn atadk. Ayrca burada, deer atama ileminin ardndan Enter tuuna bastktan sonra
Python hibir ey yapmadan bir alt satra geti. Bir de una bakalm:
16.1. Koul Deyimleri
199
>>> a == 26
True
Burada ok nemli bir durumla kar karyayz. Dikkat ederseniz, ikinci satr ilk satra
gre girintili yazdk. Elbette bunu irinlik olsun diye yapmadk. Python programlama
dilinde girintiler ok byk nem tar. Hatta ne kadarlk bir girinti verdiiniz bile
nemlidir. Eer Python kodlarna duyarl bir metin dzenleyici kullanyorsanz, kullandnz
metin dzenleyici ou durumda sizin yerinize uygun bir ekilde girintilemeyi yapacaktr.
Mesela IDLE adl gelitirme ortamn kullananlar, ilk satrdaki : iaretini koyup Enter
tuuna bastklarnda otomatik olarak girinti verildiini farkedeceklerdir. Eer kullandnz
metin dzenleyici, satrlar otomatik olarak girintilemiyorsa sizin bu girintileme ilemini
elle yapmanz gerekecektir. Yalnz elle girintilerken, ne kadar girinti vereceimize dikkat
etmeliyiz. Genel kural olarak 4 bolukluk bir girintileme uygun olacaktr. Girintileme
ilemini klavyedeki sekme (Tab ) tuuna basarak da yapabilirsiniz. Ama ayn program iinde
sekmelerle boluklar kartrmayn. Yani eer girintileme ilemini klavyedeki boluk (Space )
tuuna basarak yapyorsanz, program boyunca ayn ekilde yapn. (Ben size girinti verirken
Tab tuu yerine Space tuunu kullanmanz tavsiye ederim). Ksaca sylemek gerekirse;
Pythonda girintileme ve girintilemede tutarllk ok nemlidir. zellikle byk programlarda,
girintilemeler asndan tutarszlk gsterilmesi programn almamasna sebep olabilir.
Not:
Pythonda girintileme konusuyla ilgili daha
[Link]
ayrntl
bilgi
iin:
Eer yukardaki if blounu bir metin dzenleyici iine deil de dorudan etkileimli kabua
yazmsanz baz eyler dikkatinizi ekmi olmal. Etkileimli kabukta if say > 10: satrn
yazp Enter tuuna bastnzda yle bir grntyle karlam olmalsnz:
>>> if n > 10:
...
200
Dikkat ederseniz, >>> iareti, ... iaretine dnt. Eer bu noktada herhangi bir ey
yazmadan Enter tuuna basacak olursanz Python size yle bir hata mesaj verecektir:
File "<stdin>", line 2
^
IndentationError: expected an indented block
Hata mesajnda da sylendii gibi, Python bizden girintilenmi bir blok beklerken, biz onun bu
beklentisini karlamamz. Dolaysyla bize yukardaki hata mesajn gstermi. ... iaretini
grdkten sonra yapmamz gereken ey, drt kez boluk (Space ) tuuna basarak girinti
oluturmak ve if blounun devamn yazmak olmalyd. Yani yle:
>>> if n > 10:
...
print("say 10'dan byktr!")
...
Grdnz gibi, print() fonksiyonunu yazp Enter tuuna bastktan sonra yine ... iaretini
grdk. Python burada bizden yeni bir satr daha bekliyor. Ama bizim yazacak baka bir
kodumuz olmad iin tekrar Enter tuuna basyoruz ve nihai olarak yle bir grnt elde
ediyoruz:
>>> if n > 10:
...
print("say 10'dan byktr!")
...
say 10'dan byktr!
>>>
Demek ki 250 says 10 dan bykm! Ne byk bir bulu! Merak etmeyin, daha ok ey
rendike daha mantkl programlar yazacaz. Burada amacmz iin temelini kavramak.
Bunu da en iyi, (ok mantkl olmasa bile) basit programlar yazarak yapabiliriz.
imdi metin dzenleyicimizi aarak daha mantkl eyler yazmaya alalm. Zira yukardaki
rnekte deikeni kendimiz belirlediimiz iin, bu deikenin deerini if deyimleri yardmyla
denetlemek pek akla yatkn grnmyor. Ne de olsa deikenin deerinin ne olduunu
biliyoruz. Dolaysyla bu deikenin 10 saysndan byk olduunu da biliyoruz! Bunu if
deyimiyle kontrol etmek ok gerekli deil. Ama imdi daha makul bir i yapacaz. Deikeni
biz belirlemek yerine kullancya belirleteceiz:
say = int(input("Bir say giriniz: "))
if say > 10:
print("Girdiiniz say 10'dan byktr!")
if say < 10:
print("Girdiiniz say 10'dan kktr!")
if say == 10:
print("Girdiiniz say 10'dur!")
Grdnz gibi, art arda adet if blou kullandk. Bu kodlara gre, eer kullancnn
girdii say 10 dan bykse, ilk if blou iletilecek; eer say 10 dan kkse ikinci if blou
iletilecek; eer say 10a eit ise nc if blou iletilecektir. Peki ya kullanc muziplik
yapp say yerine harf yazarsa ne olacak? Byle bir ihtimal iin programmza herhangi bir
denetleyici yerletirmedik. Dolaysyla eer kullanc say yerine harf girerse programmz
hata verecek, yani kecektir. Bu tr durumlara kar nasl nlem alacamz ilerleyen
derslerimizde greceiz. Biz imdilik bildiimiz yolda yryelim.
201
Yukardaki rnekte input() ile gelen karakter dizisini, int() fonksiyonu yardmyla bir sayya
dntrdmze dikkat edin. Kullancdan gelen veriyi byklk-kklk ltne gre
inceleyeceimiz iin, gelen veriyi bir sayya dntrmemiz gerekiyor. Bunu da int()
fonksiyonu ile yapabileceimizi biliyorsunuz.
Elbette yukardaki dntrme ilemini yle de yapabilirdik:
say = input("Bir say giriniz: ")
say = int(say)
Burada nce input() fonksiyonuyla veriyi aldk, daha sonra bu veriyi ayr bir yerde sayya
dntrp tekrar say adl deikene atadk.
if deyimlerini kullanc ad veya parola denetlerken de kullanabiliriz.
program tasla yazabiliriz:
print("""
Dnyann en gelimi [Link] hizmetine
hogeldiniz. Yalnz hizmetimizden
yararlanmak iin nce sisteme giri
yapmalsnz.
""")
parola = input("Parola: ")
if parola == "12345678":
print("Sisteme Hogeldiniz!")
Grdnz gibi, programn banda trnak iaretlerinden yararlanarak uzun bir metni
kullancya gsterdik. Bu blm, kendiniz gze ho gelecek bir ekilde ssleyebilirsiniz de.
Eer kullanc, kendisine parola sorulduunda cevap olarak 12345678 yazarsa kullancy
sisteme alyoruz.
Yukardaki rnekte, kullancnn girdii parola 12345678 ise kendisine Sisteme
Hogeldiniz! mesajn gsteriyoruz. Mantk olarak bunun tersini yapmak da mmkndr.
Yani:
if parola != "12345678":
print("Ne yazk ki yanl parola girdiniz!")
Burada ise bir nceki rnein mantn ters evirdik. nceki rnekte parola deikeni
12345678 adl karakter dizisine eitse (if parola == "12345678") bir ilem yapyorduk.
Yukardaki rnekte ise parola deikeni 12345678 adl karakter dizisine eit deilse (if
parola != "12345678") bir ilem yapyoruz.
Bu iki rnein de aslnda ayn kapya ktn gryorsunuz.
gsterilen mesajlardadr.
16.1.2 elif
Pythonda, if deyimleriyle birlikte kullanlan ve yine koul belirten bir baka deyim de elif
deyimidir. Buna yle bir rnek verebiliriz:
ya = int(input("Yanz: "))
if ya == 18:
print("18 iyidir!")
elif ya < 0:
print("Yok canm, daha neler!...")
elif ya < 18:
print("Gen bir kardeimizsin!")
elif ya > 18:
print("Eh, artk ya yava yava kemale eriyor!")
Bu iki programn da ayn ilevi grdn dnebilirsiniz. Ancak ilk bakta pek belli olmasa
da, aslnda yukardaki iki program birbirinden farkl davranacaktr. rnein ikinci programda
eer kullanc eksi deerli bir say girerse hem if ya < 0 blou, hem de if ya < 18 blou
alacaktr. sterseniz yukardaki program altrp, cevap olarak eksi deerli bir say verin.
Ne demek istediimiz gayet net anlalacaktr.
Bu durum if ile elif arasndaki ok nemli bir farktan kaynaklanr. Buna gre if bize olas
btn sonular listeler, elif ise sadece doru olan ilk sonucu verir. Bu soyut tanmlamay
biraz daha somutlatralm:
a = int(input("Bir say giriniz: "))
if a < 100:
print("verdiiniz say 100'den kktr.")
if a < 50:
print("verdiiniz say 50'den kktr.")
if a == 100:
print("verdiiniz say 100'dr.")
if a > 100:
203
Yukardaki kodlar altrdmzda, doru olan btn sonular listelenecektir. Yani mesela
kullanc 40 saysn girmise, ekrana verilecek kt yle olacaktr:
verdiiniz say 100'den kktr.
verdiiniz say 50'den kktr.
Burada 40 says hem 100 den, hem de 50 den kk olduu iin iki sonu da kt olarak
verilecektir. Ama eer yukardaki kodlar yle yazarsak:
a = int(input("Bir say giriniz: "))
if a < 100:
print("verdiiniz say 100'den kktr.")
elif a < 50:
print("verdiiniz say 50'den kktr.")
elif a == 100:
print("verdiiniz say 100'dr.")
elif a > 150:
print("verdiiniz say 150'den byktr.")
elif a > 100:
print("verdiiniz say 100'den byktr.")
Grdnz gibi, elif deyimlerini kullandmz zaman, ekrana yalnzca doru olan ilk sonu
veriliyor. Yukarda 40 says hem 100 den hem de 50 den kk olduu halde, Python bu
saynn 100 den kk olduunu grr grmez sonucu ekrana basp, teki koul bloklarn
incelemeyi brakyor. if deyimlerini arka arkaya sraladmzda ise, Python btn olaslklar
tek tek deerlendirip, geerli olan btn sonular ekrana dkyor.
Bir sonraki blmde else deyimini rendiimiz zaman, elifin tam olarak ne ie yaradn
ok daha iyi anlamanz salayacak bir rnek vereceiz.
Not: imdiye kadar verdiimiz rneklerden de rahatlkla anlayabileceiniz gibi, ilk koul
blounda asla elif deyimi kullanlamaz. Bu deyimin kullanlabilmesi iin kendisinden nce
en az bir adet if blou olmaldr. Yani Pythonda koullu durumlar ifade ederken ilk koul
bloumuz her zaman if deyimi ile balamaldr.
elifi de incelediimize gre, koul bildiren deyimlerin sonuncusuna gz atabiliriz: else
204
16.1.3 else
imdiye kadar Pythonda koul bildiren iki deyimi rendik. Bunlar if ve elif idi. Bu blmde
ise koul deyimlerinin sonuncusu olan else deyimini greceiz. rendiimiz eyleri yle bir
gzden geirecek olursak, temel olarak yle bir durumla kar karya olduumuzu grrz:
if falanca:
bu ilemi yap
if filanca:
u ilemi yap
if ile elif arasndaki fark biliyoruz. Eer if deyimlerini art arda sralayacak olursak, Python
doru olan btn sonular listeleyecektir. Ama eer if deyiminden sonra elif deyimini
kullanrsak, Python doru olan ilk sonucu listelemekle yetinecektir.
Bu blmde greceimiz else deyimi, yukardaki tabloya bambaka bir boyut kazandryor.
Dikkat ederseniz imdiye kadar rendiimiz deyimleri kullanabilmek iin ilgili btn
durumlar tanmlamamz gerekiyordu. Yani:
eer byle bir durum varsa:
bunu yap
eer yle bir durum varsa:
unu yap
eer filancaysa:
yle git
eer falancaysa:
byle gel
gibi...
Ancak her durum iin bir if blou yazmak bir sre sonra yorucu ve skc olacaktr. te bu
noktada devreye else deyimi girecek. elsein anlam kabaca udur:
Eer yukardaki koullarn hibiri gereklemezse...
Gelin isterseniz bununla ilgili yle bir rnek verelim:
soru = input("Bir meyve ad syleyin bana:")
if soru == "elma":
print("evet, elma bir meyvedir...")
elif soru == "karpuz":
print("evet, karpuz bir meyvedir...")
elif soru == "armut":
205
Eer kullanc soruya elma, karpuz veya armut cevab verirse, evet, ... bir meyvedir kts
verilecektir. Ama eer kullanc bu dnda bir cevap verirse, ... gerekten bir meyve
midir? ktsn grrz. Burada else deyimi, programmza u anlam katyor:
Eer kullanc yukarda belirlenen meyve adlarndan hi birini girmez, bunlarn
yerine bambaka bir ey yazarsa, o zaman else blou iinde belirtilen ilemi
gerekletir.
Dikkat ederseniz yukardaki kodlarda if deyimlerini art arda sralamak yerine ilk iften sonra
elif ile devam ettik. Peki yle bir ey yazarsak ne olur?
soru = input("Bir meyve ad syleyin bana:")
if soru == "elma":
print("evet, elma bir meyvedir...")
if soru == "karpuz":
print("evet, karpuz bir meyvedir...")
if soru == "armut":
print("evet, armut bir meyvedir...")
else:
print(soru, "gerekten bir meyve midir?")
Burada olan ey u:
Soruya elma cevabn verdiimizi dnelim. Bu durumda, Python ilk olarak ilk if blounu
deerlendirecek ve soruya verdiimiz cevap elma olduu iin evet, elma bir meyvedir...
ktsn verecektir.
if ile elif arasndaki fark anlatrken, hatrlarsanz art arda gelen if bloklarnda Pythonn
olas btn sonular deerlendireceini sylemitik. te burada da byle bir durum sz
konusu. Grdnz gibi, ilk if bloundan sonra yine bir if blou geliyor. Bu nedenle Python
olas btn sonular deerlendirebilmek iin bloklar okumaya devam edecek ve sorunun
cevab karpuz olmad iin ikinci if blounu atlayacaktr.
Sonraki blok yine bir if blou olduu iin Python kodlar okumaya devam ediyor. Ancak
sorunun cevab armut da olmad iin, Python sonraki if blounu da geiyor ve bylece
else blouna ulayor.
Yukarda verdiimiz rnekteki gibi art arda if deyimlerinin sralanp en sona else deyiminin
yerletirildii durumlarda else deyimi sadece bir nceki if deyimini dikkate alarak ilem
yapar. Yani yukardaki rnekte kullancnn verdii cevap armut olmad iin else deyiminin
206
olduu blok almaya balar. Yukardaki rnee armut cevabn verirseniz ne demek
istediimi biraz daha iyi anlayabilirsiniz. armut cevab verilmesi durumunda sadece if
soru == "armut" ifadesinin olduu blok alr, else blou ise almaz. nk dediim gibi,
eer else bloundan nce art arda gelen if bloklar varsa, else deyimi yalnzca kendisinden
nceki son if blounu dikkate alr ve sanki yukardaki rnek yleymi gibi davranr:
if soru == "armut":
print("evet, armut bir meyvedir...")
else:
print(soru, "gerekten bir meyve midir?")
Bu tr durumlarda else deyimi bir nceki if bloundan nce gelen btn if bloklarn
grmezden gelir ve bylece u anlamsz grnen kt elde edilir:
evet, elma bir meyvedir...
elma gerekten bir meyve midir?
Szn z, kullancnn cevab elma olduu iin, yukardaki ktda yer alan ilk cmle ilk if
blounun almas sonucu ekrana baslyor. kinci cmle ise else bloundan bir nceki if
blou kullancnn cevabyla uyumad iin ekrana baslyor.
Yalnz bu dediimizden, else ifadesi if ile birlikte kullanlmaz, anlam karlmamal. Mesela
yle bir rnek yaplabilir:
soru = input("Programdan kmak istediinize emin misiniz? \
Eminseniz 'e' harfine basn : ")
if soru == "e":
print("Gle gle!")
else:
print("Peki, biraz daha sohbet edelim!")
Burada eer kullancnn cevab e ise if blou iletilecek, eer cevap e dnda herhangi bir
ey ise else blou alacaktr. Gayet mantkl bir sre. Ama eer yukardaki rnee bir if
blou daha eklerseniz iler beklediiniz gibi gitmez:
soru = input("Programdan kmak istediinize emin misiniz? \
Eminseniz 'e' harfine basn : ")
if soru == "e":
print("Gle gle!")
if soru == "b":
print("Kararsz kaldm imdi!")
else:
print("Peki, biraz daha sohbet edelim!")
207
Gle gle!
Peki, biraz daha sohbet edelim!
Dolaysyla, eer programnzda bir else blouna yer verecekseniz, ondan nce gelen koullu
durumlarn ilkini if ile sonrakileri ise elif ile balayn. Yani:
if koul_1:
sonu_1
elif koul_2:
sonu_2
elif koul_3:
sonu_3
else:
sonu_4
Ama eer else bloundan nce sadece tek bir koul blou yer alacaksa bunu if ile balayn.
Yani:
if koul_1:
sonu_1
else:
sonu_2
208
175 saysnn 180 den kk olduunu grnce de kt olarak boyunuz normal cevabn
verecektir.
Peki ya kullanc 190 cevabn verirse ne olacak? Python yine nce ilk if blouna
bakacak ve 190 cevabnn bu bloa uymadn grecektir. Dolaysyla ilk blou brakp
ikinci bloa bakacaktr. 190 cevabnn bu bloa da uymadn grnce, bir sonraki blou
deerlendirmeye alacaktr. Bir sonraki blokta ise else deyimimiz var. Bu blmde
rendiimiz gibi, else deyimi, eer kullancnn cevab yukardaki koullarn hibirine
uymazsa bu blou altr, anlamna geliyor. Kullancnn girdii 190 cevab ne birinci ne
de ikinci bloktaki koula uyduu iin, normal bir ekilde else blou iletilecek, dolaysyla da
ekrana boyunuz uzun kts verilecektir.
Bylece Pythonda if, elif ve else deyimlerini incelemi olduk. Ancak tabii ki bu deyimlerle
iimiz henz bitmedi. Elimizdeki bilgiler imdilik bu deyimleri ancak bu kadar incelememize
yetiyor, ama ilerleyen sayfalarda baz baka aralar da bilgi daarcmza kattktan sonra bu
deyimlerin daha farkl ynlerini renme imkanna kavuacaz.
Burada yapabildiimiz tek ey, kullancdan kullanc ad ve parola bilgilerini alp, bu bilgilerin
karakter uzunluunu lebilmekti. Ama artk koullu durumlar rendiimize gre bu
program eksiksiz olarak yazabiliriz. u kodlar dikkatlice inceleyin:
kullanc_ad = input("Kullanc adnz: ")
parola
= input("Parolanz
: ")
toplam_uzunluk = len(kullanc_ad) + len(parola)
mesaj = "Kullanc ad ve parolanz toplam {} karakterden oluuyor!"
print([Link](toplam_uzunluk))
if toplam_uzunluk > 40:
print("Kullanc adnz ile parolanzn ",
"toplam uzunluu 40 karakteri gememeli!")
else:
print("Sisteme hogeldiniz!")
209
210
BLM 17
leler
211
+
*
/
**
toplama
karma
arpma
blme
kuvvet
Burada 45 ve 33 deerlerine ilenen (operand ) ad verilir. Bu iki deer arasnda yer alan +
iareti ise bir iletir (operator ). Dikkat ederseniz + ileci 45 ve 33 adl ilenenler arasnda bir
toplama ilikisi kuruyor.
Bir rnek daha verelim:
>>> 23 * 46
1058
Burada da 23 ve 46 deerleri birer ilenendir. Bu iki deer arasnda yer alan * iareti ise,
ilenenler arasnda bir arpma ilikisi kuran bir iletir.
Ancak bir noktaya zellikle dikkatinizi ekmek istiyorum. Daha nceki derslerimizde de
deindiimiz gibi, + ve * ileleri Pythonda birden fazla anlama gelir. rnein yukardaki
rnekte + ileci, ilenenler arasnda bir toplama ilikisi kuruyor. Ama aadaki durum biraz
farkldr:
>>> "istihza" + ".com"
'[Link]'
Burada + ileci ilenenler (istihza ve .com ) arasnda bir birletirme ilikisi kuruyor.
Tpk + ilecinde olduu gibi, * ileci de Pythonda birden fazla anlama gelir. Bu ilecin,
arpma ilikisi kurma ilevi dnda tekrar etme ilikisi kurma ilevi de vardr. Yani:
>>> "hzl " * 2
'hzl hzl '
...veya:
>>> "-" * 30
'------------------------------'
Burada * ilecinin, saylar arasnda arpma ilemi yapmak dnda bir grev stlendiini
gryoruz.
Pythonda bu tr farklar, yazacanz programn salkl alabilmesi asndan byk nem
tar. O yzden bu tr farklara kar her zaman uyank olmamz gerekiyor.
+ ve * ilelerinin aksine / ve - ileleri ise ilenenler arasnda sadece blme ve karma
ilikisi kurar. Bu ileler tek ilevlidir:
212
>>> 25 / 4
6.25
>>> 10 - 5
5
nceki derslerde grdmz ve yukarda da tekrar ettiimiz drt adet temel aritmetik ilece
u iki aritmetik ileci de ekleyelim:
%
//
modls
taban blme
Burada 02 says blme ileminin kalandr. te modls denen ile de blme ileminden
kalan bu deeri gsterir. Yani:
>>> 30 % 4
2
Grdnz gibi modls ileci (% ) gerekten de blme ileminden kalan sayy gsteriyor...
Peki bu bilgi ne iimize yarar?
Mesela bu bilgiyi kullanarak bir saynn tek mi yoksa ift mi olduunu tespit edebiliriz:
say = int(input("Bir say girin: "))
if say % 2 == 0:
print("Girdiiniz say bir ift saydr.")
else:
print("Girdiiniz say bir tek saydr.")
Eer bir say 2 ye blndnde kalan deer 0 ise o say ifttir. Aksi halde o say tektir.
Mesela:
>>> 14 % 2
0
Grdnz gibi, bir ift say olan 14 2 ye bldmzde kalan say 0 oluyor. nk ift
saylar 2 ye tam blnrler.
Bir de una bakalm:
>>> 15 % 2
1
213
Bir tek say olan 15 ise 2 ye blndnde kalan say 1 oluyor. Yani 15 says 2 ye tam
blnmyor. Bu bilgiden yola karak 15 saysnn bir tek say olduunu syleyebiliyoruz.
Bir saynn tek mi yoksa ift mi olduunu tespit etme ilemini kmsememenizi tavsiye
ederim. Bir saynn tek mi yoksa ift mi olduu bilgisinin, arayz gelitirirken dahi iinize
yarayacandan emin olabilirsiniz.
Elbette modls ilecini bir saynn yalnzca 2 ye tam blnp blnmediini denetlemek
iin kullanmyoruz. Bu ileci kullanarak herhangi bir saynn herhangi bir sayya tam blnp
blnmediini de denetleyebilirsiniz. rnein:
>>> 45 % 4
1
>>> 36 % 9
0
Programmz, kullancnn girdii ilk saynn ikinci sayya tam blnp blnmediini
hesaplyor ve sonuca gre kullancy bilgilendiriyor. Bu kodlarda zellikle u satra dikkat
edin:
if blnen % blen == 0:
...
Programmzn temelini bu kod oluturuyor. nk bir saynn bir sayya tam blnp
blnmediini bu kodla belirliyoruz. Eer bir say baka bir sayya blndnde kalan deer,
yani modls 0 ise, o say br sayya tam blnyor demektir.
Ayrca bir saynn son basaman elde etmek iin de modlsten yararlanabilirsiniz. Herhangi
bir tamsay 10 a blndnde kalan (yani modls), blnen saynn son basama
olacaktr:
>>> 65 % 10
5
>>> 543 % 10
3
Programlama tecrbeniz arttka, aslnda modlsn ne kadar faydal bir ara olduunu
kendi gzlerinizle greceksiniz.
Modls ilecini rnekler eliinde ayrntl bir ekilde incelediimize gre sra geldi taban
blme ilecini aklamaya...
214
Burada, bildiimiz blme ilecini (/ ) kullanarak basit bir blme ilemi yaptk. Elde ettiimiz
sonu doal olarak 2.5.
Matematikte blme ileminin sonucunun kesirli olmas durumuna kesirli blme ad verilir.
Bunun tersi ise tamsayl blme veya taban blmedir. Eer herhangi bir sebeple kesirli blme
ilemi deil de taban blme ilemi yapmanz gerekirse // ilecinden yararlanabilirsiniz:
>>> 5 // 2
2
Grdnz gibi, // ileci sayesinde blme ileminin sonucu kesirli deil, tamsay olarak elde
ediliyor.
Yukarda yaptmz taban blme ilemi ununla ayn anlama gelir:
>>> int(5 / 2)
2
Burada olan u: 5 / 2 ileminin sonucu bir kayan noktal saydr (2.5 ). Bunu u ekilde teyit
edebiliriz:
>>> a = 5 / 2
>>> type(a)
<class 'float'>
Buradaki oat ktsnn oating point number, yani kayan noktal say anlamna geldiini
biliyorsunuz.
Bu kayan noktal saynn sadece tabann elde etmek iin bu sayy tamsayya (integer )
evirmemiz yeterli olacaktr. Yani:
>>> int(a)
2
Bu arada yeri gelmiken round() adl bir gml fonksiyondan bahsetmeden gemeyelim.
Eer bir saynn deerini yuvarlamanz gerekirse round() fonksiyonundan yararlanabilirsiniz.
Bu fonksiyon yle kullanlr:
215
>>> round(2.55)
3
Grdnz gibi, round() fonksiyonuna parametre olarak bir say veriyoruz. Bu fonksiyon da
bize o saynn yuvarlanm halini dndryor. Bu fonksiyonu kullanarak yuvarlanacak saynn
noktadan sonraki hassasiyetini de belirleyebilirsiniz. rnein:
>>> round(2.55, 1)
2.5
Burada ikinci parametre olarak 1 saysn verdiimiz iin, noktadan sonraki bir basamak
grntleniyor. Bir de una bakalm:
>>> round(2.68, 1)
2.7
Burada da yuvarlama ilemi yaplrken noktadan sonra bir basamak korunuyor. Eer 1 says
yerine 2 saysn kullanrsanz, yukardaki rnek u kty verir:
>>> round(2.68, 2)
2.68
Bir saynn 2. kuvveti o saynn karesidir. Bir saynn 0.5. kuvveti ise o saynn karekkdr:
>>> 625 ** 0.5
25.0
Bu arada, eer karekkn kayan noktal say cinsinden olmas hounuza gitmediyse, bu sayy
int() fonksiyonu ile tam sayya evirebileceinizi biliyorsunuz:
>>> int(625 ** 0.5)
25
216
>>> pow(25, 2, 5)
0
Yani pow(25, 2, 5) gibi bir komut verdiimizde, 25 saysnn 2. kuvvetini alp, elde ettiimiz
saynn 5 e blnmesinden kalan sayy hesaplam oluyoruz.
Bylece aritmetik ileleri tamamlam olduk. Artk karlatrma ilelerini inceleyebiliriz.
eittir
eit deildir
byktr
kktr
byk eittir
kk eittir
Bu ilelerin hibiri size yabanc deil, zira bunlarn hepsini aslnda daha nceki derslerde
verdiimiz rneklerde kullanmtk. Burada da bunlarla ilgili basit bir rnek vererek yolumuza
devam edelim:
parola = "xyz05"
soru = input("parolanz: ")
if soru == parola:
print("doru parola!")
elif soru != parola:
print("yanl parola!")
217
Burada a adl bir deiken tanmladk. Bu deikenin deeri 1. imdi bu deikenin deerini
sorgulayalm:
>>> a == 1 #a deeri 1'e eit mi?
True
Grdnz gibi, bool ileleri herhangi bir ifadenin doruluunu veya yanlln
sorgulamak iin kullanlabiliyor. Buna gre, eer bir sorgulamann sonucu doru ise True,
eer yanl ise False kts alyoruz.
Bool ileleri sadece yukarda verdiimiz rneklerdeki gibi, salt bir doruluk-yanllk
sorgulamaya yarayan aralar deildir. Bilgisayar biliminde her eyin bir bool deeri vardr.
Bununla ilgili genel kuralmz u: 0 deeri ve bo veri tipleri False tur. Bunlar dnda kalan
her ey ise True dur.
Bu durumu bool() adl zel bir fonksiyondan yararlanarak teyit edebiliriz:
>>> bool(3)
True
>>> bool("elma")
218
True
>>> bool(" ")
True
>>> bool("
")
True
>>> bool("fdsdfsdg")
True
>>> bool("0")
True
>>> bool(0)
False
>>> bool("")
False
Grdnz gibi, gerekten de 0 saysnn ve bo karakter dizilerinin bool deeri False tur.
Geri kalan her ey ise True dur.
Not: 0 n bir say, 0 n ise bir karakter dizisi olduunu unutmayn. Say olan 0 n bool deeri
False tur, ama karakter dizisi olan 0 n deeri True dur.
Yukardaki rneklere gre, iinde herhangi bir deer barndran karakter dizileri (0 hari) True
kts veriyor. Burada sylediimiz ey btn veri tipleri iin geerlidir. Eer herhangi bir veri
tipi herhangi bir deer iermiyorsa o veri tipi False kts verir.
Peki bu bilgi bizim ne iimize yarar? Yani mesela bo veri tiplerinin False, iinde bir veri
barndran veri tiplerinin ise True olmas bizim iin neden bu kadar nemli? Bunu birazdan
aklayacaz. Ama nce isterseniz, bool deerleri ile ilgili ok nemli bir konuya deinelim.
Belki kendiniz de farketmisinizdir; bool deerleri Pythonda koul belirten if, elif ve else
deyimlerinin de temelini oluturur. u rnei ele alalm mesela:
isim = input("sminiz: ")
if isim == "Ferhat":
print("Ne gzel bir isim bu!")
else:
print(isim, "ismini pek sevmem!")
219
Eer burada kullanc Ferhat ismini girecek olursa programmz True kts verir. Ama eer
kullanc baka bir isim girerse bu kez False ktsn alrz. te koul bildiren deyimler,
karar verme grevini, kendilerine verilen ifadelerin bool deerlerine bakarak yerine getirir.
Dolaysyla yukardaki rnei u ekilde Trkeye evirebiliriz:
Eer isim == "Ferhat" ifadesinin bool deeri True ise, Ne gzel bir isim bu! kts
ver! Ama eer isim == "Ferhat" ifadesinin bool deeri True dnda herhangi bir
ey ise (yani False ise), ... ismini pek sevmem! kts ver!
Koul bildiren deyimlerle bool deerleri arasndaki ilikiyi daha iyi anlamak iin bir rnek daha
verelim:
Hatrlarsanz ii bo veri tiplerinin bool deerinin her zaman False olacan sylemitik. Yani:
>>> a = ""
>>> bool(a)
False
Herhangi bir deere sahip veri tiplerinin bool deeri ise her zaman True olur (0 hari):
>>> a = "gdfg"
>>> bool(a)
True
i bo veri tiplerinin bool deerinin her zaman False olaca bilgisini kullanarak yle bir
uygulama yazabiliriz:
kullanc = input("Kullanc adnz: ")
if bool(kullanc) == True:
print("Teekkrler!")
else:
print("Kullanc ad alan bo braklamaz!")
220
Bu ileler
and
or
not
Eer mantk dersleri aldysanz bu ileler size hi yabanc gelmeyecektir. Eer lisede mantk
dersleri almadysanz veya aldnz derslerden hibir ey hatrlamyorsanz, yine de ziyan
yok. Biz burada bu ileleri btn ayrntlaryla inceleyeceiz.
nce and ile balayalm...
Trke sylemek gerekirse and ve anlamna gelir. Peki bu and ne iimize yarar? ok basit
bir rnek verelim:
Hatrlarsanz geen blmde koullu durumlara rnek verirken yle bir durumdan
bahsetmitik:
Diyelim ki Googlen Gmail hizmeti araclyla bir [Link] hesab aldnz. Bu
hesaba gireceiniz zaman Gmail size bir kullanc ad ve parola sorar. Siz de
kendinize ait kullanc adn ve parolay sayfadaki kutucuklara yazarsnz. Eer
yazdnz kullanc ad ve parola doruysa hesabnza eriebilirsiniz. Ama eer
kullanc adnz ve parolanz doru deilse hesabnza eriemezsiniz. Yani [Link]
hesabnza erimeniz, kullanc ad ve parolay doru girme kouluna baldr.
Burada ok nemli bir nokta var. Kullancnn Gmail sistemine girebilmesi iin hem kullanc
adn hem de parolay doru yazmas gerekiyor. Yani kullanc ad veya paroladan herhangi
biri yanl ise sisteme giri mmkn olmayacaktr.
Yukardaki durumu taklit eden bir program, u ana kadar olan bilgilerimizi kullanarak yle
yazabiliyoruz:
kullanc_ad = input("Kullanc adnz: ")
parola = input("Parolanz: ")
if kullanc_ad == "aliveli":
if parola == "12345678":
print("Programa hogeldiniz")
else:
print("Yanl kullanc ad veya parola!")
Burada yeni bir bilgiyle daha karlayoruz. Grdnz gibi, burada if deyimlerini i
ie kullandk. Pythonda istediiniz kadar i ie gemi if deyimi kullanabilirsiniz. Ancak
yazdnz bir programda eer ten fazla i ie if deyimi kullandysanz, benimsediiniz
17.3. Bool leleri
221
Burada and ilecini nasl kullandmz gryorsunuz. Bu ileci kullanarak iki farkl ifadeyi
birbirine baladk. Bylece kullancnn sisteme giriini hem kullanc adnn hem de parolann
doru olmas kouluna dayandrdk.
Peki and ilecinin alma mant nedir? Dediim gibi, and Trkede ve anlamna geliyor.
Bu ileci daha iyi anlayabilmek iin u cmleler arasndaki fark dnn:
1. Toplantya Ali ve Veli katlacak.
2. Toplantya Ali veya Veli katlacak.
lk cmlede ve balac kullanld iin, bu cmlenin gereinin yerine getirilebilmesi, hem
Alinin hem de Velinin toplantya katlmasna baldr. Sadece Ali veya sadece Velinin
toplantya katlmas durumunda bu cmlenin gerei yerine getirilememi olacaktr.
kinci cmlede ise toplantya Ali ve Veliden herhangi birisinin katlmas yeterlidir. Toplantya
sadece Alinin katlmas, sadece Velinin katlmas veya her ikisinin birden katlmas, bu
cmlenin gereinin yerine getirilebilmesi asndan yeterlidir.
te Pythondaki and ileci de ayn bu ekilde iler. u rneklere bir bakalm:
>>> a = 23
>>> b = 10
>>> a == 23
True
>>> b == 10
True
>>> a == 23 and b == 10
True
Burada deeri 23 olan bir adet a deikeni ve deeri 10 olan bir adet b deikeni tanmladk.
Daha sonra bu iki deikenin deerini tek tek sorguladk ve bunlarn gerekten de srasyla 23
ve 10 saysna eit olduunu grdk. Son olarak da bunlar and ileci ile birbirine balayarak
sorguladk. a deikeninin deeri 23, b deikeninin deeri de 10 olduu iin, yani and ile
balanan her iki nerme de True kts verdii iin a == 23 and b == 10 ifadesi True deeri
verdi.
222
Burada ise a deikenin deeri 23 tr. Dolaysyla a == 23 ifadesi True kts verir. Ancak b
deikeninin deeri 54 deildir. O yzden de b == 54 komutu False kts verir. Grdnz
gibi, and ileci ile balanan nermelerden herhangi biri False olduunda ktmz da False
oluyor. Unutmayn: and ilecinin True kts verebilmesi iin bu ile tarafndan balanan
her iki nermenin de True olmas gerekir. Eer nermelerden biri bile True deilse kt da
True olmayacaktr.
Tahmin edebileceiniz gibi, and ileci en yaygn if deyimleriyle birlikte kullanlr. Mesela
yukarda kullancdan kullanc ad ve parola alrken de bu and ilecinden yararlanmtk.
Gelelim or ilecine...
Tpk and gibi bir bool ileci olan or un Trkede karl veyadr. Yukarda Toplantya Ali
veya Veli katlacak. cmlesini tartrken aslnda bu or kelimesinin anlamn aklamtk.
Hatrlarsanz and ilecinin True kts verebilmesi iin bu ilele balanan btn nermelerin
True deerine sahip olmas gerekiyordu. or ilecinin True kts verebilmesi iin ise
or ileciyle balanan nermelerden herhangi birinin True kts vermesi yeterli olacaktr.
Sylediimiz bu eyleri birka rnek zerinde somutlatralm:
>>> a = 23
>>> b = 10
>>> a == 23
True
>>> b == 10
True
>>> a == 11
False
>>> a == 11 or b == 10
True
Grdnz gibi, a == 11 ifadesinin bool deeri False olduu halde, b == 10 ifadesinin bool
deeri True olduu iin a == 11 or b == 10 ifadesi True deerini veriyor.
and ve or ilelerini rendiimize gre, bir snavdan alnan notlarn harf karlklarn
gsteren bir uygulama yazabiliriz:
223
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Byle bir not yok")
elif x >= 90 and x <= 100:
print("A aldnz.")
elif x >= 80 and x <= 89:
print("B aldnz.")
elif x >= 70 and x <= 79:
print("C aldnz.")
elif x >= 60 and x <= 69:
print("D aldnz.")
elif x >= 0 and x <= 59:
print("F aldnz.")
Bu programda eer kullanc 100 den byk ya da 0 dan kk bir say girerse Byle bir
not yok uyars alacaktr. 0-100 aras notlarda ise, her bir not aralna karlk gelen harf
grntlecektir. Eer isterseniz yukardaki kodlar u ekilde de ksaltabilirsiniz:
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Byle bir not yok")
elif x >= 90 <= 100:
print("A aldnz.")
elif x >= 80 <= 89:
print("B aldnz.")
elif x >= 70 <= 79:
print("C aldnz.")
elif x >= 60 <= 69:
print("D aldnz.")
elif x >= 0 <= 59:
print("F aldnz.")
Grdnz gibi, and x ksmlarn kardmzda da bir nceki kodlarla ayn anlam
yakalayabiliyoruz.
Hatta yukardaki kodlar yle de yazabilirsiniz:
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Byle bir not yok")
#90 says x'ten kk veya x'e eit,
#x says 100'den kk veya 100'e eit ise,
#Yani x, 90 ile 100 arasnda bir say ise
elif 90 <= x <= 100:
224
print("A aldnz.")
#80 says x'ten kk veya x'e eit,
#x says 89'dan kk veya 89'a eit ise,
#Yani x, 80 ile 89 arasnda bir say ise
elif 80 <= x <= 89:
print("B aldnz.")
elif 70 <= x <= 79:
print("C aldnz.")
elif 60 <= x <= 69:
print("D aldnz.")
elif 0 <= x <= 59:
print("F aldnz.")
Bu kodlar bir ncekiyle ayn ii yapar. Yorumlardan da greceiniz gibi, bu iki kod arasnda
sadece mantk fark var.
Son bool ilecimiz not.
kullanyoruz:
Bu ileci yle
>>> a = 23
>>> not a
False
>>> a = ""
>>> not a
True
Bu ile, zellikle kullanc tarafndan bir deikene veri girilip girilmediini denetlemek iin
kullanlabilir. rnein:
parola = input("parola: ")
if not parola:
print("Parola bo braklamaz!")
Eer kullanc herhangi bir parola belirlemeden dorudan Enter tuuna basacak olursa
parola deikeninin deeri bo bir karakter dizisi olacaktr. Yani parola = "". Bo veri
tiplerinin bool deerinin False olacan biliyoruz. Dolaysyla, yukardaki gibi bir rnekte,
kullanc parolay bo getiinde not parola kodu True verecek ve bylece ekrana Parola bo
braklamaz! karakter dizisi yazdrlacaktr. Eer yukardaki rnein mantn kavramakta
zorluk ekiyorsanz u rnekleri incelemenizi neririm:
>>> parola = ""
>>> bool(parola)
False
>>> bool(not parola)
True
225
a deerine mesela 5 ekleyip bu deeri 28 e eitlemek iin ne yapmamz lazm? Tabii ki unu:
>>> a = a + 5
>>> print(a)
28
Burada yaptmz ey ok basit: a deikeninin tad deere 5 ilave ediyoruz ve daha sonra
bu deeri tekrar a deikenine atyoruz. Ayn ilemi ok daha kolay bir ekilde de yapabiliriz:
>>> a += 5
>>> print(a)
28
226
Bu kod, yukardakiyle tamamen ayn anlama gelir. Ama bir nceki koda gre ok daha
verimlidir. nk a += 5 kodunda Python a deikeninin deerini sadece bir kez kontrol
ettii iin, ilemi a = a + 5 koduna gre daha hzl yapacaktr.
-= ileci
Bir nceki += ileci toplama ilemi yapp, ortaya kan deeri tekrar ayn deikene atyordu.
-= ileci de buna benzer bir ilem gerekletirir:
>>> a = 23
>>> a -= 5
>>> print(a)
18
Ancak tpk += ilecinde olduu gibi, -= ileci de alternatine gre daha hzl alan bir aratr.
/= ileci
Bu ilecin alma mant da yukardaki ilelerle ayndr:
>>> a = 30
>>> a /= 3
>>> print(a)
10
*= ileci
Bu da tekiler gibi, arpma ilemi yapp, bu ilemin sonucunu ayn deikene atar:
>>> a = 20
>>> a *= 2
>>> print(a)
40
227
%= ileci
Bu ilecimiz ise blme ileminden kalan sayy ayn deikene atar:
>>> a = 40
>>> a %= 3
>>> print(a)
1
**= ileci
Bu ilecin ne yaptn tahmin etmek zor deil.
Bu ilecimiz, bir saynn kuvvetini
hesapladktan sonra kan deeri ayn deikene atyor:
>>> a = 12
>>> a **= 2
>>> print(a)
144
Edeeri:
>>> a = 12
>>> a = a ** 2
>>> print(a)
144
//= ileci
Deer atama ilelerinin sonuncusu olan //= ilecinin grevi ise taban blme ileminin
sonucunu ayn deikene atamaktr:
>>> a = 5
>>> a //= 2
>>> print(a)
2
Edeeri:
>>> a = 5
>>> a = a // 2
>>> print(a)
2
228
>>> a = 5
>>> a += 5
>>> print(a)
10
Burada, deeri 5 olan bir a deikenine 5 daha ekleyip, kan sonucu tekrar a deikenine
atadk. Bylece deeri 10 olan bir a deikeni elde ettik. += ilecinin doru kullanm
yukardaki gibidir. Bir de yukardaki rnei yle yazmay deneyelim:
>>> a = 5
>>> a =+ 5
>>> print(a)
5
a = 5
a =- 5
print(a)
-5
Grdnz gibi, in adl bu ile, bir enin, veri tipi iinde bulunup bulunmadn
sorguluyor. Eer bahsedilen e, veri tipi iinde geiyorsa True kts, eer gemiyorsa False
kts alyoruz.
Henz bu in ilecini verimli bir ekilde kullanmamz salayacak aralardan yoksunuz. Ancak
birka sayfa sonra reneceimiz yeni aralarla birlikte bu ileci ok daha dzgn ve verimli
bir ekilde kullanabilecek duruma geleceiz.
229
ktda grdmz 137990748 says a deikeninin tuttuu 100 saysnn kimlik numarasn
gsteriyor.
Bir de u rneklere bakalm:
>>> a = 50
>>> id(a)
505494576
>>> kardiz = "Elveda Zalim Dnya!"
>>> id(kardiz)
14461728
Grdnz gibi, Python a ve b deikenlerinin deeri iin ayn kimlik numarasn gsterdi.
Bu demek oluyor ki, Python iki adet 100 says iin bellekte iki farkl nesne oluturmuyor. lk
kullanmda nbelleine ald sayy, ikinci kez ihtiya olduunda bellekten alp kullanyor. Bu
tr bir nbellekleme mekanizmasnn gerekesi performans artrmaktr.
Ama bir de u rneklere bakalm:
>>> a = 1000
>>> id(a)
15163440
230
>>> b = 1000
>>> id(b)
14447040
>>> id(1000)
15163632
Bu defa Python a deikeninin tuttuu 1000 says, b deikeninin tuttuu 1000 says ve
tek bana yazdmz 1000 says iin farkl kimlik numaralar gsterdi. Bu demek oluyor ki,
Python a deikeninin tuttuu 1000 says iin, b deikeninin tuttuu 1000 says iin ve
dorudan girdiimiz 1000 says iin bellekte farkl nesne oluturuyor. Yani bu adet
1000 says Python asndan birbirinden farkl...
Yukardaki durumu grebileceimiz baka bir yntem de Pythondaki is adl kimlik ilecini
kullanmaktr. Deneyelim:
>>> a is 1000
False
>>> b is 1000
False
Grdnz gibi, Python False (Yanl) ktsn suratmza bir tokat gibi arpt... Peki bu ne
anlama geliyor?
Bu u anlama geliyor: Demek ki grnte ayn olan iki nesne aslnda birbirinin ayn
olmayabiliyor. Bunun neden bu kadar nemli olduunu ilerleyen derslerde ok daha iyi
anlayacaz.
Yukardaki durumun bir baka yansmas daha vardr. zellikle Pythona yeni balayp da
bu dilde yer alan is ilecini renenler, bu ilecin == ileciyle ayn ileve sahip olduu
yanlgsna kaplabiliyor ve is ilecini kullanarak iki nesne arasnda karlatrma ilemi
yapmaya kalkabiliyor.
Ancak Pythonda is ilecini kullanarak iki nesne arasnda karlatrma yapmak gvenli
deildir. Yani is ve == ileleri birbirleriyle ayn ilevi grmez. Bu iki ile nesnelerin farkl
ynlerini sorgular: is ileci nesnelerin kimliklerine bakp o nesnelerin ayn nesneler olup
olmadn kontrol ederken, == ileci nesnelerin ieriine bakarak o nesnelerin ayn deere
sahip olup olmadklarn sorgular. Bu iki tanm arasndaki ince farka dikkat edin.
Yani:
>>> a is 1000
False
Ama:
>>> a == 1000
True
Burada is ileci a deikeninin tuttuu veri ile 1000 saysnn ayn kimlik numarasna sahip
olup olmadn sorgularken, == ileci a deikeninin tuttuu verinin 1000 olup olmadn
17.6. Kimlik leleri
231
imdiye kadar denediimiz rnekler hep sayyd. imdi isterseniz bir de karakter dizilerinin
durumuna bakalm:
>>> a = "python"
>>> a is "python"
True
Burada True ktsn aldk. Bir de == ileci ile bir karlatrma yapalm:
>>> a == "python"
True
Ama:
>>> a == "python gl ve kolay bir programlama dilidir"
True
Not: Burada henz renmediimiz eyler var. Bunlar birka blm sonra ayrntl bir
ekilde inceleyeceiz.
Bu kod -1000 ve 1000 aralndaki iki say grubunu karlatrp, kimlikleri ayn olan saylar
ekrana dkyor. Yani bir bakma Pythonun hangi sayya kadar nbellekleme yaptn
232
gsteriyor. Buna gre -5 ile 257 arasnda kalan saylar Python tarafndan ufak olarak
deerlendiriliyor ve nbellee alnyor. Bu araln dnda kalan saylar iin ise bellekte her
defasnda ayr bir nesne oluturuluyor.
Burada aldmz sonuca gre yle bir denetleme ilemi yapalm:
>>> a = 256
>>> a is 256
True
>>> a = 257
>>> a is 257
False
>>> a = -5
>>> a is -5
True
>>> a = -6
>>> a is -6
False
233
Burada kullancya baz seenekler sunduk. Bu seenekleri ekrana yazdrmak iin trnak
iaretlerinden yararlandmza dikkat edin. Birden fazla satra yaylm bu tr ifadeleri en
kolay trnak iaretleri yardmyla yazdrabileceimizi biliyorsunuz artk.
Biz burada btn seenekleri tek bir deiken iine yerletirdik. Esasnda her bir seenek
iin ayr bir deiken tanmlamak da mmkndr. Yani aslnda yukardaki kodlar yle de
yazabiliriz:
seenek1
seenek2
seenek3
seenek4
seenek5
seenek6
=
=
=
=
=
=
"(1)
"(2)
"(3)
"(4)
"(5)
"(6)
topla"
kar"
arp"
bl"
karesini hesapla"
karekk hesapla"
Yalnz burada dikkat ederseniz, seenekler hep yan yana diziliyor. Eer programnzda
yukardaki ekli kullanmak isterseniz, bu seeneklerin yan yana deil de, alt alta grnmesini
salamak iin, nceki derslerimizde rendiimiz sep parametresini kullanabilirsiniz:
seenek1
seenek2
seenek3
seenek4
seenek5
seenek6
=
=
=
=
=
=
"(1)
"(2)
"(3)
"(4)
"(5)
"(6)
topla"
kar"
arp"
bl"
karesini hesapla"
karekk hesapla"
Gelin
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""
234
print(giri)
Bu kod yardmyla kullancya bir soru soruyoruz. Kullancdan yapmasn istediimiz ey,
yukarda belirlediimiz giri seenekleri iinden bir say semesi. Kullanc 1, 2, 3, 4, 5
veya 6 seeneklerinden herhangi birini seebilir. Kullancy, setii numarann karsnda
yazan ileme ynlendireceiz. Yani mesela eer kullanc klavyedeki 1 tuuna basarsa hesap
makinemiz toplama ilemi yapacaktr. 2 tuu ise kullancy karma ilemine ynlendirir...
input() fonksiyonunu ilediimiz blmde, bu fonksiyonun deer olarak her zaman bir
karakter dizisi (string ) verdiini sylemitik. Yukardaki kodun kts da doal olarak bir
karakter dizisi olacaktr. Bizim u aamada kullancdan karakter dizisi almamzn bir sakncas
yok. nk kullancnn girecei 1, 2, 3, 4, 5 veya 6 deerleriyle herhangi bir aritmetik ilem
yapmayacaz. Kullancnn girecei bu deerler, yalnzca bize onun hangi ilemi yapmak
istediini belirtecek. Dolaysyla input() fonksiyonunu yukardaki ekilde kullanyoruz.
sterseniz imdiye kadar grdmz ksma topluca bakalm:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""
print(giri)
soru = input("Yapmak istediiniz ilemin numarasn girin: ")
Bylece ilk if deyimimizi tanmlam olduk. Buradaki yazm ekline ok dikkat edin. Bu
kodlarla Pythona u emri vermi oluyoruz:
Eer soru adl deikenin deeri 1 ise, yani eer kullanc klavyede 1 tuuna
basarsa...
if deyimlerinin en sonuna : iaretini koymay unutmuyoruz. Pythona yeni balayanlarn
en ok yapt hatalardan birisi, sondaki bu : iaretini koymay unutmalardr. Bu iaret
bize ok ufak bir ayrntym gibi grnse de Python iin manevi deeri ok byktr!
Pythonun bize fkeli mesajlar gstermesini istemiyorsak bu iareti koymay unutmayacaz.
Bu arada, burada == iaretini kullandmza da dikkat edin. Bunun ne anlama geldiini
nceki derslerimizde renmitik. Bu iaret, iki eyin ayn deere sahip olup olmadn
sorgulamamz salyor. Biz burada soru adl deikenin deerinin 1 olup olmadn
17.7. Uygulama rnekleri
235
Bu kodlar altrp, klavyede 1 tuuna bastmzda, bizden bir say girmemiz istenecektir.
lk saymz girdikten sonra bize tekrar bir say girmemiz sylenecek. Bu emre de uyup Enter
tuuna basnca, girdiimiz bu iki saynn toplandn greceiz. Fena saylmaz, deil mi?
imdi programmzn geri kalan ksmn yazyoruz. in temelini kavradmza gre birden
fazla kod blounu ayn anda yazabiliriz:
elif soru == "2":
say3 = int(input("karma ilemi iin ilk sayy girin: "))
236
Bunlarla birlikte kodlarmzn byk blmn tamamlam oluyoruz. Bu blmdeki tek fark,
ilk if blounun aksine, burada elif bloklarn kullanm olmamz. Eer burada btn bloklar
if kullanarak yazarsanz, biraz sonra kullanacamz else blou her koulda alaca iin
beklentinizin dnda sonular elde edersiniz.
Yukardaki kodlarda az da olsa farkllk gsteren tek yer son iki elif bloumuz. Esasnda
buradaki fark da pek byk bir fark saylmaz. Neticede tek bir saynn karesini ve karekkn
hesaplayacamz iin, kullancdan yalnzca tek bir giri istiyoruz.
imdi de son bloumuzu yazalm. Az evvel tlattmz gibi, bu son blok bir else blou olacak:
else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)
ok basit bir else blou ile iimizi bitirdik. Bu bloun ne ie yaradn biliyorsunuz:
Eer kullancnn girdii deer yukardaki bloklardan hi birine uymuyorsa bu else
blounu ilet!
gibi bir emir vermi oluyoruz bu else blou yardmyla. Mesela kullancmz 1, 2, 3, 4, 5 veya
6 seeneklerini girmek yerine 7 yazarsa, bu blok iletilecek.
Gelin isterseniz son kez kodlarmz topluca bir grelim:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""
print(giri)
soru = input("Yapmak istediiniz ilemin numarasn girin: ")
237
if soru == "1":
say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))
print(say1, "+", say2, "=", say1 + say2)
elif soru == "2":
say3 = int(input("karma ilemi iin ilk sayy girin: "))
say4 = int(input("karma ilemi iin ikinci sayy girin: "))
print(say3, "-", say4, "=", say3 - say4)
elif soru == "3":
say5 = int(input("arpma ilemi iin ilk sayy girin: "))
say6 = int(input("arpma ilemi iin ikinci sayy girin: "))
print(say5, "x", say6, "=", say5 * say6)
elif soru == "4":
say7 = int(input("Blme ilemi iin ilk sayy girin: "))
say8 = int(input("Blme ilemi iin ikinci sayy girin: "))
print(say7, "/", say8, "=", say7 / say8)
elif soru == "5":
say9 = int(input("Karesini hesaplamak istediiniz sayy girin: "))
print(say9, "saysnn karesi =", say9 ** 2)
elif soru == "6":
say10 = int(input("Karekkn hesaplamak istediiniz sayy girin: "))
print(say10, "saysnn karekk = ", say10 ** 0.5)
else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)
Genel olarak baktmzda, btn programn aslnda basit bir if, elif, else yapsndan
ibaret olduunu gryoruz. Ayrca bu kodlardaki simetriye de dikkatinizi ekmek isterim.
Grdnz gibi her paragraf bir if, elif veya else bloundan oluuyor ve her blok kendi
iinde girintili bir yap sergiliyor. Temel olarak yle bir eyle kar karyayz:
Eer byle bir durum varsa:
yle bir ilem yap
Yok eer yle bir durum varsa:
byle bir ilem yap
Eer bambaka bir durum varsa:
yle bir ey yap
Bylelikle irin bir hesap makinesine sahip olmu olduk! Hesap makinemiz pek yetenekli
deil, ama olsun... Henz bildiklerimiz bunu yapmamza msaade ediyor. Yine de
balangtan bu noktaya kadar epey yol katettiimizi gryorsunuz.
imdi bu program altrn ve neler yapabildiine gz atn. Bu arada kodlar da iyice
inceleyin. Program yeterince anladktan sonra, program zerinde kendinize gre baz
deiiklikler yapn, yeni zellikler ekleyin. Eksikliklerini, zayf ynlerini bulmaya aln.
Bylece bu dersten azami fayday salam olacaksnz.
238
239
te bu ktlardaki major (ve yerine gre bununla birlikte minor ve micro ) deerini
kullanarak, programmzn hangi Python srm ile altrlmas gerektiini kontrol
edebiliriz. imdi programmz yazalm:
import sys
_2x_metni = """
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""
_3x_metni = "Programa hogeldiniz."
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)
Ardndan Pythonn 2.x srmlerinden herhangi birini kullananlar iin bir uyar metni
oluturuyoruz:
_2x_metni = """
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""
240
Bildiiniz gibi Pythonda deiken adlar bir sayyla balamaz. O yzden deiken isminin
bana bir tane alt izgi iareti koyduumuza dikkat edin.
Bu da Python3 kullanclar iin:
_3x_metni = "Programa hogeldiniz."
Artk srm kontrol ksmna geebiliriz. Eer major parametresinin deeri 3ten kkse
_2x_metnini yazdryoruz. Bunun dndaki btn durumlar iin ise _3x_metnini basyoruz:
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)
Grdnz gibi, kullanlan Python srmn kontrol etmek ve eer program istenmeyen
bir Python srmyle altrlyorsa ne yaplacan belirlemek son derece kolay.
Yukardaki ok basit bir kod paras olsa da bize Python programlama diline ve bu dilin farkl
srmlerine dair son derece nemli baz bilgiler veriyor.
Eer bu program Pythonn 3.x srmlerinden biri ile altrdysanz u kty alacaksnz:
Programa hogeldiniz.
Ama eer bu program Pythonn 2.x srmlerinden biri ile altrdysanz, beklentinizin
aksine, yle bir hata mesaj alacaksnz:
File "[Link]", line 5
SyntaxError: Non-ASCII character '\xc4' in file [Link] on line 6, but no
encoding declared; see [Link] for details
Biz _2x_metni adl deikenin ekrana baslmasn beklerken Python bize bir hata mesaj
gsterdi. Aslnda siz bu hata mesajna hi yabanc deilsiniz. Bunu daha nce de
grmtnz. Hatrlarsanz nceki derslerimizde karakter kodlamalarndan bahsederken,
Pythonn 2.x srmlerinde ntanml karakter kodlamasnn ASCII olduundan sz etmitik.
Bu yzden programlarmzda Trke karakterleri kullanrken baz ilave ilemler yapmamz
gerekiyordu.
Burada ilk olarak karakter kodlamasn UTF-8 olarak deitirmemiz gerekiyor. Bunun nasl
yaplacan biliyorsunuz. Programmzn ilk satrna u kodu ekliyoruz:
# -*- coding: utf-8 -*-
Bu satr Python3 iin gerekli deil. nk Python3te ntanml karakter kodlamas zaten
UTF-8. Ama Python2de ntanml karakter kodlamas ASCII. O yzden Python2 kullanclarn
da dnerek UTF-8 kodlamasn aka belirtiyoruz. Bylece programmzn Pythonn 2.x
srmlerinde Trke karakterler yznden kmesini nlyoruz.
Ama burada bir problem daha var. Programmz Trke karakterler yznden kmyor
kmemesine ama, bu defa da Trke karakterleri dzgn gstermiyor:
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal.
Programmz Pythonn 2.x srmlerinden biri ile altranlarn uyar mesajn dzgn bir
ekilde grntleyebilmesini istiyorsanz, Trke karakterler ieren karakter dizilerinin en
241
bana bir u har eklemelisiniz. Yani _2x_metni adl deikeni yle yazmalsnz:
_2x_metni = u"""
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""
Bu karakter dizisinin en bana bir u har ekleyerek bu karakter dizisini unicode olarak
tanmlam olduk. Eer unicode kavramn bilmiyorsanz endie etmeyin. lerde bu
kavramdan bolca sz edeceiz. Biz imdilik, iinde Trke karakterler geen karakter
dizilerinin Python2 kullanclar tarafndan dzgn grntlenebilmesi iin balarna bir u
har eklenmesi gerektiini bilelim yeter.
Eer siz bir Windows kullancsysanz ve btn bu ilemlerden sonra bile Trke karakterleri
dzgn grntleyemiyorsanz, bu durum muhtemelen MS-DOS komut satrnn kulland
yaz tipinin Trke karakterleri gsterememesinden kaynaklanyordur. Bu problemi zmek
iin MS-DOS komut satrnn balk ubuuna sa tklayp zellikler seeneini seerek yaz
tipini Lucida Console olarak deitirin. Bu ilemin ardndan da komut satrnda u komutu
verin:
chcp 1254
242
Burada kullanlan Python serisinin 3.x ten dk olduu durumlar sorguladk. Peki ayn
serinin farkl srmlerini denetlemek istersek ne yapacaz? Mesela Pythonn 3.2 srmn
sorgulamak istersek nasl bir kod kullanacaz?
Bunun iin yle bir ey yazabiliriz:
if sys.version_info.major == 3 and sys.version_info.minor == 2:
...
Bildiiniz gibi, version deikeni Pythonn 3.x srmlerinde una benzer bir kt veriyor:
`Python 3.5.1 (default, 16.02.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
te biz burada in ilecini kullanarak, version deikeninin verdii karakter dizisi iinde 3.2
diye bir ifade aradk.
Bu konuyu daha iyi anlamak iin kendi kendinize baz denemeler yapmanz tavsiye ederim.
Ne kadar ok rnek kod yazarsanz, o kadar ok tecrbe kazanrsnz.
243
BLM 18
Dngler (Loops)
imdiye kadar rendiklerimiz sayesinde Pythonla ufak tefek programlar yazabilecek dzeye
geldik. Mesela rendiimiz bilgiler yardmyla bir nceki blmde ok basit bir hesap
makinesi yazabilmitik. Yalnz o hesap makinesinde farkettiyseniz ok nemli bir eksiklik
vard. Hesap makinemizle hesap yaptktan sonra programmz kapanyor, yeni hesap
yapabilmek iin program yeniden balatmamz gerekiyordu.
Hesap makinesi programndaki sorun, rnein, aadaki program iin de geerlidir:
tuttuum_say = 23
bilbakalm = int(input("Aklmdan bir say tuttum. Bil bakalm ka tuttum? "))
if bilbakalm == tuttuum_say:
print("Tebrikler! Bildiniz...")
else:
print("Ne yazk ki tuttuum say bu deildi...")
Burada tuttuum_say adl bir deiken belirledik. Bu deikenin deeri 23. Kullancdan
tuttuumuz sayy tahmin etmesini istiyoruz. Eer kullancnn verdii cevap tuttuum_say
deikeninin deeriyle aynysa (yani 23 ise), ekrana Tebrikler!... yazs dklecektir. Aksi
halde Ne yazk ki... cmlesi ekrana dklecektir.
Bu program iyi, ho, ama ok nemli bir eksii var. Bu program yalnzca bir kez
kullanabiliyoruz. Yani kullanc yalnzca bir kez tahminde bulunabiliyor. Eer kullanc bir
kez daha tahminde bulunmak isterse program yeniden altrmas gerekecek. Bunun hi
iyi bir yntem olmad ortada. Halbuki yazdmz bir program, ilk almann ardndan
kapanmasa, biz bu program tekrar tekrar altrabilsek, programmz srekli olarak baa
dnse ve program ancak biz istediimizde kapansa ne iyi olurdu deil mi? Yani mesela
yukardaki rnekte kullanc bir say tahmin ettikten sonra, eer bu say bizim tuttuumuz
sayyla ayn deilse, kullancya tekrar tahmin etme frsat verebilsek ok ho olurdu...
Yukarda aklamaya altmz sre, yani bir srecin tekrar tekrar devam etmesi Pythonda
dng (loop ) olarak adlandrlr.
te bu blmde, programlarmzn srekli olarak almasn nasl salayabileceimizi, yani
programlarmz bir dng iine nasl sokabileceimizi reneceiz.
Pythonda programlarmz tekrar tekrar altrabilmek iin dng ad verilen baz ifadelerden
yararlanacaz.
Pythonda iki tane dng bulunur: while ve for
244
Burada a adl bir deiken oluturduk. Bu deikenin deeri 1. Bir sonraki satrda ise while
a == 1: gibi bir ifade yazdk. En bata da sylediimiz gibi while kelimesi, ... iken, olduu
srece gibi anlamlar tayor. Python programlama dilindeki anlam da buna olduka yakndr.
Burada while a == 1 ifadesi programmza yle bir anlam katyor:
a deikeninin deeri 1 olduu srece...
Grdnz gibi cmlemiz henz eksik. Yani belli ki bunun bir de devam olacak. Ayrca
while ifadesinin sonundaki : iaretinden anladmz gibi, bundan sonra gelecek satr girintili
yazlacak. Devam edelim:
a = 1
while a == 1:
print("bilgisayar ldrd!")
245
a = 1
Burada normal bir ekilde a deikenine 1 deerini atadk. imdi devam ediyoruz:
a = 1
while a < 10:
while ile verdiimiz ilk rnekte while a == 1 gibi bir ifade kullanmtk. Bu ifade;
a nn deeri 1 olduu mddete...
gibi bir anlama geliyordu.
while a < 10 ifadesi ise;
a nn deeri 10 dan kk olduu mddete...
anlamna gelir. te burada programmzn sonsuz dngye girmesini engelleyecek bir lt
koymu olduk. Buna gre, a deikeninin imdiki deeri 1 dir. Biz, a nn deeri 10 dan kk
olduu mddete bir ilem yapacaz. Devam edelim:
a = 1
while a < 10:
print("bilgisayar yine ldrd!")
Ne oldu? stediimizi elde edemedik, deil mi? Programmz yine sonsuz dngye girdi. Bu
sonsuz dngy krmak iin Ctrl+C (veya Ctrl+Z )ye basmamz gerekecek yine...
Sizce buradaki hata nereden kaynakland? Yani neyi eksik yaptk da programmz sonsuz
dngye girmekten kurtulamad? Aslnda bunun cevab ok basit. Biz yukardaki kodlar
yazarak Pythona u emri vermi olduk:
a nn deeri 10 dan kk olduu mddete ekrana bilgisayar yine ldrd!
yazsn bas!
a deikeninin deeri 1. Yani 10 dan kk. Dolaysyla Pythonn ekrana o kty basmasn
engelleyecek herhangi bir ey yok...
imdi bu problemi nasl aacamz grelim:
a = 1
while a < 10:
a += 1
print("bilgisayar yine ldrd!")
Burada Pythonun arkada ne iler evirdiini daha net grebiliyoruz. Kodlarmz iine
eklediimiz while dngs sayesinde Python her defasnda a deikeninin deerini kontrol
ediyor ve bu deer 10 dan kk olduu mddete a deikeninin deerini 1 artrp, yeni
deeri ekrana basyor. Bu deikenin deeri 10 a ulatnda ise, bu deerin artk 10 dan
kk olmadn anlayp btn ilemleri durduruyor.
Gelin isterseniz bu while dngsn daha nce yazdmz hesap makinemize uygulayalm:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""
print(giri)
anahtar = 1
while anahtar == 1:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")
if soru == "q":
print("klyor...")
anahtar = 0
elif soru == "1":
say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))
247
Bu kodlarda yaptmz ey aslnda ok basit. ncelikle deeri 1 olan anahtar adl bir deiken
tanmladk. Bir alt satrda ise, programmzn srekli olarak almasn salayacak olan
while dngmz yazyoruz. Programmz, anahtar deikeninin deeri 1 olduu mddete
almaya devam edecek. Daha nce de dediimiz gibi, eer bu anahtar deikeninin deerini
programn bir noktasnda deitirmezsek programmz sonsuza kadar almaya devam
edecektir. nk biz programmz anahtar deikeninin deeri 1 olduu srece almaya
ayarladk. te programmzn bu tr bir sonsuz dngye girmesini nlemek iin bir if
blou oluturuyoruz. Buna gre, eer kullanc klavyede q tuuna basarsa programmz nce
klyor... kts verecek, ardndan da anahtar deikeninin 1 olan deerini 0 yapacaktr.
Bylece artk anahtar n deeri 1 olmayaca iin programmz almaya son verecektir.
Buradaki mantn ne kadar basit olduunu grmenizi isterim.
nce bir deiken
tanmlyoruz, ardndan bu deikenin deeri ayn kald mddete programmz almaya
ayarlyoruz. Bu dngy krmak iin de bata tanmladmz o deikene baka bir deer
atyoruz. Burada anahtar deikenine atadmz 1 ve 0 deerleri tamamen tesaddir.
Yani siz bu deerleri istediiniz gibi deitirebilirsiniz. Mesela yukardaki kodlar yle de
248
yazabilirsiniz:
anahtar = "hoyda bre!"
#anahtar'n deeri 'hoyda bre!' olduu mddete aadaki blou
#altrmaya devam et.
while anahtar == "hoyda bre!":
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")
if soru == "q":
print("klyor...")
anahtar = "dur yolcu!"
#anahtar'n deeri artk 'hoyda bre!' deil, 'dur yolcu'
#olduu iin dngden k ve bylece program sona erdirmi ol.
Grdnz gibi, ama herhangi bir deikene herhangi bir deer atamak ve o deer ayn
kald mddete programn almaya devam etmesini salamak. Kurduumuz bu dngy
krmak iin de o deikene herhangi baka bir deer atamak...
Yukarda verdiimiz son rnekte nce anahtar adl bir deiken atayp, while dngsnn
ileyiini bu deikenin deerine gre yaplandrdk. Ama aslnda yukardaki kodlar ok daha
basit bir ekilde de yazabiliriz. Dikkatlice bakn:
while True:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")
if soru == "q":
print("klyor...")
break
249
Bu yap sayesinde anahtar gibi bir deiken atama zorunluluundan kurtulmu olduk.
Yukardaki kodlarn nasl altn aklayalm:
while True ifadesi yle bir anlama gelir:
True olduu mddete...
Peki ne True olduu mddete? Burada neyin True olmas gerektiini belirtmediimiz iin,
aslnda bu kod paras u anlama geliyor:
Aksi belirtilmedii srece almaya devam et!
Eer yukardaki aklamay biraz bulank bulduysanz u rnei inceleyebilirsiniz:
while True:
print("Bilgisayar ldrd!")
Dikkat ederseniz burada break adl yeni bir ara gryoruz. Bu aracn tam olarak ne ie
yaradn ilerleyen sayfalarda inceleyeceiz. imdilik yalnzca unu bilelim: break kelimesi
ngilizcede krmak, koparmak, bozmak gibi anlamlara gelir. Bu aracn yukardaki grevi
250
dngy krmaktr. Dolaysyla kullanc klavyede q tuuna bastnda, while True ifadesi
ile almaya balayan dng krlacak ve programmz sona erecektir.
Bu yapy daha iyi anlayabilmek iin yle basit bir rnek daha verelim:
#Aksi belirtilmedii srece kullancya
#aadaki soruyu sormaya devam et!
while True:
soru = input("Naslsnz, iyi misiniz?")
#Eer kullanc 'q' tuuna basarsa...
if soru == "q":
break #dngy kr ve programdan k.
Burada programmz kullancya kez Naslsnz, iyi misiniz? sorusunu soracak ve ardndan
kapanacaktr. Bu kodlarda while dngsn nasl kullandmza dikkat edin. Aslnda
programn mant ok basit:
1. ncelikle deeri 1 olan tekrar adl bir deiken tanmlyoruz.
2. Bu deikenin deeri 3 e eit veya 3 ten kk olduu mddete (while tekrar <= 3)
deikenin deerine 1 ekliyoruz (tekrar += 1).
3. Baka bir deyile bool(tekrar <= 3) ifadesi True olduu mddete deikenin
deerine 1 ekliyoruz.
4. tekrar deikenine her 1 ekleyiimizde kullancya Naslsnz, iyi misiniz? sorusunu
soruyoruz (input("Naslsnz, iyi misiniz?")).
5. tekrar deikeninin deeri 3 atnda bool(tekrar <= 3) ifadesi artk False deeri
verdii iin programmz sona eriyor.
Yukardaki uygulamada Pythonn alttan alta neler evirdiini daha iyi grmek iin bu
uygulamay yle yazmay deneyin:
tekrar = 1
while tekrar <= 3:
print("tekrar: ", tekrar)
tekrar += 1
input("Naslsnz, iyi misiniz?")
print("bool deeri: ", bool(tekrar <= 3))
251
Daha nce de dediimiz gibi, bir Python programnn nasl altn anlamann en iyi yolu,
program iinde uygun yerlere print() fonksiyonlar yerletirerek arka planda hangi kodlarn
hangi ktlar verdiini izlemektir. te yukarda da bu yntemi kullandk. Yani tekrar
deikenininin deerini ve bool(tekrar <= 3) ifadesinin ktsn ekrana yazdrarak arka
tarafta neler olup bittiini canl canl grme imkanna kavutuk.
Yukardaki program altrdmzda una benzer ktlar gryoruz:
tekrar: 1
Naslsnz, iyi misiniz? evet
bool deeri: True
tekrar: 2
Naslsnz, iyi misiniz? evet
bool deeri: True
tekrar: 3
Naslsnz, iyi misiniz? evet
bool deeri: False
Grdnz gibi, tekrar deikeninin deeri her dngde 1 artyor. tekrar <= 3 ifadesinin
bool deeri, tekrar adl deikenin deeri 3 aana kadar hep True olacaktr. Bu deikenin
deeri 3 at anda tekrar <= 3 ifadesinin bool deeri False a dnyor ve bylece while
dngs sona eriyor.
Peki size yle bir soru sorsam: Acaba while dngsn kullanarak 1 den 100 e kadar olan
aralktaki ift saylar nasl bulursunuz?
ok basit:
a = 0
while a < 100:
a += 1
if a % 2 == 0:
print(a)
programlar vardr. Ancak for dngs Pythonda o kadar yaygndr ve o kadar geni bir
kullanm alanna sahiptir ki, hemen hemen btn Python programlar bu for dngsnden
en az bir kez yararlanr.
Peki nedir bu for dngs denen ey?
for da tpk while gibi bir dngdr.
Yani tpk while dngsnde olduu gibi,
programlarmzn birden fazla sayda almasn salar. Ancak for dngs while dngsne
gre biraz daha yeteneklidir. while dngs ile yapamayacanz veya yaparken ok
zorlanacanz eyleri for dngs yardmyla ok kolay bir ekilde halledebilirsiniz.
Yalnz, sylediimiz bu cmleden, for dngsnn while dngsne bir alternatif olduu
sonucunu karmayn. Evet, while ile yapabildiiniz bir ilemi for ile de yapabilirsiniz ou
zaman, ama bu dnglerin, belli vakalar iin tek seenek olduu durumlar da vardr. Zira bu
iki dngnn alma mant birbirinden farkldr.
imdi gelelim for dngsnn nasl kullanlacana...
Dikkatlice bakn:
tr_harfler = ""
for harf in tr_harfler:
print(harf)
Burada ncelikle tr_harer adl bir deiken tanmladk. Bu deiken Trkeye zg hareri
tutuyor. Daha sonra bir for dngs kurarak, tr_harer adl deikenin her bir esini tek
tek ekrana yazdrdk.
Peki bu for dngsn nasl kurduk?
for dnglerinin sz dizimi yledir:
for deiken_ad in deiken:
yaplacak_ilem
Bu soyut yaplar kendi rneimize uygulayarak durumu daha net anlamaya alalm:
tr_harfler adl deiken iindeki herbir eyi harf olarak adlandr:
ve harf olarak adlandrlan bu eleri ekrana yazdr.
Yukardaki rnekte bir for dngs yardmyla tr_harer adl deiken iindeki herbir eyi
ekrana yazdrdk. Esasnda for dngsnn yeteneklerini dndmzde bu rnek pek
heyecan verici deil. Zira ayn ii aslnda print() fonksiyonu ile de yapabilirdik:
tr_harfler = ""
print(*tr_harfler, sep="\n")
Aslnda bu ilemi while ile de yapmak mmkn (Bu kodlardaki, henz renmediimiz ksm
imdilik grmezden gelin):
tr_harfler = ""
a = 0
253
Buradaki hata mesajndan da greceiniz gibi int (tam say) trndeki nesneler zerinde
dng kuramyoruz. Hata mesajnda grnen not iterable (zerinde dng kurulamaz)
ifadesiyle kastedilen de budur.
Gelin isterseniz for dngs ile bir rnek daha vererek durumu iyice anlamaya alalm:
saylar = "123456789"
for say in saylar:
print(int(say) * 2)
Burada saylar adl deikenin herbir esini say olarak adlandrdktan sonra, int()
fonksiyonu yardmyla bu eleri tek tek sayya evirdik ve herbir eyi 2 ile arptk.
for dngsnn mantn az ok anlam olmalsnz. Bu dng bir deiken iindeki herbir
eyi tek tek ele alp, iki nokta st ste iaretinden sonra yazdmz kod blounu bu elere
tek tek uyguluyor.
for kelimesi ngilizcede iin anlamna gelir. Dngnn yaps iinde geen in ifadesini de
tanyorsunuz. Biz bu ifadeyi Aitlik leleri konusunu ilerken de grmtk. Hatrlarsanz in
ileci bir enin bir veri tipi iinde bulunup bulunmadn sorguluyordu. Mesela:
>>> a = "[Link]"
>>> "h" in a
True
h esi [Link] adl karakter dizisi iinde getii iin "h" in a kodu True kts
veriyor. Bir de una bakn:
>>> "b" in a
False
254
u anlama geliyor:
istihza karakter dizisi iinde s adn verdiimiz herbir e iin: s
ekrana basma ilemi gerekletir!
esini
Ya da u kod:
saylar = "123456789"
for i in saylar:
if int(i) > 3:
print(i)
u anlama geliyor:
saylar deikeni iinde i adn verdiimiz herbir e iin:
eer sayya dntrlm i deeri 3 ten bykse: i
basma ilemi gerekletir!
esini
ekrana
Yukardaki temsili kodlarn Trkesi bozuk olsa da for dngsnn alma mantn
anlamaya yardmc olacan zannediyorum. Ama yine de, eer bu dngnn mantn
henz kavrayamadysanz hi endie etmeyin. Zira bu dngy olduka sk bir biimde
kullanacamz iin, siz istemeseniz de bu dng kafanzda yer etmi olacak.
Bu for dngsn biraz daha iyi anlayabilmek iin son bir rnek yapalm:
tr_harfler = ""
parola = input("Parolanz: ")
for karakter in parola:
if karakter in tr_harfler:
print("parolada Trke karakter kullanlamaz")
Bu program, kullancya bir parola soruyor. Eer kullancnn girdii parola iinde Trke
karakterlerden herhangi biri varsa kullancy Trke karakter kullanmamas konusunda
uyaryor. Buradaki for dngsn nasl kurduumuzu gryorsunuz. Aslnda burada u
Trke cmleyi Pythoncaya evirmi olduk:
parola deikeni iinde karakter adn verdiimiz herbir e iin:
eer karakter deikeni tr_harer adl deiken iinde geiyorsa:
parolada Trke karakter kullanlamaz uyarsn gster!
Burada kullandmz for dngs sayesinde kullancnn girdii parola adl deiken iindeki
btn karakterlere tek tek bakp, eer baklan karakter tr_harer adl deiken iinde
255
Burada ncelikle, programnzn srekli olarak almasn salamak iin bir while dngs
oluturduk. Buna gre, aksi belirtilmedike (while True) programmz almaya devam
edecek.
while dngsn kurduktan sonra kullancya bir parola soruyoruz (parola = input("Bir
parola belirleyin: "))
Eer kullanc herhangi bir parola belirlemeden dorudan Enter tuuna basarsa, yani parola
deikeninin bool deeri False olursa (if not parola), kullancya parola blm bo
geilemez! uyars veriyoruz.
Eer kullanc tarafndan belirlenen parolann uzunluu 8 karakterden fazlaysa ya da 3
karakterden ksaysa, parola 8 karakterden uzun 3 karakterden ksa olmamal uyars
veriyoruz.
Yukardaki koullar harici durumlar iin ise (else), belirlenen yeni parolay kullancya gsterip
dngden kyoruz (break).
Bu arada, hatrlarsanz eval() fonksiyonunu anlatrken yle bir rnek vermitik:
print("""
Basit bir hesap makinesi uygulamas.
leler:
+
*
/
toplama
karma
arpma
blme
256
toplama
karma
arpma
blme
Burada ncelikle programmz bir while dngs iine aldk. Bylece programmzn ne
zaman sona ereceini kendimiz belirleyebileceiz. Buna gre eer kullanc klavyede q
tuuna basarsa while dngs sona erecek.
Bu programda bizi zellikle ilgilendiren ksm u:
izinli_karakterler = "0123456789+-/*= "
for s in veri:
if s not in izinli_karakterler:
print("Neyin peindesin?!")
quit()
hesap = eval(veri)
257
Grdnz gibi, ilk olarak izinli_karakterler adl bir deiken tanmladk. Program iinde
kullanlmasna izin verdiimiz karakterleri bu deiken iine yazyoruz. Buna gre kullanc
yalnzca 0, 1, 2, 3, 4, 5, 6, 7, 8 ve 9 saylarn, +, -, /, * ve = ilelerini, ayrca boluk karakterini
( ) kullanabilecek.
Kullancnn girdii veri zerinde bir for dngs kurarak, veri iindeki her bir karakterin
izinli_karakterler deikeni iinde yer alp almadn denetliyoruz. zin verilen karakterler
dnda herhangi bir karakterin girilmesi Neyin peindesin?! ktsnn verilip programdan
tamamen klmasna (quit()) yol aacaktr.
Eer kullanc izinli karakterleri kullanarak bir ilem gerekletirmise hesap = eval(veri)
kodu araclyla, kullancnn yapt ilemi eval() fonksiyonuna gnderiyoruz.
Bylece eval() fonksiyonunu daha gvenli bir hale getirebilmek iin basit bir kontrol
mekanizmasnn nasl kurulabileceini grm olduk. Kurduumuz kontrol mekanizmasnn
esas, kullancnn girebilecei veri trlerini snrlamaya dayanyor. Bylece kullanc mesela
yle tehlikeli bir komut giremiyor:
__import__("os").system("dir")
Grdnz gibi, range(0, 10) kodu sayesinde ve for dngsn de kullanarak, 0 ile 10 (10
hari) aralndaki saylar ekrana yazdrdk.
258
Yukardaki kodda range() fonksiyonuna 0 ve 10 olmak zere iki adet parametre verdiimizi
gryorsunuz. Burada 0 says, aralktaki ilk sayy, 10 says ise aralktaki son sayy
gsteriyor. Yani range() fonksiyonunun forml yledir:
range(ilk_say, son_say)
259
else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")
Burada if i == 2 kodu sayesinde for dngs iinde belirttiimiz i adl deikenin deeri 2
olduu anda parolay 3 kez yanl girdiniz... uyars gsterilecektir. Daha nce de birka yerde
ifade ettiimiz gibi, eer yukardaki kodlarn alma mantn anlamakta zorlanyorsanz,
programn uygun yerlerine print() fonksiyonu yerletirerek arka planda Pythonn neler
evirdiini daha net grebilirsiniz. rnein:
for i in range(3):
print(i)
parola = input("parola belirleyin: ")
if i == 2:
print("parolay 3 kez yanl girdiniz.",
"Ltfen 30 dakika sonra tekrar deneyin!")
elif not parola:
print("parola blm bo geilemez!")
elif len(parola) in range(3, 8):
print("Yeni parolanz", parola)
break
else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")
Buna gre range() fonksiyonu iki parametre alyor. Ama aslnda bu fonksiyonun nc bir
parametresi daha vardr. Buna gre formlmz gncelleyelim:
range(ilk_say, son_say, atlama_deeri)
Formldeki son parametre olan atlama_deeri, aralktaki saylarn kaar kaar ilerleyeceini
gsterir. Yani:
>>> for i in range(0, 10, 2):
...
print(i)
...
0
2
4
6
8
Grdnz gibi, son parametre olarak verdiimiz 2 says sayesinde 0 dan 10 a kadar olan
saylar ikier ikier atlayarak ekrana dklyor.
Bu arada, bir ey dikkatinizi ekmi olmal:
260
range() fonksiyonu farkl parametre alan bir fonksiyon. Eer ilk parametre 0 olacaksa bu
parametreyi belirtmek zorunda olmadmz biliyoruz. Yani:
>>> range(10)
Python bu kodu range(0, 10) olarak alglayp buna gre deerlendiriyor. Ancak eer
range() fonksiyonunda nc parametreyi de kullanacaksak, yani range(0, 10, 2) gibi
bir komut vereceksek, parametrenin tamamn da belirtmemiz gerekiyor. Eer burada
btn parametreleri belirtmezsek Python hangi saynn hangi parametreye karlk geldiini
anlayamaz. Yani mesela 0 dan 10 a kadar olan saylar ikier ikier atlayarak ekrana dkmek
iin yle bir ey yazmaya altmz dnn:
>>> for i in range(10, 2):
...
print(i)
Burada Python ne yapmaya altnz anlayamaz. Parantez iinde ilk deer olarak 10, ikinci
deer olarak ise 2 yazdnz iin, Python bu 10 saysn balang deeri; 2 saysn ise biti
deeri olarak alglayacaktr. Dolaysyla da Python bu durumda sizin 10 dan 2 ye kadar olan
saylar listelemek istediinizi zannedecek, range() fonksiyonuyla bu ekilde geriye doru
sayamayacamz iin de bo bir kt verecektir. Bu yzden, Pythonun armamas iin
yukardaki rnei u ekilde yazmalyz:
>>> for i in range(0, 10, 2):
...
print(i)
Ksacas, eer range() fonksiyonunun kaar kaar sayacan da belirtmek istiyorsak, parantez
iinde, gerekli btn parametreleri belirtmeliyiz.
Grdnz gibi, range() fonksiyonunu kullanarak belirli bir aralktaki saylar alabiliyoruz.
Peki bu saylar tersten alabilir miyiz? Elbette:
>>> for i in range(10, 0, -1):
...
print(i)
...
10
9
8
7
6
5
4
3
2
1
Burada range() fonksiyonunu nasl yazdmza ok dikkat edin. Saylar tersten alacamz
iin, ilk parametre 10, ikinci parametre ise 0. nc parametre olarak ise eksi deerli bir
say veriyoruz. Eer saylar hem tersten, hem de mesela 3er 3er atlayarak yazmak isterseniz
yle bir komut verebilirsiniz:
>>> for i in range(10, 0, -3):
...
print(i)
...
10
7
4
1
261
Bu arada, etkileimli kabukta range(10) gibi bir komut verdiinizde range(0, 10) kts
aldnz gryorsunuz. Bu kt, verdiimiz komutun 0 ile 10 aras saylar elde etmemizi
salayacan belirtiyor, ama bu saylar o anda bize gstermiyor. Daha nce verdiimiz
rneklerden de anlalaca gibi, 0 -10 aralndaki saylar grebilmek iin range(10)
ifadesi zerinde bir for dngs kurmamz gerekiyor. range(10) ifadesinin tad
saylar grebilmek iin for dngs kurmak tek seenek deildir. Bu ilem iin yldzl
parametrelerden de yararlanabiliriz. print() fonksiyonunu incelediimiz derste yldzl
parametrelerin nasl kullanldn gstermitik. Dilerseniz imdi bu parametre tipini range()
fonksiyonuna nasl uygulayabileceimizi grelim:
>>> print(*range(10))
0 1 2 3 4 5 6 7 8 9
Burada mesela eer kullanc parolay bo brakrsa parola blm bo geilemez! uyars
gsteriyoruz. imdi o if blounu yle yazdmz dnn:
262
while True:
parola = input("parola belirleyin: ")
if not parola:
pass
elif len(parola) in range(3, 8): #eer parolann uzunluu 3 ile 8 karakter
#aralnda ise...
print("Yeni parolanz", parola)
break
else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")
Burada, eer kullanc parolay bo brakrsa programmz hibir ey yapmadan yoluna devam
edecektir. Yani burada pass deyimi yardmyla programmza u emri vermi oluyoruz:
Eer kullanc parolay bo geerse grmezden gel. Hibir ey yapmadan yoluna
devam et!
Baka bir rnek daha verelim:
while True:
say = int(input("Bir say girin: "))
if say == 0:
break
elif say < 0:
pass
else:
print(say)
Burada eer kullanc 0 saysn girerse programmz sona erer (break deyimini biraz sonra
inceleyeceiz). Eer kullanc 0 dan kk bir say girerse, yani kullancnn girdii say
eksi deerli ise, pass deyimininin etkisiyle programmz hibir ey yapmadan yoluna devam
eder. Bu koullarn dndaki durumlarda ise programmz kullancnn girdii saylar ekrana
yazdracaktr.
Yukarda anlatlan durumlarn dnda, pass deyimini kodlarnz henz taslak aamasnda
olduu zaman da kullanabilirsiniz. rnein, diyelim ki bir kod yazyorsunuz. Programn
gidiatna gre, bir noktada yapmanz gereken bir ilem var, ama henz ne yapacanza
karar vermediniz. Byle bir durumda pass deyiminden yararlanabilirsiniz. Mesela birtakm
if deyimleri yazmay dnyor olun:
if .....:
byle yap
elif .....:
yle yap
else:
pass
Burada henz else blounda ne yaplacana karar vermemi olduunuz iin, oraya bir pass
koyarak durumu imdilik geitiriyorsunuz. Program son haline gelene kadar oraya bir eyler
263
yazm olacaksnz.
Szn z, pass deyimlerini, herhangi bir ilem yaplmasnn gerekli olmad durumlar iin
kullanyoruz. lerde ie yarar programlar yazdnzda, bu pass deyiminin grndnden
daha faydal bir ara olduunu anlayacaksnz.
Burada, eer kullancnn girdii parolann uzunluu 5 karakterden azsa, Parola 5 karakterden
az olmamal! uyars gsterilecektir. Eer kullanc 5 karakterden uzun bir parola belirlemise,
kendisine Parolanz belirlendi! mesajn gsterip, break deyimi yardmyla programdan
kyoruz.
Grdnz gibi, break ifadesinin temel grevi bir dngy sona erdirmek. Buradan
anlayacamz gibi, break ifadesinin her zaman bir dng iinde yer almas gerekiyor. Aksi
halde Python bize yle bir hata verecektir:
SyntaxError: 'break' outside loop
Yani:
SzDizimiHatas: ``break`` dng dnda ..
264
Eer kullanc tarafndan girilen say haneli veya daha az haneli bir say ise, continue
ifadesinin etkisiyle:
>>> print("En fazla haneli bir say girebilirsiniz.")
cmlesi yazdrlacaktr.
Dolaysyla buradan anladmza gre, continue deyiminin grevi kendisinden sonra gelen
her eyin es geilip dngnn bana dnlmesini salamaktr. Bu bilgiye gre, yukardaki
programda eer kullanc, uzunluu karakterden az bir say girerse continue deyiminin
etkisiyle programmz dngnn en bana geri gidiyor. Ama eer kullanc, uzunluu
karakterden fazla bir say girerse, ekrana En fazla haneli bir say girebilirsiniz, cmlesinin
yazdrldn gryoruz.
Siz burada, ilk_metin adl deiken iinde bulunan, ama ikinci_metin adl deiken iinde
bulunmayan eleri ayklamak istiyorsunuz. Yani bu iki metnin ieriini karlatrp, farkl
eleri bulmay amalyorsunuz. Bu ilem iin, bu blmde rendiimiz dnglerden ve
daha nce rendiimiz baka aralardan yararlanabilirsiniz. imdi dikkatlice bakn:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
for s in ilk_metin:
if not s in ikinci_metin:
print(s)
Demek ki ilk_metin adl deikende olup da ikinci_metin adl deikende olmayan eler
bunlarm...
18.4. rnek Uygulamalar
265
Bu kodlarda anlayamayacanz hibir ey yok. Ama dilerseniz biz yine de bu kodlar tek tek
inceleyelim.
lk olarak deikenlerimizi tanmladk:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
Amacmz ilk_metin de olan, ama ikinci_metin de olmayan eleri grmek. Bunun iin
ilk_metin deki eleri tek tek ikinci_metin deki elerle karlatrmamz gerekiyor. Tahmin
edebileceiniz gibi, bir metnin btn elerine tek tek bakabilmenin en iyi yolu for
dnglerini kullanmaktr. O halde dngmz yazalm:
for s in ilk_metin: #ilk_metin'deki, 's' adn verdiimiz btn eler iin
if not s in ikinci_metin: #eer 's' adl bu e ikinci_metin'de yoksa
print(s) #'s' adl eyi ekrana bas
Grdnz gibi, dngleri (for), bool ilelerini (not ) ve aitlik ilelerini (in ) kullanarak,
istediimiz eyi rahatlkla yapabiliyoruz. Burada kullandmz if deyimi, bir nceki satrda
for dngs ile zerinden getiimiz eleri szmemizi salyor. Burada temel olarak u
ilemi yapyoruz:
1. ilk_metin iindeki btn elerin zerinden geiyoruz,
2. Bu eleri belli bir lte gre szyoruz,
3. lte uyan eleri ekrana basyoruz.
Elbette yukarda yaptmz ilemin tersini yapmak da mmkndr. Biz yukardaki kodlarda
ilk_metin de olan, ama ikinci_metin de olmayan eleri szdk. Eer istersek ikinci_metin de
olan, ama ilk_metin de olmayan eleri de szebiliriz. Mantmz yine ayn:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
for s in ikinci_metin: #ikinci_metin'deki, 's' adn verdiimiz btn eler iin
if not s in ilk_metin: #eer 's' adl bu e ilk_metin'de yoksa
print(s) #'s' adl eyi ekrana bas
o
r
y
e
u
r
u
e
e
e
u
Grdnz gibi, yaptmz tek ey, ilk_metin ile ikinci_metin in yerlerini deitirmek oldu.
Kullandmz mantk ise deimedi.
266
Bu arada, yukardaki ktda bizi rahatsz eden bir durum var. ktda baz harer birbirini
tekrar ediyor. Aslnda temel olarak sadece u harer var:
u
o
r
y
e
Ama metin iinde baz harer birden fazla sayda getii iin, doal olarak ktda da bu harer
birden fazla sayda grnyor. Ama tabii ki, eer biz istersek farkl olan her harften yalnzca
bir tanesini ktda grmeyi de tercih edebiliriz. Bunun iin yle bir kod yazabiliriz:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
fark = ""
for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)
Daha sonra fark adl bo bir karakter dizisi tanmlyoruz. Metinler iindeki farkl karakter
dizilerini fark adl bu karakter dizisi iinde depolayacaz.
Ardndan da for dngmz yazyoruz:
for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)
#
#
#
#
#
267
'[Link]'
Burada sanki a adl zgn karakter dizisini deitirmiiz ve [Link] deerini elde etmiiz
gibi grnyor. Ama aslnda a nn durumunda hibir deiiklik yok:
>>> a
'istihza'
Burada sanki deeri istihza olan a adl bir deikene .com deerini eklemiiz gibi
grnyor, ama aslnda biz burada a deikenini yok edip, [Link] deerini ieren, a
adl baka bir deiken tanmladk. Bu durumu nasl teyit edeceinizi biliyorsunuz:
>>> a = 'istihza'
>>> id(a)
15063200
>>> a = a + '.com'
>>> id(a)
15067960
te ilk_metin ile ikinci_metin deikenleri arasndaki farkl hareri yalnzca birer kez
yazdrmak iin kullandmz kodlarda da yukardaki ilemi yaptk:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
fark = ''
for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)
268
Grdnz gibi, nce bo bir fark deikeni oluturduk. Daha sonra bu deikene for
dngs iinde yeni deerler atayabilmek (daha dorusu atarm gibi yapmak) iin fark += s
gibi bir kod kullandk. Bylece for dngsnn her dnnde s adn verdiimiz herbir eyi
tek tek fark deikenine yolladk. Bylece program sonunda elimizde, farkl eleri yalnzca
birer kez ieren fark adl bir deiken olmu oldu. Dediimiz gibi, ilk bata tanmladmz
bo fark deikeni ile, program sonunda farkl deerleri ieren fark deikeni aslnda ayn
deil. Yani biz ilk fark deikenine dngnn her dnnde yeni bir e eklemek yerine,
dngnn her dnnde yeni bir fark deikeni oluturmu oluyoruz. Ama programn
sonunda sanki fark deikenine her defasnda yeni bir deer atamz gibi grnyor ve bu
da bizim iimizi grmemize yetiyor...
Programn bandaki ve sonundaki fark deikenlerinin aslnda birbirinden farkl olduunu
teyit etmek iin u kodlar kullanabilirsiniz:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
fark = ""
print("fark'n ilk tanmland zamanki kimlik numaras: ", id(fark))
for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print("fark'n program sonundaki kimlik numaras: ", id(fark))
Bu durumu id()
Burada iki farkl if deyimini iki farkl satrda yazmak yerine, bu deyimleri and ileci ile
birbirine baladk.
Bu rnek ile ilgili syleyeceklerimiz imdilik bu kadar. Gelin biz imdi isterseniz bilgilerimizi
pekitirmek iin baka bir rnek daha yapalm.
269
Yine ierii u olan bir de [Link] adl baka bir dosya daha olduunu dnelim:
Grsel
Mehmet
Sevgi
Sami
Deniz
Ege
Efe
Ferhat
Frat
Tlay
Derya
Hazan
Mahmut
Tezcan
Cemal
zhan
zkan
zcan
Dilek
Amacmz bu iki dosyann ieriini karlatrp, farkl eleri ortaya sermek. Dediimiz gibi,
bir nceki rnekte izlediimiz yolu burada da takip edebiliriz. Dikkatlice bakn:
d1 = open("[Link]") # dosyay ayoruz
d1_satrlar = [Link]() # satrlar okuyoruz
d2 = open("[Link]")
d2_satrlar = [Link]()
for i in d2_satrlar:
if not i in d1_satrlar:
print(i)
[Link]()
[Link]()
270
Gerekten de mantn bir nceki rnekle tamamen ayn olduunu gryorsunuz. Biz henz
Pythonda dosyalarn nasl ileneceini renmedik, ama daha nce grdmz open()
fonksiyonu yardmyla en azndan dosyalar aabilecek kadar biliyoruz dosya ilemlerinin nasl
yrtleceini...
Burada farkl olarak readlines() adl bir metot gryoruz. Biz burada bu metodun
ayrntlarna inmeyeceiz, ama imdilik dosya ieriinin satrlar halinde okunmasn
saladn bilelim yeter.
Bu arada, eer ktda Trke karakterleri dzgn grntleyemiyorsanz open()
fonksiyonunun encoding adl bir parametresi vastasyla ierii UTF-8 olarak kodlayabilirsiniz:
d1 = open("[Link]", encoding="utf-8") # dosyay ayoruz
d1_satrlar = [Link]() # satrlar okuyoruz
d2 = open("[Link]", encoding="utf-8")
d2_satrlar = [Link]()
for i in d2_satrlar:
if not i in d1_satrlar:
print(i)
[Link]()
[Link]()
Yukardaki rneklerde bir ierik karlatrmas yapp, farkl eleri aykladk. Ayn ekilde
benzer eleri ayklamak da mmkndr. Bu ilemin nasl yaplacan az ok tahmin
ettiinizi zannediyorum:
d1 = open("[Link]")
d1_satrlar = [Link]()
d2 = open("[Link]")
d2_satrlar = [Link]()
for i in d2_satrlar:
if i in d1_satrlar:
print(i)
[Link]()
[Link]()
Burada bir ncekinden farkl olarak if not i in d2_satrlar kodu yerine, doal olarak, if
i in d2_satrlar kodunu kullandmza dikkat edin.
Dosyalar zerinde yaptmz ilemleri tamamladktan sonra close() metodu ile bunlar
kapatmay unutmuyoruz:
[Link]()
[Link]()
271
Yapmamz gereken bir istatistik almas gereince bu metinde her harn ka kez getiini
hesaplamanz gerekiyor.
Bunun iin yle bir program yazabiliriz:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin Python olmasna aldanarak, bu programlama dilinin, adn piton
ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin
ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty
Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl
gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa
da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil
edilmesi neredeyse bir gelenek halini almtr."""
harf = input("Sorgulamak istediiniz harf: ")
say = ''
for s in metin:
if harf == s:
say += harf
print(len(say))
Burada ncelikle metnimizi bir deiken olarak tanmladk. Ardndan da kullancya hangi
har sorgulamak istediini sorduk.
Bu kodlarda tanmladmz say adl deiken, sorgulanan har, metinde getii sayda iinde
barndracaktr. Yani mesela metin 5 tane a har varsa say deikeninin deeri aaaaa
olacaktr.
Sonraki satrlarda for dngmz tanmlyoruz:
for s in metin:
if harf == s:
say += harf
Dediimiz gibi, say deikeni, sorgulanan har, metinde getii sayda barndryor.
Dolaysyla bir harn metinde ka kez getiini bulmak iin say deikeninin uzunluunu
yazdrmamz yeterli olacaktr:
272
print(len(say))
Dilerseniz yukardaki program yazmak iin daha farkl bir mantk da kullanabilirsiniz.
Dikkatlice bakn:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin Python olmasna aldanarak, bu programlama dilinin, adn piton
ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin
ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty
Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl
gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa
da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil
edilmesi neredeyse bir gelenek halini almtr."""
harf = input("Sorgulamak istediiniz harf: ")
say = 0
for s in metin:
if harf == s:
say += 1
print(say)
Burada say deikeninin ilk deeri 0 olarak belirledik. Dng iinde de, sorgulanan harn
metin iinde her geiinde say deikeninin deerini 1 say artrdk. Dolaysyla sorgulanan
harn metinde ka kez getiini bulmak iin say deikeninin son deerini yazdrmamz
yeterli oldu.
Bu komutla, [Link] adl dosyay UTF-8 kodlamas ile atk. Daha sonra kullancya,
sorgulamak istedii har soruyoruz:
273
Ardndan da sorgulanan harn dosyada ka kez getii bilgisini tutacak olan say adl bir
deiken tanmlyoruz:
say = 0
Bu dngy anlamakta bir miktar zorlanm olabilirsiniz. Her zaman sylediimiz gibi,
Pythonda bir kod parasn anlamann en iyi yntemi, gerekli yerlere print() fonksiyonlar
yerletirerek, programn verdii ktlar incelemektir:
for karakter_dizisi in hakknda:
print(karakter_dizisi)
#for karakter in karakter_dizisi:
#
if harf == karakter:
#
say += 1
Grdnz gibi, ilk for dngsnn hemen sonrasna bir print() fonksiyonu yerletirerek
bu dngnn verdii ktlar inceliyoruz. Bu arada, amacmza hizmet etmeyen satrlar da
yorum iine alarak etkisizletirdiimize dikkat edin.
ktya baktmz zaman, yle bir durumla karlayoruz:
Bu programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin Python olmasna aldanarak, bu programlama dilinin, adn piton
ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin
ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty
Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl
gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa
da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil
edilmesi neredeyse bir gelenek halini almtr.
Burada herbir satr ayr bir karakter dizisidir. Eer herbir satrn ayr bir karakter dizisi
olduunu daha net bir ekilde grmek istiyorsanz repr() adl zel bir fonksiyondan
yararlanabilirsiniz:
for karakter_dizisi in hakknda:
print(repr(karakter_dizisi))
#for karakter in karakter_dizisi:
#
if harf == karakter:
#
say += 1
274
Bu ktya ok dikkatlice bakn. repr() fonksiyonu sayesinde Pythonn alttan alta neler
evirdiini bariz bir biimde gryoruz. Karakter dizisinin balang ve bitiini gsteren trnak
iaretleri ve \n ka dizilerinin grnr vaziyette olmas sayesinde herbir satrn ayr bir
karakter dizisi olduunu daha net bir ekilde grebiliyoruz.
Biz yazdmz kodlarda, kullancdan bir harf girmesini istiyoruz. Kullandmz algoritma
gereince bu har metindeki karakter dizileri iinde geen herbir karakterle tek tek
karlatrmamz gerekiyor. input() metodu araclyla kullancdan tek bir karakter alyoruz.
Kullandmz for dngs ise bize bir karakter yerine her satrda bir karakter dizisi veriyor.
Dolaysyla mesela kullanc a harni sorgulamsa, ilk for dngs bu harn karsna Bu
programlama dili Guido Van Rossum adl Hollandal bir programcn adl karakter dizisini
karacaktr. Dolaysyla bizim bir seviye daha alta inerek, ilk for dngsnden elde edilen
deiken zerinde baka bir for dngs daha kurmamz gerekiyor. Bu yzden yle bir kod
yazyoruz:
for karakter_dizisi in hakknda:
for karakter in karakter_dizisi:
...
Bylece i ie iki for dngs oluturmu oluyoruz. sterseniz bu anlattmz eyleri daha
net grmek iin yine print() fonksiyonundan yararlanabilirsiniz:
hakknda = open("[Link]", encoding="utf-8")
harf = input("Sorgulamak istediiniz harf: ")
say = 0
for karakter_dizisi in hakknda:
for karakter in karakter_dizisi:
print(karakter)
#
if harf == karakter:
#
say += 1
#print(say)
karakter deikenin deerini ekrana yazdrarak Pythonn alttan alta neler evirdiini daha
net grebiliyoruz.
Kodlarn geri kalannda ise, kullancnn sorgulad harn, for dngs ile zerinden
getiimiz karakter_dizisi adl deiken iindeki karakterlerle eleip elemediini
denetliyoruz. Eer eleiyorsa, her elemede say deikeninin deerini 1 say artryoruz.
Bylece en elimizde sorgulanan harn metin iinde ka kez getii bilgisi olmu oluyor.
Son olarak da, ilk bata atmz dosyay kapatyoruz:
275
[Link]()
Nihayet bir konunun daha sonuna ulatk. Dngler, ve dnglerle ilikili aralar da epey
ayrntl bir ekilde incelediimize gre gnl rahatlyla bir sonraki konuya geebiliriz.
276
BLM 19
Hata Yakalama
imdiye kadar yazdmz btn programlar, dikkat ettiyseniz tek bir ortak varsaym zerine
kurulu. Buna gre biz, yazdmz programn kullanc tarafndan nasl kullanlmasn
istiyorsak, her zaman o ekilde kullanlacan varsayyoruz. rnein saylar toplayan bir
program yazdmzda, kullancnn her zaman say deerli bir veri gireceini dnyoruz.
Ancak btn iyi niyetimize ramen, yazdmz programlarda iler her zaman beklediimiz
gibi gitmeyebilir. rnein, dediimiz gibi, yazdmz program, kullancnn bir say girmesi
temeli zerine kurgulamsak, kullancnn her zaman say deerli bir veri gireceinden emin
olamayz
Mesela yle bir program yazdmz dnn:
veri1 = input("Karekkn hesaplamak istediiniz say: ")
karekk = int(veri1) ** 0.5
print(veri1, "saysnn karekk: ", karekk)
veri2 = input("Karesini hesaplamak istediiniz say: ")
kare = int(veri2) ** 2
print(veri2, "saysnn karesi: ", kare)
Bu kodlardaki sorunu anlamaya almadan nce dilerseniz kodlar yle bir inceleyelim.
Grdnz gibi, burada kullancnn girecei saylara gre karekk ve kare alma ilemleri
yapyoruz. Bu kodlarda grdmz ** ileci yardmyla bir saynn herhangi bir kuvvetini
hesaplayabileceimizi biliyorsunuz. Mesela 217 nin ka ettiini hesaplamak iin ** ilecini
kullanabiliyoruz:
>>> 21 ** 7
1801088541
Yine bildiiniz gibi, bu ileten, bir saynn karesini hesaplamak iin de yararlanabiliyoruz.
nk neticede bir saynn karesi, o saynn 2. kuvvetidir:
>>> 12 ** 2
144
Ayn ekilde, eer bir saynn, 0.5inci kuvvetini hesaplarsak o saynn karekkn bulmu
oluyoruz. (Bu bilgileri nceki konulardan hatrlyor olmalsnz):
277
last):
in <module>
0.5
for int() with base 10: 'fds'
278
^
SyntaxError: invalid syntax
Bu hata mesajnda bizi ilgilendiren ksm son cmlede yer alyor: SyntaxError, yani Sz dizimi
hatas.
Bu hatalar, programlama diline ilikin bir zelliin yanl kullanmndan veya en basit
ekilde programcnn yapt yazm hatalarndan kaynaklanr. Programcnn hatalar genellikle
SyntaxError eklinde ortaya kar. Bu hatalar ounlukla programc tarafndan farkedilir ve
program kullancya ulamadan nce programc tarafndan dzeltilir. Bu tr hatalarn tespiti
dier hatalara kyasla kolaydr. nk bu tr hatalar programnzn almasn engelledii
iin bunlar farketmemek pek mmkn deildir...
Program kusurlar, baka bir deyile bug lar ise ok daha karmaktr. Kusurlu programlar
ou zaman herhangi bir hata vermeden alr. Ancak programn rettii ktlar beklediiniz
gibi deildir. rnein yazdnz programda bir forml hatas yapm olabilirsiniz. Bu
durumda programnz hibir ey yokmu gibi alr, ancak forml hatal olduu iin
hesaplamalarn sonular yanltr. rnein daha nceki derslerimizde yazdmz u program
yukardaki gibi bir kusur ierir:
say1 = input("Toplama ilemi iin ilk sayy girin: ")
say2 = input("Toplama ilemi iin ikinci sayy girin: ")
print(say1, "+", say2, "=", say1 + say2)
Bu programda kullanc veri girdii zaman, programmz toplama ilemi deil karakter dizisi
birletirme ilemi yapacaktr. Byle bir program alma srasnda hata vermeyecei iin
buradaki sorunu tespit etmek, zellikle byk programlarda ok gtr. Yani sizin dzgn
altn zannettiiniz program aslnda gizliden gizliye bir bug barndryor olabilir.
Ayn ekilde, mesela eval() fonksiyonunun dikkatsizce kullanld programlar da gvenlik
asndan kusurludur. Yani bu tr programlar bir gvenlik kusuru (security bug veya security
aw ) barndrr.
Dediimiz gibi, program kusurlar ok boyutlu olup, burada anlattmzdan ok daha
karmaktr.
Gelelim nc kategori olan istisnalara (exceptions )...
stisnalar, adndan da az ok anlalaca gibi, bir programn almas srasnda ortaya kan,
normalden farkl, istisnai durumlardr. rnein u programa bakalm:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")
ilk_say = int(ilk_say)
ikinci_say = int(ikinci_say)
print(ilk_say, "/", ikinci_say, "=", ilk_say / ikinci_say)
Burada ilk sayy ikinci sayya blen bir program yazdk. Bu program her trl blme ilemini
yapabilir. Ama burada hesaba katmamz gereken iki ey var:
1. Kullanc say yerine, say deerli olmayan bir veri tipi girebilir. Mesela ilk sayya karlk
23, ikinci sayya karlk fdsfd gibi bir ey yazabilir.
279
2. Kullanc bir sayy 0 a blmeye alabilir. Mesela ilk sayya karlk 23, ikinci sayya
karlk 0 yazabilir.
lk durumda programmz yle bir hata verir:
ilk say: 23
ikinci say: fdsfd
Traceback (most recent call last):
File "[Link]", line 5, in <module>
ikinci_say = int(ikinci_say)
ValueError: invalid literal for int() with base 10: 'fdsfd'
Buradaki sorun, say deerli olmayan bir verinin, int() fonksiyonu araclyla sayya
evrilmeye allyor olmas.
kinci durumda ise programmz yle bir hata verir:
ilk say: 23
ikinci say: 0
Traceback (most recent call last):
File "[Link]", line 7, in <module>
print(ilk_say, "/", ikinci_say, "=", ilk_say / ikinci_say)
ZeroDivisionError: division by zero
Buradaki sorun ise, bir saynn 0 a blnmeye allyor olmas. Matematikte saylar 0 a
blnemez...
te bu iki rnekte grdmz ValueError ve ZeroDivisionError birer istisnadr. Yani
kullanclarn, kendilerinden say beklenirken say deerli olmayan veri girmesi veya bir sayy
0a blmeye almas istisnai birer durumdur ve yazdmz programlarn exception (istisna)
retmesine yol aar.
Bylece hata (error ), kusur (bug ) ve istisna (exception ) arasndaki farklar yle bir gzden
geirmi olduk. Yalnz burada unu sylemekte yarar var: Bu kavram arasndaki fark belli
belirsizdir. Yani bu kavramlarn ou yerde birbirlerinin yerine kullanldn da grebilirsiniz.
rnein exception kavram iin Trkede ou zaman hata kelimesini kullanyoruz. Zaten
dikkat ederseniz bu blmn bal da stisna Yakalama deil, Hata Yakalamadr. Ayn
ekilde, ngilizcede de bu kavramlarn ou yerde birbirleri yerine kullanldn grebilirsiniz.
Dolaysyla, konuya kar zel bir ilginiz yoksa, hata, kusur ve istisna kavramlarn birbirinden
ayrmak iin kendinizi zorlamanza gerek yok. Bu kavram ou zaman birbirinin yerine
kullanlyor da olsa, aslnda aralarnda baz farklar olduunu renmiseniz bu blm
amacna ulam demektir.
Konuyla ilgili temel bilgileri edindiimize gre asl meseleye geebiliriz...
ilk_say
= input("ilk say: ")
ikinci_say = input("ikinci say: ")
280
try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ValueError:
print("Ltfen sadece say girin!")
Biliyoruz ki, bir veriyi sayya dntrmek istediimizde eer kullanc say deerli bir
veri yerine harf deerli bir veri girerse programmz ker. Dolaysyla int(ilk_say) ve
int(ikinci_say) kodlar, kullancnn girecei veri trne gre hata retme potansiyeline
sahiptir. O yzden, burada hata vereceini bildiimiz o kodlar try blou iine aldk.
Yine bildiimiz gibi, veri dntrme ilemi srasnda kullancnn uygun olmayan bir veri
girmesi halinde retilecek hata bir ValueErrordr. Dolaysyla except blou iine yazacamz
hata trnn ad da ValueError olacaktr. O yzden ValueError adl hatay yakalayabilmek
iin u satrlar yazdk:
except ValueError:
print("Ltfen sadece say girin!")
Daha nce de sylediimiz gibi, bu hata mesajnda bizi ilgilendiren ksm ZeroDivisionError.
Demek ki bir say 0 a blndnde Python ZeroDivisionError veriyormu. O halde yle
bir kod yazabiliriz:
ilk_say
= input("ilk say: ")
ikinci_say = input("ikinci say: ")
281
try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ZeroDivisionError:
print("Bir sayy 0'a blemezsiniz!")
Grdnz gibi zm gayet mantkl. Birden fazla hata tr reteceini bildiimiz kodlar
yine tek bir try blou iine alyoruz. Hata trlerini ise ayr except bloklar iinde ele alyoruz.
Bir program yazarken, en iyi yaklam, yukarda yaptmz gibi, her hata tr iin kullancya
ayr bir uyar mesaj gstermektir. Bylece kullanclarmz bir hatayla karlatklarnda
sorunu nasl zebilecekleri konusunda en azndan bir kir sahibi olabilirler.
Dediimiz gibi, her hata iin ayr bir mesaj gstermek en iyisidir. Ama tabii dilerseniz hata
trlerini gruplayp hepsi iin tek bir hata mesaj gstermeyi de tercih edebilirsiniz. Bunu nasl
yapacamz grelim:
ilk_say
= input("ilk say: ")
ikinci_say = input("ikinci say: ")
try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except (ValueError, ZeroDivisionError):
print("Bir hata olutu!")
Grdnz gibi, burada ValueError ve ZeroDivisionError adl hata trlerini tek bir
parantez iinde topladk. Burada dikkat edeceimiz nokta, bu hata trlerini gruplarken
bunlar parantez iine almak ve birbirlerinden virglle ayrmaktr.
282
Bu arada, grdnz gibi yukardaki programlar sadece bir kez alp kapanyor. Ama biz
bu programlar tekrar tekrar nasl altrabileceimizi gayet iyi biliyoruz:
while True:
ilk_say = input("ilk say (Programdan kmak iin q tuuna basn): ")
if ilk_say == "q":
break
ikinci_say = input("ikinci say: ")
try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except (ValueError, ZeroDivisionError):
print("Bir hata olutu!")
print("Ltfen tekrar deneyin!")
Pythonda hata yakalamann en yaygn yolu yukarda gsterdiimiz gibi kodlar try...
except bloklar iine almaktr. Programclk maceranzn byk blmnde bu yapy
kullanacaksnz. Ama bazen, kar karya olduunuz duruma veya ihtiyacnza gre try...
except bloklarnn farkl varyasyonlarn kullanmanz gerekebilir. te imdi biz de bu farkl
varyasyonlarn neler olduunu incelemeye alacaz.
Burada ValueError hata trnn ad, invalid literal for int() with base 10: f ise hatann
aklamasdr. Eer istersek, yazdmz programda bu hata aklamasna eriebiliriz.
Dikkatlice bakn:
ilk_say
= input("ilk say: ")
ikinci_say = input("ikinci say: ")
try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ValueError as hata:
print(hata)
Bu program altrp say deerli olmayan bir veri girersek hata kts yle olacaktr:
invalid literal for int() with base 10: 'f'
Grdnz gibi, bu defa ktda hata trnn ad (ValueError) grnmyor. Onun yerine
sadece hata aklamas var.
Diyelim ki kullancya olas bir hata durumunda hem kendi yazdnz hata mesajn, hem
de zgn hata mesajn gstermek istiyorsunuz. te yukardaki yap byle durumlarda ie
yarayabilir:
19.3. try... except... as...
283
ilk_say
= input("ilk say: ")
ikinci_say = input("ikinci say: ")
try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ValueError as hata:
print("Sadece say girin!")
print("orijinal hata mesaj: ", hata)
Burada eer kullanc say yerine harf girerse ValueError hatas alrz. Bu hatay except
ValueError: ifadesiyle yakalyoruz ve hata verildiinde kullancya bir mesaj gstererek
programmzn kmesini engelliyoruz. Ama biliyoruz ki, bu kodlar altrdmzda Pythonn
verebilecei tek hata ValueError deildir. Eer kullanc bir sayy 0a blmeye alrsa Python
284
ZeroDivisionError adl hatay verecektir. Dolaysyla bu hatay da yakalamak iin yle bir
ey yazabiliriz:
try:
blnen = int(input("blnecek say: "))
blen = int(input("blen say: "))
print(blnen/blen)
except ValueError:
print("Ltfen sadece say girin!")
except ZeroDivisionError:
print("Bir sayy 0'a blemezsiniz!")
285
except...
except...
try:
...bir takm iler...
except birHata:
...hata alnnca yaplacak ilemler...
finally:
...hata olsa da olmasa da yaplmas gerekenler...
finally.. blounun en nemli zellii, programn almas srasnda herhangi bir hata
gereklese de gereklemese de iletilecek olmasdr. Eer yazdnz programda mutlaka
ama mutlaka iletilmesi gereken bir ksm varsa, o ksm finally... blou iine yazabilirsiniz.
finally... blou zellikle dosya ilemlerinde iimize yarayabilir. Henz Pythonda
dosyalarla nasl alacamz renmedik, ama ben imdilik size en azndan dosyalarla
alma prensibi hakknda bir eyler syleyeyim.
Genel olarak Pythonda dosyalarla alabilmek iin ncelikle bilgisayarda bulunan bir dosyay
okuma veya yazma kipinde aarz. Dosyay atktan sonra bu dosyayla ihtiyacmz olan
birtakm ilemler gerekletiririz. Dosyayla iimiz bittikten sonra ise dosyamz mutlaka
kapatmamz gerekir. Ancak eer dosya zerinde ilem yaplrken bir hata ile karlalrsa
dosyamz kapatma ilemini gerekletirdiimiz blme hi ulalamayabilir. te finally...
blou byle bir durumda iimize yarayacaktr:
try:
dosya = open("dosyaad", "r")
...burada dosyayla baz ilemler yapyoruz...
...ve anszn bir hata oluuyor...
except IOError:
print("bir hata olutu!")
finally:
[Link]()
Burada finally... blou iine yazdmz [Link]() ifadesi dosyamz gvenli bir
ekilde kapatmaya yaryor. Bu blok, yazdmz program hata verse de vermese de
iletilecektir.
19.6 raise
Bazen, yazdmz bir programda, kullancnn yapt bir ilem normal artlar altnda hata
vermeyecek olsa bile biz ona Python tarz bir hata mesaj gstermek isteyebiliriz. Byle
bir durumda ihtiyacmz olan ey Pythonn bize sunduu raise adl deyimdir. Bu deyim
yardmyla duruma zg hata mesajlar retebiliriz. Bir rnek verelim:
blnen = int(input("blnecek say: "))
if blnen == 23:
raise Exception("Bu programda 23 saysn grmek istemiyorum!")
blen = int(input("blen say: "))
print(blnen/blen)
286
Burada eer kullanc 23 saysn girerse, kullancya bir hata mesaj gsterilip programdan
klacaktr. Biz bu kodlarda Exception adl genel hata mesajn kullandk. Burada Exception
yerine her istediimizi yazamayz. Yazabileceklerimiz ancak Pythonda tanml hata mesajlar
olabilir. rnein NameError, TypeError, ZeroDivisionError, IOError, vb...
Bir rnek verelim:
tr_karakter = ""
parola = input("Parolanz: ")
for i in parola:
if i in tr_karakter:
raise TypeError("Parolada Trke karakter kullanlamaz!")
else:
pass
print("Parola kabul edildi!")
Bu kodlar altrldnda, eer kullanc, iinde Trke karakter geen bir parola yazarsa
kendisine TypeError tipinde bir hata mesaj gsteriyoruz. Eer kullancnn parolas Trke
karakter iermiyorsa hibir ey yapmadan geiyoruz ve bir sonraki satrda kendisine Parola
kabul edildi! mesajn gsteriyoruz.
raise deyimini, bir hata mesajna ek olarak bir ilem yapmak istediimizde de kullanabiliriz.
rnein:
try:
blnen = int(input("blnecek say: "))
blen = int(input("blen say: "))
print(blnen/blen)
except ZeroDivisionError:
print("bir sayy 0'a blemezsiniz")
raise
Burada, eer kullanc bir sayy 0 a blmeye alrsa, normal bir ekilde ZeroDivisionError
hatas verilecek ve programdan klacaktr. Ama bu hata mesajyla birlikte kullancya bir
sayy 0a blemezsiniz, uyarsn da gsterme imkann elde edeceiz. Yani burada except
ZeroDivisionError blounu herhangi bir hatay engellemek iin deil, hataya ilave bilgi
eklemek iin kullanyoruz. Bunu yapmamz salayan ey tabii ki bu kodlar iinde grnen
raise adl deyimdir...
287
dnda kalacaktr. Ama eer istersek yukardaki kodu u ekilde yazarak olas btn hatalar
yakalayabiliriz:
try:
....birtakm iler...
except:
...hata mesaj...
Grdnz gibi, burada herhangi bir hata ad belirtmedik. Bylece Python, yazdmz
programda hangi hata oluursa olusun hepsini yakalayabilecektir.
Bu yntem gznze ok pratik grnm olabilir, ama aslnda hi de yle saylmaz. Hatta
olduka kt bir yntem olduunu syleyebiliriz bunun. nk bu tarz bir kod yazmnn
baz dezavantajlar vardr. rnein bu ekilde btn hata mesajlarn ayn kefeye koyarsak,
programmzda ne tr bir hata oluursa olusun, kullancya hep ayn mesaj gstermek
zorunda kalacaz. Bu da, herhangi bir hata durumunda kullancy ne yapmas gerektii
konusunda doru dzgn bilgilendiremeyeceimiz anlamna geliyor. Yani kullanc bir hataya
sebep olduunda tersliin nereden kaynaklandn tam olarak kestiremeyecektir.
Ayrca, eer kendimiz bir program gelitirirken srekli olarak bu tarz bir yazm benimsersek,
kendi kodlarmzdaki hatalar da maskelemi oluruz. Dolaysyla, Python yukardaki geni
kapsaml except... blou nedeniyle programmzdaki btn hatalar gizleyecei iin,
programmzdaki potansiyel aksaklklar grme imkanmz olmaz. Dolaysyla bu tr bir
yapdan olabildiince kanmakta fayda var. Ancak elbette byle bir kod yazmanz gerektiren
bir durumla da karlaabilirsiniz. rnein:
try:
birtakm kodlar
except ValueError:
print("Yanl deer")
except ZeroDivisionError:
print("Sfra blme hatas")
except:
print("Beklenmeyen bir hata olutu!")
Burada olas btn hata trlerini yakaladktan sonra, bunlarn dnda bizim o anda
ngremediimiz bir hatann olumas ihtimaline kar except: kodunu kullanarak
kullancya genel bir hata mesaj gstermeyi tercih edebiliriz. Bylece beklenmeyen bir hata
meydana gelmesi durumunda da programmz kmek yerine almaya devam edebilecektir.
288
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)
Grdnz gibi, AttributeError adl hatay vereceini bildiimiz ksm bir try... except
blou iine aldk. Eer programmz AttributeError hatasn veriyorsa, programmzn
altrld sistem Pythonn 2.7 srmnden daha dk bir srm kullanyor demektir.
O yzden kullancya _2x_metni ni gsteriyoruz.
Elbette yukardaki program yazmann ok daha dzgn yollar vardr. Ama biz hata yakalama
yntemlerinin buna benzer durumlarda da bir alternatif olarak kullanlabileceini bilelim.
Ayrca, dediimiz gibi, try... except bloklar yukardaki sorunun zm iin en uygun
aralar olmasa da, baz durumlarda hatay nlemenin makul tek yoludur.
289
BLM 20
Karakter Dizileri
Buraya gelene kadar Python programlama diline ilikin epey bilgi edindik. Artk yazdmz
programlarda input() fonksiyonu sayesinde kullancyla iletiim kurabiliyor; if, elif, else
deyimleri yardmyla programlarmzn karar vermesini salayabiliyor; ileler ve dngler
yoluyla programlarmz istediimiz sayda altrabiliyoruz.
Eer buraya kadar olan
blmleri dikkatlice takip ettiyseniz, u ana kadar rendiklerinize dayanarak, Python
giri dzeyinde bildiinizi rahatlkla iddia edebilirsiniz. Zira imdiye kadar rendiklerinizi
kullanarak ufak tefek de olsa ie yarar programlar yazabilecek durumdasnz.
Buraya kadar rendiimiz bilgiler Python programlama dilinin temellerini oluturuyordu.
Temel Python bilgilerini edindiimize gre, artk balang-orta dzey aras konular
incelemeye balayabileceiz.
Bu blmde, nceki derslerde stnkr bakp getiimiz bir konu olan karakter dizilerini
ok daha derinlemesine ele alacaz. Python programlama dili iindeki nemi nedeniyle bu
blm epey uzun olacak.
Aslnda biz karakter dizisi kavramnn ne olduunu biliyoruz. ok kaba bir ekilde ifade etmek
gerekirse, karakter dizileri, adndan da anlalaca gibi, karakterlerin bir araya gelmesiyle
oluan bir dizidir. Karakter dizileri; tek, ift veya trnak iinde gsterilen, teki veri
tiplerinden de bu trnaklar araclyla ayrt edilen zel bir veri tipidir. Teknik olarak ifade
etmek gerekirse, bir nesneyi type() fonksiyonu yardmyla sorguladmzda, eer <class str>
kts alyorsak bu nesne bir karakter dizisidir.
Her ne kadar ayrntlarna girmemi de olsak, dediimiz gibi, biz karakter dizilerini daha
ilk blmlerden bu yana her frsatta kullanyoruz. Dolaysyla bu veri tipinin ne olduu
konusunda bir skntmz yok. Bu blmde, imdiye kadar karakter dizileri ile ilgili
rendiimiz eylere ek olarak, karakter dizilerin metotlarndan da sz edeceiz.
Peki bu metot denen ey de ne oluyor?
Kabaca ifade etmek gerekirse, metotlar Pythonda nesnelerin niteliklerini deitirmemizi,
sorgulamamz veya bu nesnelere yeni zellikler katmamz salayan aralardr. Metotlar
sayesinde karakter dizilerini istediimiz gibi eip bkebileceiz.
Elbette bu blmde bahsedeceimiz tek ey karakter dizilerinin metotlar olmayacak. Bu
blmde ayn zamanda karakter dizilerinin yaps ve zelliklerine dair syleyeceklerimiz de
olacak.
Pythonda imdiye kadar yapabildiimiz eylerin sizi tatmin etmekten uzak olduunu, daha
fazlasn yapabilmek iin sabrszlandnz tahmin edebiliyorum. O halde ne duruyoruz, hi
vakit kaybetmeden yola koyulalm.
290
Burada deeri karakter dizisi olan nesne adl bir deiken tanmladk. Yazdmz
programlarda bu deikene erimek iin, deikenin adn kullanmamz yeterlidir. rnein:
>>> print(nesne)
Tpk kendi tanmladmz karakter dizilerinde olduu gibi, kullancdan gelen karakter
dizilerini de aadaki komut yardmyla ekranda grntleyebiliriz:
print(veri)
for dngsyle elde ettiimiz bu etkiyi u kodlar yardmyla da elde edebileceimizi gayet iyi
biliyor olmalsnz:
print(*nesne, sep="\n")
Burada nesne deikeni iindeki say deerli karakter dizilerini n olarak adlandrdktan sonra,
n deikenlerinin her birini tek tek 2 says ile arptk. Yani arpma ilemini karakter
dizisinin btn elerine tek seferde uygulayabildik. Bu arada, yukardaki rnekte nesne
deikeninin her bir esini for dngs iinde int() fonksiyonu yardmyla tam sayya
evirdiimizi gryorsunuz. Daha nce de defalarca sylediimiz gibi, Pythonda o anda
20.1. Karakter Dizilerinin elerine Erimek
291
elinizde olan verinin tipini bilmeniz ok nemlidir. Eer kendi yazdnz veya mesela input()
fonksiyonundan gelen bir verinin karakter dizisi olduunu bilmezseniz yukardaki kodlar u
ekilde yazma gaetine debilirsiniz:
nesne = "123456789"
for n in nesne:
print(n * 2)
Grdnz gibi, aslnda nesne iindeki eleri 2 ile arpmak isterken, biz her bir eyi
iki kez ekrana yazdrm olduk. nk bildiiniz gibi karakter dizileri ile aritmetik ilemler
yapamyoruz. Eer say deerli karakter dizileri arasnda aritmetik ilem yapacaksak
ncelikle bu karakter dizilerini sayya evirmemiz gerekir. Ayrca gerek bir program iinde
yukardaki gibi bir durumun ne kadar ykc sonular douracabileceini dnn. Yukardaki
program alma srasnda hibir hata vermeyecei iin, siz programnzn dzgn altn
zannederek hayatnza devam edeceksiniz. Ama belki de yukardaki sinsi hata yznden,
programnz kullanan bir irket veri, zaman ve para kaybna urayacak.
Yukardaki rneklerde bir ey daha dikkatinizi ekmi olmal: Grdnz gibi, karakter
dizisinin elerine eriirken bu elerin tamamn elde ediyoruz. Mesela print(nesne)
komutunu verdiimizde veya nesne deikenini bir dng iine aldmzda sonu olarak elde
ettiimiz ey, ilgili karakter dizisinin tamamdr. Yani aslnda karakter dizisinin hangi esine
erieceimizi seemiyoruz. Peki ya biz bir karakter dizisinin elerinin tamamna deil de,
sadece tek bir esine erimek istersek ne yapacaz? Mesela yukardaki rnekte nesne adl
deiken iindeki saylarn tamamn deil de sadece tek bir esini (veya belli bir lte gre
yalnzca baz elerini) 2 ile arpmak istersek nasl bir yol izleyeceiz?
Pythonda karakter dizilerinin iindeki elerin bir sras vardr.
rnein Python
dediimizde, bu karakter dizisinin ilk esi olan P karakterinin sras 0 dr. y karakteri
ise 1. sradadr. Ayn ekilde devam edersek, t karakteri 2., h karakteri 3., o karakteri 4.,
n karakteri ise 5. srada yer alr.
Bu anlattmz soyut durumu bir rnekle somutlatrmaya alalm:
Dedik ki, Python gibi bir karakter dizisinin her bir esinin belli bir sras vardr. te eer
biz bu karakter dizisinin btn elerini deil de, sadece belli karakterlerini almak istersek,
karakter dizisindeki elerin sahip olduu bu sradan yararlanacaz.
Diyelim ki Python karakter dizisinin ilk karakterini almak istiyoruz. Yani biz bu karakter
dizisinin sadece P harne ulamay amalyoruz.
Bu isteimizi nasl yerine getirebileceimizi basit bir rnek zerinde gstermeye alalm:
>>> kardiz = "Python"
292
Burada deeri Python olan kardiz adl bir deiken tanmladk. imdi bu karakter dizisinin
ilk esine erieceiz:
>>> kardiz[0]
'P'
Burada yaptmz ileme ok dikkat edin. Karakter dizisinin istediimiz bir esine ulamak
iin, ilgili enin srasn keli parantezler iinde belirttik. Biz bu rnekte karakter dizisinin
ilk esine ulamak istediimiz iin keli parantez iinde 0 saysn kullandk.
imdi de, ilk verdiimiz rnekteki nesne deikeni iinde yer alan saylar arasndan sadece
birini 2 ile arpmak istediimizi dnelim:
>>> nesne = "123456789"
>>> int(nesne[1]) * 2
4
Burada da ncelikle nesne deikeninin birinci srasnda yer alan eyi (dikkat: sfrnc srada
yer alan eyi deil!) elde etmek iin keli parantezler iinde 1 saysn kullandk. Daha sonra
int() fonksiyonu yardmyla bu karakter dizisini tam sayya evirdik, ki bununla aritmetik
ilem yapabilelim... Son olarak da elimizdeki tam sayy 2 ile arparak istediimiz sonuca
ulatk.
Elbette yukardaki kodlar yle de yazabilirdik:
>>> nesne = "123456789"
>>> say = int(nesne[1])
>>> say * 2
4
Belki farkndasnz, belki de deilsiniz, ama aslnda u noktada karakter dizilerinin ok nemli
bir zellii ile kar karyayz. Grdnz gibi, yukarda bahsettiimiz sra kavram sayesinde
Pythonda karakter dizilerinin btn elerine tek tek ve herhangi bir sra gzetmeksizin
erimemiz mmkn. Mesela yukardaki ilk rnekte kardiz[0] gibi bir yap kullanarak karakter
dizisinin sfrnc (yani ilk) esini, nesne[1] gibi bir yap kullanarak da karakter dizisinin birinci
(yani aslnda ikinci) esini alabildik.
Bu yapnn mantn kavramak iin u rnekleri dikkatlice inceleyin:
>>> kardiz = "Python"
>>> kardiz[0]
'P'
>>> kardiz[1]
'y'
>>> kardiz[3]
'h'
>>> kardiz[5]
293
'n'
>>> kardiz[2]
't'
>>> kardiz[4]
'o'
>>> nesne = "123456789"
>>> nesne[0]
'1'
>>> nesne[1]
'2'
>>> nesne[2]
'3'
>>> nesne[3]
'4'
>>> nesne[4]
'5'
>>> nesne[5]
'6'
>>> nesne[6]
'7'
>>> nesne[7]
'8'
>>> nesne[8]
'9'
Bu forml uygulayarak karakter dizilerinin her bir esine tek tek erimemiz mmkn.
Burada ok nemli bir noktaya daha dikkatinizi ekmek isterim. Yukardaki rneklerden
de grdnz gibi, Pythonda e sralamas 0 dan balyor. Yani bir karakter dizisinin ilk
esinin sras 0 oluyor. Python programlama dilini zellikle yeni renenlerin en sk yapt
hatalardan biri de bir karakter dizisinin ilk esine ulamak iin 1 saysn kullanmalardr.
294
Asla unutmayn, Python saymaya her zaman 0 dan balar. Dolaysyla bir karakter dizisinin
ilk esinin sras 0 dr. Eer ilk eye ulaaym derken 1 saysn kullanrsanz ulatnz e
ilk e deil, ikinci e olacaktr. Bu ayrnty gzden karmamaya dikkat etmelisiniz.
Karakter dizilerinin elerine tek tek eriirken dikkat etmemiz gereken nemli noktalardan
biri de, e sras belirtirken, karakter dizisinin toplam uzunluu dna kmamaktr. Yani
mesela 7 karakterlik bir karakter dizimiz varsa, bu karakter dizisinin son esinin sras 6
olacaktr. nk biliyorsunuz, Python saymaya 0 dan balyor. Dolaysyla ilk karakterin sras
0 olaca iin, 7 karakterlik bir karakter dizisinde son enin sras 6 olacaktr. rnein:
>>> kardiz = "istihza"
>>> len(kardiz)
7
Grdnz gibi, istihza adl karakter dizisinin uzunluu 7. Yani bu karakter dizisi iinde 7
adet karakter var. Bu karakter dizisini incelemeye devam edelim:
>>> kardiz[0]
'i'
Dediimiz gibi, karakter dizisinin ilk esinin sras 0. Dolaysyla son enin sras 6 olacaktr:
>>> kardiz[6]
'a'
Yani;
Bir karakter dizisinin uzunluunun 1 eksii, o karakter dizisinin son esini verir.
Yukardaki forml eer yle yazsaydk hata alrdk:
>>> kardiz[len(kardiz)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
nk len(kardiz) kodu bize karakter dizisinin uzunluunu veriyor. Yani yukardaki istihza
karakter dizisini gz nne alrsak, len(kardiz) kts 7 olacaktr. Dolaysyla istihza
karakter dizisinin son esine ulamak istersek bu deerin 1 eksiini almamz gerekiyor. Yani
len(kardiz)-1.
u ana kadar e sras olarak hep art deerli saylar kullandk. Ancak istersek e sras
olarak eksi deerli saylar da kullanabiliriz. Eer bir karakter dizisine e sras olarak eksi
deerli bir say verirsek Python o karakter dizisini sondan baa doru okumaya balayacaktr.
Yani:
>>> kardiz[-1]
'a'
295
Grdnz gibi -1 says karakter dizisini tersten okuyup, sondan baa doru ilk eyi
veriyor. Dolaysyla, yukarda anlattmz len(kardiz)-1 ynteminin yansra, -1 saysn
kullanarak da karakter dizilerinin son karakterini elde edebiliyoruz. Bir de una bakalm:
>>> kardiz[-2]
'z'
Dediimiz gibi, eksi deerli saylar karakter dizisindeki karakterleri sondan baa doru
elde etmemizi salar. Dolaysyla -2 says, karakter dizisinde sondan bir nceki karakteri
verecektir.
Karakter dizilerinin elerine tek tek erimek amacyla e sras belirtirken, karakter
dizisinin toplam uzunluu dna kmamamz gerektiini sylemitik. Peki karakter dizisinin
uzunluunu aan bir say verirsek ne olur? Ne olacan yukardaki rneklerden birinde
grmtk aslnda. Ama konunun neminden dolay bir kez daha tekrar edelim.
>>> kardiz = "istihza"
>>> kardiz[7]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
...veya:
>>> kardiz[-8]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
Eer karakter dizisinin uzunluunu aan bir say belirtirsek Python bize IndexError trnde
bir hata mesaj verecektir.
Grdnz gibi, kardiz[0], kardiz[1], kardiz[2], vb. komutlarla karakter dizisinin
elerine eriebiliyoruz. Burada e sralarn tek tek yazmak yerine range() fonksiyonunu
kullanarak da elere tek tek eriebilirsiniz:
for i in range(7):
print(kardiz[i])
Bu kodlarda, kardiz[0], kardiz[1], kardiz[2] eklinde e sralarn tek tek elle yazmak
yerine, range(7) aralndaki saylar bir for dngsne alyoruz.
Bylece Python
kardiz[e_sras] gibi bir yap iinde e_sras yerine range(7) aralndaki btn saylar
(yani 0, 1, 2, 3, 4, 5, 6 saylarn) tek tek uyguluyor.
Burada aklnza hemen yle bir soru gelmi olabilir:
Biz kendi tanmladmz karakter dizisinin uzunluunun toplam 7 karakter
olduunu bildiimiz iin yukardaki rnekte range() fonksiyonunu range(7)
eklinde kullanabildik.
Ama baka kaynaktan gelen bir karakter dizisinin
uzunluunu nasl bileceiz?
Aslnda bu sorunun cevab ok basit. Uzunluunu bilmediiniz karakter dizileri iin range()
fonksiyonuyla birlikte len() fonksiyonundan yararlanabilirsiniz. Nasl m? Hemen bir rnek
verelim:
296
Grdnz gibi, kullancnn girdii kelimenin uzunluu ka ise o say otomatik olarak
range() fonksiyonuna atanyor. Diyelim ki kullanc Ferhat ismini girmi olsun. Bu kelimede
toplam 6 karakter var. Dolaysyla Python for satrn yle yorumlayacaktr:
for i in range(6):
...
297
Burada ilk i deikeninin deerini 1 say artrdk. Bylece 0 says 1 e, 1 says 2 ye, 2
says 3 e... dnm oldu. Bu ekilde kullanclarnza ok daha doal grnen bir kt
verebilmi oluyorsunuz. Eer bu ilemi yapmazsanz, kullanclarnzn doal grnmeyen
bir kt almalarnn yansra, programnzn verdii kt kimi durumlarda epey yanltc da
olabilir...
Grdnz gibi, karakter dizisine keli parantez iinde baz deerler vererek bu karakter
dizisini dilim dilim ayrdk. Peki bunu nasl yaptk? Yukardaki rneklerde yle bir yap
gzmze arpyor:
karakter_dizisi[alnacak_ilk_enin_sras:alnacak_son_enin_srasnn_bir_fazlas]
298
Burada alacamz ilk enin sra numaras 0. Yani istanbul karakter dizisindeki i har.
Alacamz son enin sra numarasnn 1 fazlas ise 3. Yani 2. sradaki t har. te
karakter_dizisi[0:3] dediimizde, Python 0. e ile 3. e arasnda kalan btn eleri
bize verecektir. Bizim rneimizde bu aralktaki eler i, s ve t hareri. Dolaysyla Python
bize istanbul kelimesindeki ist ksmn dilimleyip veriyor.
Bu bilgileri kullanarak yle bir uygulama yazalm:
site1
site2
site3
site4
=
=
=
=
"[Link]"
"[Link]"
"[Link]"
"[Link]"
Bu rnek Pythonda dilimleme ilemlerinin yaps ve zellikleri hakknda bize epey bilgi
veriyor. Grdnz gibi, hem art hem de eksi deerli saylar kullanabiliyoruz. nceki
blmden hatrlayacanz gibi, eer verilen say eksi deerliyse Python karakter dizisini
sadan sola (yani sondan baa doru) okuyacaktr. Yukardaki rnekte isim[4:-4] yapsn
kullanarak, site1, site2, site3, site4 adl karakter dizilerini, ilk drt ve son drt karakterler
hari olacak ekilde dilimledik. Bylece elimizde ilk drt ve son drt karakter arasndaki btn
karakterler kalm oldu. Yani google, istihza, yahoo ve gnu.
Btn bu anlattklarmz daha iyi anlayabilmek iin bir rnek daha verelim:
ata1
ata2
ata3
ata4
ata5
=
=
=
=
=
Burada be adet atasz verdik. Bizim grevimiz, bu ataszlerinin sonunda bulunan nlem
iaretlerini ortadan kaldrmak:
for ata in ata1, ata2, ata3, ata4, ata5:
print(ata[0:-1])
Burada yaptmz ey u: ata1, ata2, ata3, ata4 ve ata5 adl deikenlerin her birini ata
olarak adlandrdktan sonra ata adl deikenin en bandan en sonuna kadar olan ksm
dilimleyip aldk. Yani ata[0] ile ata[-1] arasnda kalan btn karakterleri elde etmi olduk.
Peki bu nlem iaretlerini kaldrdktan sonra bunlarn yerine birer nokta koymak istersek ne
yapacaz?
O da ok basit bir ilem:
for ata in ata1, ata2, ata3, ata4, ata5:
print(ata[0:-1] + ".")
Grdnz gibi, son karakter olan nlem iaretini attktan sonra onun yerine bir nokta
iareti koymak iin yaptmz tek ey, dilimlediimiz karakter dizisine, art iareti (+ )
yardmyla bir . karakteri eklemekten ibarettir.
Bylece karakter dizilerini nasl dilimleyeceimizi renmi olduk. Bu konuyu kapatmadan
nce dilimlemeye ilikin baz ayrntlardan sz edelim. Diyelim ki elimizde yle bir karakter
dizisi var:
299
Bu karakter dizisi iinden sadece Sana ksmn dilimlemek iin yle bir ey yazabileceimizi
biliyorsunuz:
>>> kardiz[0:4]
'Sana'
Burada 0. karakterden 4. karaktere kadar olan ksm dilimlemi oluyoruz. Python bize bu
tr durumlarda yle bir kolaylk salar: Eer karakter dizisi iinden alnan ilk karakterin
srasn gsteren say 0 ise, bu sayy belirtmesek de olur. Yani kardiz[0:4] kodunu yle
de yazabiliriz:
>>> kardiz[:4]
'Sana'
Grdnz gibi, ilk sra saysn yazmazsak Python ilk sayy 0 kabul ediyor.
imdi de ayn karakter dizisi iindeki Vadetmedim ksmn dilimlemeye alalm:
>>> kardiz[17:27]
'Vadetmedim'
Burada da 17. karakter ile 27. karakter arasnda kalan btn karakterleri dilimledik. Tpk,
alacamz ilk karakterin sras 0 olduunda bu sayy belirtmemize gerek olmad gibi,
alacamz son karakterin sras karakter dizisinin sonuncu karakterine denk geliyorsa o sayy
da yazmamza gerek yok. Yani yukardaki kardiz[17:27] kodunu yle de yazabiliriz:
>>> kardiz[17:]
'Vadetmedim'
Pythondaki bu dilimleme zelliini kullanarak karakter dizilerini istediiniz gibi eip bkebilir,
evirip evirebilirsiniz.
Pythondaki bu dilimleme yaps ilk bakta gznze biraz karmakm gibi grnebilir. Ama
aslnda hi de yle deildir. Bu yapnn mantn bir kez kavradktan sonra kodlarnz hatasz
bir ekilde yazabilirsiniz.
Dilimleme yapsn daha iyi anlayabilmek iin kendi kendinize baz denemeler yapmanz
tavsiye ederim. Bu yapnn nasl altn anlamann en iyi yolu bol bol rnek kod yazmaktr.
300
Grdnz gibi, Sana Gl Bahesi Vadetmedim adl karakter dizisi iindeki btn
karakterler sondan baa doru ekrana dizildi.
Aslnda bu komutla Pythona yle bir emir vermi oluyoruz:
kardiz deikeni iindeki btn karakterleri, en son karakterden ilk karaktere
kadar sondan baa doru tek tek ekrana yazdr!
Bildiiniz gibi, eer almak istediimiz karakter, dizi iindeki ilk karakterse bu karakterin dizi
iindeki srasn belirtmemize gerek yok. Ayn ekilde, eer almak istediimiz karakter, dizi
iindeki son karakterse, bu karakterin de dizi iindeki srasn belirtmemize gerek yok. te
yukardaki rnekte bu kuraldan yararlandk.
Eer bir karakter dizisinin tamamnn deil de, sadece belli bir ksmnn ters evrilmi
halini elde etmek istiyorsanz elbette yapmanz gereken ey, almak istediiniz ilk ve son
karakterlerin srasn parantez iinde belirtmek olacaktr. Mesela yukardaki karakter dizisinde
sadece Gl kelimesini ters evirmek istersek yle bir ey yazabiliriz:
>>> kardiz[7:4:-1]
'lG'
Yukardaki rnek, karakter dizisi dilimlemeye ilikin olarak bize baz baka ipular da veriyor.
Grdnz gibi, keli parantez iinde toplam adet parametre kullanabiliyoruz. Yani
formlmz yle:
kardiz[ilk_karakter:son_karakter:atlama_says]
Burada istanbul adl karakter dizisinin btn elerini birer birer ekrana dktk. Bir de
una bakalm:
>>> kardiz[0:8:2]
'itnu'
Burada ise istanbul adl karakter dizisinin btn elerini ikier ikier atlayarak ekrana
dktk. Yani bir karakter yazp bir karakter atladk (istanbul).
Pythonn kurallar gereince yukardaki kodu yle yazabileceimizi de biliyorsunuz:
>>> kardiz[::2]
'itnu'
Eer karakter dizisini ters evirmek istiyorsak, yukardaki rnei eksi deerli bir atlama says
ile yazmamz gerekir:
>>> kardiz = "istanbul"
>>> kardiz[::-1]
'lubnatsi'
301
>>> kardiz[::-2]
'lbas'
Dediimiz gibi, yukardaki yntemi kullanarak karakter dizilerini ters evirebilirsiniz. Ama eer
isterseniz reversed() adl bir fonksiyondan da yararlanabiliriz.
Gelelim bu fonksiyonun nasl kullanlacana... nce yle bir deneme yapalm:
>>> reversed("Sana Gl Bahesi Vadetmedim")
<reversed object at 0x00E8E250>
Grdnz gibi, bu fonksiyonu dz bir ekilde kullandmzda bize bir reversed nesnesi
vermekle yetiniyor. Buna benzer bir olguyla range() fonksiyonunda da karlamtk:
>>> range(10)
range(0, 10)
Hatrlarsanz, range(10) gibi bir komutun ieriini grebilmek iin bu komut zerinde bir for
dngs kurmamz gerekiyordu:
for i in range(10):
print(i)
...veya:
print(*range(10))
...veya:
print(*reversed("Sana Gl Bahesi Vadetmedim"), sep="")
Nasl input() fonksiyonu kt olarak bir karakter dizisi ve len() fonksiyonu bir say veriyorsa,
sorted() fonksiyonu da bize kt olarak, birka blm sonra inceleyeceimiz liste adl bir veri
tipi verir.
302
...veya:
for i in sorted("kitap"):
print(i, end="")
Burada Trke bir karakter olan harnin dzgn sralanamadn gryoruz. Bu sorun
btn Trke karakterler iin geerlidir.
Bu sorunu amak iin yle bir yntem deneyebilirsiniz:
>>>
>>>
>>>
>>>
import locale
[Link](locale.LC_ALL, "Turkish_Turkey.1254") #Windows iin
[Link](locale.LC_ALL, "tr_TR") #GNU/Linux iin
sorted("iek", key=[Link])
Burada locale adl bir modlden yararlandk. locale de tpk sys, os ve keyword gibi bir
modl olup, iinde pek ok deiken ve fonksiyon barndrr.
locale modl bize belli bir dilin kendine has zelliklerine gre programlama yapma
imkan verir. rnein bu modlnn iinde yer alan fonksiyonlardan biri olan setlocale()
fonksiyonunu kullanarak, programmzda ntanml dil ayarlarna uygun bir ekilde
programlama yapma olana salarz.
Bu modl ilerleyen derslerde daha ayrntl bir ekilde inceleyeceiz. O yzden locale
modln bir kenara brakp yolumuza devam edelim.
Yukardaki rnekte Trke karakterleri doru sralayabilmek iin sorted() fonksiyonunu nasl
kullandmza dikkat edin:
>>> sorted("iek", key=[Link])
Burada sorted() metodunun key adl zel bir parametresine [Link] deerini vererek
Trkeye duyarl bir sralama yaplmasn saladk. Yukardaki yntem pek ok durumda
iinize yarar. Ancak bu yntem tek bir yerde ie yaramaz. Dikkatlice bakn:
>>> sorted("afgdhki", key=[Link])
['a', 'd', 'f', 'g', 'h', 'i', '', 'k']
303
Grdnz gibi, bu yntem i harni harnden nce getiriyor. Halbuki Trk alfabesine
gre bunun tersi olmalyd. Buna benzer problemlerle ngiliz alfabesi dndaki pek ok
alfabede karlarsnz. Dolaysyla bu sadece Trkeye zg bir sorun deil.
Bu soruna kar yle bir kod da yazabilirsiniz:
>>> harfler = "abcdefghijklmnoprstuvyz"
>>> evrim = {i: [Link](i) for i in harfler}
>>> sorted("afgdhki", key=[Link])
['a', 'd', 'f', 'g', 'h', '', 'i', 'k']
Grdnz gibi burada ilk i olarak Trk alfabesindeki btn hareri harer adl bir
deikene atadk. Daha sonra ise yle bir kod yazdk:
>>> evrim = {i: [Link](i) for i in harfler}
Burada henz renmediimiz bir yap var, ama ne olup bittiini daha iyi anlamak iin bu
evrim deikeninin ieriini kontrol etmeyi deneyebilirsiniz:
>>> print(evrim)
{'': 8, '': 10, 'v': 26, 'g': 7, '': 22, 'a': 0, 'c': 2, 'b': 1, 'e': 5,
'd': 4, '': 3, 'f': 6, 'i': 11, 'h': 9, 'k': 13, 'j': 12, 'm': 15, 'l': 14,
'o': 17, 'n': 16, 'p': 19, 's': 21, 'r': 20, 'u': 24, 't': 23, '': 18,
'y': 27, 'z': 28, '': 25}
Bu ktya dikkatlice bakarsanz, her bir harn bir sayya karlk gelecek ekilde birbiriyle
eletirildiini greceksiniz. Mesela har 8 ile, f har 6 ile elemi. Yine dikkatlice
bakarsanz, biraz nce bize sorun karan harnin 10, i harnin ise 11 ile eletiini
greceksiniz. Evet, doru tahmin ettiniz. Hareri saylarla eletirerek, Pythonn harer
yerine saylar sralamasn salayacaz. Bunu da yine key parametresini kullanarak
yapyoruz:
>>> sorted("afgdhki", key=[Link])
Bu yapy daha iyi anlayabilmek iin kendi kendinize baz denemeler yapn. Eer burada
olan biteni anlamakta zorlanyorsanz hi endie etmeyin. Bir-iki blm sonra bunlar da
kolayca anlayabilecek duruma geleceksiniz. Bizim burada bu bilgileri vermekteki amacmz,
Pythonn Trke harerle sralama ilemini sorunsuz bir ekilde yapabileceini gstermektir.
Bu esnada bir-iki yeni bilgi krnts da kapmanz salayabildiysek kendimizi baarl sayacaz.
304
Burada E har ile, meyve deikeninin ilk har dnda kalan btn hareri birletirdik.
Bir rnek daha verelim.
Elimizde yle drt adet internet sitesi adresi olsun:
site1
site2
site3
site4
=
=
=
=
"[Link]"
"[Link]"
"[Link]"
"[Link]"
Bizim amacmz bu adreslerin her birinin ba tarafna http:// ifadesini eklemek. Bunun iin
de yine karakter dizisi birletirme ilemlerinden yararlanabiliriz. Dikkatlice inceleyin:
site1
site2
site3
site4
=
=
=
=
"[Link]"
"[Link]"
"[Link]"
"[Link]"
Eer www. ksmlarn atmak isterseniz karakter dizisi birletirme ilemleri ile birlikte
dilimleme yntemini de kullanmanz gerekir:
for i in site1, site2, site3, site4:
print("[Link] i[4:], sep="")
Belki farkndayz, belki de deiliz, ama aslnda yukardaki rnekler karakter dizileri hakknda
bize ok nemli bir bilgi veriyor. Dikkat ettiyseniz yukardaki rneklerde karakter dizileri
zerinde bir deiiklik yapmz gibi grnyor. Esasnda yle de denebilir. Ancak burada
nemli bir ayrnt var. Yukardaki rneklerde grdmz deiiklikler kalc deildir. Yani
aslnda bu deiikliklerin orijinal karakter dizisi zerinde hibir etkisi yoktur. Gelin isterseniz
bunu teyit edelim:
>>> kardiz = "istihza"
>>> "" + kardiz[1:]
'stihza'
Dediimiz gibi, sanki burada istihza karakter dizisini stihza karakter dizisine evirmiiz
gibi duruyor. Ama aslnda yle deil:
>>> print(kardiz)
istihza
Grdnz gibi, kardiz deikeninin orijinalinde hibir deiiklik yok. Ayrca burada ""
+ kardiz[1:] satr ile elde ettiiniz sonuca tekrar ulamanzn imkan yok. Bu deiiklik
kaybolmu durumda. Peki bunun sebebi nedir?
Bunun nedeni, karakter dizilerinin deitirilemeyen (immutable ) bir veri tipi olmasdr.
Pythonda iki tr veri tipi bulunur: deitirilemeyen veri tipleri (immutable datatypes ) ve
deitirilebilen veri tipleri (mutable datatypes ). Bizim imdiye kadar grdmz veri tipleri
305
(saylar ve karakter dizileri), deitirilemeyen veri tipleridir. Henz deitirilebilen bir veri tipi
grmedik. Ama birka blm sonra deitirilebilen veri tiplerini de inceleyeceiz.
Neyse... Dediimiz gibi, karakter dizileri zerinde yaptmz deiikliklerin kalc olmamasn
nedeni, karakter dizilerinin deitirilemeyen bir veri tipi olmasdr. Pythonda bir karakter
dizisini bir kez tanmladktan sonra bu karakter dizisi zerinde artk deiiklik yapamazsnz.
Eer bir karakter dizisi zerinde deiiklik yapmanz gerekiyorsa, yapabileceiniz tek ey
o karakter dizisini yeniden tanmlamaktr. Mesela yukardaki rnekte kardiz deikeninin
tuttuu karakter dizisini deitirmek isterseniz yle bir kod yazabilirsiniz:
>>> kardiz = "" + kardiz[1:]
>>> print(kardiz)
stihza
Burada yaptmz ey kardiz deikeninin deerini deitirmek deildir. Biz burada aslnda
bambaka bir kardiz deikeni daha tanmlyoruz. Yani ilk kardiz deikeni ile sonraki kardiz
deikeni ayn eyler deil. Bunu teyit etmek iin nceki derslerimizde grdmz id()
fonksiyonundan yararlanabilirsiniz:
>>> kardiz = "istihza"
>>> id(kardiz)
3075853248
>>> kardiz = "" + kardiz[1:]
>>> id(kardiz)
3075853280
Grdnz gibi, ilk kardiz deikeni ile sonraki kardiz deikeni farkl kimlik numaralarna
sahip. Yani bu iki deiken bellek iinde farkl adreslerde tutuluyor. Daha dorusu, ikinci
kardiz, ilk kardiz i silip zerine yazyor.
Her ne kadar kardiz = "" + kardiz[1:] kodu kardiz in deerini aslnda deitirmiyor olsa
da, sanki kardiz deikeninin tuttuu karakter dizisi deiiyormu gibi bir etki elde ediyoruz.
Bu da bizi memnun etmeye yetiyor...
Yukardaki rnekte karakter dizisinin ba ksm zerinde deiiklik yaptk. Eer karakter
dizisinin ortasnda kalan bir ksm deitirmek isterseniz de yle bir ey yazabilirsiniz:
>>> kardiz = "istihza"
>>> kardiz = kardiz[:3] + "H" + kardiz[5:]
>>> kardiz
'istHza'
Grdnz gibi, yukardaki kodlarda karakter dizilerini dilimleyip birletirerek, yani bir
bakma kesip bierek istediimiz kty elde ettik.
Mesela ilk rnekte kardiz deikeninin ilk karakteri dnda kalan ksmn (kardiz[1:])
har ile birletirdik ("" + kardiz[1:]").
kinci rnekte ise kardiz deikeninin ilk karakterine H ifadesini ekledik ve sonra buna
kardiz deikeninin 5. karakterinden sonraki ksmn ilave ettik.
Karakter dizileri zerinde deiiklik yapmanzn hangi durumlarda gerekli olacan gsteren
bir rnek daha verip bu konuyu kapatalm.
306
Diyelim ki, bir kelime iindeki sesli ve sessiz hareri birbirinden ayrmanz gereken bir
program yazyorsunuz. Yani mesela amacnz istanbul kelimesi iinde geen i, a ve u
harerini bir yerde, s, t, n, b ve l harerini ise ayr bir yerde toplamak. Bunun iin yle
bir program yazabilirsiniz:
sesli_harfler = "aeiou"
sessiz_harfler = "bcdfghjklmnprstvyz"
sesliler = ""
sessizler = ""
kelime = "istanbul"
for i in kelime:
if i in sesli_harfler:
sesliler += i
else:
sessizler += i
print("sesli harfler: ", sesliler)
print("sessiz harfler: ", sessizler)
Ardndan da, sesli ve sessiz harerini ayklayacamz kelimedeki sesli harer ve sessiz harer
iin bo birer karakter dizisi tanmlyoruz:
sesliler = ""
sessizler = ""
imdi bu kelime zerinde bir for dngs kuruyoruz ve kelime iinde geen herbir harfe tek
tek bakyoruz. Kelime iinde geen harerden, sesli_harer deikeninde tanml karakter
dizisinde geenleri sesliler adl deikene atyoruz. Aksi durumda ise, yani kelime iinde
geen harerden, sessiz_harer deikeninde tanml karakter dizisinde geenleri, sessizler
adl deikene gnderiyoruz:
for i in kelime:
if i in sesli_harfler:
sesliler += i
else:
sessizler += i
Bunun iin for dngs iinde basit bir if-else blou tanmladmz gryorsunuz.
Ayrca bunu yaparken, sesliler ve sessizler adl deikenlere, for dngsnn her bir
dnnde yeni bir harf gnderip, bu deikenleri, dngnn her dnnde yeni batan
tanmladmza dikkat edin. nk, dediimiz gibi, karakter dizileri deitirilemeyen veri
tipleridir. Bir karakter dizisi zerinde deiiklik yapmak istiyorsak, o karakter dizisini batan
tanmlamamz gerekir.
307
20.6.1 dir()
lk olarak dir() adl zel bir fonksiyondan sz edeceiz. Bu metot bize Pythondaki bir
nesnenin zellikleri hakknda bilgi edinme imkan verecek. Mesela karakter dizilerinin bize
hangi metotlar sunduunu grmek iin bu fonksiyonu yle kullanabiliriz:
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', 'capitalize', 'center', 'count', 'encode', 'endswith',
'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha',
'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']
308
>>> dir("")
Burada dir() fonksiyonuna parametre olarak bo bir karakter dizisi verdik. Bu kodun
dir(str) kodundan hibir fark yoktur. Bu komut da bize karakter dizilerinin metotlarn
listeler.
Ayn etkiyi dilersek yle de elde edebiliriz:
>>> a = "karakter"
>>> dir(a)
Karakter dizilerinin metotlarn listelemek iin, siz hangi yntem kolaynza geliyorsa onu
kullanabilirsiniz. Bu satrlarn yazar genellikle u yntemi kullanyor:
>>> dir("")
dir("") komutunun ktsndan da greceiniz gibi, karakter dizilerinin epey metodu var.
Metot listesi iinde bizi ilgilendirenler banda veya sonunda _ iareti olmayanlar. Yani unlar:
>>> for i in dir(""):
...
if "_" not in i[0]:
...
print(i)
...
Bu arada bu metotlar listelemek iin nasl bir kod kullandmza dikkat edin:
for i in dir(""):
if "_" not in i[0]:
print(i)
Burada dir("") komutunun ierdii her bir metoda tek tek bakyoruz. Bu metotlar iinde, ilk
har _ karakteri olmayan btn metotlar listeliyoruz. Bylece istediimiz listeyi elde etmi
oluyoruz. sterseniz ilgilendiimiz metotlarn saysn da ktya ekleyebiliriz:
saya = 0
for i in dir(""):
if "_" not in i[0]:
saya += 1
print(i)
print("Toplam {} adet metot ile ilgileniyoruz.".format(saya))
Burada da, ilk karakteri _ olmayan her bir metot iin saya deikeninin deerini 1 artryoruz.
Bylece programn sonunda saya deikeni ilgilendiimiz metot saysn gstermi oluyor.
Eer her metodun soluna, sra numarasn da eklemek isterseniz elbette yle bir kod da
yazabilirsiniz:
saya = 0
for i in dir(""):
if "_" not in i[0]:
saya += 1
print(saya, i)
print("Toplam {} adet metot ile ilgileniyoruz.".format(saya))
309
20.6.2 enumerate()
Eer yazdnz bir programda numaralandrmaya ilikin ilemler yapmanz gerekiyorsa
Pythonn size sunduu ok zel bir fonksiyondan yararlanabilirsiniz. Bu fonksiyonun ad
enumerate().
Gelelim bu fonksiyonun nasl kullanlacana... nce yle bir deneme yapalm:
>>> enumerate("istihza")
<enumerate object at 0x00E3BC88>
Tpk reversed() fonksiyonunun bir reversed nesnesi vermesi gibi, bu fonksiyonun da bize
yalnzca bir enumerate nesnesi verdiini gryorsunuz.
reversed() fonksiyonunu kullanabilmek iin yle bir kod yazmtk:
>>> print(*reversed("istihza"))
for i in enumerate("istihza"):
print(i)
'i')
's')
't')
'i')
'h')
'z')
'a')
Grdnz gibi, gerekten de bu fonksiyon bize bir e (mesela i har) ve bu eye ait bir
sra numaras (mesela 0 ) veriyor.
Hatrlarsanz, enumerate() fonksiyonunu renmeden nce, dir("") komutundan elde
ettiimiz ktlar u ekilde numaralandrabileceimizi sylemitik:
saya = 0
310
for i in dir(""):
if "_" not in i[0]:
saya += 1
print(saya, i)
Ama artk enumerate() fonksiyonunu rendiimize gre, ayn ii ok daha verimli bir ekilde
gerekletirebiliriz:
for sra, metot in enumerate(dir("")):
print(sra, metot)
enumerate() metodunun verdii her bir ktnn iki eli olduunu biliyoruz (enin kendisi ve
o enin sra numaras). Yukardaki kodlar yardmyla, bu elerin her birini ayr bir deikene
(sra ve metot ) atam oluyoruz. Bylece bu kty maniple etmek bizim iin daha kolay
oluyor. Mesela bu zellii kullanarak metot ve sra numarasnn yerlerini deitirebiliriz:
>>> for sra, metot in enumerate(dir("")):
...
print(metot, sra)
...
__add__ 0
__class__ 1
__contains__ 2
__delattr__ 3
__doc__ 4
__eq__ 5
__format__ 6
__ge__ 7
(...)
Burada, dir("") ile elde ettiimiz metotlarn srasn (sra ), bu metotlarn adlarn (metot ) ve
her bir metodun ka karakterden olutuunu (len(metot)) gsteren bir kt elde ettik.
Bu arada, grdnz gibi, enumerate() fonksiyonu numaralandrmaya 0 dan balyor.
Elbette eer isterseniz bu fonksiyonun numaralandrmaya katan balayacan kendiniz de
belirleyebilirsiniz. Dikkatlice bakn:
>>> for sra, harf in enumerate("istihza", 1):
...
print(sra, harf)
...
1 i
2 s
3 t
311
4
5
6
7
i
h
z
a
20.6.3 help()
Pythonla ilgili herhangi bir konuda yardma ihtiyacnz olduunda, internetten aratrma
yaparak pek ok ayrntl belgeye ulaabilirsiniz. Ama eer herhangi bir nesne hakknda
hzl bir ekilde ve ngilizce olarak yardm almak isterseniz help() adl zel bir fonksiyondan
yararlanabilirsiniz.
Bu fonksiyonu iki farkl ekilde kullanyoruz. Birinci yntemde, etkileimli kabua help()
yazp Enter dmesine basyoruz:
>>> help()
Welcome to Python 3.3!
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at [Link]
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".
To get a list of available modules, keywords, or topics, type "modules",
"keywords", or "topics". Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".
help>
Grdnz gibi, Python bu komutu verdiimizde zel bir yardm ekran ayor bize. Bu
ekranda >>> yerine help> ifadesinin olduuna dikkat edin. Mesela dir() fonksiyonu
hakknda bilgi almak iin help> ifadesinden hemen sonra, hi boluk brakmadan, u komutu
verebiliriz:
help> dir
312
help ekranndan kmak iin Enter dmesine basabilir veya quit komutu verebilirsiniz.
En bata da dediimiz gibi Pythonda etkileimli kabuk zerinde ngilizce yardm almak iin
iki farkl yntem kullanabiliyoruz. Bu yntemlerden ilkini yukarda anlattk. kincisi ise
dorudan etkileimli kabukta u komutu kullanmaktr: (Mesela dir() fonksiyonu hakknda
yardm alalm...)
>>> help(dir)
Help on built-in function dir in module builtins:
dir(...)
dir([object]) -> list of strings
If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes of its bases.
for any other object: its attributes, its class's attributes, and
recursively the attributes of its class's base classes.
Grdnz gibi, help ekrann amadan, dorudan etkileimli kabuk zerinden de help()
fonksiyonunu herhangi bir fonksiyon gibi kullanp, hakknda yardm almak istediimiz nesneyi
help() fonksiyonunun parantezleri iine parametre olarak yazabiliyoruz.
Bylece dir(), enumerate() ve help() adl nemli fonksiyonu da geride brakm olduk.
Dilerseniz imdi karakter dizilerine dair birka ufak not delim.
313
20.7 Notlar
Hatrlarsanz dngleri anlatrken yle bir rnek vermitik:
tr_harfler = ""
a = 0
while a < len(tr_harfler):
print(tr_harfler[a], sep="\n")
a += 1
Bu kodlarn for dngs ile yazlabilecek olan u kodlara alternatif olduundan sz etmitik:
tr_harfler = ""
for tr_harf in tr_harfler:
print(tr_harf)
Yukardaki while rneini verirken, henz karakter dizilerinin elerine tek tek nasl
eriebileceimizi renmemitik. Ama artk bu konuyu da rendiimiz iin yukardaki while
dngsn rahatlkla anlayabiliyoruz:
while a < len(tr_harfler):
print(tr_harfler[a], sep="\n")
a += 1
`3.|minor3|.|micro3|'
Elbette, yukardaki karakter dizisini elde etmek iin, kullanmas ve ynetmesi daha kolay bir
ara olan version_info deikeninden de yararlanabilirdiniz:
>>> '{}.{}.{}'.format(sys.version_info.major, sys.version_info.minor, sys.version_info.micro)
314
`3.|minor3|.|micro3|'
Ancak burada yle bir sorun olduunu biliyorsunuz: Pythonn 2.7 ncesi srmlerinde
version_info nun major, minor ve micro gibi nitelikleri yok.
Dolaysyla 2.7 ncesi
srmlerde version_info yu kullanrken hata almamak iin try... except bloklarndan
yararlanabileceimizi grmtk. Ancak version_info yu btn Python srmlerinde gvenli
bir ekilde kullanmann baka bir yntemi daha var. Dikkatlice bakn:
>>> major = sys.version_info[0]
>>> minor = sys.version_info[1]
>>> micro = sys.version_info[2]
>>> print(major, minor, micro, sep=".")
3.5.1
Bu yntem btn Python srmlerinde alr. Dolaysyla, farkl Python srmlerinde
almasn tasarladnz programlarnzda srm kontroln sys.version_info nun major,
minor veya micro nitelikleri ile yapmak yerine yukardaki yntemle yapabilirsiniz:
if sys.version_info[1] < 3:
print("Kullandnz Python srm eski!")
Grdnz gibi, karakter dizisi dilimleme ilemleri pek ok farkl kullanm alanna
sahip. Programlama maceranz boyunca karakter dizilerinin bu zelliinden bol bol
yararlanacanzdan hi kukunuz olmasn.
20.7. Notlar
315
BLM 21
Geen blmde karakter dizilerinin genel zelliklerinden sz ettik. Bu ikinci blmde ise
karakter dizilerini biraz daha ayrntl bir ekilde incelemeye ve karakter dizilerinin yepyeni
zelliklerini grmeye balayacaz.
Hatrlarsanz, geen blmn en banda, metot diye bir eyden sz edeceimizi
sylemitik. Orada da kabaca tarif ettiimiz gibi, metotlar Pythonda nesnelerin niteliklerini
deitirmemizi, sorgulamamz veya bu nesnelere yeni zellikler katmamz salayan
aralardr. Metotlar sayesinde karakter dizilerini istediimiz gibi eip bkebileceiz.
Geen blmn sonlarna doru, bir karakter dizisinin hangi metotlara sahip olduunu u
komut yardmyla listeleyebileceimizi renmitik:
>>> dir("")
21.1 replace()
Karakter dizisi metotlar arasnda inceleyeceimiz ilk metot replace() metodu olacak.
replace kelimesi Trkede deitirmek, yerine koymak gibi anlamlar tar. te bu metodun
yerine getirdii grev de tam olarak budur. Yani bu metodu kullanarak bir karakter dizisi
iindeki karakterleri baka karakterlerle deitirebileceiz.
Peki bu metodu nasl kullanacaz? Hemen bir rnek verelim:
>>> kardiz = "elma"
316
Burada elma deerini tayan kardiz adl bir karakter dizisi tanmladk. imdi bu karakter
dizisinin iinde geen e harni E ile deitirelim. Dikkatlice bakn:
>>> [Link]("e", "E")
'Elma'
Grdnz gibi, replace() son derece yararl ve kullanm olduka kolay bir metot. Bu arada
bu ilk metodumuz sayesinde Pythondaki metotlarn nasl kullanlaca konusunda da bilgi
edinmi olduk. Yukardaki rneklerin bize gsterdii gibi yle bir formlle kar karyayz:
karakter_dizisi.metot(parametre)
Metotlar karakter dizilerinden nokta ile ayrlr. Pythonda bu ynteme noktal gsterim (dot
notation ) ad verilir.
Bu arada metotlarn grn ve kullanm olarak fonksiyonlara ne kadar benzediine dikkat
edin. Tpk fonksiyonlarda olduu gibi, metotlar da birtakm parametreler alabiliyor.
Yukardaki rnekte, replace() metodunun iki farkl parametre aldn gryoruz. Bu metoda
verdiimiz ilk parametre deitirmek istediimiz karakter dizisini gsteriyor. kinci parametre
ise birinci parametrede belirlediimiz karakter dizisinin yerine ne koyacamz belirtiyor. Yani
replace() metodu yle bir formle sahiptir:
karakter_dizisi.replace(eski_karakter_dizisi, yeni_karakter_dizisi)
Gelin isterseniz elimizin almas iin replace() metoduyla birka rnek daha verelim:
>>> kardiz = "memleket"
>>> [Link]("ket", "KET")
'memleKET'
Burada grdnz gibi, replace() metodu ayn anda birden fazla karakteri deitirme
yeteneine de sahip.
replace() metodunun iki parametreden olutuunu, ilk parametrenin deitirilecek karakter
dizisini, ikinci parametrenin ise ilk karakter dizisinin yerine geecek yeni karakter dizisini
gsterdiini sylemitik. Aslnda replace() metodu nc bir parametre daha alr. Bu
parametre ise bir karakter dizisi iindeki karakterlerin ka tanesinin deitirileceini gsterir.
Eer bu parametreyi belirtmezsek replace() metodu ilgili karakterlerin tamamn deitirir.
Yani:
>>> kardiz = "memleket"
>>> [Link]("e", "")
'mmlkt'
21.1. replace()
317
Burada ilk rnekte nc parametre olarak 2 saysn kullandmz iin, replace ileminden
karakter dizisi iindeki 2 adet e har etkilendi. nc rnekte ise memleket adl karakter
dizisi iinde geen adet e har deiiklikten etkilendi.
Karakter dizileri konusunun ilk blmnde deitirilebilirlik (mutability ) zerine sylediimiz
eylerin burada da geerli olduunu unutmayn. Orada da sylediimiz gibi, karakter dizileri
deitirilemeyen veri tipleridir. Dolaysyla eer bir karakter dizisi zerinde deiiklik yapmak
istiyorsanz, o karakter dizisini batan tanmlamalsnz. rnein:
>>> meyve = "elma"
>>> meyve = [Link]("e", "E")
>>> meyve
'Elma'
318
Grdnz gibi bu metot sayesinde stanbul Bykehir Belediyesi adl karakter dizisini
kelimelere blmeyi baardk. Eer bu kt zerine bir for dngs uygularsak yle bir sonu
elde ederiz:
>>> for i in [Link]():
...
print(i)
...
stanbul
Bykehir
Belediyesi
Burada kullanc hangi kurum adn girerse girsin, bu kurum adnn her kelimesinin ilk
har ekrana dklecektir. rnein kullanc burada Trkiye Byk Millet Meclisi ifadesini
girmise split() metodu ncelikle bu ifadeyi alp u ekle dntrr:
['Trkiye', 'Byk', 'Millet', 'Meclisi']
Daha sonra biz bu kt zerinde bir for dngs kurarsak bu kelime grubunun her bir
esine tek tek mdahale etme imkanna eriiriz. rnein yukardaki programda bu kelime
grubunun her bir esinin ilk harni tek tek ekrana dktk ve TBMM ktsn elde ettik.
Yukardaki rneklerde split() metodunu herhangi bir parametre iermeyecek ekilde
kullandk. Yani metodun parantezleri iine herhangi bir ey eklemedik. split() metodunu
bu ekilde parametresiz olarak kullandmzda bu metot karakter dizilerini blerken boluk
karakterini lt alacaktr. Yani karakter dizisi iinde karlat her boluk karakterinde bir
blme ilemi uygulayacaktr. Ama bazen istediimiz ey, bir karakter dizisini boluklardan
blmek deildir. Mesela u rnee bakalm:
>>> kardiz = "Bolvadin, Kilis, Siverek, skenderun, stanbul"
Eer bu karakter dizisi zerine split() metodunu parametresiz olarak uygularsak yle bir
kt elde ederiz:
['Bolvadin,', 'Kilis,', 'Siverek,', 'skenderun,', 'stanbul']
split() metoduna herhangi bir parametre vermediimiz iin bu metot karakter dizisi iindeki
kelimeleri boluklardan bld. Bu yzden karakter dizisi iindeki virgl iaretleri de blnen
kelimeler iinde grnyor:
>>> kardiz = [Link]()
>>> for i in kardiz:
...
print(i)
...
Bolvadin,
319
Kilis,
Siverek,
skenderun,
stanbul
Grdnz gibi, split() metodu tam da istediimiz gibi, karakter dizisini bu kez
boluklardan deil virgllerden bld. Peki bunu nasl baard? Aslnda bu sorunun cevab
gayet net bir ekilde grnyor. Dikkat ederseniz yukardaki rnekte split() metoduna
parametre olarak virgl karakter dizisini verdik. Yani yle bir ey yazdk:
[Link](",")
320
Eer parametre olarak verdiiniz deer karakter dizisi iinde hi gemiyorsa karakter dizisi
zerinde herhangi bir deiiklik yaplmaz:
>>> [Link]("z")
['Bolvadin, Kilis, Siverek, skenderun, stanbul']
Ayn ey, split() metodundan nce rendiimiz replace() metodu iin de geerlidir. Yani
eer deitirilmek istenen karakter, karakter dizisi iinde yer almyorsa herhangi bir ilem
yaplmaz.
split() metodu ounlukla, yukarda anlattmz ekilde parametresiz olarak veya tek
parametre ile kullanlr. Ama aslnda bu metot ikinci bir parametre daha alr. Bu ikinci
parametre, karakter dizisinin ka kez blneceini belirler:
>>> kardiz = "Ankara Bykehir Belediyesi"
>>> [Link](" ", 1)
['Ankara', 'Bykehir Belediyesi']
>>> [Link](" ", 2)
['Ankara', 'Bykehir', 'Belediyesi']
Grdnz gibi, ilk rnekte kullandmz 1 says sayesinde blme ilemi karakter dizisi
zerine bir kez uyguland. kinci rnekte ise 2 saysnn etkisiyle karakter dizimiz iki kez blme
ilemine maruz kald.
Elbette, split() metodunun ikinci parametresini kullanabilmek iin ilk parametreyi de
mutlaka yazmanz gerekir. Aksi halde Python ne yapmaya altnz anlayamaz:
>>> [Link](2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
Grdnz gibi, ilk parametreyi es geip dorudan ikinci parametreyi yazmaya altmzda
Python parametre olarak verdiimiz 2 saysnn blme lt olduunu zannediyor.
Yukardaki hatay engellemek iin blme ltn de aka belirtmemiz gerekir. Yukardaki
rnekte blme ltmz bir adet boluk karakteri idi. Bildiiniz gibi, blme lt herhangi
bir ey olabilir. Mesela virgl.
>>> arkadalar = "Ahmet, Mehmet, Kezban, Mualla, Sreyya, Veli"
>>> [Link](",", 3)
['Ahmet', ' Mehmet', ' Kezban', ' Mualla, Sreyya, Veli']
Burada da blme lt olarak virgl karakterini kullandk ve arkadalar adl karakter dizisi
zerine 3 kez blme ilemi uyguladk. lk blme ilemi Ahmet karakter dizisini; ikinci blme
ilemi Mehmet karakter dizisini; nc blme ilemi ise Kezban karakter dizisini ayrd.
arkadalar adl karakter dizisinin geri kalann oluturan Mualla, Sreyya, Veli ksm ise
herhangi bir blme ilemine tabi tutulmadan tek para olarak kald.
split() metoduyla son bir rnek verip yolumuza devam edelim.
Bildiiniz gibi sys modlnn version deikeni bize bir karakter dizisi veriyor:
21.2. split(), rsplit(), splitlines()
321
Grdnz gibi, split() metodu karakter dizisini soldan saa doru okuduu iin blme
ilemini Ankara karakter dizisine uygulad. rsplit() metodu ise karakter dizisini sadan
sola soru okuduu iin blme ilemini Belediyesi adl karakter dizisine uygulad.
rsplit() metodunun pek yaygn kullanlan bir metot olmadn belirterek splitlines()
metoduna geelim.
Bildiiniz gibi, split() metodunu bir karakter dizisini kelime kelime ayrabilmek iin
kullanabiliyoruz. splitlines() metodunu ise bir karakter dizisini satr satr ayrmak iin
322
kullanabiliriz. Mesela elinizde uzun bir metin olduunu ve amacnzn bu metin iindeki
herbir satr ayr ayr almak olduunu dnn. te splitlines() metoduyla bu amacnz
gerekletirebilirsiniz. Hemen bir rnek verelim:
metin = """Python programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin
Python olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn
dnr. Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan
gelmez. Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz
komedi grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek
adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python programlama
dilinin pek ok yerde bir ylan figr ile temsil edilmesi neredeyse bir gelenek
halini almtr diyebiliriz."""
print([Link]())
Grdnz gibi, metnimiz Enter tuuna bastmz noktalardan blnd. Biz henz bu kty
nasl deerlendireceimizi ve bu ktdan nasl yararlanacamz bilmiyoruz. Ayrca u anda
bu kt gznze ok anlaml grnmemi olabilir. Ama Listeler adl konuyu rendiimizde
bu kt size ok daha anlaml grnecek.
splitlines() metodu yukardaki gibi parametresiz olarak kullanlabilecei gibi, bir adet
parametre ile de kullanlabilir. Bunu bir rnek zerinde gsterelim:
metin = """Python programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin
Python olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn
dnr. Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan
gelmez. Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz
komedi grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek
adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python programlama
dilinin pek ok yerde bir ylan figr ile temsil edilmesi neredeyse bir gelenek
halini almtr diyebiliriz."""
print([Link](True))
323
Ancak her ne kadar gerek byle olsa da, Python programlama \n', 'dilinin pek
ok yerde bir ylan figr ile temsil edilmesi neredeyse bir gelenek \n',
'halini almtr diyebiliriz.']
21.3 lower()
Mutlaka karlamsnzdr. Baz programlarda kullancdan istenen veriler byk-kk
harfe duyarldr. Yani mesela kullancdan bir parola isteniyorsa, kullancnn bu parolay
byk-kk harfe dikkat ederek yazmas gerekir. Bu programlar asndan, rnein parola
ve Parola ayn kelimeler deildir. Mesela kullancnn parolas parola ise, bu kullanc
programa Parola yazarak giremez.
Baz baka programlarda ise bu durumun tam tersi sz konusudur. Yani byk-kk harfe
duyarl programlarn aksine baz programlar da kullancdan gelen verinin byk hari mi
yoksa kk hari mi olduunu nemsemez. Kullanc doru kelimeyi byk hare de
yazsa, kk hare de yazsa program istenen ilemi gerekletirir. Mesela Googleda yaplan
aramalar bu mantk zerine alr. rnein kitap kelimesini Googleda aratyorsanz, bu
kelimeyi byk hare de yazsanz, kk hare de yazsanz Google size ayn sonular
gsterecektir. Google asndan, aradnz kelimeyi byk ya da kk hare yazmanzn
bir nemi yoktur.
imdi yle bir program yazdmz dnn:
kii = input("Aradnz kiinin ad ve soyad: ")
if kii == "Ahmet
print("email:
print("tel :
print("ehir:
z":
aoz@[Link]")
02121231212")
istanbul")
Bu programn doru alabilmesi iin kullancnn, rnein, Ahmet z adl kiiyi ararken
byk-kk harfe dikkat etmesi gerekir. Eer kullanc Ahmet z yazarsa o kiiyle ilgili
bilgileri alabilir, ama eer mesela Ahmet z yazarsa bilgileri alamaz. Peki acaba biz
bu sorunun stesinden nasl gelebiliriz? Yani programmzn byk-kk harfe duyarl
olmamasn nasl salayabiliriz?
324
Bu ii yapmann iki yolu var: Birincisi if bloklarn her trl ihtimali dnerek yazabiliriz.
Mesela:
if kii == "Ahmet z" or "Ahmet z" or "ahmet z":
...
Ama burada baz problemler var. Birincisi, kullancnn ka trl veri girebileceini
kestiremeyebilirsiniz. kincisi, kestirebilseniz bile, her kii iin olaslklar girmeye almak
eziyetten baka bir ey deildir...
te burada imdadmza lower() metodu yetiecek. Dikkatlice inceleyin:
kii = input("Aradnz kiinin ad ve soyad: ")
kii = [Link]()
if kii == "ahmet
print("email:
print("tel :
print("ehir:
z":
aoz@[Link]")
02121231212")
istanbul")
Artk kullanc ahmet z de yazsa, Ahmet z de yazsa, hatta AhMeT Z de yazsa programmz
doru alacaktr. Peki bu nasl oluyor? Elbette lower() metodu sayesinde...
Yukardaki rneklerin de bize gsterdii gibi, lower() metodu, karakter dizisindeki btn
hareri kk harfe eviriyor. rnein:
>>> kardiz = "ELMA"
>>> [Link]()
'elma'
>>> kardiz = "arMuT"
>>> [Link]()
'armut'
>>> kardiz = "PYTHON PROGRAMLAMA"
>>> [Link]()
'python programlama'
Eer karakter dizisi zaten tamamen kk harerden oluuyorsa bu metot hibir ilem
yapmaz:
21.3. lower()
325
Peki bu durumda ne yapacaz? Elimiz kolumuz bal oturacak myz? Elbette hayr! Biz bu tr
kk sorunlar aabilecek kadar Python bilgisine sahibiz. ve I hareri ile ilgili problemi,
yalnzca mevcut bilgilerimizi kullanarak rahatlkla zebiliriz:
iller = "ISPARTA, ADIYAMAN, DYARBAKIR, AYDIN, BALIKESR, ARI"
iller = [Link]("I", "").replace("", "i").lower()
print(iller)
326
3. Bu iki ilemin ardndan karakter dizisi iinde geen I ve harerini kltm olduk.
Ancak teki harer henz klmedi. O yzden de karakter dizimiz zerine bir de
lower() metodunu uyguluyoruz. Bylece btn harer dzgn bir ekilde klm
oluyor.
4. Bu kodlarda farkl metotlar u uca nasl eklediimize dikkat edin.
Bu rnek size unu gstermi olmal: Aslnda programlama dediimiz ey gerekten de ok
basit paralarn uygun bir ekilde birletirilmesinden ibaret. Tpk bir yap-bozun paralarn
birletirmek gibi...
Ayrca bu rnek sizi bir gerekle daha tantryor: Grdnz gibi, artk Pythonda
o kadar ilerlediniz ki Pythonn problemlerini tespit edip bu problemlere zm dahi
retebiliyorsunuz!
21.4 upper()
Bu metot biraz nce rendiimiz lower() metodunun yapt iin tam tersini yapar.
Hatrlarsanz lower() metodu yardmyla karakter dizileri iindeki hareri kltyorduk.
upper() metodu ise bu hareri bytmemizi salar.
rnein:
>>> kardiz = "kalem"
>>> [Link]()
'KALEM'
lower() metodunu anlatrken, kullancdan gelen verileri belli bir dzene sokmak konusunda
bu metodun olduka faydal olduunu sylemitik. Kullancdan gelen verilerin lower()
metodu yardmyla standart bir hale getirilmesi sayesinde, kullancnn girdii kelimelerin
byk-kk hari olmasnn nemli olmad programlar yazabiliyoruz. Elbette eer
isterseniz kullancdan gelen btn verileri lower() metoduyla kk harfe evirmek yerine,
upper() metoduyla byk harfe evirmeyi de tercih edebilirsiniz. Python programclar
genellikle kullanc verilerini standart bir hale getirmek iin btn hareri kltmeyi tercih
eder, ama tabii ki sizin bunun tersini yapmak istemenizin nnde hibir engel yok.
Diyelim ki, ehirlere gre hava durumu bilgisi veren bir program yazmak istiyorsunuz. Bunun
iin yle bir kod yazarak ie balayabilirsiniz:
ehir = input("Hava durumunu renmek iin bir ehir ad girin: ")
if ehir == "ADANA":
print("paral bulutlu")
elif ehir == "ERZURUM":
print("karla kark yamurlu")
elif ehir == "ANTAKYA":
print("ak ve gneli")
else:
print("Girdiiniz ehir veritabannda yok!")
Burada programmzn doru alabilmesi, kullancnn ehir adlarn byk hare girmesine
baldr. rnein programmz ADANA cevabn kabul edecek, ama mesela Adana cevabn
21.4. upper()
327
Burada yazdmz ehir = [Link]() kodu sayesinde artk kullanc ehir adn byk
hare de girse, kk hare de girse programmz dzgn alacaktr.
Hatrlarsanz lower() metodunu anlatrken bu metodun baz Trke karakterlerle problemi
olduunu sylemitik. Ayn sorun, tahmin edebileceiniz gibi, upper() metodu iin de
geerlidir.
Dikkatlice inceleyin:
>>> kardiz = "istanbul"
>>> [Link]()
'ISTANBUL'
lower() metodu Trkedeki I harni i eklinde kltyordu. upper() metodu ise i harni
yanl olarak I eklinde bytyor. Elbette bu sorun da zlemeyecek gibi deil. Burada da
lower() metodu iin uyguladmz yntemin bir benzerini uygulayacaz:
iller = "istanbul, izmir, siirt, mersin"
iller = [Link]("i", "").upper()
print(iller)
Bu kodlarla, nce karakter dizisi iinde geen i harerini ile deitiriyoruz. Bylece yle
bir ey elde etmi oluyoruz:
stanbul, zmr, srt, mersn
Grdnz gibi teki harer eski hallerinde kald. teki hareri de bytebilmek iin
karakter dizisine upper() metodunu uygulamamz yeterli olacaktr.
Bir sorunun daha stesinden geldiimize gre kendimizden emin bir ekilde bir sonraki
metodumuzu incelemeye geebiliriz.
328
istihza tamamen kk harerden oluan bir karakter dizisi olduu iin islower() sorgusu
True kts veriyor. Bir de una bakalm:
>>> kardiz = "Ankara"
>>> [Link]()
False
Ankara ise iinde bir adet byk harf barndrd iin islower() sorgusuna False cevab
veriyor.
Yazdnz programlarda, rnein, kullancdan gelen verinin sadece kk harerden
olumasn istiyorsanz bu metottan yararlanarak kullancdan gelen verinin gerekten
tamamen kk harerden oluup olumadn denetleyebilirsiniz:
veri = input("Adnz: ")
if not [Link]():
print("Ltfen isminizi sadece kk harflerle yazn")
isupper() metodu da islower() metodunun yapt iin tam tersini yapar. Bildiiniz gibi,
upper() metodu bir karakter dizisini tamamen byk harerden oluacak ekle getiriyordu.
isupper() metodu ise bir karakter dizisinin tamamen byk harerden oluup olmadn
sorguluyor:
>>> kardiz = "STHZA"
>>> [Link]()
True
>>> kardiz = "python"
>>> [Link]()
False
329
Tpk islower() metodunda olduu gibi, isupper() metodunu da kullancdan gelen verinin
byk hari mi yoksa kk hari mi olduunu denetlemek iin kullanabilirsiniz.
rnein, internet kltrnde kullanclarn forum ve [Link] listesi gibi yerlerde tamam
byk harerden oluan kelimelerle yazmas kaba bir davran olarak kabul edilir.
Kullanclarn tamam byk harerden oluan kelimeler kullanmasn engellemek iin
yukardaki metotlardan yararlanabilirsiniz:
veri = input("mesajnz: ")
bl = [Link]()
for i in bl:
if [Link]():
print("Tamam byk harflerden oluan kelimeler kullanmayn!")
Burada kullancnn girdii mesaj iindeki her kelimeyi tek tek sorgulayabilmek iin ncelikle
split() metodu yardmyla karakter dizisini paralarna ayrdmza dikkat edin. bl =
[Link]() satrnn tam olarak ne ie yaradn anlamak iin bu program bir de o satr
olmadan altrmay deneyebilirsiniz.
islower() ve isupper() metotlar programlamada sklkla kullanlan karakter dizisi
metotlarndan ikisidir. Dolaysyla bu iki metodu iyi renmek programlama maceranz
srasnda ilerinizi epey kolaylatracaktr.
21.6 endswith()
Tpk isupper() ve islower() metotlar gibi, endswith() metodu da sorgulayc metotlardan
biridir. endswith() metodu karakter dizileri zerinde herhangi bir deiiklik yapmamz
salamaz. Bu metodun grevi karakter dizisinin durumunu sorgulamaktr.
Bu metot yardmyla bir karakter dizisinin hangi karakter dizisi ile bittiini sorgulayabiliyoruz.
Yani rnein:
>>> kardiz = "istihza"
>>> [Link]("a")
True
Burada, deeri istihza olan kardiz adl bir karakter dizisi tanmladk. Daha sonra da
[Link]("a") ifadesiyle bu karakter dizisinin a karakteri ile bitip bitmediini
sorguladk. Gerekten de istihza karakter dizisinin sonunda a karakteri bulunduu iin
Python bize True cevab verdi. Bir de una bakalm:
>>> [Link]("z")
False
=
=
=
=
=
330
"[Link]"
"tkinter.mp3"
"[Link]"
"[Link]"
"sarki.mp3"
d6 = "[Link]"
d7 = "falanca.mp3"
d8 = "[Link]"
d9 = "[Link]"
d10 = "[Link]"
d11 = "c++.mp3"
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if [Link](".mp3"):
print(i)
Bu rnekte, elimizde farkl uzantlara sahip baz dosyalar olduunu varsaydk ve bu dosya
adlarnn herbirini ayr birer deiken iinde depoladk. Grdnz gibi, dosya uzantlar
.ogg, .mp3 veya .avi. Bizim burada amacmz elimizdeki mp3 dosyalarn listelemek. Bu ilem
iin endswith() metodundan yararlanabiliyoruz. Burada yaptmz ey u:
ncelikle d1, d2, d3, d4, d5, d6, d7, d8, d9, d10 ve d11 adl deikenleri bir for dngs
iine alyoruz ve bu deikenlerinin herbirinin ieriini tek tek kontrol ediyoruz (for i in d1,
d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:). Ardndan, eer baktmz bu deikenlerin
deerleri .mp3 ifadesi ile bitiyorsa (if [Link](".mp3"):), lte uyan btn karakter
dizilerini ekrana dkyoruz (print(i)).
Yukardaki rnei, dilerseniz, endswith() metodunu kullanmadan yle de yazabilirsiniz:
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i[-4:len(i)] == ".mp3":
print(i)
21.7 startswith()
Bu metot, biraz nce grdmz endswith() metodunun yapt iin tam tersini yapar.
Hatrlarsanz endswith() metodu bir karakter dizisinin hangi karakter veya karakterlerle
bittiini denetliyordu. startswith() metodu ise bir karakter dizisinin hangi karakter veya
karakterlerle baladn denetler:
>>> kardiz = "python"
>>> [Link]("p")
True
>>> [Link]("a")
False
Grdnz gibi, eer karakter dizisi gerekten belirtilen karakterle balyorsa Python True
kts, yok eer belirtilen karakterle balamyorsa False kts veriyor.
Bu metodun gerek hayatta nasl kullanlabileceine dair bir rnek verelim:
21.7. startswith()
331
d1 = "[Link]"
d2 = "tkinter.mp3"
d3 = "[Link]"
d4 = "[Link]"
d5 = "sarki.mp3"
d6 = "[Link]"
d7 = "falanca.mp3"
d8 = "[Link]"
d9 = "[Link]"
d10 = "[Link]"
d11 = "c++.mp3"
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if [Link]("p"):
print(i)
Burada p haryle balayan btn dosyalar listeledik. Elbette ayn etkiyi u ekilde de elde
edebilirsiniz:
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i[0] == "p":
print(i)
Dediim gibi, birden fazla karakteri sorguladnz durumlarda, dilimlemek istediiniz ksmn
karakter dizisi iinde hangi arala denk geldiini hesaplamaya uramak yerine, daha kolay
bir yntem olan startswith() metodundan yararlanmay tercih edebilirsiniz.
Bylece karakter dizilerinin 2. blmn de bitirmi olduk. Sonraki blmde yine karakter
dizilerinin metotlarndan sz etmeye devam edeceiz.
332
BLM 22
Karakter dizileri konusunun en banda sylediimiz gibi, karakter dizileri metot ynnden
bir hayli zengin bir veri tipidir. Bir nceki blmde karakter dizileri metotlarnn bir ksmn
incelemitik. Bu blmde yine metotlar incelemeye devam edeceiz.
22.1 capitalize()
Hatrlarsanz, bir nceki blmde rendiimiz startswith() ve endswith() metotlar
karakter dizileri zerinde herhangi bir deiiklik yapmyordu. Bu iki metodun grevi, karakter
dizilerini sorgulamamz salamakt. imdi greceimiz capitalize() metodu ise karakter
dizileri zerinde deiiklik yapmamz salayacak. Dolaysyla bu capitalize() metodu da
deitirici metotlardan biridir diyebiliriz.
Hatrlarsanz, upper() ve lower() metotlar bir karakter dizisi iindeki btn karakterleri
etkiliyordu. Yani mesela upper() metodunu bir karakter dizisine uygularsak, o karakter
dizisi iindeki btn karakterler byk harfe dnecektir. Ayn ekilde lower() metodu da
bir karakter dizisi iindeki btn karakterleri kk harfe evirir.
imdi greceimiz capitalize() metodu da upper() ve lower() metotlarna benzemekle
birlikte onlardan biraz daha farkl davranr: capitalize() metodunun grevi karakter
dizilerinin yalnzca ilk harni bytmektir. rnein:
>>> a = "python"
>>> [Link]()
'Python'
Bu metodu kullanrken dikkat etmemiz gereken bir nokta var: Bu metot bir karakter dizisinin
yalnzca ilk harni bytr. Yani birden fazla kelimeden oluan karakter dizilerine bu metodu
uyguladmzda btn kelimelerin ilk har bymez. Yalnzca ilk kelimenin ilk har byr.
Yani:
>>> a = "python programlama dili"
>>> [Link]()
'Python programlama dili'
python programlama dili kelimeden oluan bir karakter dizisidir. Bu karakter dizisi
zerine capitalize() metodunu uyguladmzda bu kelimenin tamamnn ilk hareri
bymyor. Yalnzca ilk python kelimesinin ilk har bu metottan etkileniyor.
333
istanbul kelimesinin ilk har bytldnde olmas gerekirken I oldu. Bildiiniz gibi bu
problem , , , ve gibi teki Trke karakterlerde karmza kmaz. Sadece i ve
hareri karakter dizisi metotlarnda bize problem karacaktr. Ama endie etmemize hi
gerek yok. Bu sorunu da basit bir if-else yapsyla zebilecek kadar Python bilgisine sahibiz:
kardiz = "istanbul bykehir belediyesi"
if [Link]("i"):
kardiz = "" + kardiz[1:]
kardiz = [Link]()
print(kardiz)
Burada yaptmz ey u: Eer deikenin tuttuu karakter dizisi i har ile balyorsa,
"" + kardiz[1:] kodunu kullanarak karakter dizisinin ilk har dnda kalan ksmyla
harni birletiriyoruz. Bu yapy daha iyi anlayabilmek iin etkileimli kabukta u denemeleri
yapabilirsiniz:
>>> kardiz = "istanbul"
>>> kardiz[1:]
'stanbul'
Grdnz gibi, kardiz[1:] kodu bize karakter dizisinin ilk har hari geri kalan ksmn
veriyor. Bu yapy dilimleme konusundan hatrlyor olmalsnz. te biz dilimleme tekniinin
bu zelliinden yararlanarak, karakter dizisinin ilk harni kesip, ba tarafa bir adet har
ekliyoruz:
>>> "" + kardiz[1:]
'stanbul'
kardiz = [Link]()
334
Buna gre, hangi hare balarsa balasn Pythonn standart capitalize() metodunu bu
karakter dizisi zerine uyguluyoruz.
Son olarak da print(kardiz) kodunu kullanarak yeni karakter dizisini ekrana yazdryoruz
ve bylece capitalize() metodundaki Trke karakter sorununu kvrak bir almla am
oluyoruz.
22.2 title()
Bu metot biraz nce rendiimiz capitalize() metoduna benzer.
Bildiiniz gibi
capitalize() metodu bir karakter dizisinin yalnzca ilk harni bytyordu. title() metodu
da karakter dizilerinin ilk harni bytr. Ama capitalize() metodundan farkl olarak
bu metot, birden fazla kelimeden oluan karakter dizilerinin her kelimesinin ilk harerini
bytr.
Bunu bir rnek zerinde anlatsak sanrm daha iyi olacak:
>>> a = "python programlama dili"
>>> [Link]()
'Python programlama dili'
>>> [Link]()
'Python Programlama Dili'
capitalize() metodu ile title() metodu arasndaki fark bariz bir biimde grnyor.
Dediimiz gibi, capitalize() metodu yalnzca ilk kelimenin ilk harni bytmekle yetinirken,
title() metodu karakter dizisi iindeki btn kelimelerin ilk harerini bytyor.
Tahmin edebileceiniz gibi, capitalize() metodundaki Trke karakter problemi title()
metodu iin de geerlidir. Yani:
>>> kardiz = "istanbul"
>>> [Link]()
'Istanbul'
>>> kardiz = "istanbul bykehir belediyesi"
>>> [Link]()
'Istanbul Bykehir Belediyesi'
Grdnz gibi, burada da Python i harni dzgn bytemedi. Ama tabii ki bu bizi
durduramaz! zmmz hazr:
kardiz = "istanbul"
if [Link]("i"):
kardiz = "" + kardiz[1:]
kardiz = [Link]()
else:
kardiz = [Link]()
print(kardiz)
22.2. title()
335
Burada yalnzca ilk kelimenin ilk har byd. Halbuki title() metodunun ileyii gereince
karakter dizisi iindeki btn kelimelerin ilk harerinin bymesi gerekiyordu. te o satr
btn kelimelerin ilk harerinin bymesini salyor. Eer bir kelimenin ilk har zaten
bykse title() metodu bu harfe dokunmaz, ama karakter dizisi iindeki br kelimelerin
ilk harerini yine de bytr.
te yukarda title() metodunun bu zelliinden faydalanyoruz.
kardiz = "" +
kardiz[1:] komutu karakter dizisinin ilk kelimesinin ilk harni dzgn bir ekilde bytyor,
ama geri kalan kelimelere hibir ey yapmyor. kardiz = [Link]() komutu ise
karakter dizisi iindeki geri kalan kelimelerin ilk harerini bytyor. Bylece istediimiz
kty elde edebilmi oluyoruz. Yalnz bu kodlarda bir ey dikkatinizi ekmi olmal.
kardiz = [Link]() komutunu program iinde iki yerde kullandk. Programclktaki
en nemli ilkelerden biri de mmkn olduunca tekrardan kanmaktr. Eer yazdnz
bir programda ayn kodlar program boyunca tekrar tekrar yazyorsanz muhtemelen bir
yerde hata yapyorsunuzdur. yle bir durumda yapmanz gereken ey kodlarnz tekrar
gzden geirip, tekrar eden kodlar nasl azaltabileceinizi dnmektir. te burada da byle
bir tekrar sz konusu. Biz tekrara dmekten kurtulmak iin yukardaki kodlar yle de
yazabiliriz:
kardiz = "istanbul bykehir belediyesi"
if [Link]("i"):
kardiz = "" + kardiz[1:]
kardiz = [Link]()
print(kardiz)
336
Bu defa istediimizi gerekletiren bir kod yazabildik. Bu kodlar, i har karakter dizisini
oluturan kelimelerin hangisinde bulunursa bulunsun, karakter dizisini Trkeye uygun bir
ekilde bytebilecektir.
Bir nceki kodlara gre, bu son kodlardaki tek farkn split() metodu ve for dngs
olduuna dikkat edin.
Bu kodlar daha iyi anlayabilmek iin etkileimli kabukta kendi kendinize baz deneme
almalar yapabilirsiniz:
22.2. title()
337
Grdnz gibi, split() metodu "on iki ada" adl karakter dizisini kelimelerine ayryor.
te biz de kelimelerine ayrlm bu yap zerinde bir for dngs kurarak herbir enin ilk
harnin i olup olmadn kontrol edebiliyoruz.
22.3 swapcase()
swapcase() metodu da byk-kk hare ilgili bir metottur. Bu metot bir karakter dizisi
iindeki byk hareri kk harfe; kk hareri de byk harfe dntrr. rnein:
>>> kardiz = "python"
>>> [Link]()
'PYTHON'
>>> kardiz = "PYTHON"
>>> [Link]()
'python'
>>> kardiz = "Python"
>>> [Link]()
'pYTHON'
Grdnz gibi, bu metot aynen dediimiz gibi iliyor. Yani kk hareri byk harfe;
byk hareri de kk harfe dntryor.
Yine tahmin edebileceiniz gibi, bu metodun da baz Trke karakterlerle problemi var:
>>> kardiz = "istihza"
>>> [Link]()
'ISTIHZA'
338
Daha nceki rneklerde de olduu gibi, bu kodlarda da i ve I harerini tek tek kontrolden
geiriyoruz. Eer bir karakter dizisi iinde bu iki harften biri varsa, bunlarn byk harf veya
kk harf karlklarn elle yerine koyuyoruz. Bu karakterler dnda kalan karakterlere ise
dorudan swapcase() metodunu uygulayarak istediimiz sonucu elde ediyoruz. Bu kodlarda
kafanza yatmayan yerler varsa, kodlar iinde kendinize gre baz eklemeler karmalar
yaparak neyin ne ie yaradn daha kolay anlayabilirsiniz.
22.4 casefold()
Bu metot ilev olarak lower() metoduna ok benzer. Hatta Trke asndan, bu metodun
lower() metodundan hibir fark yoktur. Ancak baz baka dillerde, bu metot baz harer
iin lower() metodunun verdiinden farkl bir kt verir. rnein Almancadaki har bu
duruma bir rnek olabilir:
>>> "".lower()
''
>>> "".casefold()
'ss'
Burada deeri istihza olan kardiz adl bir karakter dizisi tanmladk. Dikkat ederseniz
bu karakter dizisinin sanda ve solunda birer boluk karakteri var. Baz durumlarda
kullancdan ya da baka kaynaktan gelen karakter dizilerinde bu tr istenmeyen boluklar
olabilir. Ama sizin kullancdan veya baka bir kaynaktan gelen o karakter dizisini dzgn
kullanabilmeniz iin ncelikle o karakter dizisinin sanda ve solunda bulunan boluk
22.4. casefold()
339
Grdnz gibi, strip() metodunu kullanarak, karakter dizisinin orijinalinde bulunan sal
sollu boluk karakterlerini bir rpda ortadan kaldrdk.
strip() metodu yukardaki rnekte olduu gibi parametresiz olarak kullanldnda, bir
karakter dizisinin sanda veya solunda bulunan belli bal karakterleri krpar. strip()
metodunun ntanml olarak krpt karakterler unlardr:
\t
\n
\r
\v
\f
boluk karakteri
sekme (TAB) oluturan ka dizisi
satr bana geiren ka dizisi
imleci ayn satrn bana dndren ka dizisi
dey sekme oluturan ka dizisi
yeni bir sayfaya geiren ka dizisi
Yani eer strip() metoduna herhangi bir parametre vermezsek bu metot otomatik olarak
karakter dizilerinin sanda ve solunda bulunan yukardaki karakterleri krpacaktr. Ancak
eer biz istersek strip() metoduna bir parametre vererek bu metodun istediimiz herhangi
baka bir karakteri krpmasn da salayabiliriz. rnein:
>>> kardiz = "python"
>>> [Link]("p")
'ython'
karlayorsanz, gereksiz karakterleri silme grevini sizin yerinize Python yerine getirebilir.
imdi u kodlar dikkatlice inceleyin:
metin = """
> Python programlama dili Guido Van Rossum adl Hollandal bir programc tarafndan
> 90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin Python
> olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn dnr.
> Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan gelmez.
> Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz komedi
> grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr.
> Ancak her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
> bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr diyebiliriz.
"""
for i in [Link]():
print([Link]("> "), end=" ")
Grdnz gibi, her satrn banda bulunan > karakterlerini ufack birka kod yardmyla
rahatlkla temizledik. Burada strip() metoduyla birlikte split() metodunu da kullandmz
gryorsunuz. split() metodu ile nce metin adl karakter dizisini paraladk. Daha sonra
da strip() metodu yardmyla ba taraftaki istenmeyen karakterleri temizledik.
Yukardaki rnekte verdiimiz metin, istenmeyen karakterleri yalnzca tek bir tarafta ieriyor.
Ama elbette istenmeyen karakterler, karakter dizisinin ne tarafnda olursa olsun strip()
metodu bu karakterleri baaryla krpacaktr.
Bu blmn balnda strip() metodu ile birlikte lstrip() ve rstrip() adl iki metodun
daha ad geiyordu. strip() metodunun ne ie yaradn rendik. Peki bu lstrip() ve
rstrip() metotlar ne ie yaryor?
lstrip() metodundan balayalm anlatmaya...
strip() metodunu anlatrken, bu metodun bir karakter dizisinin sanda ve solunda
bulunan istenmeyen karakterleri krptn sylemitik. Ancak bazen, istediimiz ey bu
olmayabilir. Yani biz bir karakter dizisinin hem sanda, hem de solunda bulunan gereksiz
karakterleri deil, yalnzca sanda veya yalnzca solunda bulunan gereksiz karakterleri
krpmak isteyebiliriz. rnein strip() metodunu anlatrken verdiimiz kazak rneini ele
alalm. yle bir komutun ne yapacan biliyorsunuz:
>>> "kazak".strip("k")
Bu komut hem sol, hem de sa taraftaki k karakterlerini krpacaktr. Ama peki ya biz
sadece sol taraftaki k karakterini atmak istersek ne olacak? te byle bir durumda strip()
metodundan deil, lstrip() metodundan faydalanacaz.
lstrip() metodu bir karakter dizisinin sol tarafndaki gereksiz karakterlerden kurtulmamz
salar. Mesela bu bilgiyi yukardaki rnee uygulayalm:
22.5. strip(), lstrip(), rstrip()
341
>>> "kazak".lstrip("k")
'azak'
Grdnz gibi, lstrip() metodu yalnzca sol bataki k haryle ilgilendi. Sa taraftaki k
harne ise dokunmad. Eer sol taraftaki karakteri deil de yalnzca sa taraftaki karakteri
uurmak istemeniz halinde ise rstrip() metodundan yararlanacaksnz:
>>> "kazak".rstrip("k")
'kaza'
veya:
>>> "karakter dizisi".metot_ad()
22.6 join()
Hatrlarsanz imdiye kadar rendiimiz metotlar arasnda split() adl bir metot vard. Bu
metodun ne ie yaradn ve nasl kullanldn biliyorsunuz:
>>> kardiz = "Beikta Jimnastik Kulb"
>>> blnm = [Link]()
>>> print(blnm)
['Beikta', 'Jimnastik', 'Kulb']
Grdnz gibi split() metodu bir karakter dizisini belli yerlerden blerek paralara
ayryor. Bu noktada insann aklna yle bir soru geliyor: Diyelim ki elimizde byle blnm
bir karakter dizisi grubu var. Biz bu grup iindeki karakter dizilerini tekrar birletirmek istersek
ne yapacaz?
imdi u kodlara ok dikkatlice bakn:
>>> " ".join(blnm)
'Beikta Jimnastik Kulb'
Grdnz gibi, Beikta Jimnastik Kulb adl karakter dizisinin ilk halini tekrar elde ettik.
Yani bu karakter dizisine ait, blnm paralar tekrar bir araya getirdik. Ancak bu ii yapan
kod gznzne biraz tuhaf ve anlalmaz grnm olabilir.
lk bata dikkatimizi eken ey, bu metodun br metotlara gre biraz daha farkl bir yapya
sahipmi gibi grnmesi. Ama belki yukardaki rnei yle yazarsak bu rnek biraz daha
anlalr gelebilir gznze:
>>> birletirme_karakteri = " "
>>> birletirme_karakteri.join(blnm)
342
Burada da tpk teki metotlarda olduu gibi, join() metodunu bir karakter dizisi zerine
uyguladk. Bu karakter dizisi bir adet boluk karakteri. Ayrca grdnz gibi join()
metodu bir adet de parametre alyor. Bu rnekte join() metoduna verdiimiz parametre
blnm adl deiken. Aslnda yle bir dnnce yukardaki kodlarn sanki yle
yazlmas gerekiyormu gibi gelebilir size:
>>> [Link](birletirme_karakteri)
Ama bu kullanm yanltr. stelik kodunuzu byle yazarsanz Python size bir hata mesaj
gsterecektir:
>>> [Link](birletirme_karakteri)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'
Buradaki hata mesaj bize yle diyor: liste nesnesinin join adl bir nitelii yoktur!. Bu
cmledeki liste nesnesi ifadesine zellikle dikkatinizi ekmek istiyorum. Biz imdiye kadar iki
tr nesne (ya da baka bir ifadeyle veri tipi) grmtk. Bunlar karakter dizileri ve saylard.
Burada karmza nc bir nesne kyor. Grdmz kadaryla bu yeni nesnenin ad liste.
(Liste adl veri tipini birka blm sonra en ince ayrntsna kadar inceleyeceiz. Pythonda
byle bir veri tipi olduunu bilmemiz bizim iin imdilik yeterli.)
te yukardaki hatay almamzn nedeni, aslnda karakter dizilerine ait bir metot olan join()
metodunu bir liste zerinde uygulamaya almamz. Byle bir durumda da Python doal
olarak bizi liste nesnelerinin join adl bir nitelii olmad konusunda uyaryor. Btn bu
anlattklarmz bizi u sonuca ulatryor: Bir veri tipine ait metotlar doal olarak yalnzca o
veri tipi zerinde kullanlabilir. Mesela yukardaki rnekte grdmz gibi, bir karakter dizisi
metodu olan join()i baka bir veri tipine uygulamaya alrsak hata alrz.
Sonu olarak, join() adl metodu blnm adl deikene uygulayamayacamz anlam
bulunuyoruz. O halde bu metotla birlikte kullanlmak zere bir karakter dizisi bulmamz
gerekiyor.
En bata da sylediimiz gibi, join() metodunun grevi blnm karakter dizisi gruplarn
birletirmektir.
Bu metot grevini yerine getirirken, yani karakter dizisi gruplarn
birletirirken bir birletirme karakterine ihtiya duyar. Bizim rneimizde bu birletirme
karakteri bir adet boluktur. Durumu daha iyi anlayabilmek iin rneimizi tekrar gzmnn
nne getirelim:
>>> kardiz = "Beikta Jimnastik Kulb"
>>> blnm = [Link]()
>>> print(blnm)
['Beikta', 'Jimnastik', 'Kulb']
>>> kardiz = " ".join(blnm)
>>> print(kardiz)
Beikta Jimnastik Kulb
Grdnz gibi, orijinal karakter dizisinin blnm paralarn, her bir parann arasnda
bir adet boluk olacak ekilde yeniden birletirdik.
Elbette sadece boluk karakteri
kullanabileceiz diye bir kaide yok. Mesela u rneklere bakn:
22.6. join()
343
lk rnekte, blnm karakter dizilerini - iareti ile birletirdik. kinci rnekte ise bu karakter
dizilerini birletirmek iin bo bir karakter dizisi kullandk. Yani paralar birletirirken arada
boluk olmamasn saladk.
join() metodu ile bol bol pratik yaparak bu metodu hakkyla renmenizi tavsiye ederim.
Zira programclk maceranz boyunca en sk kullanacanz karakter dizisi metotlar listesinin
en balarnda bu metot yer alr.
22.7 count()
Tpk daha nce rendiimiz sorgulayc metotlar gibi, count() metodu da bir karakter dizisi
zerinde herhangi bir deiiklik yapmamz salamaz. Bu metodun grevi bir karakter dizisi
iinde belli bir karakterin ka kez getiini sorgulamaktr. Bununla ilgili hemen bir rnek
verelim:
>>> ehir = "Kahramanmara"
>>> [Link]("a")
5
Buradan anlyoruz ki, Kahramanmara adl karakter dizisi iinde toplam 5 adet a karakteri
geiyor.
count() metodu yaygn olarak yukardaki rnekte grld ekilde sadece tek bir parametre
ile kullanlr. Ama aslnda bu metot toplam 3 parametre alr. imdi u rnekleri dikkatlice
inceleyin:
>>> ehir = "adana"
>>> [Link]("a")
3
>>> [Link]("a", 1)
2
>>> [Link]("a", 2)
2
>>> [Link]("a", 3)
1
>>> [Link]("a", 4)
1
344
lk rnekte count() metodunu tek bir parametre ile birlikte kullandmz iin adana adl
karakter dizisi iindeki btn a harerinin toplam says kt olarak verildi.
kinci rnekte, ise count() metodununa ikinci bir parametre daha verdik. Bu ikinci parametre,
count() metodunun bir karakteri saymaya balarken karakter dizisinin kanc srasndan
balayacan gsteriyor. Bu rnekte ikinci parametre olarak 1 saysn verdiimiz iin, Python
saymaya adana karakter dizisinin 1. srasndan balayacak. Dolaysyla 0. sradaki a
har saym ileminin dnda kalaca iin toplam a says 4 deil 3 olarak grnecek.
Grdnz gibi, sonraki rneklerde de ayn mant takip ettiimiz iin aradmz karakterin
toplam says rnekten rnee farkllk gsteriyor.
Peki bu metodu gerek programlarda ne amala kullanabilirsiniz? Bu metodu kullanarak,
rnein, kullancy ayn karakterden yalnzca bir adet girmeye zorlayabilirsiniz. Bunun iin
mesela yle bir yap kullanabilirsiniz:
parola = input("parolanz: ")
kontrol = True
for i in parola:
if [Link](i) > 1:
kontrol = False
if kontrol:
print('Parolanz onayland!')
else:
print('Parolanzda ayn harfi bir kez kullanabilirsiniz!')
Burada kontrol deikeninin deerini True olarak belirledik. Eer parola iindeki harerden
herhangi biri 1den fazla geiyorsa bu durumda kontrol deikeninin deerini False
yapyoruz:
for i in parola:
if [Link](i) > 1:
kontrol = False
Daha sonra da kontrol deikeninin durumuna gre kullancya parolann onayland veya
onaylanmad bilgisini veriyoruz. Buna gre eer kontrol deikeninin deeri True ise u
kty veriyoruz:
Parolanz onayland!
Burada amacmz kullancnn girdii bir kelime iindeki btn harerin o kelime iinde
ka kez getiini bulmak. count() metodunu kullanarak bu ii ok kolay bir ekilde
22.7. count()
345
harfi
harfi
harfi
harfi
harfi
adana
adana
adana
adana
adana
kelimesinde
kelimesinde
kelimesinde
kelimesinde
kelimesinde
3
1
3
1
3
kez
kez
kez
kez
kez
geiyor!
geiyor!
geiyor!
geiyor!
geiyor!
Ancak burada yle bir problem var: adana kelimesi iinde birden fazla geen harer
(mesela a har) ktda birka kez tekrarlanyor. Yani mesela a harnin getii her yerde
programmz a harnin kelime iinde ka kez getiini rapor ediyor. stediiniz davran bu
olabilir. Ama baz durumlarda her harn kelime iinde ka kez getii bilgisinin yalnzca bir
kez raporlanmasn isteyebilirsiniz. Yani siz yukardaki gibi bir kt yerine yle bir kt elde
etmek istiyor olabilirsiniz:
a harfi adana kelimesinde 3 kez geiyor!
d harfi adana kelimesinde 1 kez geiyor!
n harfi adana kelimesinde 1 kez geiyor!
lk dngmz sayesinde, kullancnn girdii kelime iindeki her har teke indirerek, bu
hareri saya deikeni iinde topladk. imdi yapmamz gereken ey, saya deikenine
gnderilen her bir harn, kelime adl deiken iinde ka kez getiini hesaplamak olmal.
Bunu da yine bir for dngs ile yapabiliriz:
346
Burada yaptmz ey u: count() metodunu kullanarak, saya deikeninin iindeki her bir
harn, kelime deikeninin iinde ka kez getiini buluyoruz. Bu dngnn nasl altn
daha iyi anlayabilmek iin, isterseniz bu dngy u ekilde sadeletirebilirsiniz:
for harf in saya:
print(harf, kelime, [Link](harf))
Grdnz gibi, saya deikeni iindeki herbir harn kelime adl karakter dizisi iinde ka
kez getiini tek tek sorguladk.
Yukardaki rneklerde count() metodunun iki farkl parametre aldn grdk. Bu metot
bunlarn dnda nc bir parametre daha alr. Bu nc parametre ikinci parametreyle
ilikilidir. Dilerseniz bu ilikiyi bir rnek zerinde grelim:
>>> kardiz = "python programlama dili"
>>> [Link]("a")
3
>>> [Link]("a", 15)
2
Bu rneklerden anladmza gre, python programlama dili adl karakter dizisi iinde
toplam 3 adet a har var. Eer bu karakter dizisi iindeki a harerini karakter dizisinin
en bandan itibaren deil de, 15. karakterden itibaren saymaya balarsak bu durumda 2
adet a har buluyoruz. imdi de u rnee bakalm:
>>> [Link]("a", 15, 17)
1
Burada, 15. karakter ile 17. karakter arasnda kalan a harerini saym olduk. 15. karakter
ile 17. karakter arasnda toplam 1 adet a har olduu iin de Python bize 1 sonucunu verdi.
Btn bu rneklerden sonra count() metoduna ilikin olarak yle bir tespitte bulunabiliriz:
count() metodu bir karakter dizisi iinde belli bir karakterin ka kez getiini
sorgulamamz salar. rnein bu metodu count("a") eklinde kullanrsak
Python bize karakter dizisi iindeki btn a harerinin saysn verecektir. Eer
bu metoda 2. ve 3. parametreleri de verirsek, sorgulama ilemi karakter
dizisinin belli bir ksmnda gerekletirilecektir. rnein count("a", 4, 7) gibi bir
kullanm, bize karakter dizisinin 4. ve 7. karakterleri arasnda kalan a harerinin
saysn verecektir.
Bylece bir metodu daha ayrntl bir ekilde incelemi olduk.
incelemeye geebiliriz.
22.7. count()
347
Bu metodun zellii, sorguladmz karakterin, karakter dizisi iinde getii ilk konumu
vermesidir. Yani rnein:
>>> kardiz = "adana"
>>> [Link]("a")
0
adana adl karakter dizisi iinde 3 adet a har var. Ancak biz index() metodu yardmyla
adana karakter dizisi iindeki a harnin konumunu sorgularsak, Python bize a harnin
getii ilk konumu, yani 0. konumu, bildirecektir. Halbuki adana karakter dizisi iinde 2. ve
4. sralarda da birer a har var. Ancak index() metodu 0. konumdaki a harni grdkten
sonra karakter dizisinin geri kalanna bakmaz.
index() metodunu biz yukarda tek bir parametre ile birlikte kullandk. Bu parametre,
karakter dizisi iinde konumunu renmek istediimiz karakteri gsteriyor. Ama bu metot
aslnda toplam 3 parametre alr. u rnekleri dikkatlice inceleyelim:
>>> kardiz = "adana"
>>> [Link]("a")
0
Burada normal bir ekilde index() metodunu tek bir parametre ile birlikte kullandk. Bylece
Python bize a harnin karakter dizisi iinde ilk olarak hangi srada bulunduunu gsterdi. Bir
de u rnee bakalm:
>>> [Link]("a", 1)
2
348
Grdnz gibi, bu defa index() metoduna ikinci bir parametre daha verdik. index()
metodunun ikinci parametresi, Pythonn aramaya kanc sradan itibaren balayacan
gsteriyor. Biz yukardaki rnekte Pythonn aramaya 1. sradan itibaren balamasn istedik.
Bu yzden Python 0. sradaki a karakterini es geti ve 2. srada bulunan a karakterini
grd. Bir de una bakalm:
>>> [Link]("a", 3)
Hatrlarsanz, bundan nce count() adl bir metot renmitik. O metot da toplam 3
parametre alyordu. count() metodunda kullandmz 2. ve 3. parametrelerin grevlerini
hatrlyor olmalsnz. te index() metodunun 2. ve 3. parametreleri de aynen count()
metodundaki gibi alr. Yani Pythonn sorgulama ilemini hangi sra aralklarndan
gerekletireceini gsterir. Mesela yukardaki rnekte biz adana karakter dizisinin 1. ve 3.
sralar arasndaki a harerini sorguladk. Yani yukardaki rnekte Python a harni aramaya
1. konumdan balad ve aramay 3. konumda kesti. Bylece adana karakter dizisinin 2.
srasndaki a harnin konumunu bize bildirdi.
Grdnz gibi, index() metodu bize aradmz karakterin yalnzca ilk konumunu
bildiriyor. Peki biz mesela adana karakter dizisi iindeki btn a harerinin srasn
renmek istersek ne yapacaz?
Bu isteimizi yerine getirmek iin karakter dizisinin her bir srasn tek tek kontrol etmemiz
yeterli olacaktr. Yani yle bir ey yazmamz gerekiyor:
kardiz = "adana"
print([Link]("a",
print([Link]("a",
print([Link]("a",
print([Link]("a",
print([Link]("a",
0))
1))
2))
3))
4))
349
Grdnz gibi, yukardaki kodlar yardmyla, bir nceki verimsiz kodlar hem ksalttk, hem
de daha geni kapsaml bir hale getirdik. Hatta yukardaki kodlar yle yazarsanz karakter
dizisi ve bu karakter dizisi iinde aranacak karakteri kullancdan da alabilirsiniz:
kardiz = input("Metin girin: ")
aranacak = input("Aradnz harf: ")
for i in range(len(kardiz)):
print([Link](aranacak, i))
Bu kodlarda baz problemler dikkatinizi ekmi olmal. Mesela, aranan karakter dizisinin
bulunduu konumlar ktda tekrar ediyor. rnein, kullancnn adana karakter dizisi iinde
a harni aramak istediini varsayarsak programmz yle bir kt veriyor:
0
2
2
4
4
Burada 2 ve 4 saylarnn birden fazla getiini gryoruz. Bunu engellemek iin yle bir
kod yazabiliriz:
kardiz = input("Metin girin: ")
aranacak = input("Aradnz harf: ")
for i in range(len(kardiz)):
if i == [Link](aranacak, i):
print(i)
Daha sonra for dngs iinde tanmladmz i deikeninin deerinin, karakter dizisi iinde
aradmz karakterin konumu ile eleip elemediini kontrol ediyoruz ve deeri eleen
saylar print() fonksiyonunu kullanarak ekrana dkyoruz.
Eer bu kodlar ilk bakta gznze anlalmaz grndyse bu kodlar bir de u ekilde
yazarak arka planda neler olup bittiini daha net grebilirsiniz:
kardiz = input("Metin girin: ")
aranacak = input("Aradnz harf: ")
for i in range(len(kardiz)):
print("i'nin deeri: ", i)
if i == [Link](aranacak, i):
350
Grdnz gibi index() metodu bir karakter dizisi iindeki karakterleri ararken karakter
dizisini soldan saa doru okuyor. Pythonda bu ilemin tersi de mmkndr. Yani isterseniz
Pythonn, karakter dizisini soldan saa doru deil de, sadan sola doru okumasn da
salayabilirsiniz. Bu i iin rindex() adl bir metottan yararlanacaz. Bu metot her ynden
index() metoduyla ayndr. index() ve rindex() metotlarnn birbirinden tek fark, index()
metodunun karakter dizilerini soldan saa, rindex() metodunun ise sadan sola doru
okumasdr. Hemen bir rnekle durumu aklamaya alalm:
>>> kardiz = "adana"
>>> [Link]("a")
0
>>> [Link]("a")
4
Bu iki rnek, index() ve rindex() metotlar arasndaki fark gayet net bir ekilde ortaya
koyuyor. index() metodu, karakter dizisini soldan saa doru okuduu iin adana karakter
dizisinin 0. srasndaki a harni yakalad. rindex() metodu ise karakter dizisini sadan sola
doru okuduu iin adana karakter dizisinin 4. srasndaki a harni yakalad...
351
22.10 center()
Center kelimesi ngilizcede orta, merkez, ortalamak gibi anlamlara gelir. Bu anlama uygun
olarak, center() metodunu karakter dizilerini ortalamak iin kullanabilirsiniz. rnein:
for metot in dir(""):
print([Link](15))
Grdnz gibi center() metodu bir adet parametre alyor. Bu parametre, karakter dizisine
uygulanacak ortalama ileminin geniliini gsteriyor. Bu parametrenin nasl bir etki ortaya
kardn daha iyi anlayabilmek iin isterseniz bir iki basit rnek verelim:
>>> kardiz = "python"
Burada ise center() metoduna parametre olarak 1 saysn verdik. Ancak bu parametre
karakter dizimizinin uzunluundan az olduu iin kt zerinde herhangi bir etkisi olmad.
Bir de una bakalm:
>>> [Link](10)
'
python
'
352
' python'
' python '
' python '
' python '
'
python '
'
python
'
'
python
'
'
python
'
'
python
'
'
python
'
'
python
'
'
python
'
'
python
'
Bu rnekte, karakter dizisinin her admda nasl ortaya doru kayd aka grlyor. Dikkat
ederseniz ktnn ilk alt satrnda karakter dizisinin konumu deimiyor. Ancak center()
metoduna verilen parametrenin deeri karakter dizisinin uzunluunu at anda karakter
dizisi ortaya doru ilermeye balyor.
center() metodu genellikle yukardaki gsterdiimiz ekilde tek bir parametre ile birlikte
kullanlr. Ancak bu metot aslnda bir parametre daha alr. u rnei inceleyelim:
>>> kardiz = "elma"
>>> [Link](10, "-")
'---elma---'
ljust() metodu bize zellikle karakter dizilerinin hizalama ilemlerinde yardmc oluyor. Bu
metot yardmyla karakter dizilerimizi sola yaslayp, sa tarafna da istediimiz karakterleri
yerletirebiliyoruz. Hemen bir rnek verelim:
>>> kardiz = "tel no"
>>> [Link](10, ".")
'tel no....'
353
Grdnz gibi, karakter dizisinde herhangi bir deiiklik olmad. ljust() metoduna
verdiimiz . karakterini grebilmemiz iin, verdiimiz say cinsli parametrenin en az
karakter dizisinin boyunun bir fazlas olmas gerekir:
>>> [Link](7, ".")
'tel no.'
Grdnz gibi, bu metot karakter dizilerini k bir biimde sola hizalamamza yardmc
oluyor.
rjust() metodu ise, ljust() metodunun yapt iin tam tersini yapar. Yani karakter dizilerini
sola deil saa yaslar:
>>> for i in "elma", "armut", "patlcan":
...
[Link](10, ".")
...
'......elma'
'.....armut'
'..patlcan'
22.12 zll()
Bu metot kimi yerlerde iimizi epey kolaylatrabilir. zfill() metodu yardmyla karakter
dizilerinin sol tarafna istediimiz sayda sfr ekleyebiliriz:
>>> a = "12"
>>> [Link](3)
'012'
354
01
02
03
04
05
06
07
08
09
10
Burada str() fonksiyonunu kullanarak, range() fonksiyonundan elde ettiimiz saylar birer
karakter dizisine evirdiimize dikkat edin. nk zfill() karakter dizilerinin bir metodudur.
Saylarn deil...
Gelelim rpartition() metoduna... Bu metot da partition() metodu ile ayn ii yapar, ama
yntemi biraz farkldr. partition() metodu karakter dizilerini soldan saa doru okur.
rpartition() metodu ise sadan sola doru. Peki bu durumun ne gibi bir sonucu vardr?
Hemen grelim:
>>> b = "istihza"
>>> [Link]("i")
('', 'i', 'stihza')
Grdnz gibi, partition() metodu karakter dizisini ilk i harnden bld. imdi ayn
ilemi rpartition() metodu ile yapalm:
>>> [Link]("i")
('ist', 'i', 'hza')
rpartition() metodu ise, karakter dizisini sadan sola doru okuduu iin ilk i harnden
deil, son i harnden bld karakter dizisini.
partition() ve rpartition() metotlar, ltn karakter dizisi iinde bulunmad
durumlarda da farkl tepkiler verir:
355
>>> [Link]("g")
('istihza', '', '')
>>> [Link]("g")
('', '', 'istihza')
22.14 encode()
Bu metot yardmyla karakter dizilerimizi istediimiz kodlama sistemine gre kodlayabiliriz.
Python [Link] varsaylan karakter kodlamas utf-8 dir. Eer istersek u karakter dizisini utf-8
yerine cp1254 ile kodlayabiliriz:
>>> "ilek".encode("cp1254")
22.15 expandtabs()
Bu metot yardmyla bir karakter dizisi iindeki sekme boluklarn geniletebiliyoruz.
rnein:
>>> a = "elma\tbir\tmeyvedir"
>>> [Link](10)
'elma bir meyvedir'
Bylece bir metot grubunu daha geride brakm olduk. Grdnz gibi baz metotlar
sklkla kullanlabilme potansiyeli tarken, baz metotlar pek yle sk kullanlacakm gibi
grnmyor...
Sonraki blmde metotlar incelemeye devam edeceiz.
356
BLM 23
357
Grdnz gibi, kaynak adl karakter dizisi iinde belirttiimiz btn harer hedef adl
karakter dizisi iindeki harerle tek tek deitirildi. Bylece Trkeye zg karakterleri
() en yakn noktasz benzerleriyle (scoguiSCOGUI) deitirmi olduk.
Peki yukarda nasl bir sre iledi de biz istediimiz sonucu elde edebildik. Dilerseniz
yukardaki kodlara biraz daha yakndan bakalm. Mesela eviri_tablosu adl deikenin
ktsna bakarak [Link]() metodunun alttan alta neler kartrdn grelim:
kaynak = ""
hedef = "scoguiSCOGUI"
eviri_tablosu = [Link](kaynak, hedef)
print(eviri_tablosu)
Bu kt size tamamen anlamsz grnm olabilir. Ama aslnda son derece anlaml ve bir o
kadar da nemli bir ktdr bu. Gelin isterseniz bu ktnn yapsn biraz inceleyelim. (Buna
benzer bir kty sorted() metodunu incelerken de grmtk)
Grdnz gibi, tamamen saylardan oluan bir kt bu. Burada birbirlerinden virgl ile
ayrlm say iftleri gryoruz. Bu say iftlerini daha net grebilmek iin bu kty derli toplu
bir hale getirelim:
{214:
231:
220:
199:
304:
305:
286:
246:
351:
252:
350:
287:
79,
99,
85,
67,
73,
105,
71,
111,
115,
117,
83,
103}
Bu ekilde sanrm ktmz biraz daha anlam kazand. Grdnz gibi, iki nokta st ste
iaretinin solunda ve sanda baz saylar var. Tahmin edebileceiniz gibi, soldaki saylar
sadaki saylarla ilikili.
Peki btn bu saylar ne anlama geliyor ve bu saylar arasnda ne tr bir iliki var?
Teknik olarak, bilgisayarlarn temelinde saylar olduunu duymusunuzdur. Bilgisayarnzda
grdnz her karakter aslnda bir sayya karlk gelir. Zaten bilgisayarlar a, b, c, vb.
kavramlar anlayamaz. Bilgisayarlarn anlayabildii tek ey saylardr. Mesela siz klavyeden a
harni girdiinizde bilgisayar bunu 97 olarak alglar. Ya da siz i har girdiinizde, bilgisayarn
grd tek ey 105 saysdr... Bu durumu Pythondaki chr() adl zel bir fonksiyon
yardmyla teyit edebiliriz. Dikkatlice inceleyin:
358
>>> chr(97)
'a'
>>> chr(105)
'i'
>>> chr(65)
'A'
sterseniz bir de
for i in 214, 231, 220, 199, 304, 305, 286, 246, 351, 252, 350, 287:
print(i, chr(i))
Bu kt sayesinde baz eyler zihninizde yava yava akla kavuuyor olmal. Bu kt mesela
214 saysnn harne, 220 saysnn harne, 305 saysnn da harne karlk geldiini
gsteriyor.
Burada iki nokta iaretinin sol tarafnda kalan saylarn karakter karlklarn grdk. Bir de
iki nokta iaretinin sa tarafnda kalan saylara bakalm:
for i in 79, 99, 85, 67, 73, 105, 71, 111, 115, 117, 83, 103:
print(i, chr(i))
Bu da u kty verdi:
79
99
85
67
73
105
71
111
115
117
83
103
O
c
U
C
I
i
G
o
s
u
S
g
359
O
c
U
C
I
i
G
o
s
u
S
g
"O",
"c",
"U",
"C",
"I",
"i",
"G",
"o",
"s",
"u",
"S",
"g"}
360
"O",
"c",
"U",
"C",
"I",
"i",
"G",
"o",
"s",
"u",
"": "S",
"": "g"}
print(eviri_tablosu[""])
Grdnz gibi, szlk iinde geen adl eyi parantez iinde belirttiimiz zaman,
Python bize bu enin karsndaki deeri veriyor. Szlk iinde esinin karl O
har olduu iin de ktmz O oluyor. Bir de unlara bakalm:
eviri_tablosu = {"":
"":
"":
"":
"":
"":
"":
"":
"":
"":
"":
"":
"O",
"c",
"U",
"C",
"I",
"i",
"G",
"o",
"s",
"u",
"S",
"g"}
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
Grdnz gibi, szlk iinde iki nokta st ste iaretinin sol tarafnda grnen eleri
parantez iinde yazarak, iki nokta st ste iaretinin sa tarafndaki deerleri elde
edebiliyoruz.
Btn bu anlattklarmzdan sonra u satrlar gayet iyi anlam olmalsnz:
kaynak = ""
hedef = "scoguiSCOGUI"
361
Burada Python, kaynak ve hedef adl deikenler iindeki karakter dizilerini birer birer
eletirerek bize bir szlk veriyor. Bu szlkte:
""
""
""
""
""
""
""
""
""
""
""
""
harfi
harfi
harfi
harfi
harfi
harfi
harfi
harfi
harfi
harfi
harfi
harfi
"s"
"c"
"o"
"g"
"u"
"i"
"S"
"C"
"O"
"G"
"U"
"I"
harfine;
harfine;
harfine;
harfine;
harfine;
harfine;
harfine;
harfine;
harfine;
harfine;
harfine;
harfine
karlk geliyor...
Kodlarn geri kalannda ise u satrlar grmtk:
metin = "Bildiiniz gibi, internet zerinde bazen Trke karakterleri kullanamyoruz."
print([Link](eviri_tablosu))
Burada da orijinal metnimizi tanmladktan sonra translate() adl metot yardmyla, eviri
tablosundaki e elemesi dorultusunda metnimizi tercme ediyoruz. Bu kodlarda
[Link](eviri_tablosu) satrnn yapt tek ey eviri_tablosu adl szlkteki
eleme kriterlerini metin adl karakter dizisine uygulamaktan ibarettir.
Karakter dizilerinin bu maketrans() adl metodu kullanm olarak gznze teki metotlardan
farkl grnm olabilir. Daha ak bir dille ifade etmek gerekirse, bu metodu bir karakter
dizisi zerine deil de str zerine uyguluyor olmamz, yani [Link]() yazyor olmamz
sizi artm olabilir. Eer anlamanz kolaylatracaksa;
eviri_tablosu = [Link](kaynak, hedef)
Ama tabii dikkat datmamak asndan en uygun hareket, bu karakter dizisini str zerine
uygulamak olacaktr:
eviri_tablosu = [Link](kaynak, hedef)
Burada amacmz yanllkla q klavye dzeninde yazld iin karman orman bir hale gelmi
metni dzgn bir ekilde f klavye dzenine dntrmek. Yani burada k noktamz
(kaynamz) q_klavye_dzeni iken, var noktamz (hedemiz) f_klavye_dzeni. Buna gre
eviri tablomuzu oluturabiliriz:
eviri_tablosu = [Link](q_klavye_dzeni, f_klavye_dzeni)
Tpk bir nceki rnekte olduu gibi, burada da eviri_tablosu adl deikeni print()
fonksiyonunu kullanarak yazdrrsanz yle bir ktyla karlarsnz:
{231:
287:
44 :
46 :
305:
246:
351:
97 :
98 :
99 :
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
46,
113,
120,
44,
110,
98,
121,
117,
231,
118,
101,
287,
97,
252,
116,
351,
107,
109,
108,
115,
122,
363
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
252:
104,
112,
102,
305,
105,
111,
114,
99,
103,
246,
100,
106,
119}
Tahmin edebileceiniz gibi, bu szlkte iki nokta st ste iaretinin solundaki saylar
q_klavye_dzeni adl deiken iindeki karakterleri; sandaki saylar ise f_klavye_dzeni adl
deiken iindeki karakterleri temsil ediyor.
Son olarak translate() metodunu yardmyla szlkteki e elemesini metin adl
deikenin zerine uyguluyoruz:
print([Link](eviri_tablosu))
Ne elde ettiniz?
Yukardaki iki rnekte de grdmz gibi, [Link]() metodu kaynak ve hedef
karakter dizilerini alp bunlar birletirerek bize bir szlk veri tipinde bir nesne veriyor. Yani
tpk input() fonksiyonunun bize bir karakter dizisi verdii gibi, [Link]() metodu da
bize bir szlk veriyor.
Eer isterseniz, szl [Link]() metoduna oluturtmak yerine, kendiniz de bir
szlk oluturarak [Link]() metoduna parametre olarak atayabilirsiniz. rnein:
metin = "Bfjflrk a kdhs yteua idjslyd bdcusldvdj ks?"
szlk = {"q":
"w":
"e":
"r":
"t":
"y":
"u":
"":
"o":
"p":
"":
"":
364
"f",
"g",
"",
"",
"o",
"d",
"r",
"n",
"h",
"p",
"q",
"w",
"a":
"s":
"d":
"f":
"g":
"h":
"j":
"k":
"l":
"":
"i":
",":
"z":
"x":
"c":
"v":
"b":
"n":
"m":
"":
"":
".":
"u",
"i",
"e",
"a",
"",
"t",
"k",
"m",
"l",
"y",
"",
"x",
"j",
"",
"v",
"c",
"",
"z",
"s",
"b",
".",
","}
eviri_tablosu = [Link](szlk)
print([Link](eviri_tablosu))
Burada birbiriyle eleecek karakterleri kendimiz yazp bir szlk oluturduk ve bunu
parametre olarak dorudan [Link]() metoduna verdik. Bu kodlarda kaynak ve
hedef diye iki ayr karakter dizisi tanmlamak yerine tek bir szlk oluturduumuz iin,
[Link]() metodunu iki parametreyle deil, tek parametreyle kullandmza dikkat
edin. Ayrca szl nasl oluturduumuzu da dikkatlice inceleyin.
Szlkteki e iftlerini byle alt alta yazmamzn nedeni zorunluluk deil, bir tercihtir.
stersek bu szl yle de tanmlayabilirdik:
szlk = {"q":
"":
"d":
"":
"b":
"f",
"n",
"e",
"y",
"",
"w":
"o":
"f":
"i":
"n":
"g",
"h",
"a",
"",
"z",
"e":
"p":
"g":
",":
"m":
"",
"p",
"",
"x",
"s",
"r":
"":
"h":
"z":
"":
"",
"q",
"t",
"j",
"b",
"t":
"":
"j":
"x":
"":
"o",
"w",
"k",
"",
".",
"y":
"a":
"k":
"c":
".":
"d",
"u",
"m",
"v",
","}
"u":
"s":
"l":
"v":
"r",
"i",
"l",
"c",
Burada da e iftlerini yan yana yazdk. Bu iki yntemden hangisi size daha okunakl
geliyorsa onu tercih edebilirsiniz.
imdi size bir soru sormama izin verin. Acaba aadaki metin iinde geen btn sesli
hareri silin desem, nasl bir kod yazarsnz?
Bu programlama dili Guido Van Rossum adl Hollandal bir programc tarafndan
90l yllarn banda gelitirilmeye balanmtr. ou insan, isminin Python
olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn
dnr.
Ancak zannedildiinin aksine bu programlama dilinin ad piton
ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty Python
adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl gsterisinden
esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python
programlama dilinin pek ok yerde bir ylan gr ile temsil edilmesi neredeyse
bir gelenek halini almtr diyebiliriz.
365
Burada ncelikle metin adl bir deiken tanmlayarak metnimizi bu deiken iine
yerletirdik. Ardndan da Trkedeki sesli hareri ieren bir karakter dizisi tanmladk.
Daha sonra da yeni_metin adl bo bir karakter dizisi oluturduk. Bu karakter dizisi, orijinal
metnin, sesli harer ayklandktan sonraki halini barndracak. Biliyorsunuz, karakter dizileri
deitirilemeyen (immutable ) bir veri tipidir. Dolaysyla bir karakter dizisi iinde yaptmz
deiiklikleri koruyabilmek iin bu deiiklikleri baka bir deiken iinde tutmamz gerekiyor.
Bu kodlarn ardndan bir for dngs tanmlyoruz. Buna gre, metin iinde geen her
bir karaktere tek tek bakyoruz (for i in metin:) ve bu karakterler arasnda, sesli_harer
deikeni iinde gemeyenleri, yani btn sessiz hareri (if not i in sesli_harfler:) tek
tek yeni_metin adl deikene yolluyoruz (yeni_metin += i)
Son olarak da yeni_metin adl karakter dizisini ekrana basyoruz. Bylece orijinal metin
iindeki btn sesli hareri ayklam oluyoruz.
Yukardaki, gayet doru ve geerli bir yntemdir. Byle bir kod yazmanzn hibir sakncas
yok. Ama eer isterseniz ayn ii [Link]() ve translate() metotlar yardmyla da
halledebilirsiniz:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir
programc tarafndan 90'l yllarn banda gelitirilmeye balanmtr.
ou insan, isminin Python olmasna bakarak, bu programlama dilinin, adn
piton ylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin ad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty Python adl bir ngiliz komedi grubunun, Monty
Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr. Ancak
her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr
diyebiliriz."""
silinecek = "aeiouAEIOU"
eviri_tablosu = [Link]('', '', silinecek)
366
print([Link](eviri_tablosu))
Burada da ncelikle metnimizi bir karakter dizisi iine yerletirdik. Daha sonra da u kodu
yazdk:
silinecek = "aeiouAEIOU"
Bu kodlar yardmyla, metin iinden karmak istediimiz hareri tek tek belirledik.
Ardndan [Link]() fonksiyonumuzu yazarak eviri tablosunu oluturduk. Burada
ilk iki parametrenin bo birer karakter dizisi olduuna dikkat ediyoruz. lk iki parametreyi
bu ekilde yazmamzn nedeni u: Biz orijinal metin iindeki herhangi bir eyi deitirmek
istemiyoruz. Bizim amacmz orijinal metin iindeki sesli hareri silmek. Tabii o iki
parametreyi yazmasak da olmaz. O yzden o iki parametrenin yerine birer tane bo karakter
dizisi yerletiriyoruz.
Bu noktada eviri_tablosu adl deikeni yazdrarak neler olup bittiini daha net grebilirsiniz:
{214:
97 :
101:
65 :
105:
111:
304:
305:
220:
117:
246:
73 :
79 :
252:
85 :
69 :
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None}
Grdnz gibi, silinecek adl deiken iindeki btn karakterler None deeriyle eleiyor...
None hi, sfr, yokluk gibi anlamlara gelir. Dolaysyla Python, iki nokta st ste iaretinin
sol tarafndaki karakterlerle karlatnda bunlarn yerine birer adet yokluk koyuyor! Yani
sonu olarak bu karakterleri metinden silmi oluyor...
Bu kodlarda iki nokta st ste iaretinin solundaki karakterlerin None ile elemesini salayan
ey, [Link]() metoduna verdiimiz nc parametredir. Eer o parametreyi
yazmazsak, yani kodlarmz u ekle getirirsek eviri_tablosu deikeninin kts farkl
olacaktr:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir
programc tarafndan 90'l yllarn banda gelitirilmeye balanmtr.
ou insan, isminin Python olmasna bakarak, bu programlama dilinin, adn
piton ylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin ad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty Python adl bir ngiliz komedi grubunun, Monty
Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr. Ancak
her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr
diyebiliriz."""
silinecek = "aeiouAEIOU"
367
Grdnz gibi, elde ettiimiz ey bo bir szlktr. Szlk bo olduu, yani deitirilecek
herhangi bir karakter olmad iin bu kodlar orijinal metin zerinde herhangi bir deiiklik
yapmaz.
sterseniz nc parametrenin ne ie yaradn ve nasl altn daha iyi anlayabilmek iin
daha basit bir rnek verelim:
metin = "Cem Ylmaz"
kaynak = "CY"
hedef = "cy"
silinecek = "ea "
eviri_tablosu = [Link](kaynak, hedef, silinecek)
print([Link](eviri_tablosu))
23.2 isalpha()
Bu metot yardmyla bir karakter dizisinin alfabetik olup olmadn denetleyeceiz. Peki
alfabetik ne demek?
Eer bir karakter dizisi iinde yalnzca alfabe hareri (a, b, c gibi...) varsa o karakter dizisi
iin alfabetik diyoruz. Bir rnekle bunu dorulayalm:
>>> a = "kezban"
>>> [Link]()
True
Ama:
>>> b = "k3zb6n"
>>> [Link]()
False
368
23.3 isdigit()
Bu metot da isalpha() metoduna benzer. Bunun yardmyla bir karakter dizisinin saysal
olup olmadn denetleyebiliriz. Saylardan oluan karakter dizilerine say deerli karakter
dizileri ad verilir. rnein u bir say deerli karakter dizisidir:
>>> a = "12345"
23.4 isalnum()
Bu metot, bir karakter dizisinin alfanmerik olup olmadn denetlememizi salar. Peki
alfanmerik nedir?
Daha nce bahsettiimiz metotlardan hatrlayacaksnz:
Alfabetik karakter dizileri, alfabe harerinden oluan karakter dizileridir.
Saysal karakter dizileri, saylardan oluan karakter dizileridir.
Alfanmerik karakter dizileri ise bunun birleimidir. Yani say ve harerden oluan karakter
dizilerine alfanmerik karakter dizileri ad verilir. rnein u karakter dizisi alfanmerik bir
karakter dizisidir:
>>> a = "123abc"
Eer denetleme sonucunda True alyorsak, o karakter dizisi alfanmeriktir. Bir de una
bakalm:
>>> b = "123abc>"
>>> [Link]()
False
369
Dolaysyla, bir karakter dizisi iinde en az bir adet alfanmerik olmayan bir karakter dizisi
bulunursa (bizim rneimizde "<"), o karakter dizisi alfanmerik olmayacaktr.
23.5 isdecimal()
Bu metot yardmyla bir karakter dizisinin ondalk say cinsinden olup olmadn denetliyoruz.
Mesela aadaki rnek ondalk say cinsinden bir karakter dizisidir:
>>> a = "123"
>>> [Link]()
True
Ama u ise kayan noktal (oating-point ) say cinsinden bir karakter dizisidir:
>>> a = "123.3"
>>> [Link]()
False
23.6 isidentier()
Identier kelimesi Trkede tanmlayc anlamna gelir. Pythonda deikenler, fonksiyon
ve modl adlarna tanmlayc denir. te balkta grdmz isidentifier() metodu,
neyin tanmlayc olup neyin tanmlayc olamayacan denetlememizi salar. Hatrlarsanz
deikenler konusundan bahsederken, deiken ad belirlemenin baz kurallar olduunu
sylemitik. Buna gre, rnein, deiken adlar bir say ile balayamyordu. Dolaysyla yle
bir deiken ad belirleyemiyoruz:
>>> 1a = 12
Dediimiz gibi, deikenler birer tanmlaycdr. Dolaysyla bir deiken adnn geerli olup
olmadn isidentifier() metodu yardmyla denetleyebiliriz:
>>> "1a".isidentifier()
False
Demek ki "1a" ifadesini herhangi bir tanmlayc ad olarak kullanamyoruz. Yani bu ada sahip
bir deiken, fonksiyon ad veya modl ad oluturamyoruz. Ama mesela "liste1" ifadesi
geerli bir tanmlaycdr. Hemen denetleyelim:
>>> "liste1".isidentifier()
True
23.7 isnumeric()
Bu metot bir karakter dizisinin nmerik olup olmadn denetler. Yani bu metot yardmyla
bir karakter dizisinin say deerli olup olmadn denetleyebiliriz:
370
>>> "12".isnumeric()
True
>>> "dasd".isnumeric()
False
23.8 isspace()
Bu metot yardmyla bir karakter dizisinin tamamen boluklardan oluup olumadn
denetleyebiliriz. Eer karakter dizimiz boluklardan oluuyorsa bu metot True kts verecek,
ama eer karakter dizimizin iinde bir tane bile boluk harici karakter varsa bu metot False
kts verecektir:
>>> a = " "
>>> [Link]()
True
>>> a = "
>>> [Link]()
"
True
>>> a = "" #karakter dizimiz tamamen bo. inde boluk karakteri bile yok...
>>> [Link]()
False
>>> a = "fd"
>>> [Link]()
False
23.9 isprintable()
Hatrlarsanz nceki derslerimizde \n, \t, \r ve buna benzer karakterlerden sz etmitik.
rnein \n karakterinin satr ba anlamna geldiini ve bu karakterin grevinin karakter
dizisini bir alt satra almak olduunu sylemitik. rnek verelim:
>>> print("birinci satr\nikinci satr")
birinci satr
ikinci satr
23.8. isspace()
371
372
BLM 24
Buradan elde ettiimiz kt ihtiyacmz ksmen karlyor. Ama kt tam istediimiz gibi deil.
nk normalde isme bitiik olmas gereken nokta iareti, isimden bir boluk ile ayrlm.
Yani biz yle bir kt isterken:
Abdul...
373
veya:
isim = input("isminiz: ")
if len(isim) <= 5:
print(isim[:5])
else:
print(isim[:5], "...", sep="")
Yukardaki gibi basit durumlarda klasik karakter dizisi birletirme yntemlerini kullanarak
iinizi halledebilirsiniz. Ama daha karmak durumlarda, farkl kaynaklardan gelen karakter
dizilerini ihtiyalarnza gre bir araya getirmek, karakter dizisi birletirme yntemleri ile pek
mmkn olmayacak veya ok zor olacaktr.
Mesela yle bir durum dnn:
Yazdnz programda kullancya bir parola soruyorsunuz.
Amacnz bu parolann,
programnzda belirlediiniz ltlere uyup uymadn tespit etmek. Eer kullanc tarafndan
belirlenen parola uygunsa ona u kty gstermek istiyorsunuz (parolann b5tY6g olduunu
varsayalm):
Girdiiniz parola (b5tY6g) kurallara uygun bir paroladr!
Grdnz gibi, sadece karakter dizisi birletirme yntemlerini kullanarak istediimiz kty
elde ettik, ama farkettiyseniz bu defa iler biraz da olsa zorlat.
Bir de uzun ve karmak bir metnin iine dardan deerler yerletirmeniz gereken yle bir
metinle kar karya olduunuzu dnn:
Sayn .........
.... tarihinde yapm olduunuz, ........ hakkndaki bavurunuz incelemeye alnmtr.
Size .... ign iinde cevap verilecektir.
Sayglarmzla,
......
Byle bir metin iine dardan deer yerletirmek iin karakter dizisi birletirme
yntemlerine bavurmak iinizi epey zorlatracaktr.
te klasik karakter dizisi birletirme ilemlerinin yetersiz kald veya ileri bsbtn
zorlatrd bu tr durumlarda Pythonn size sunduu karakter dizisi biimlendirme
374
aralarndan yararlanabilirsiniz.
Bunun iin biz bu blmde iki farkl yntemden sz edeceiz:
1. % iareti ile biimlendirme
2. format() metodu ile biimlendirme.
% iareti ile biimlendirme, karakter dizisi biimlendirmenin eski yntemidir. Bu yntem
arlkl olarak Pythonn 3.x srmlerinden nce kullanlyordu.
Ama Pythonn 3.x
srmlerinde de bu yntemi kullanma imkanmz var. Her ne kadar bu yntem Python3te
geerliliini korusa da muhtemelen ileride dilden tamamen kaldrlacak. Ancak hem etrafta
bu yntemle yazlm eski programlar olmas, hem de bu yntemin halen geerliliini
korumas nedeniyle bu yntemi (kendimiz kullanmayacak bile olsak) mutlaka renmemiz
gerekiyor.
format() metodu ise Pythonn 3.x srmleri ile dile dahil olan bir zelliktir. Pythonn 2.x
srmlerinde bu metodu kullanamazsnz. Dilin geleceinde bu metot olduu iin, yeni
yazlan kodlarda format() metodunu kullanmak daha akllca olacaktr.
Biz bu sayfalarda yukarda adn andmz her iki yntemi de inceleyeceiz. lk olarak %
iareti ile biimlendirmeden sz edelim.
Dediim gibi, bu basit rnek karakter dizilerinin nasl biimlendirildiini gayet ak bir ekilde
gsteriyor. Dilerseniz yapy yle bir inceleyelim:
1. Pythonda %s yaps, karakter dizisi iinde bir yer tutma vazifesi grr.
2. %s yaps bir anlamda deikenlere benzer.
yapsnn deeri deiebilir.
375
3. Bir karakter dizisi iindeki her %s ifadesi iin, karakter dizisi dnda bu ifadeye karlk
gelen bir deer olmaldr. Python, karakter dizisi iinde geen her %s ifadesinin yerine,
karakter dizisi dndaki her bir deeri tek tek yerletirir. Bizim rneimizde karakter
dizisi iindeki ilk %s ifadesinin karakter dizisi dndaki karl Python ; karakter dizisi
iindeki ikinci %s ifadesinin karakter dizisi dndaki karl ise Django dur.
4. Eer karakter dizisi iindeki %s iaretlerinin says ile karakter dizisi dnda bu
iaretlere karlk gelen deerlerin says birbirini tutmazsa Python bize bir hata mesaj
gsterecektir. Mesela:
>>> print("Benim adm %s, soyadm %s" %"istihza")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
Grdnz gibi bu kodlar hata verdi. nk karakter dizisi iindeki iki adet %s ifadesine
karlk, karakter dizisinin dnda tek bir deer var (istihza ). Halbuki bizim yle bir kod
yazmamz gerekiyordu:
>>> isim = "istihza"
>>> print("%s adl kiinin mekan www.%[Link] adresidir." %(isim, isim))
Bu defa herhangi bir hata mesaj almadk. nk bu kodlarda, olmas gerektii gibi, karakter
dizisi iindeki iki adet %s ifadesine karlk, darda da iki adet deer var.
Eer karakter dizisi iinde tek bir %s ifadesi varsa, karakter dizisi dnda buna karlk
gelen deeri gsterirken, bu deeri parantez iine almamza gerek yok. Ama eer karakter
dizisi iinde birden fazla %s iareti varsa, bunlara karlk gelen deerleri parantez iinde
gsteriyoruz. Mesela yukardaki parola rneinde, karakter dizisinin iinde tek bir %s ifadesi
var. Dolaysyla karakter dizisi dnda bu ifadeye karlk gelen parola deikenini parantez
iine almyoruz. Ama Python ve Django rneinde karakter dizisi iinde iki adet %s
ifadesi yer ald iin, karakter dizisi dnda bu ifadelere karlk gelen Python ve Django
kelimelerini parantez iinde gsteriyoruz.
Btn bu anlattklarmz sindirebilmek iin dilerseniz bir rnek verelim:
kardiz = "istihza"
for sra, karakter in enumerate(kardiz, 1):
print("%s. karakter: '%s'" %(sra, karakter))
Grdnz gibi, istihza adl karakter dizisi iindeki her bir harn srasn ve harn kendisini
uygun bir dzen iinde ekrana yazdrdk. karakter srasnn ve karakterin kendisinin cmle
iinde gelecei yerleri %s iaretleri ile gsteriyoruz. Python da her bir deeri, ilgili konumlara
tek tek yerletiriyor.
Hatrlarsanz nceki derslerimizde basit bir hesap makinesi rnei vermitik. te imdi
rendiklerimizi o programa uygularsak karakter dizisi biimlendiricileri zerine epey pratik
yapm oluruz:
giri =
(1)
(2)
(3)
(4)
(5)
376
"""
topla
kar
arp
bl
karesini hesapla
Bu arada, grdnz gibi, Pythonda biim dzenleyici olarak kullanlan simge ayn zamanda
yzde (% ) anlamna da geliyor. O halde size yle bir soru soraym: Acaba 0 dan 100 e kadar
olan saylarn bana birer yzde iareti koyarak bu saylar nasl gsterirsiniz? %0, %1, %10,
%15, gibi... nce yle bir ey deneyelim:
377
Bu kodlar tabii ki sadece 0 dan 100 e kadar olan saylar ekrana dkmekle yetinecektir.
Saylarn banda % iaretini gremeyeceiz.
Bir de yle bir ey deneyelim:
>>> for i in range(100):
...
print("%%s" %i)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: not all arguments converted during string formatting
Burada % iaretini arka arkaya iki kez kullanarak bir adet % iareti elde ettik. Daha sonra da
normal bir ekilde %s biimini kullandk. Yani adet % iaretini yan yana getirmi olduk.
Btn bu rneklerden sonra, karakter dizisi biimlendiricilerinin iimizi ne kadar
kolaylatrdn grm olmalsnz. stediimiz etkiyi elde etmek iin karakter dizisi
biimlendiricilerini kullanmak, karakter dizilerini birletirme ilemlerinden yararlanmaya
gre ok daha esnek bir yntemdir. Hatta baz durumlarda karakter dizisi biimlendiricilerini
kullanmak makul tek yntemdir.
Yukarda verdiimiz rnekler, %s ile biimlendirme konusunun en temel ynlerini gsteriyor.
Ama aslnda bu arac kullanarak ok daha karmak biimlendirme ilemleri de yapabiliriz.
Yani yukardaki rneklerde %s yapsn en basit ekilde mesela yle kullandk:
>>> print("Karakter dizilerinin toplam %s adet metodu vardr" %len(dir(str)))
Grdnz gibi % ile s iaretleri arasna bir say yerletirdik. Bu say, biimlendirilecek
karakter dizisinin toplam ka karakterlik yer kaplayacan gsteriyor. Durumu daha net
grebilmeniz iin yle bir rnek verelim:
>>> print("|%15s|" %"istihza")
|
istihza|
Karakter dizisinin bana ve sonuna eklediimiz | iaretleri sayesinde karakter dizisinin nasl
ve ne ekilde hizalandn daha belirgin bir ekilde grebiliyoruz. Aslnda yukardaki rnein
yapt i size hi yabanc deil. Ayn etkiyi, karakter dizisi metotlarndan rjust() ile de
yapabileceimizi biliyorsunuz:
378
>>> print("istihza".rjust(15))
Aynen yukardaki kty rjust() metodunu kullanarak elde etmek iin ise yle bir ey
yazabilirsiniz:
>>> print("|%s|" %"istihza".rjust(15))
|
istihza|
Yukardaki rnekte istihza karakter dizisini saa doru yasladk. Sola yaslamak iin ise
negatif saylardan yararlanabilirsiniz:
>>> print("|%-15s|" %"istihza")
|istihza
Tpk biraz nce verdiimiz rnekteki gibi, ayn etkiyi ljust() metoduyla da elde edebilirsiniz:
>>> print("|%s|" %"istihza".ljust(15))
|istihza
Grdnz gibi, %s yapsn farkl ekillerde kullanarak epey karmak ktlar elde
edebiliyoruz. Ama aslnda karakter dizisi biimlendiricilerini kullanarak yapabileceklerimiz
bunlarla da snrl deildir. Mesela size yle bir soru sorduumu dnn: Acaba aadaki
ierie sahip bir HTML ablonunu nasl elde edebiliriz?
<html>
<head>
<title> {{ sayfa bal }} </title>
</head>
<body>
<h1> {{ birinci seviye balk }} </h1>
<p>Web sitemize hogeldiniz! Konumuz: {{ konu }}</p>
</body>
</html>
Burada btn deikenler tek bir deere sahip olacak. rnein deikenimiz Python
Programlama Dili ise yukardaki ablon yle bir HTML sayfas retecek:
<html>
<head>
<title> Python Programlama Dili </title>
</head>
<body>
<h1> Python Programlama Dili </h1>
<p>Web sitemize hogeldiniz! Konumuz: Python Programlama Dili</p>
</body>
</html>
379
</head>
<body>
<h1> %s </h1>
<p>Web sitemize hogeldiniz! Konumuz: %s</p>
</body>
</html>
"""
print(sayfa % ("Python Programlama Dili",
"Python Programlama Dili",
"Python Programlama Dili"))
Bu gayet makul ve doru bir zmdr. Ancak grdnz gibi yukardaki kodlarda bizi
rahatsz eden bir nokta var. Bu kodlarda ayn karakter dizisini (Python Programlama
Dili ) kez tekrar ediyoruz. En batan beri sylediimiz gibi, kod yazarken tekrarlardan
olabildiince kanmaya almamz programmzn performansn artracaktr. Burada da
tekrardan kanmak amacyla yle bir kod yazmay tercih edebiliriz. Dikkatlice inceleyin:
sayfa = """
<html>
<head>
<title> %(dil)s </title>
</head>
<body>
<h1> %(dil)s </h1>
<p>Web sitemize hogeldiniz! Konumuz: %(dil)s</p>
</body>
</html>
"""
print(sayfa % {"dil": "Python Programlama Dili"})
Grdnz gibi, yukardaki kodlar bizi ayn karakter dizisini tekrar tekrar yazma
zahmetinden kurtard. Peki ama nasl? Gelin isterseniz bu yapy daha iyi anlayabilmek iin
daha basit bir rnek verelim:
print("depoda %(miktar)s kilo %(rn)s kald" %{"miktar": 25,
"rn": "elma"})
{deiken_ad:
deiken_deeri} yapsyla nceki derslerimizde karlamtnz.
Dolaysyla bu yapnn temel olarak ne ie yaradn biliyorsunuz. Hatta bu yapnn
adnn szlk olduunu da renmitiniz. te burada, szlk adl veri tipinden yararlanarak
deiken adlar ile deiken deerlerini eletirdik. Bylece ayn eyleri tekrar tekrar
yazmamza gerek kalmad. Ayrca yukardaki rnekte deerleri srasna gre deil, ismine
gre ardmz iin, karakter dizisi iindeki deerlerin srasn takip etme zahmetinden de
kurtulmu olduk.
Bylece % yapsnn tm temel ayrntlarn renmi olduk. Artk % iaretinin baka ynlerini
incelemeye balayabiliriz.
380
Grdnz gibi, % iaretiyle birlikte bu defa s yerine d harni kullandk. Buna uygun olarak
da d tarafta 28 saysn kullandk. Peki yukardaki ifadeyi yle de yazamaz mydk?
>>> print("ubat ay bu yl %s gn ekiyor" %28)
381
Elbette yazabilirdik. Bu kod da bize doru kt verecektir. nk daha nce de dediimiz gibi,
s har karakter dizilerini ve karakter dizisine evrilebilen deerleri temsil eder. Pythonda
saylar karakter dizisine evrilebildii iin %s gibi bir yapy hata almadan kullanabiliyoruz.
Ama mesela yle bir ey yazamayz:
>>> print("ubat ay bu yl %d gn ekiyor" %"yirmi sekiz")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: %d format: a number is required, not str
Grdnz gibi bu defa hata aldk. nk d har yalnzca say deerleri temsil edebilir. Bu
hare birlikte karakter dizilerini kullanamayz.
Dorusunu sylemek gerekirse, d har aslnda tam say (integer ) deerleri temsil eder. Eer
bu harn kullanld bir karakter dizisinde deer olarak mesela bir kayan noktal say (oat )
verirsek, bu deer tamsayya evrilecektir. Bunun ne demek olduunu hemen bir rnekle
grelim:
>>> print("%d" %13.5)
13
Elbette Pythonda bir ondalk saynn sadece taban ksmn almann baka yntemleri de
vardr. Ama yukarda verdiimiz rnek bir ondalk saynn sadece tabann almann gayet
basit ve etkili bir yoludur.
%s yapsn anlatrken gsterdiimiz ileri dzey biimlendirme tekniklerini %d ile de
kullanabilirsiniz. rnein:
>>> print("|%7d|" %23)
|
23|
veya:
382
...veya:
>>> print("%.5d" %23)
00023
Hatta hem saynn kaplayaca boluk miktarn hem de bu boluklarn ne kadarnn 0 ile
doldurulacan da belirleyebilirsiniz:
>>> print("%10.5d" %23)
00023
Burada ise 23 saysnn toplam 10 bolukluk bir yer kaplamasn ve bu 10 adet bolua 23
says yerletirildikten sonra arta kalan ksmn 0 saylar ile doldurulmasn istedik.
Bu arada, son rnekte yaptmz eyi, daha nce rendiimiz zfill() metoduyla da
yapabileceimizi biliyorsunuz:
>>> "23".zfill(10)
'0000000023'
Yukardaki kullanmlar ilk bakta gznze kark grnm olabilir. Ama eer yeterince
pratik yaparsanz, aslnda bu biimlerin hi de o kadar karmak olmadn anlarsnz.
sterseniz bu biimlerle neler yapabileceimizi yle bir ksaca tarif edelim:
d har, % iaretiyle birlikte kullanldnda saylar temsil eder. Bu iki karakterin en temel
kullanm yledir:
>>> "%d" %10
'10'
d har ile % iareti arasna bir pozitif veya negatif say getirerek, temsil edilecek saynn
toplam ka boluktan oluan bir alan iine yerletirileceini belirleyebiliyoruz:
>>> "%5d" %10
'
10'
383
Burada 10 saysn toplam 5 bolukluk bir alan iine yerletirdik. Grdnz gibi, bir pozitif
say kullandmzda, saymz kendisine ayrlan alan iinde saa yaslanyor. Eer bu sayy sola
yaslamak istersek negatif saylardan yararlanabiliriz:
>>> "%-5d" %10
'10
'
Eer saa yasladmz bir saynn sol tarafn sfrla doldurmak istersek, hizalama miktarn
belirtmek iin kullandmz saynn soluna bir sfr ekleyebiliriz:
>>> "%05d" %10
'00010'
Eer nokta iaretinden nce bir say belirtirseniz, karakter dizisi o belirttiiniz say kadar saa
yaslanacaktr. Yani:
>>> "%10.5d" %10
'
00010'
'
Her iki ekilde de, karakter dizisini toplam 10 boluktan oluan bir alan iine yerletirmi
olduk. Bu toplam alann 5 bolukluk ksm saynn kendisi ve saynn soluna gelecek 0 lar
arasnda paylatrld.
Grdnz gibi, biimlendirme mantnn aslnda o kadar da korkulacak bir yan yok. Kendi
kendinize yukardakilere benzer rnekler yaparak bu yapy daha iyi bir ekilde anlamaya
alabilirsiniz.
i
Bu harf de integer, yani tam say kelimesinin ksaltmasdr. Kullanm ve ilev olarak, d
harnden hi bir fark yoktur.
o
Bu harf octal (sekizli) kelimesinin ksaltmasdr. Adndan da anlalaca gibi, sekizli dzendeki
saylar temsil eder. Dolaysyla bu har kullanarak onlu dzendeki bir sayy sekizli dzendeki
karlna dntrebilirsiniz. rnein:
>>> print("%i saysnn sekizli dzendeki karl %o saysdr." %(10, 10))
10 saysnn sekizli dzendeki karl 12 saysdr.
384
x
Bu harf hexadecimal, yani onaltl dzendeki saylar temsil eder. Dolaysyla bu har
kullanarak onlu dzendeki bir sayy onaltl dzendeki karlna evirebilirsiniz:
>>> print("%i saysnn onaltl dzendeki karl %x saysdr." %(20, 20))
20 saysnn onaltl dzendeki karl 14 saysdr.
X
Bu da tpk x harnde olduu gibi, onaltl dzendeki saylar temsil eder. Ancak bunun fark,
hare gsterilen onaltl saylar byk hare temsil etmesidir:
>>> print("%i saysnn onaltl dzendeki karl %X saysdr." %(10, 10))
10 saysnn onaltl dzendeki karl A saysdr.
f
Pythonda karakter dizilerini biimlendirirken s harnden sonra en ok kullanlan harf f
hardir. Bu harf ngilizcedeki oat, yani kayan noktal say kelimesinin ksaltmasdr.
Adndan da anlalaca gibi, karakter dizileri iindeki kayan noktal saylar temsil etmek iin
kullanlr.
>>> print("Dolar %f TL olmu..." %1.4710)
Dolar 1.471000 TL olmu...
385
Grdnz gibi, gerekten de 10 tam says %f yaps ile kayan noktal sayya
dntrldnde noktadan sonra 6 adet sfra sahip oluyor.
Baka bir rnek daha verelim:
>>> print("%f"%23.6)
23.600000
%f yapsnda, % ile f arasna .2 gibi bir ifade yerletirerek noktadan sonra 2 hane olmasn
saladk.
Not:
Daha nce gsterdiimiz ileri dzey biimlendirme tekniklerini %f ile de
kullanabilirsiniz.
c
Bu harf de Pythondaki nemli karakter dizisi biimlendiricilerinden biridir. Bu harf tek bir
karakteri temsil eder:
>>> print("%c" %"a")
a
Ama:
>>> print("%c" %"istihza")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: %c requires int or char
Grdnz gibi, c har sadece tek bir karakteri kabul ediyor. Karakter says birden fazla
olduunda bu komut hata veriyor.
c harnin bir baka zellii de ASCII tablosunda saylara karlk gelen karakterleri de
gsterebilmesidir:
>>> print("%c" %65)
A
ASCII tablosunda 65 says A harne karlk geldii iin yukardaki komutun kts A harni
gsteriyor. Eer isterseniz c harni kullanarak btn ASCII tablosunu ekrana dkebilirsiniz:
386
Burada, grdnz gibi, karakter dizisi metotlarn bir tablo grnm iinde ekrana
yazdrdk. u satrlar yardmyla tablodaki stun saysn 3 olarak belirledik:
if sra % 3 == 0:
print("\n", end="")
Burada modls ilecini nasl kullandmza ok dikkat edin. sra deikeninin deerini 3 e
bldmzde kalan deerin 0 olduu her sayda satr bana geiyoruz. Bylece her 3.
stunda bir satr aa geilmi oluyor.
Bununla ilgili bir rnek daha verelim:
for i in range(20):
print("%5d%5o%5x" %(i, i, i))
Burada 0 dan 20 ye kadar olan saylarn onlu, sekizli ve onaltl dzendeki karlklarn bir
tablo grnm iinde ekrana kt verdik. Bu arada, eer isterseniz yukardaki kodlar yle
de yazabileceinizi biliyorsunuz:
for i in range(20):
print("%(deger)5d%(deger)5o%(deger)5x" %({"deger": i}))
Burada da, tablomuzu biimlendirmek iin szlk adn verdiimiz yapdan yararlandk.
387
=
=
=
=
Grdnz gibi, {} iaretleri karakter dizisi iinde bir yer tutma grevi gryor. Tutulan bu
yerlere nelerin geleceini format() metodunun parametreleri vastasyla belirliyoruz.
Elbette eer isterseniz yukardaki rnei u ekilde de yazabilirsiniz:
kalk
var
isim_soyisim
bilet_says
=
=
=
=
Ancak yaygn olarak kullanlan yntem, karakter dizisini herhangi bir deikene atamadan,
dorudan format() metoduna balamaktr. Elbette hangi yntem kolaynza geliyorsa onu
388
tercih etmekte zgrsnz. Ama zellikle biimlendirilecek karakter dizisinin ok uzun olduu
durumlarda, yukardaki gibi, karakter dizisini nce bir deikene atayp, sonra da bu deiken
zerine format() metodunu uygulamak daha mantkl olabilir.
Verdiimiz bu rnei, her zaman olduu gibi, format() metoduna bavurmadan yazmak da
mmkndr:
kalk
var
isim_soyisim
bilet_says
=
=
=
=
Tpk daha nce verdiimiz rnekte olduu gibi, burada da format() metodunu kullanmak
karakter dizilerini birletirme yntemine gre daha mantkl ve kolay grnyor. Ayrca
bir karakter dizisi karmaklatka bu karakter dizisini sadece karakter dizisi birletirme
yntemleriyle biimlendirmeye almak bir sre sonra tam bir eziyet halini alabilir. O
yzden, Ben format() metodunu renmesem de olur, diye dnmeyin sakn. Mesela yle
bir program format() metodu kullanmadan yazmaya almak hi akl kr deildir:
kodlama
site_ad
dosya
ierik
<html>
=
=
=
=
"utf-8"
"Python Programlama Dili"
open("[Link]", "w", encoding=kodlama)
"""
<head>
<meta http-equiv="Content-Type" content="text/html; charset={}" />
<title>{}</title>
</head>
<body>
<h1>[Link] web sitesine ho geldiniz!</h1>
<p><b>{}</b> iin bir Trke belgelendirme projesi...</p>
</body>
</html>
"""
print([Link](kodlama, site_ad, site_ad), file=dosya)
[Link]()
389
Kme parantezleri iinde say kullanabilme imkan sayesinde deerlerin srasn istediiniz
gibi dzenleyebilirsiniz:
>>> "{1} {0}".format("Frat", "zgl")
'zgl Frat'
Hatta bu zellik sayesinde deerleri bir kez yazp, birden fazla sayda tekrar edebilirsiniz:
>>> "{0} {1} ({1} {0})".format("Frat", "zgl")
'Frat zgl (zgl Frat)'
Dolaysyla, {} iaretleri iinde elerin srasn da belirterek, biraz nce verdiimiz HTML
sayfas rneini u ekilde yazabilirsiniz:
kodlama
site_ad
dosya
ierik
<html>
=
=
=
=
"utf-8"
"Python Programlama Dili"
open("[Link]", "w", encoding=kodlama)
"""
<head>
<meta http-equiv="Content-Type" content="text/html; charset={0}" />
<title>{1}</title>
</head>
<body>
<h1>[Link] web sitesine ho geldiniz!</h1>
<p><b>{1}</b> iin bir Trke belgelendirme projesi...</p>
</body>
</html>
"""
print([Link](kodlama, site_ad), file=dosya)
[Link]()
Grdnz gibi, elerin sra numarasn belirtmemiz sayesinde, karakter dizisi iinde iki kez
ihtiya duyduumuz site_ad adl deikeni format() metodu iinde iki kez yazmak zorunda
kalmadk.
Yukardaki rnekler bize, format() metodunun parametrelerine sra numarasna gre
eriebileceimizi gsteriyor. Biz ayn zamanda bu metodun parametrelerine isme gre de
eriebiliriz. ok basit bir rnek:
390
print("{dil} dersleri".format(dil="python"))
format() metodunun yetenekleri yukarda gsterdiimiz eylerle snrl deildir. Tpk eski
biimlendirme ynteminde olduu gibi, {} iaretleri arasnda baz saylar kullanarak, karakter
dizileri zerinde hizalama ilemleri de yapabiliriz.
Dikkatlice bakn:
>>> print("{:>15}".format("istihza"))
istihza
Bu gsterim gznze olduka yabanc ve kark gelmi olabilir. Ama aslnda hi de yle
anlalmaz bir yan yoktur bu kodlarn. Grdnz gibi, burada ncelikle : adl bir iaretten
yararlanyoruz. Bu iaretin ardndan > adl baka bir iaret gryoruz. Son olarak da 15
saysn kullanyoruz.
: iareti, bir biimlendirme ilemi yapacamz gsteriyor. > iareti ise bu biimlendirmenin
bir hizalama ilemini olacan haber veriyor. En sondaki 15 says ise bu hizalama ileminin
15 karakterlik bir alan ile ilgili olduunu sylyor. Bu ekilde karakter dizisini 15 karakterlik
bir alan iine yerletirip karakter dizisini saa yasladk. Yukardaki kty daha iyi anlayabilmek
iin kodlar yle de yazabilirsiniz:
>>> print("|{:>15}|".format("istihza"))
|
istihza|
Grdnz gibi, karakter dizimiz, kendisine ayrlan 15 karakterlik alan iinde saa yaslanm
vaziyette duruyor.
Eer ayn karakter dizisini sola yaslamak isterseniz yle bir ey yazabilirsiniz:
>>> print("|{:<15}|".format("istihza"))
|istihza
391
Yukardaki yntemi kullanarak, karakter dizilerini sola veya saa yaslamann yansra,
kendilerine ayrlan alan iinde ortalayabilirsiniz de:
>>> print("|{:^15}|".format("istihza"))
|
istihza
Grdnz gibi, python3 ile gelen format() metodunu hizalama ilemleri iin kullanrken
farkl iaretten yararlanyoruz:
>
<
^
saa yaslama
sola yaslama
ortalama
Yukardaki iaretler, yaptklar ii artrdklar iin, bunlar aklda tutmak ok zor olmasa
gerek. Mesela rnek olmas asndan, eski biimlendirme ynteminin son ksmnda
verdiimiz u rnei:
for sra, karakter in enumerate(dir(str)):
if sra % 3 == 0:
print("\n", end="")
print("%-20s" %karakter, end="")
Bu rnei inceleyerek, eski ile yeni yntem arasnda nelerin deitiini, neyin neye karlk
geldiini grebilirsiniz.
392
Yalnz, s har karakter dizilerini temsil ettii iin, {} iaretleri arasnda bu har
kullandmzda, format() metodunun alabilecei parametreyi karakter dizisiyle
snrlandrm oluruz. Dolaysyla bu har kullandktan sonra format() metodu iinde
sadece karakter dizilerini kullanabiliriz. Eer say kullanrsak Python bize bir hata mesaj
gsterecektir:
>>> print("{:s}".format(12))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 's' for object of type 'int'
Bu yzden, eer amacnz format() metoduna parametre olarak karakter dizisi vermekse, {}
iaretleri iinde herhangi bir harf kullanmamak daha akllca olabilir:
print("{} ve {} iyi bir ikilidir!".format("Python", "Django"))
c
Bu harf 0 ile 256 aras saylarn ASCII tablosundaki karlklarn temsil eder:
>>> print("{:c}".format(65))
A
d
Bu harf saylar temsil eder:
>>> print("{:d}".format(65))
65
Eer say dnda bir deer kullanrsanz Python size bir hata mesaj gsterir:
>>> print("{:d}".format("65"))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object of type 'str'
o
Bu harf onlu dzendeki saylar sekizli dzendeki karlklarna evirir:
>>> print("{:o}".format(65))
101
393
x
Bu harf onlu dzendeki saylar onaltl dzendeki karlklarna evirir:
>>> print("{:x}".format(65))
41
X
Tpk x harnde olduu gibi, bu harf de onlu dzendeki saylar onaltl dzendeki
karlklarna evirir:
>>> "{:X}".format(65)
'41'
Peki x ile X har arasnda ne fark var? Fark udur: x ; onaltl dzende hare gsterilen saylar
kk harf eklinde temsil eder. X iare bu saylar byk harf eklinde temsil eder. Bu ikisi
arasndaki fark daha net grmek iin yle bir kod yazabilirsiniz:
>>> for i in range(20):
...
print("{:x}{:10X}".format(i, i))
...
0
0
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
a
A
b
B
c
C
d
D
e
E
f
F
10
10
11
11
12
12
13
13
Grdnz gibi gerekten de x har onaltl dzende harerle gsterilen saylar kk harf
olarak; X har ise byk harf olarak temsil ediyor.
b
Bu iaret, onlu dzendeki saylar ikili dzendeki karlklarna evirir:
>>> "{:b}".format(2)
'10'
394
f
Bu iaret, eski biimlendirme yntemini anlatrken gsterdiimiz f iaretiyle benzer bir ileve
sahiptir:
print("{:.2f}".format(50))
,
: iaretini , iareti (basamak ayrac) ile birlikte kullanarak, saylar basamaklarna
ayrabilirsiniz:
>>> "{:,}".format(1234567890)
'1,234,567,890'
Bylece Pythonda karakter dizisi biimlendirmenin hem eski hem de yeni yntemini, u ana
kadarki Python bilgimiz elverdii lde ayrntl bir ekilde incelemi olduk. Buradaki bilgileri
kullanarak bol bol rnek yapmak bu konuyu daha iyi anlamanza yardmc olacaktr.
395
BLM 25
Listeler ve Demetler
Bu blme gelene kadar yalnzca iki farkl veri tipi grmtk. Bunlardan biri karakter dizileri,
teki ise saylard. Ancak tabii ki Pythondaki veri tipleri yalnzca bu ikisiyle snrl deildir.
Pythonda karakter dizileri ve saylarn dnda, baka amalara hizmet eden, baka veri tipleri
de vardr. te biz bu blmde iki farkl veri tipi daha reneceiz. Bu blmde ele alacamz
veri tiplerinin ad liste (list ) ve demet (tuple ).
Bu blmde birer veri tipi olarak listeler ve demetlerden sz etmenin yansra liste
ve demetlerin metotlarndan da bahsedeceiz. Listelerle demetleri rendikten sonra
Pythondaki hareket imkannzn bir hayli genilediine tank olacaksnz.
Python programlama diline yeni balayan biri, karakter dizilerini rendikten sonra bu dilde
her eyi karakter dizileri yardmyla halledebileceini zannedebilir. O yzden yeni bir veri
tipi ile karlatnda (rnein listeler veya demetler), bu yeni veri tipi ona anlamsz ve
gereksizmi gibi grnebilir. Aslnda daha nce de sylediimiz gibi, bir programlama dilini
yeni renenlerin genel sorunudur bu. renci, bir programlama dilini oluturan minik
paralar renirken, rencinin zihni bu paralarn ne iine yarayaca konusunda pheyle
dolar. Sanki gereksiz eylerle vakit kaybediyormu gibi hissedebilir. En nemli ve en byk
programlarn, bu minik paralarn sistematik bir ekilde birletirilmesiyle ortaya kacak
olmas rencinin kafasna yatmayabilir. Halbuki en karmak programlarn bile kaynak
kodlarn incelediinizde grecekleriniz karakter dizileri, listeler, demetler, saylar ve buna
benzer baka veri tiplerinden ibarettir. Nasl en lezzetli yemekler birka basit malzemenin
bir araya gelmesi ile ortaya kyorsa, en abidevi programlar da ilk bakta birbiriyle ilgisiz
grnen ok basit paralarn incelikli bir ekilde birletirilmesinden oluur.
O halde bu noktada, Python programlama diline yeni balayan hemen herkesin sorduu o
soruyu soralm kendimize: Neden farkl veri tipleri var? Bu veri tiplerinin hepsine gerekten
ihtiyacm olacak m?
Bu soruyu baka bir soruyla cevaplamaya alalm: Acaba neden farkl giysi tipleri var?
Neden kot pantolon, kuma pantolon, tirt, gmlek ve buna benzer ayrmlara ihtiya
duyuyoruz? Bu sorunun cevab ok basit: nk farkl durumlara farkl giysi trleri
uygundur!
rnein ev tayacaksanz, herhalde kuma pantolon ve gmlek giymezsiniz zerinize. Buna
benzer bir ekilde i grmesine giderken de kot pantolon ve tirt doru bir tercih
olmayabilir. te buna benzer sebeplerden, programlama dillerinde de belli durumlarda
belli veri tiplerini kullanmanz gerekir. rnein bir durumda karakter dizilerini kullanmak
uygunken, baka bir durumda listeleri veya demetleri kullanmak daha mantkl olabilir. Zira
her veri tipinin kendine has gl ve zayf yanlar vardr. Veri tiplerini ve bunlarn ayrntlarn
rendike, hangi veri tipinin hangi sorun iin daha kullanl olduunu kestirebilecek duruma
396
25.1 Listeler
Giri blmnde de deindiimiz gibi, listeler Pythondaki veri tiplerinden biridir.
karakter dizileri ve saylar gibi...
Tpk
Yani herhangi bir eyi karakter dizisi olarak tanmlayabilmek iin yapmamz gereken tek ey
o eyi trnak iine almakt. Herhangi bir eyi (tek, ift veya ) trnak iine aldmzda
karakter dizimizi tanmlam oluyoruz. Liste tanmlamak iin de buna benzer bir ey
yapyoruz. Dikkatlice bakn:
>>> liste = ["e1", "e2", "e3"]
Grdnz gibi, liste tanmlamak da son derece kolay. Bir liste elde etmek iin, eleri
birbirinden virglle ayrp, bunlarn hepsini keli parantezler iine alyoruz.
Karakter dizilerini anlatrken, herhangi bir nesnenin karakter dizisi olup olmadndan emin
olmak iin type() fonksiyonundan yararlanabileceimizi sylemitik. Eer bir nesne type()
fonksiyonuna <class str> cevab veriyorsa o nesne bir karakter dizisidir. Listeler iin de buna
benzer bir sorgulama yapabiliriz:
>>> liste = ["e1", "e2", "e3"]
>>> type(liste)
<class 'list'>
Bu ktdan anlyoruz ki, liste veri tipi type() fonksiyonuna <class list> cevab veriyor.
Dolaysyla, eer bir nesne type() fonksiyonuna <class list> cevab veriyorsa o nesnenin
bir liste olduunu rahatlkla syleyebiliriz.
Yukarda tanmladmz liste adl listeye baktmzda dikkatimizi bir ey ekiyor olmal. Bu
listeye yle bir baktmzda, aslnda bu listenin, iinde adet karakter dizisi barndrdn
gryoruz. Gerekten de listeler, bir veya daha fazla veri tipini iinde barndran kapsayc bir
veri tipidir. Mesela u listeye bir bakalm:
>>> liste = ["Ahmet", "Mehmet", 23, 65, 3.2]
Grdnz gibi, liste iinde hem karakter dizileri (Ahmet, Mehmet ), hem de saylar (23,
65, 3.2 ) var.
Dahas, listelerin iinde baka listeler de bulunabilir:
25.1. Listeler
397
>>> liste = ["Ali", "Veli", ["Aye", "Nazan", "Zeynep"], 34, 65, 33, 5.6]
Bu kodlar bize unu gsteriyor: farkl eleri bir araya getirip bunlar keli parantezler iine
alrsak liste adl veri tipini oluturmu oluyoruz. Bu listenin eleri farkl veri tiplerine ait
olabilir. Yukardaki kodlarn da gsterdii gibi, liste iinde yer alan Ali ve Veli eleri birer
karakter dizisi, [Aye, Nazan, Zeynep] adl e bir liste, 34, 65 ve 33 eleri birer tam
say, 5.6 esi ise bir kayan noktal saydr. te farkl veri tiplerine ait bu elerin hepsi bir
araya gelerek liste denen veri tipini oluturuyor. Yukardaki rnekten de grdnz gibi, bir
listenin iinde baka bir liste de yer alabiliyor. rnein burada listemizin elerinden biri,
[Aye, Nazan, Zeynep] adl baka bir listedir.
Hatrlarsanz karakter dizilerinin belirleyici zellii trnak iaretleri idi. Yukardaki rneklerden
de grdnz gibi listelerin belirleyici zellii de keli parantezlerdir. Mesela:
>>> karakter = ""
398
Artk bu kt size ok daha anlaml geliyor olmal. Grdnz gibi ktmz keli parantezler
arasnda yer alyor. Yani aslnda yukardaki kt bir liste. Dilerseniz bunu nasl teyit
edebileceinizi biliyorsunuz:
>>> komut = dir(str)
>>> type(komut)
<class 'list'>
Grdnz gibi, tpk input() fonksiyonundan gelen verinin bir karakter dizisi olmas gibi,
dir() fonksiyonundan gelen veri tipi de bir listedir.
dir() fonksiyonu dnda, baka bir eyin daha bize liste verdiini biliyoruz. Bu ey, karakter
dizilerinin split() adl metodudur:
>>> kardiz = "stanbul Bykehir Belediyesi"
>>> [Link]()
['stanbul', 'Bykehir', 'Belediyesi']
Gryorsunuz, split() metodunun kts da keli parantezler iinde yer alyor. Demek ki
bu kt da bir listedir.
Peki bir fonksiyonun bize karakter dizisi mi, liste mi yoksa baka bir veri tipi mi verdiini
bilmenin ne faydas var?
Her zaman sylediimiz gibi, Pythonda o anda elinizde olan verinin tipini bilmeniz son derece
nemlidir. Aksi halde o veriyi nasl evirip evireceinizi, o veriyle neler yapabileceinizi
bilemezsiniz. Mesela stanbul Bykehir Belediyesi ifadesini ele alalm. Bu ifadeyle ilgili
size yle bir soru sorduumu dnn: Acaba bu ifadenin ilk harni nasl alrz?
Eer bu ifade size input() fonksiyonundan gelmise, yani bir karakter dizisiyse
uygulayacanz yntem farkl, split() metoduyla gelmise, yani liste ise uygulayacanz
yntem farkl olacaktr.
Eer bu ifade bir karakter dizisi ise ilk har u ekilde alabilirsiniz:
>>> kardiz = "stanbul Bykehir Belediyesi"
>>> kardiz[0]
''
Ama eer bu ifade bir liste ise yukardaki yntem size farkl bir sonu verir:
25.1. Listeler
399
nk stanbul Bykehir Belediyesi adl karakter dizisinin ilk esi karakteridir, ama
[stanbul, Bykehir, Belediyesi] adl listenin ilk esi karakteri deil, stanbul
kelimesidir.
Grdnz gibi, bir nesnenin hangi veri tipine ait olduunu bilmek o nesneyle neleri nasl
yapabileceimizi dorudan etkiliyor. O yzden programlama almalarnz esnasnda veri
tiplerine kar her zaman uyank olmalsnz.
Not:
Pythonda bir nesnenin hangi veri tipine ait olduunu bilmenin neden
bu kadar nemli olduunu gerek bir rnek zerinde grmek isterseniz
[Link]/forum/[Link]?f=43&t=62 adresindeki tartmay inceleyebilirsiniz.
Her ne kadar karakter dizileri ve listeler iki farkl veri tipi olsa ve bu iki veri tipinin birbirinden
ok farkl ynleri ve yetenekleri olsa da, bu iki veri tipi arasnda nemli benzerlikler de
vardr. rnein karakter dizilerini ilerken rendiimiz pek ok fonksiyonu listelerle birlikte
de kullanabilirsiniz. Mesela karakter dizilerini incelerken rendiimiz len() fonksiyonu
listelerin boyutunu hesaplamada da kullanlabilir:
>>> diller = ["ngilizce", "Franszca", "Trke", "talyanca", "spanyolca"]
>>> len(diller)
5
Karakter dizileri karakterlerden oluan bir veri tipi olduu iin len() fonksiyonu karakter dizisi
iindeki karakterlerin saysn veriyor. Listeler ise baka veri tiplerini bir araya toplayan bir veri
tipi olduu iin len() fonksiyonu liste iindeki veri tiplerinin saysn sylyor.
len() fonksiyonu dnda, range() fonksiyonuyla listeleri de birlikte kullanabilirsiniz. Mesela
herhangi bir kaynaktan size unlar gibi iki eli listeler geliyor olabilir:
[0, 10]
[6, 60]
[12, 54]
[67, 99]
Bu iki eli listeleri tek bir liste iinde topladmz dnrsek yle bir kod yazabiliriz:
saylar = [[0, 10], [6, 60], [12, 54], [67, 99]]
for i in saylar:
print(*range(*i))
Eer ilk bakta bu kod gznze anlalmaz grndyse bu kodu paralara ayrarak
inceleyebilirsiniz.
Burada ncelikle bir for dngs oluturduk. Bu sayede saylar adl listedeki elerin
zerinden tek tek geebileceiz. Eer dng iinde sadece eleri ekrana yazdryor olsaydk
yle bir kodumuz olacakt:
for i in saylar:
print(i)
400
Yukardaki aklamalarda grdnz gibi, i deikeninin kts ikier eli bir liste oluyor.
te burada yaptmz ey, bu ikier eli listelerin ilk esini (i[0]) range() fonksiyonunun
ilk parametresi, ikinci esini (i[1]) ise range() fonksiyonunun ikinci parametresi olarak
atamaktan ibaret. Ancak ilk derslerimizden hatrlayacanz gibi, bunu yapmann daha ksa
bir yolu var. Bildiiniz gibi, elerden oluan dizileri ayrtrmak iin yldz iaretinden
yararlanabiliyoruz. Dolaysyla yukardaki kodlar yle yazmak daha pratik olabilir:
saylar = [[0, 10], [6, 60], [12, 54], [67, 99]]
for i in saylar:
print(range(*i))
Grdnz gibi, i deikeninin soluna bir yldz ekleyerek bu deiken iindeki deerleri
ayrtrdk ve yle bir kt elde ettik:
range(0, 10)
range(6, 60)
range(12, 54)
range(67, 99)
Hatrlarsanz, range(0, 10) gibi bir kod yazdmzda Python bize 0 ile 10 arasndaki saylar
dorudan gstermiyordu. Aralktaki saylar grmek iin range() fonksiyonunun ktsn bir
dng iine almalyz:
for i in range(0, 10):
print(i)
range(0, 10) ktsn grmek iin dng kurmak yerine yine yldz iaretinden
yararlanabiliyoruz. rnein:
>>> print(*range(0, 10))
0 1 2 3 4 5 6 7 8 9
401
Grdnz gibi, yldz iaretini hem i deikenine, hem de range() fonksiyonuna ayr ayr
uygulayarak istediimiz sonucu elde ettik.
Bu arada, yukardaki rnek bize listeler hakknda nemli bir bilgi de verdi. Karakter dizilerinin
elerine erimek iin nasl kardiz[e_sras] gibi bir formlden yararlanyorsak,
listelerin elerine erimek iin de ayn ekilde liste[e_sras] gibi bir formlden
yararlanabiliyoruz.
Listelerin elerine nasl ulaacamzn ayrntlarn biraz sonra greceiz. Ama biz imdi
listelere ilikin nemli bir fonksiyonu inceleyerek yolumuza devam edelim.
Ancak split() metodunun bir karakter dizisini blp bize bir liste verebilmesi iin karakter
dizisinin belli bir lte gre blnebilir durumda olmas gerekiyor. Mesela yukardaki isimler
adl karakter dizisi belli bir lte gre blnebilir durumdadr. Neden? nk karakter dizisi
iindeki her para arasnda bir boluk karakteri var. Dolaysyla split() metodu bu karakter
dizisini boluklardan blebiliyor. Ayn ey u karakter dizisi iin de geerlidir:
>>> isimler = "elma, armut, ilek"
Bu karakter dizisini oluturan her bir para arasnda bir adet virgl ve bir adet boluk
karakteri var. Dolaysyla biz bu karakter dizisini split() metodunu kullanarak virgl +
boluk karakteri ltne gre blebiliriz:
>>> [Link](", ")
['elma', 'armut', 'ilek']
Ancak blmn banda tanmladmz alfabe adl karakter dizisi biraz farkldr:
>>> alfabe = "abcdefghijklmnoprstuvyz"
402
Grdnz gibi, bu karakter dizisi tek bir paradan oluuyor. Dolaysyla bu karakter dizisini
elerine blmemizi salayacak bir lt yok. Yani bu karakter dizisini u ekilde blemeyiz:
>>> [Link]()
['abcdefghijklmnoprstuvyz']
Grdnz gibi, biz burada alfabe karakter dizisini i harnden blebildik. Ama istediimiz
ey bu deil. Biz aslnda yle bir kt elde etmek istiyoruz:
['a', 'b', 'c', '', 'd', 'e', 'f', 'g', '', 'h', '', 'i', 'j',
'k', 'l', 'm', 'n', 'o', '', 'p', 'r', 's', '', 't', 'u', '',
'v', 'y', 'z']
Yani bizim amacmz, alfabe karakter dizisi iindeki her bir eyi birbirinden ayrmak. te
Trk alfabesindeki harerden oluan bu karakter dizisini, list() adl bir fonksiyondan
yararlanarak istediimiz ekilde blebiliriz:
>>> harf_listesi = list(alfabe)
>>> print(harf_listesi)
['a', 'b', 'c', '', 'd', 'e', 'f', 'g', '', 'h', '', 'i', 'j',
'k', 'l', 'm', 'n', 'o', '', 'p', 'r', 's', '', 't', 'u', '',
'v', 'y', 'z']
Bylece list() fonksiyonu yardmyla bu karakter dizisini tek hamlede listeye evirmi olduk.
Peki bir karakter dizisini neden listeye evirme ihtiyac duyarz? u anda listelerle ilgili
pek ok eyi henz bilmediimiz iin ilk bakta bu evirme ilemi gznze gereksizmi
gibi grnebilir, ama ilerleyen zamanda sizin de greceiniz gibi, baz durumlarda listeleri
maniple etmek karakter dizilerini maniple etmeye kyasla ok daha kolaydr. O yzden
kimi zaman karakter dizilerini listeye evirmek durumunda kalabilirsiniz.
list() fonksiyonunun yapt ii, daha nce rendiimiz str(), int() ve float()
fonksiyonlarnn yapt ile kyaslayabilirsiniz. list() fonksiyonu da tpk str(), int() ve
float() fonksiyonlar gibi bir dntrme fonksiyonudur. rnein int() fonksiyonunu
kullanarak say deerli karakter dizilerini sayya dntrebiliyoruz:
>>> k = "123"
>>> int(k)
123
Bu dntrme ilemi sayesinde saylar zerinde aritmetik ilem yapma imkanmz olabiliyor.
te list() fonksiyonu da buna benzer bir amaca hizmet eder.
Mesela input()
fonksiyonundan gelen bir karakter dizisi ile toplama karma yapabilmek iin nasl bu
karakter dizisini nce sayya dntrmemiz gerekiyorsa, baz durumlarda bu karakter
dizisini (veya baka veri tiplerini) listeye evirmemiz de gerekebilir. Byle bir durumda list()
fonksiyonunu kullanarak farkl veri tiplerini rahatlkla listeye evirebiliriz.
Yukardaki ilevlerinin dnda, list() fonksiyonu bo bir liste oluturmak iin de
kullanlabilir:
25.1. Listeler
403
>>> li = list()
>>> print(li)
[]
Yukardaki kodlardan grdnz gibi, bo bir liste oluturmak iin liste = [] koduna
alternatif olarak list() fonksiyonundan da yararlanabilirsiniz.
list() fonksiyonunun nemli bir grevi de range() fonksiyonunun, say araln ekrana
basmasn salamaktr. Bildiiniz gibi, range() fonksiyonu tek bana bir say araln ekrana
dkmez. Bu fonksiyon bize yalnzca yle bir kt verir:
>>> range(10)
range(0, 10)
Bu say araln ekrana dkmek iin range() fonksiyonu zerinde bir for dngs kurmamz
gerekir:
>>> for i in range(10):
...
print(i)
...
0
1
2
3
4
5
6
7
8
9
Grdnz gibi, yukardaki yntem de aralktaki saylar ekrana dkyor. Yalnz dikkat
ederseniz bu yntemin ktlar aslnda grn olarak birbirlerinden ince farklarla
404
ayrlyor. Yazdnz programda nasl bir ktya ihtiyacnz olduuna bal olarak yukardaki
yntemlerden herhangi birini tercih edebilirsiniz.
Bylece Pythonda listelerin ne olduunu ve bu veri tipinin nasl oluturulacan renmi
olduk. O halde bir adm daha atarak listelerin baka zelliklerine deinelim.
Yalnz yntem ayn olsa da yukardaki iki kt arasnda baz farklar olduunu da gzden
karmayn. Bir karakter dizisinin 0. esini aldmzda o karakter dizisinin ilk karakterini
alm oluyoruz. Bir listenin 0. esini aldmzda ise o listenin ilk esini alm oluyoruz.
Sayma yntemi olarak ise karakter dizileri ve listelerde ayn mantk geerli. Hem listelerde
hem de karakter dizilerinde Python saymaya 0 dan balyor. Yani karakter dizilerinde olduu
gibi, listelerde de ilk enin sras 0.
Eer bu listenin elerinin hepsine tek tek ulamak isterseniz for dngsnden
yararlanabilirsiniz:
meyveler = ["elma", "armut", "ilek", "kiraz"]
for meyve in meyveler:
print(meyve)
Dediimiz gibi, liste elerine ulamak iin kullandmz yntem, karakter dizilerinin
elerine ulamak iin kullandmz yntemle ayn. Aslnda karakter dizileri ile listeler
arasndaki benzerlik bununla snrl deildir. Benzerlikleri birka rnek zerinde gsterelim:
25.1. Listeler
405
Karakter dizilerinde olduu gibi, e srasn eksi deerli bir say yaptmzda liste eleri
sondan baa doru okunuyor. Dolaysyla meyveler[-1] komutu bize meyveler adl listenin
son esini veriyor.
>>> meyveler[0:2]
['elma', 'armut']
Karakter dizileri konusunu ilerken rendiimiz dilimleme yntemi listeler iin de aynen
geerlidir. Orada rendiimiz dilimleme kurallarn listelere de uygulayabiliyoruz. rnein
liste elerini ters evirmek iin yle bir kod yazabiliyoruz:
>>> meyveler[::-1]
['kiraz', 'ilek', 'armut', 'elma']
Bu blmn banda da sylediimiz gibi, liste adl veri tipi, iinde baka bir liste de
barndrabilir. Buna yle bir rnek vermitik:
>>> liste = ["Ali", "Veli", ["Aye", "Nazan", "Zeynep"], 34, 65, 33, 5.6]
Grdnz gibi, bu liste iinde [Aye, Nazan, Zeynep] gibi bir liste daha var. Bu liste ana
listenin elerinden biridir ve bu da teki eler gibi tek elik bir yer kaplar. Yani:
>>> len(liste)
7
Bu ktdan anlyoruz ki, listemiz toplam 7 eden oluuyor. Listenin 2. srasnda yer alan
listenin kendisi eden olutuu halde bu e ana liste iinde sadece tek elik bir yer
kaplyor. Yani 2. sradaki listenin eleri tek tek saylmyor. Peki byle bir liste iindeki gml
listenin elerini elde etmek istersek ne yapacaz? Yani mesela ie gemi listenin tamamn
deil de, rnein sadece Aye esini almak istersek ne yapmamz gerekiyor? Dikkatlice
bakn:
>>> liste[2][0]
'Aye'
406
>>> liste[2][1]
'Nazan'
Grdnz gibi, i ie gemi listelerin elerini almak olduka basit. Yapmamz gereken
tek ey, gml listenin nce ana listedeki konumunu, ardndan da almak istediimiz enin
gml listedeki konumunu belirtmektir.
stersek gml listeyi ayr bir liste olarak da alabiliriz:
>>> yeni_liste = liste[2]
>>> yeni_liste
['Aye', 'Nazan', 'Zeynep']
Eer bir listenin elerine erimeye alrken, varolmayan bir sra says belirtirseniz Python
size bir hata mesaj gsterecektir:
>>> liste = range(10)
>>> print(len(liste))
10
Burada range() fonksiyonundan yararlanarak 10 eli bir liste tanmladk. Bu listenin son
esinin u formle gre bulunabileceini karakter dizileri konusundan hatrlyor olmalsnz:
>>> liste[len(liste)-1]
9
25.1. Listeler
407
Grdnz gibi, listemizde 10. e diye bir ey olmad iin Python bize IndexError tipinde
bir hata mesaj gsteriyor. nk bu listenin son esinin sras len(liste)-1, yani 9 dur.
Listeler ise deitirilebilen (mutable ) bir veri tipidir. Dolaysyla listeler zerinde dorudan
deiiklik yapabiliriz.
Bir liste zerinde deiiklik yapabilmek iin o listeyi yeniden
tanmlamamza gerek yok. u rnei dikkatlice inceleyin:
>>> renkler = ["krmz", "sar", "mavi", "yeil", "beyaz"]
>>> print(renkler)
['krmz', 'sar', 'mavi', 'yeil', 'beyaz']
>>> renkler[0] = "siyah"
>>> print(renkler)
['siyah', 'sar', 'mavi', 'yeil', 'beyaz']
Liste elerini nasl deitirdiimize ok dikkat edin. Yukardaki rnekte renkler adl listenin
0. esini deitirmek istiyoruz. Bunun iin yle bir forml kullandk:
renkler[e_sras] = yeni_e
rnek olmas asndan, ayn listenin 2. srasndaki mavi adl eyi mor yapalm bir de:
>>> renkler[2] = "mor"
>>> print(renkler)
['siyah', 'sar', 'mor', 'yeil', 'beyaz']
Grdnz gibi, listeler zerinde deiiklik yapmak son derece kolay. Srf bu zellik bile,
neden baz durumlarda listelerin karakter dizileri yerine tercih edilebileceini gsterecek
gtedir.
Liste elerini deitirmeye alrken, eer var olmayan bir sra numarasna atfta
bulunursanz Python size IndexError tipinde bir hata mesaj gsterecektir:
>>> renkler[10] = "pembe"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
Sra numaralarn kullanarak listeler zerinde daha ilgin ilemler de yapabilirsiniz. Mesela u
rnee bakn:
408
Burada liste adl listenin btn elerini bir rpda deitirdik. Peki bunu nasl yaptk?
Yukardaki rnei u ekilde yazarsak biraz daha aklayc olabilir:
>>> liste[0:3] = 5, 6, 7
Bu kodlarla yaptmz ey, listenin 0. ve 3. esi arasnda kalan btn elerin yerine 5, 6 ve
7 elerini yerletirmekten ibarettir.
Karakter dizilerinden hatrlayacanz gibi, eer sra numaras bir karakter dizisinin ilk esine
karlk geliyorsa o sra numarasn belirtmeyebiliriz. Ayn ekilde eer sra numaras bir
karakter dizisinin son esine karlk geliyorsa o sra numarasn da belirtmeyebiliriz. Bu
kural listeler iin de geerlidir. Dolaysyla yukardaki rnei yle de yazabilirdik:
>>> liste[:] = 5, 6, 7
Sra numaralarn kullanarak gerekten son derece enteresan ilemler yapabilirsiniz. Sra
numaralar ile neler yapabileceinizi grmek iin kendi kendinize ve hayal gcnz
zorlayarak baz denemeler yapmanz tavsiye ederim.
Bu rnek, bize listeler hakknda nemli bir bilgi veriyor. Pythonda + iareti kullanarak bir
listeye e ekleyecekseniz, eklediiniz enin de liste olmas gerekiyor. Mesela bir listeye
dorudan karakter dizilerini veya saylar ekleyemezsiniz:
>>> liste + 8
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list
>>> liste + "8"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
Listelere + iareti ile ekleyeceiniz elerin de bir liste olmas gerekiyor. Aksi halde Python
bize bir hata mesaj gsteriyor.
25.1. Listeler
409
Bu iki farkl listeyi tek bir liste haline getirmek iin yle bir kod yazabiliriz:
>>> programlama_dilleri = derlenen_diller + yorumlanan_diller
['C', 'C++', 'C#', 'Java', 'Python', 'Perl', 'Ruby']
adl
listelerin
elerini
Bu program kullancnn 10 adet say girmesine izin verip, program knda, girilen saylarn
ortalamasn verecektir.
Peki girilen saylarn ortalamas ile birlikte, hangi saylarn girildiini de gstermek isterseniz
nasl bir kod yazarsnz?
Eer byle bir eyi karakter dizileri ile yazmaya kalkrsanz epey eziyet ekersiniz. Ama yle
bir kod yardmyla istediiniz eyi basit bir ekilde elde edebilirsiniz:
saylar = 0
notlar = []
for i in range(10):
veri = int(input("{}. not: ".format(i+1)))
saylar += veri
notlar += [veri]
print("Girdiiniz notlar: ", *notlar)
print("Not ortalamanz: ", saylar/10)
Burada kullancdan gelen verileri her dngde tek tek notlar adl listeye gnderiyoruz.
Bylece programn sonunda, kullancdan gelen veriler bir liste halinde elimizde bulunmu
410
oluyor.
Bu arada, yukardaki kodlarda dikkatinizi bir ey ekmi olmal. Kullancdan gelen verileri
notlar adl listeye gnderirken yle bir kod yazdk:
notlar += [veri]
Buradaki [veri] ifadesine dikkat edin. Bu kod yardmyla kullancdan gelen veri adl
deikeni liste haline getiriyoruz. Bu yntem bizim iin yeni bir ey. Peki neden burada
list() fonksiyonundan yararlanmadk?
Bunu anlamak iin list() fonksiyonunun alma mantn anlamamz gerekiyor.
Elinizde yle bir karakter dizisi olduunu dnn:
>>> alfabe = "abcdefghijklmnoprstuvyz"
Diyelim ki siz bu karakter dizisindeki btn eleri tek tek bir listeye atmak istiyorsunuz. Bu
i iin list() fonksiyonunu kullanabileceimizi daha nce sylemitik:
>>> liste = list(alfabe)
Peki list() fonksiyonu bu karakter dizisinin elerini listeye atarken nasl bir yntem izliyor?
Aslnda list() fonksiyonunun yapt i una edeerdir:
liste = []
alfabe = "abcdefghijklmnoprstuvyz"
for harf in alfabe:
liste += harf
print(liste)
list() fonksiyonu da tam olarak byle alr. Yani bir karakter dizisi zerinde dng kurarak,
o karakter dizisinin her bir esini tek tek bir listeye atar.
for dnglerini ilerken, bu dngnn saylar zerinde almayacan sylemitik. nk
saylar, karakter dizilerinin aksine, zerinde dng kurulabilen bir veri tipi deildir. Bunu bir
rnek zerinde tekrar grelim:
>>> for i in 12345:
...
print(i)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Grdnz gibi, 12345 says zerinde dng kuramyoruz. Ayn hata mesajn list()
fonksiyonunda da grrsnz:
>>> list(12345)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Dediimiz gibi, tpk for dngsnde olduu gibi, list() fonksiyonu da ancak, zerinde
dng kurulabilen nesneler zerinde alabilir. Mesela:
25.1. Listeler
411
>>> list("12345")
['1', '2', '3', '4', '5']
Bu bilgilerin nda, yukarda yazdmz kodlarn u ekilde yazlmas halinde Pythonn bize
hata mesaj gstereceini syleyebiliriz:
notlar = []
for i in range(10):
veri = int(input("{}. not: ".format(i+1)))
notlar += list(veri)
print("Girdiiniz notlar: ", *notlar)
Kullancdan gelen veri deerini int() fonksiyonuyla sayya dntrdmz iin ve saylar
da zerinde dng kurulabilen bir veri tipi olmad iin list() fonksiyonuna parametre
olarak atanamaz.
Peki kullancdan gelen veri deerini sayya dntrmeden, karakter dizisi biiminde list()
fonksiyonuna parametre olarak verirsek ne olur? Bu durumda list() fonksiyonu alr, ama
istediimiz gibi bir sonu vermez. u kodlar dikkatlice inceleyin:
notlar = []
for i in range(10):
veri = input("{}. not: ".format(i+1))
notlar += list(veri)
print("Girdiiniz notlar: ", *notlar)
Bu kodlar altrdnzda, tek haneli saylar dzgn bir ekilde listeye eklenir, ancak ift ve
daha fazla haneli saylar ise listeye para para eklenir. rnein 234 saysn girdiinizde
listeye 2, 3 ve 4 saylar tek tek eklenir. nk, yukarda da dediim gibi, list() fonksiyonu,
aslnda karakter dizileri zerine bir for dngs kurar. Yani:
>>> for i in "234":
...
print(i)
2
3
4
Dolaysyla listeye 234 says bir btn olarak deil de, para para eklendii iin istediiniz
sonucu alamam olursunuz.
Peki bu sorunun stesinden nasl geleceiz? Aslnda bu sorunun zm ok basittir. Eer bir
verinin listeye para para deil de, bir btn olarak eklenmesini istiyorsanz [] iaretlerinden
yararlanabilirsiniz. Tpk u rnekte olduu gibi:
liste = []
while True:
say = input("Bir say girin: (kmak iin q) ")
if say == "q":
break
412
say = int(say)
if say not in liste:
liste += [say]
print(liste)
else:
print("Bu sayy daha nce girdiniz!")
Grdnz gibi, kullanc tarafndan ayn verinin birden fazla girilmesini nlemek iin de
listelerden yararlanabiliyoruz.
Yalnz burada unu syleyelim: Gerek programlarda listelere e eklemek veya listeleri
birletirmek gibi ilemler iin yukardaki gibi + ilecinden yararlanmayacaz. Yukarda
gsterdiimiz yntem de doru olmakla birlikte, bu i iin genellikle liste metotlarndan
yararlanlr. Bu metotlar birazdan greceiz.
Amacmz bu listeden bir tane daha oluturmak. lk olarak aklnza yle bir yntem gelmi
olabilir:
>>> li2 = li1
25.1. Listeler
413
>>> print(li1)
["elma", "armut", "erik"]
>>> print(li2)
["elma", "armut", "erik"]
Gelin imdi ilk listemiz olan li1 zerinde bir deiiklik yapalm. Mesela bu listenin elma olan
ilk esini karpuz olarak deitirelim:
>>> li1[0] = "karpuz"
>>> print(li1)
["karpuz", "armut", "erik"]
Grdnz gibi, li1 adl listenin ilk esini baaryla deitirdik. imdi u noktada, li2 adl
br listemizin durumunu kontrol edelim:
>>> print(li2)
["karpuz", "armut", "erik"]
O da ne! Biz biraz nce li1 zerinde deiiklik yapmtk, ama grne gre bu deiiklikten
li2 de etkilenmi. Muhtemelen beklediiniz ey bu deildi. Yani siz li2 listesinin ieriinin
ayn kalp, deiiklikten yalnzca li1 listesinin etkilenmesini istiyordunuz. Biraz sonra bu
isteinizi nasl yerine getirebileceinizi gstereceiz. Ama nce dilerseniz, bir liste zerindeki
deiiklikten teki listenin de neden etkilendiini anlamaya alalm.
Hatrlarsanz, listelerin deitirilebilir (mutable ) bir veri tipi olduunu sylemitik. Listeler
bu zellikleriyle karakter dizilerinden ayrlyor. Zira biraz nce li1 ve li2 zerinde yaptmz
ilemin bir benzerini karakter dizileri ile yaparsak farkl bir sonu alrz. Dikkatlice bakn:
>>> a = "elma"
Burada, deeri elma olan a adl bir karakter dizisi tanmladk. imdi bu karakter dizisini
kopyalayalm:
>>> b = a
>>> a
'elma'
>>> b
'elma'
Bylece ayn deere sahip iki farkl karakter dizimiz olmu oldu.
imdi a adl karakter dizisi zerinde deiiklik yapalm. Ama biz biliyoruz ki, bir karakter
dizisini deitirmenin tek yolu, o karakter dizisini yeniden tanmlamaktr:
>>> a = "E" + a[1:]
>>> a
'Elma'
414
Burada yaptmz eyin bir deiiklik olmadna dikkatinizi ekmek isterim. nk aslnda
biz burada varolan a adl deiken zerinde bir deiiklik yapmak yerine, yine a ad tayan
baka bir deiken oluturuyoruz.
Peki bu deiiklikten br karakter dizisi etkilendi mi?
>>> b
'elma'
Grdnz gibi, bu deiiklik teki karakter dizisini etkilememi. Bunun sebebinin, karakter
dizilerinin deitirilemeyen (immutable ) bir veri tipi olmas olduunu sylemitik.
Gelin isterseniz bu olgunun derinlerine inelim biraz...
Yukarda a ve b adl iki deiken var. Bunlarn kimliklerini kontrol edelim:
>>> id(a)
15182784
>>> id(b)
15181184
Grdnz gibi, bu iki deiken farkl kimlik numaralarna sahip. Bu durumu u ekilde de
teyit edebileceimizi biliyorsunuz:
>>> id(a) == id(b)
False
Demek ki gerekten de id(a) ile id(b) birbirinden farklym. Yani aslnda biz ayn nesne
zerinde bir deiiklik yapmak yerine, farkl bir nesne oluturmuuz.
Bu sonu bize, bu iki karakter dizisinin bellekte farkl konumlarda saklandn gsteriyor.
Dolaysyla Python, bir karakter dizisini kopyaladmzda bellekte ikinci bir nesne daha
oluturuyor. Bu nedenle birbirinden kopyalanan karakter dizilerinin biri zerinde yaplan
herhangi bir ilem brn etkilemiyor. Ama listelerde (ve deitirilebilir btn veri
tiplerinde) durum farkl. imdi u rneklere dikkatlice bakn:
>>> liste1 = ["ahmet", "mehmet", "zlem"]
Bu listeyi kopyalayalm:
>>> liste2 = liste1
25.1. Listeler
415
>>> id(liste1)
14901376
>>> id(liste2)
14901376
>>> id(liste1) == id(liste2)
True
Grdnz gibi, liste1 ve liste2 adl listeler ayn kimlik numarasna sahip. Yani bu iki nesne
birbiriyle ayn. Dolaysyla birinde yaptnz deiiklik brn de etkiler. Eer birbirinden
kopyalanan listelerin birbirini etkilemesini istemiyorsanuz, nnzde birka seenek var.
lk seenee gre yle bir kod yazabilirsiniz:
nce zgn listemizi oluturalm:
>>> liste1 = ["ahmet", "mehmet", "zlem"]
416
Grdnz gibi, her ey yolunda. Dilerseniz bu nesnelerin birbirinden farkl olduunu id()
fonksiyonu araclyla teyit edebileceinizi biliyorsunuz.
Listeleri kopyalamann nc bir yntemi daha var. Bu yntemi de bir sonraki blmde liste
metotlarn incelerken ele alacaz.
Burada 0dan 1000e kadar olan saylar tek satrda bir liste haline getirdik. Bu kodlarn sz
dizimine ok dikkat edin. Aslnda yukardaki kod u ekilde de yazlabilir:
liste = []
for i in range(1000):
liste += [i]
Burada nce liste adl bo bir liste tanmladk. Daha sonra 0 ile 1000 aralnda btn saylar
bu bo listeye teker teker gnderdik. Bylece elimizde 0dan 1000e kadar olan saylar tutan
bir liste olmu oldu. Ayn i iin liste retelerini kullandmzda ise bu etkiyi ok daha ksa
bir yoldan halletmi oluyoruz. Liste retelerini kullandmz kodu tekrar nmze alalm:
liste = [i for i in range(1000)]
Grdnz gibi, burada nceden bo bir liste tanmlamamza gerek kalmad. Ayrca bu
kodlarda for dngsnn parantezler iine alnarak nasl sadeletirildiine de dikkatinizi
ekmek isterim. u kod:
for i in range(1000):
liste += [i]
25.1. Listeler
417
Pek ok durumda liste reteleri br seeneklere kyasla bir alternatif olma ilevi grr.
Yani liste reteleri ile elde edeceiniz sonucu baka aralarla da elde edebilirsiniz. Mesela
yukardaki kodlarn yapt ilevi yerine getirmek iin baka bir seenek olarak list()
fonksiyonundan da yararlanabileceimizi biliyorsunuz:
liste = list(range(1000))
Bu basit rneklerde liste retelerini kullanmann erdemi pek gze arpmyor. Ama baz
durumlarda liste reteleri teki alternatiere kyasla ok daha pratik bir zm sunar.
Byle durumlarda baka seeneklere bavurup yolunuzu uzatmak yerine liste retelerini
kullanarak iinizi ksa yoldan halledebilirsiniz.
rnein 0 ile 1000 arasndaki ift saylar listelemek iin liste retelerini kullanmak,
alternatierine gre daha makul bir tercih olabilir:
liste = [i for i in range(1000) if i % 2 == 0]
Ayn ii for dngs ile yapmak iin yle bir kod yazmamz gerekir:
liste = []
for i in range(1000):
if i % 2 == 0:
liste += [i]
Grdnz gibi, liste reteleri bize ayn ii daha ksa bir yoldan halletme imkan tanyor. Bu
arada for dngsnn ve bu dng iinde yer alan if deyiminin liste reteleri iinde nasl
grndne dikkat ediyoruz.
Liste reteleri ile ilgili bir rnek daha verelim. Mesela elinizde yle bir liste olduunu
dnn:
liste = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
Burada i ie gemi 4 adet liste var. Bu listenin btn elerini tek bir listeye nasl alabiliriz?
Yani yle bir kty nasl elde ederiz?
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
418
print(tm)
Bu liste reteci gerekten de bize ksa bir zm sunuyor, ama bu tip i ie gemi for
dnglerinden oluan liste retelerinde bazen okunakllk sorunu ortaya kabilir. Yani bu
tr i ie gemi for dnglerinden oluan liste retelerini anlamak, alternatif yntemlere
gre daha zor olabilir.
Baz durumlarda ise liste reteleri bir sorunun zm iin tek makul yol olabilir. Diyelim
ki bir X.O.X Oyunu (Tic Tac Toe ) yazyorsunuz. Bu oyunda oyuncular oyun tahtas zerine X
veya O iaretlerinden birini yerletirecek. Oyuncunun bu oyunu kazanabilmesi iin, X veya
O iaretlerinden birisinin oyun tahtas zerinde belli konumlarda bulunmas gerekiyor. Yani
mesela X iaretinin oyunu kazanabilmesi iin bu iaretin oyun tahtas zerinde u ekilde bir
dizilime sahip olmas gerekir:
O
___
___
___
Bu dizilime gre oyunu X iareti kazanr. Peki X iaretinin, oyunu kazanmasn salayacak bu
dizilime ulatn nasl tespit edeceksiniz?
Bunun iin ncelikle oyun tahtas zerinde hangi dizilim ekillerinin galibiyeti getireceini
gsteren bir liste hazrlayabilirsiniz. Mesela yukardaki gibi 3x3 boyutundaki bir oyun
tahtasnda X iaretinin oyunu kazanabilmesi iin u dizilimlerden herhangi birine sahip olmas
gerekir:
[0, 0], [1, 0], [2, 0]
X
___
___
___
___
___
___
___
___
___
___
___
25.1. Listeler
419
___
___
___
___
___
X
___
X
___
___
___
___
___
___
X
___
X
___
X
___
___
___
___
___
___
___
___
___
___
___
___
___
___
___
___
___
Ayn dizilimler O iareti iin de geerlidir. Dolaysyla bu kazanma ltlerini yle bir liste
iinde toplayabilirsiniz:
kazanma_ltleri = [[[0,
[[0,
[[0,
[[0,
420
0],
1],
2],
0],
[1,
[1,
[1,
[0,
0],
1],
2],
1],
[2,
[2,
[2,
[0,
0]],
1]],
2]],
2]],
[[1,
[[2,
[[0,
[[0,
0],
0],
0],
2],
[1,
[2,
[1,
[1,
1],
1],
1],
1],
[1,
[2,
[2,
[2,
2]],
2]],
2]],
0]]]
Oyun srasnda X veya O iaretlerinin ald konumu bu kazanma ltleri ile karlatrarak
oyunu kimin kazandn tespit edebilirsiniz. Yani kazanma_ltleri adl liste iindeki, i ie
gemi listelerden herhangi biri ile oyunun herhangi bir aamasnda tamamen eleen iaret,
oyunu kazanm demektir.
Bir sonraki blmde bu bahsettiimiz X.O.X Oyununu yazacaz. O zaman bu srecin nasl
ilediini daha ayrntl bir ekilde inceleyeceiz. imdilik yukardaki durumu temsil eden basit
bir rnek vererek liste retelerinin kullanmn incelemeye devam edelim.
rnein elinizde, yukarda bahsettiimiz kazanma ltlerini temsil eden yle bir liste
olduunu dnn:
liste1 = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15],
[16, 17, 18],
[19, 20, 21],
[22, 23, 24],
[25, 26, 27],
[28, 29, 30],
[31, 32, 33]]
Burada amacnz liste1 iinde yer alan i ie gemi listelerden hangisinin liste2 iindeki
saylarn alt kmesi olduunu, yani liste2 iindeki saylarn, liste1 iindeki l listelerden
hangisiyle birebir eletiini bulmak. Bunun iin yle bir kod yazabiliriz:
for i in liste1:
ortak = [z for z in i if z in liste2]
if len(ortak) == len(i):
print(i)
Bu kodlar ilk bakta gznze ok karmak gelmi olabilir. Ama aslnda hi de karmak
deildir bu kodlar. imdi bu kodlar Trkeye evirelim:
1. satr: liste1 adl listedeki her bir eye i adn verelim
2. satr: i iindeki, liste2 de de yer alan her bir eye de z adn verelim ve bunlar ortak adl
bir listede toplayalm.
25.1. Listeler
421
3. satr: eer ortak adl listenin uzunluu i deikeninin uzunluu ile aynysa
4. satr: i yi ekrana basalm ve bylece alt kmeyi bulmu olalm.
Eer bu satrlar anlamakta zorluk ekiyorsanz okumaya devam edin. Biraz sonra vereceimiz
rnek programda da bu kodlar grecek ve bu kodlarn ne ie yaradn orada daha iyi
anlayacaksnz.
Bu tahtada oyuncu soldan saa ve yukardan aaya doru iki adet konum bilgisi girecek ve
oyunu oynayan kiinin girecei bu konumlara X ve O hareri iaretlenecek.
Byle bir grnt oluturmak iin pek ok farkl yntem kullanlabilir. Ama oyuncunun her
konum bilgisi giriinde, X veya O iaretini tahta zerinde gstereceimiz iin tahta zerinde
oyun boyunca srekli birtakm deiiklikler olacak. Bildiiniz gibi karakter dizileri, zerinde
deiiklik yapmaya msait bir veri tipi deil. Byle bir grev iin listeler daha uygun bir ara
olacaktr. O yzden tahtay oluturmada listeleri kullanmay tercih edeceiz.
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]
Grdnz gibi, burada i ie gemi adet listeden oluan bir liste var. print(tahta)
komutunu kullanarak bu listeyi ekrana yazdrrsanz listenin yaps daha belirgin bir ekilde
ortaya kacaktr:
[['___', '___', '___'], ['___', '___', '___'], ['___', '___', '___']]
422
Bu kodlarda bilmediiniz hibir ey yok. Burada grdnz her eyi nceki derslerde
renmitiniz.
Yukardaki kodlar yazarken tamamen, elde etmek istediimiz grntye odaklanyoruz.
Mesela print("\n"*15) kodunu yazmamzn nedeni, oyun tahtas iin ekranda bo bir alan
oluturmak. Bu etkiyi elde etmek iin 15 adet yeni satr karakteri bastk ekrana. Bu kodla elde
edilen etkiyi daha iyi grebilmek iin bu kodu programdan karmay deneyebilirsiniz.
Alttaki satrda ise bir for dngs tanmladk. Bu dngnn amac tahta adl listedeki __
elerini dzgn bir ekilde oyuncuya gsterebilmek. Oyun tahtasnn, ekran (yaklak olarak
da olsa) ortalamasn istiyoruz. O yzden, tahta elerine soldan girinti verebilmek iin
print() fonksiyonunun ilk parametresini "\t".expandtabs(30) eklinde yazdk. Karakter
dizilerinin expandtabs() adl metodunu nceki derslerimizden hatrlyor olmalsnz. Bu
metodu kullanarak sekme (TAB) karakterlerini geniletebiliyorduk. Burada da \t karakterini
bu metot yardmyla genileterek liste elerini sol batan girintiledik.
print() fonksiyonunun ikinci parametresi ise *i. Bu parametrenin ne i yaptn anlamak
iin yle bir kod yazalm:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]
for i in tahta:
print(i)
Grdnz gibi, i ie gemi adet listeden oluan tahta adl liste iindeki bu i listeler
ekrana dkld. Bir de una bakn:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]
for i in tahta:
print(*i)
25.1. Listeler
423
Bu defa liste yapsn deil, listeyi oluturan elerin kendisini gryoruz. Yldz iaretinin,
birlikte kullanld eler zerinde nasl bir etkiye sahip olduunu yine nceki derslerimizden
hatrlyorsunuz. Mesela u rnee bakn:
kardiz = "istihza"
for i in kardiz:
print(i, end=" ")
print()
te oyun tahtasn ekrana dkmek iin kullandmz kodda da benzer bir ey yaptk. Yldz
iareti yardmyla, tahta adl listeyi oluturan i ie gemi listeleri liste dna karp dzgn
bir ekilde kullancya gsterdik.
print() fonksiyonu iindeki son parametremiz u: end="\n"*2
Bu parametrenin ne ie yaradn kolaylkla anlayabildiinizi zannediyorum. Bu parametre
de istediimiz kty elde etmeye ynelik bir abadan ibarettir. tahta adl liste iindeki i ie
gemi listelerin her birinin sonuna ikier adet \n karakteri yerletirerek, ktdaki satrlar
arasnda yeterli miktarda aralk braktk. Eer oyun tahtasndaki satrlarn biraz daha aralkl
olmasn isterseniz bu parametredeki 2 arpann artrabilirsiniz. Mesela: end="\n"*3
imdi yapmamz gereken ey, oyundaki kazanma ltlerini belirlemek. Hatrlarsanz bu
konuya bir nceki blmde deinmitik. O yzden aada syleyeceklerimizin bir blmne
zaten ainasnz. Burada nceden sylediimiz baz eylerin yeniden zerinden geeceiz.
Dediim gibi, kodlarn bu blmnde, hangi durumda oyununun biteceini ve kazanann
kim olacan tespit edebilmemiz gerekiyor. Mesela oyun srasnda yle bir grnt ortaya
karsa hemen oyunu durdurup O KAZANDI! gibi bir kt verebilmemiz lazm:
O
___
___
___ ___
Yukardaki iki rnek zerinden dnecek olursak, herhangi bir iaretin u konumlarda
bulunmas o iaretin kazandn gsteriyor:
yukardan aaya 0; soldan saa 0
yukardan aaya 1; soldan saa 0
yukardan aaya 2; soldan saa 0
424
veya:
yukardan aaya 0; soldan saa 0
yukardan aaya 0; soldan saa 1
yukardan aaya 0; soldan saa 2
te bizim yapmamz gereken ey, bir iaretin oyun tahtas zerinde hangi konumlarda
bulunmas halinde oyunun biteceini tespit etmek. Yukardaki rnekleri gz nne alarak
bunun iin yle bir liste hazrlayabiliriz:
kazanma_ltleri = [[[0, 0], [1, 0], [2, 0]],
[[0, 0], [0, 1], [0, 2]]]
Burada iki adet listeden oluan, kazanma_ltleri adl bir listemiz var. Liste iinde, her biri
er eden oluan u listeleri gryoruz:
[[0, 0], [1, 0], [2, 0]]
[[0, 0], [0, 1], [0, 2]]
Bu listeler de kendi iinde ikier eli baz listelerden oluuyor. Mesela ilk liste iinde u
listeler var:
[0, 0], [1, 0], [2, 0]
Burada her bir liste iindeki ilk say oyun tahtasnda yukardan aaya doru olan dzlemi;
ikinci say ise soldan saa doru olan dzlemi gsteriyor.
Tabii ki oyun iindeki tek kazanma lt bu ikisi olmayacak. teki kazanma ltlerini de tek
tek tanmlamalyz:
kazanma_ltleri = [[[0,
[[0,
[[0,
[[0,
[[1,
[[2,
[[0,
[[0,
0],
1],
2],
0],
0],
0],
0],
2],
[1,
[1,
[1,
[0,
[1,
[2,
[1,
[1,
0],
1],
2],
1],
1],
1],
1],
1],
[2,
[2,
[2,
[0,
[1,
[2,
[2,
[2,
0]],
1]],
2]],
2]],
2]],
2]],
2]],
0]]]
425
Burada saylarn tek veya ift olma zelliinden yararlanarak X ve Y iaretleri arasnda gei
yaptk. nce sra adl bir deiken tanmlayp bunun deerini 1 olarak belirledik. while
dngsnde ise bu deikenin deerini her defasnda 1 artrdk. Eer saynn deeri iftse
iaret X; tekse O olacak. Bu arada X ve O adl karakter dizilerini, center() metodu yardmyla
ortaladmza dikkat edin.
Yukardaki kodlar bu ekilde altrdnzda X ve Y harerinin ok hzl bir ekilde ekrandan
getiini greceksiniz. Eer ekranda son hz akp giden bu verileri yavalatmak ve neler olup
bittiini daha net grmek isterseniz yukardaki kodlar yle yazabilirsiniz:
from time import sleep
sra = 1
while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)
sra += 1
print()
print("ARET: {}\n".format(iaret))
sleep(0.3)
426
Burada X veya O iaretlerini tahta zerinde uygun yerlere yerletirebilmek iin kullancnn
konum bilgisi girmesini istiyoruz. x deikeni yukardan aaya doru olan dzlemdeki
konumu, y deikeni ise soldan saa doru olan dzlemdeki konumu depolayacak. Oyunda
kullancnn girebilecei deerler 1, 2 veya 3 olacak. Mesela oyuncu O iareti iin yukardan
aaya 1; soldan saa 2 deerini girmise yle bir grnt elde edeceiz:
___
___
Burada ljust() metotlarn, kullancya gsterilecek verinin dzgn bir ekilde hizalanmas
amacyla kullandk.
Eer kullanc x veya y deikenlerinden herhangi birine q cevab verirse oyundan kyoruz.
Yukardaki kodlarn son iki satrnda ise kullancdan gelen karakter dizilerini birer sayya
dntryoruz. Bu arada, bildiiniz gibi Python saymaya 0dan balyor. Ama insanlar
asndan doal olan saymaya 1den balamaktr. O yzden mesela kullanc 1 saysn
girdiinde Pythonn bunu 0 olarak alglamasn salamamz gerekiyor. Bunun iin x ve y
deerlerinden 1 karyoruz.
Kullancdan gerekli konum bilgilerini aldmza gre, bu bilgilere dayanarak X ve O
iaretlerini oyun tahtas zerine yerletirebiliriz. imdi u kodlar dikkatlice inceleyin:
print("\n"*15)
if tahta[x][y] == "___":
tahta[x][y] = iaret
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
sra += 1
else:
print("\nORASI DOLU! TEKRAR DENEYN\n")
Burada ncelikle 15 adet satr ba karakteri basyoruz. Bylece oyun tahtas iin ekranda bo
bir alan oluturmu oluyoruz. Bu satr tamamen gzel bir grnt elde etmeye ynelik bir
uygulamadr. Yani bu satr yazmasanz da programnz alr. Veya siz kendi zevkinize gre
daha farkl bir grnm elde etmeye alabilirsiniz.
kinci satrda grdmz if tahta[x][y] == "___": kodu, oyun tahtas zerindeki bir
konumun halihazrda bo mu yoksa dolu mu olduunu tespit etmemizi salyor. Amacmz
oyuncunun ayn konuma iki kez giri yapmasn engellemek. Bunun iin tahta zerinde x ve
25.1. Listeler
427
y konumlarna denk gelen yerde ___ iaretinin olup olmadna bakmamz yeterli olacaktr.
Eer baklan konumda ___ iareti varsa oras bo demektir. O konuma iaret koyulabilir.
Ama eer o konumda ___ iareti yoksa X veya O iaretlerinden biri var demektir. Dolaysyla
o konuma iaret koyulamaz. Byle bir durumda kullancya ORASI DOLU! TEKRAR DENEYN
uyarsn gsteriyoruz.
Oyun tahtas zerinde deiiklik yapabilmek iin nasl bir yol izlediimize dikkat edin:
tahta[x][y] = iaret
Mesela oyuncu yukardan aaya 1; soldan saa 2 saysn girmise, kullancdan gelen
saylardan 1 kardmz iin, Python yukardaki kodu yle deerlendirecektir:
tahta[0][1] = iaret
Yani tahta adl liste iindeki ilk listenin ikinci srasna ilgili iaret yerletirilecektir.
Ayrca yukardaki kodlarda u satrlar da gryoruz:
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
Eer iaret sras Xte ise oyuncunun girdii konum bilgilerini x_durumu adl deikene,
eer iaret sras Oda ise konum bilgilerini o_durumu adl deikene yolluyoruz. Oyunu
hangi iaretin kazandn tespit edebilmemiz asndan bu kodlar byk nem tayor.
x_durumu ve o_durumu deikenlerini kazanma_ltleri adl liste ile karlatrarak oyunu
kimin kazandna karar vereceiz.
Bu arada, oyunun en banda tanmladmz sra adl deikeni if blou iinde artrdmza
dikkat edin. Bu sayede, kullancnn yanllkla ayn konuma iki kez iaret yerletirmeye
almas halinde iaret sras deimeyecek. Yani mesela o anda sra Xte ise ve oyuncu yanl
bir konum girdiyse sra yine Xte olacak. Eer sra deikenini if blou iine yazmazsak, yanl
konum girildiinde iaret sras Oa geecektir.
sterseniz imdiye kadar yazdmz kodlar yle bir topluca grelim:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]
print("\n"*15)
for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)
kazanma_ltleri = [[[0,
[[0,
[[0,
[[0,
[[1,
[[2,
[[0,
[[0,
0],
1],
2],
0],
0],
0],
0],
2],
[1,
[1,
[1,
[0,
[1,
[2,
[1,
[1,
0],
1],
2],
1],
1],
1],
1],
1],
[2,
[2,
[2,
[0,
[1,
[2,
[2,
[2,
0]],
1]],
2]],
2]],
2]],
2]],
2]],
0]]]
x_durumu = []
o_durumu = []
428
sra = 1
while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)
print()
print("ARET: {}\n".format(iaret))
x = input("yukardan aaya [1, 2, 3]: ".ljust(30))
if x == "q":
break
y = input("soldan saa [1, 2, 3]: ".ljust(30))
if y == "q":
break
x = int(x)-1
y = int(y)-1
print("\n"*15)
if tahta[x][y] == "___":
tahta[x][y] = iaret
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
sra += 1
else:
print("\nORASI DOLU! TEKRAR DENEYN\n")
Grdnz gibi epey kod yazmz. Kodlarmz topluca incelediimize gre yazmaya devam
edebiliriz:
for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)
Sra geldi oyunun en nemli ksmna. Bu noktada oyunu kimin kazandn belirlememiz
gerekiyor. Dikkatlice inceleyin:
for i in kazanma_ltleri:
o = [z for z in i if z in o_durumu]
x = [z for z in i if z in x_durumu]
if len(o) == len(i):
print("O KAZANDI!")
quit()
if len(x) == len(i):
print("X KAZANDI!")
quit()
Bu kodlar anlayabilmek iin en iyi yol uygun yerlere print() fonksiyonlar yerletirerek
ktlar incelemektir. Mesela bu kodlar yle yazarak o ve x deikenlerinin deerlerini
25.1. Listeler
429
izleyebilirsiniz:
for i in kazanma_ltleri:
o = [z for z in i if z in o_durumu]
x = [z for z in i if z in x_durumu]
print("o: ", o)
print("x: ", x)
if len(o) == len(i):
print("O KAZANDI!")
quit()
if len(x) == len(i):
print("X KAZANDI!")
quit()
0],
1],
2],
0],
0],
0],
0],
2],
[1,
[1,
[1,
[0,
[1,
[2,
[1,
[1,
0],
1],
2],
1],
1],
1],
1],
1],
[2,
[2,
[2,
[0,
[1,
[2,
[2,
[2,
0]],
1]],
2]],
2]],
2]],
2]],
2]],
0]]]
x_durumu = []
o_durumu = []
sra = 1
while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)
print()
print("ARET: {}\n".format(iaret))
x = input("yukardan aaya [1, 2, 3]: ".ljust(30))
if x == "q":
break
y = input("soldan saa [1, 2, 3]: ".ljust(30))
430
if y == "q":
break
x = int(x)-1
y = int(y)-1
print("\n"*15)
if tahta[x][y] == "___":
tahta[x][y] = iaret
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
sra += 1
else:
print("\nORASI DOLU! TEKRAR DENEYN\n")
for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)
for i in kazanma_ltleri:
o = [z for z in i if z in o_durumu]
x = [z for z in i if z in x_durumu]
if len(o) ==
print("O
quit()
if len(x) ==
print("X
quit()
len(i):
KAZANDI!")
len(i):
KAZANDI!")
Grdnz gibi, sadece u ana kadar rendiimiz bilgileri kullanarak bir oyun yazabilecek
duruma geldik. Burada kk paralar birletirerek bir btne nasl ulatmz zellikle
grmenizi isterim. Dikkat ederseniz, yukardaki programda sadece karakter dizileri, saylar,
listeler ve birka fonksiyon var. Nasl sadece 7 nota ile mzik aheserleri meydana
getirilebiliyorsa, yalnzca 4-5 veri tipi ile de dnyay ayaa kaldracak programlar da yazlabilir.
Listeleri temel olarak incelediimize gre biraz da demetlerden sz edebiliriz.
25.2 Demetler
Demetler, zellikle grn olarak listelere ok benzeyen bir veri tipidir. Bu veri tipi de, tpk
listeler gibi, farkl veri tiplerini iinde barndran kapsayc bir veri tipidir.
25.2. Demetler
431
Grdnz gibi, karakter dizilerinin type() sorgusuna str, listelerin ise list cevab vermesi
gibi, demetler de type() sorgusuna tuple cevab veriyor.
Yalnz, dediimiz gibi Pythonda demet tanmlamann birden fazla yolu vardr.
yukardaki demeti yle de tanmlayabiliriz:
Mesela
Grdnz gibi, parantez iaretlerini kullanmadan, eleri yalnzca virgl iareti ile
ayrdmzda da elde ettiimiz ey bir demet oluyor.
Demet oluturmak iin tuple() adl bir fonksiyondan da yararlanabilirsiniz. Bu fonksiyon,
liste oluturan list() fonksiyonuna ok benzer:
>>> tuple('abcdefg')
('a', 'b', 'c', 'd', 'e', 'f', 'g')
Burada, [ahmet, mehmet, 34, 45] adl bir listeyi tuple() fonksiyonu yardmyla demete
dntrdk.
Bu tek eli bir karakter dizisidir. Bir de tek eli bir liste tanmlayalm:
>>> liste = ['ahmet']
Bu da tek eli bir listedir. Gelin bir de tek eli bir demet oluturmaya alalm:
>>> demet = ('ahmet')
Python programlama dilinde tek eli bir demet oluturma ilemi biraz tuhaftr. Eer tek
eye sahip bir demet oluturacaksak yle bir ey yazmalyz:
432
veya:
>>> demet = 'ahmet',
Grdnz gibi, tek eli bir demet tanmlarken, o tek enin yanna bir tane virgl iareti
yerletiriyoruz. Bylece demet tanmlamak isterken, yanllkla alelade bir ekilde ahmet adl
bir karakter dizisini demet adl bir deikene atamam oluyoruz...
Grdnz gibi, daha nce rendiimiz indeksleme ve dilimleme kurallar aynen demetler
iin de geerli.
Grdnz gibi, demetin herhangi bir esini deitirmeye altmzda Python bize bir
hata mesaj gsteriyor.
Bu bakmdan, eer programn ak esnasnda zerinde deiiklik yapmayacanz veya
deiiklik yaplmasn istemediiniz birtakm veriler varsa ve eer siz bu verileri liste benzeri
bir tayc iine yerletirmek istiyorsanz, listeler yerine demetleri kullanabilirsiniz. Ayrca
demetler zerinde ilem yapmak listelere kyasla daha hzldr. Dolaysyla, performans
avantaj nedeniyle de listeler yerine demetleri kullanmak isteyebilirsiniz.
25.2. Demetler
433
Tahmin edebileceiniz gibi, tpk karakter dizilerinde olduu gibi, nceden tanmlanm
bir demetin zerinde deiiklik yapabilmek iin, rnein bir demetle baka bir demeti
birletirmek iin o demeti yeniden tanmlamak da mmkndr:
>>> demet = ('ahmet', 'mehmet')
>>> demet = demet + ('selin',)
Eer sadece demet + (selin,) demi olsaydk. zgn demet zerinde herhangi bir
deiiklik yapm olmayacaktk. Siz bu olguya karakter dizilerinden de ainasnz. O yzden,
zgn demet zerinde herhangi bir deiiklik yapabilmek iin, daha dorusu zgn demet
zerinde bir deiiklik yapm gibi grnebilmek iin, zgn demeti sfrdan tanmlamamz
gerekiyor...
Burada ayrca ahmet ve mehmet elerinden oluan bir demete selin esini nasl
eklediimize de dikkat edin. Asla unutmamalsnz: Python programlama dilinde sadece ayn
tr verileri birbiriyle birletirebilirsiniz. Mesela yukardaki rnekte selin adl eyi demet adl
demete bir karakter dizisi olarak ekleyemezsiniz:
>>> demet = demet + 'selin'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "str") to tuple
Bu arada, yukardaki kodu yle yazdnzda da aslnda bir demetle karakter dizisini
birletirmeye alyor olduunuza dikkat edin:
>>> demet = demet + ('selin')
Hatrlarsanz, tek eli bir demet tanmlayabilmek iin parantez iindeki tek enin yanna bir
virgl iareti yerletirmemiz gerekiyordu. Aksi halde demet deil, karakter dizisi tanmlam
oluyorduk. Zaten bir Python programcs olarak, demetler zerinde alrken en sk
yapacanz hata da demet tanmlamaya alrken yanllkla karakter dizisi tanmlamak
olacaktr.
Dediimiz ve yukarda da rneklerle gsterdiimiz gibi, bir demeti yeni batan tanmlayarak
da o demet zerinde deiiklik yapm etkisi elde edebilirsiniz. Ancak elbette bir araya
topladnz veriler zerinde sk sk deiiklikler yapacaksanz demetler yerine listeleri tercih
etmelisiniz.
Burada, ablon dosyalarnn hangi dizinde yer alacan bir demet iinde gsteriyoruz. Bu
demet iine birden fazla dizin ad yazabilirdik. Ama biz btn ablon dosyalarn tek bir dizin
altnda tutmay tercih ettiimiz iin tek eli bir demet tanmlamz. Bu arada, daha nce
de sylediimiz gibi, demetlerle ilgili en sk yapacanz hata, tek eli demet tanmlamaya
434
alrken aslnda yanllkla bir karakter dizisi tanmlamak olacaktr. rnein yukardaki
TEMPLATE_DIRS deikenini yle yazsaydk:
TEMPLATE_DIRS = ('/home/projects/djprojects/blog/templates')
Aslnda bir demet deil, alelade bir karakter dizisi tanmlam olurduk...
25.2. Demetler
435
BLM 26
Grdnz gibi, tpk karakter dizilerinde olduu gibi, listelerin metotlarn grmek iin de
dir() fonksiyonuna parametre olarak veri tipinin teknik adn veriyoruz. Pythonda listelerin
teknik ad list olduu iin bu komutu dir(list) eklinde kullanyoruz. Elbette, eer istersek,
listelerin metotlarn almak iin herhangi bir listeyi de kullanabiliriz. Mesela bo bir liste
kullanalm:
>>> dir([])
Bu komut da dir(list) ile ayn kty verecektir. Bu listede bizi ilgilendiren metotlar ise
unlardr:
>>> [i for i in dir(list) if not "_" in i]
['append', 'clear', 'copy', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
deitirme, e silme gibi ilemleri orada anlattmz yntemlerle deil, biraz sonra
greceimiz metotlar araclyla yapmay tercih edeceiz. Ama tabii ki, metotlar tercih
edecek olmamz, birinci blmde anlattmz yntemleri bir kenara atmanz gerektirmez.
Unutmayn, bir dildeki herhangi bir zellii siz kullanmasanz bile, etrafta bu zellii kullanan
baka programclar var. Dolaysyla en azndan bakalarnn yazd kodlar anlayabilmek iin
dahi olsa, kendinizin kullanmayacanz yntem ve yollar renmeniz gerekir.
append() metoduyla balayalm...
26.1.1 append()
append kelimesi ngilizcede eklemek, ilave etmek, ilitirmek gibi anlamlara gelir. append()
metodunun grevi de kelime anlamyla uyumludur. Bu metodu, bir listeye e eklemek iin
kullanyoruz. Mesela:
>>> liste = ["elma", "armut", "ilek"]
>>> [Link]("erik")
Bu metot, yeni eyi listenin en sonuna ekler. Mesela yukardaki rnekte erik adl karakter
dizisi listede ilek adl karakter dizisinin sana eklendi.
Hatrlarsanz bir nceki blmde listeye e ekleme iini + ileci ile de yapabileceimizi
sylemitik. Dolaysyla, aslnda yukardaki kodu yle de yazabiliriz:
>>> liste = ["elma", "armut", "ilek"]
>>> liste = liste + ["erik"]
>>> print(liste)
['elma', 'armut', 'ilek', 'erik']
Bu iki yntem birbiriyle ayn sonucu verse de hem pratiklik hem de ileyi bakmndan bu iki
yntemin birbirinden farkl olduunu gryoruz.
Pratiklik asndan bakarsak, append() metodununu kullanmann + ilecini kullanmaya
kyasla daha kolay olduunu herhalde kimse reddetmeyecektir. Bu iki yntem ileyi
bakmndan da birbirinden ayrlyor. Zira + ilecini kullandmzda listeye yeni bir e
eklerken aslnda liste adl baka bir liste daha oluturmu oluyoruz. Hatrlarsanz nceki
blmlerde listelerin deitirilebilir (mutable ) veri tipleri olduunu sylemitik. te append()
metodu sayesinde listelerin bu zelliinden sonuna kadar yararlanabiliyoruz. + ilecini
kullandmzda ise, orijinal listeyi deitirmek yerine yeni bir liste oluturduumuz iin, sanki
listelere karakter dizisi muamelesi yapm gibi oluyoruz. Grdnz gibi, listeye append()
metodunu uyguladktan sonra bunu bir deikene atamamza gerek kalmyor. append()
metodu orijinal liste zerinde dorudan deiiklik yapmamza izin verdii iin daha az kod
yazmamz ve programmzn daha performansl almasn salyor.
+ ileci ile append() metodu ilev olarak birbirine benzese de bu iki yntem arasnda nemli
farkllklar da vardr. Mesela u rnee bir gz atalm:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
hepsi = iletim_sistemleri + platformlar
print(hepsi)
['Windows', 'GNU/Linux', 'Mac OS X', 'IPhone', 'Android', 'S60']
437
Burada iki farkl listeyi, + ileci kullanarak birletirdik. Ayn ii append() metoduyla u ekilde
yapabiliriz:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
for i in platformlar:
iletim_sistemleri.append(i)
print(iletim_sistemleri)
Burada platformlar adl liste zerinde bir for dngs kurmamzn nedeni, append()
metodunun yalnzca tek bir parametre alabilmesidir. Yani bu metodu kullanarak bir listeye
birden fazla e ekleyemezsiniz:
>>> liste = [1, 2, 3]
>>> [Link](4, 5, 6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: append() takes exactly one argument (3 given)
Bu sebeple, ekleyeceiniz listenin eleri zerinde bir for dngs kurmanz gerekir:
>>> liste = [1, 2, 3]
>>> for i in [4, 5, 6]:
...
[Link](i)
...
>>> print(liste)
[1, 2, 3, 4, 5, 6]
Bir listeye birden fazla e eklemek iin aklnza yle bir yntem de gelmi olabilir:
>>> liste = [1, 2, 3]
>>> [Link]([4, 5, 6])
Grdnz gibi, [4, 5, 6] esi listeye tek para olarak eklendi. Eer istediiniz ey buysa
ne l! Ama deilse, for dngs ya da + ileci ile istediiniz kty elde edebilirsiniz.
yle bir rnek daha dnn: Diyelim ki kullancnn girdii btn saylar birbiriyle arpan
bir uygulama yazmak istiyoruz. Bunun iin yle bir kod yazabiliriz:
sonu = 1
while True:
say = input("say (hesaplamak iin q): ")
if say == "q":
break
sonu *= int(say)
print(sonu)
438
Burada kullanc her dngde bir say girecek ve programmz girilen bu sayy sonu
deikeninin o anki deeriyle arparak yine sonu deikenine gnderecek. Bylece kullanc
tarafndan girilen btn saylarn arpmn elde etmi olacaz. Kullancnn q harne
basmasyla birlikte de sonu deikeninin deeri ekranda grnecek. Yalnz burada birka
sorun var. Diyelim ki kullanc hibir say girmeden q harne basarsa, sonu deikeninin
1 olan deeri ekranda grnecek ve bu ekilde kullanc yanl bir sonu elde etmi olacak.
Ayrca arpma ilemi iin en az 2 adet say gerekiyor. Dolaysyla kullanc 2 den az say girerse
de programmz yanl sonu verecektir. Kullancnn yeterli miktarda say girip girmediini
tespit edebilmek iin yine listelerden ve listelerin append() metodundan yararlanabiliriz:
kontrol = []
sonu = 1
while True:
say = input("say (hesaplamak iin q): ")
if say == "q":
break
[Link](say)
sonu *= int(say)
if len(kontrol) < 2:
print("Yeterli say girilmedi!")
else:
print(sonu)
Burada nceki koda ilave olarak, kontrol adl bo bir liste tanmladk. Bu liste kullancnn
girdii saylar depolayacak. Bir nceki rnekte kullancnn girdii saylar hibir yerde
depolamadk. Orada yaptmz ey her dngde kullanc tarafndan girilen sayy sonu
deikeninin deeriyle arpp yine sonu deikenine gndermekti. Dolaysyla kullanc
tarafndan girilen saylar bir yerde tutulmad iin kaybolup gidiyordu. Burada ise kontrol
adl liste, kullanc tarafndan girilen saylar tuttuu iin, bu saylar daha sonra istediimiz
gibi kullanabilme imkanna kavuuyoruz.
Ayrca bu ikinci kodlarda kontrol deikeninin boyutuna bakarak kullancnn 2 den az say
girip girmediini denetliyoruz. Eer kontrol listesinin uzunluu 2 den azsa kullanc arpma
ilemi iin yeterli say girmemi demektir. Byle bir durumda arpma ilemini yapmak yerine,
kullancya Yeterli say girilmedi! eklinde bir uyar mesaj gsteriyoruz.
append() metodu listelerin en nemli metotlarndan biridir. Hem kendi yazdnz, hem
de bakalarnn yazd programlarda append() metodunu ska greceksiniz. Dolaysyla
listelerin hibir metodunu bilmeseniz bile append() metodunu renmelisiniz.
26.1.2 extend()
extend kelimesi ngilizcede geniletmek, yaymak gibi anlamlara gelir. te extend() adl
metot da kelime anlamna uygun olarak listeleri geniletir.
yle bir dndnzde extend() metodunun append() metoduyla ayn ii yaptn
zannedebilirsiniz. Ama aslnda bu iki metot ileyi olarak birbirinden ok farkldr.
append() metodunu kullanarak yazdmz u koda dikkatlice bakn:
li1 = [1, 3, 4]
li2 = [10, 11, 12]
li1. append(li2)
439
print(li1)
append() metodunu anlatrken sylediimiz gibi, bu metot bir listeye her defasnda sadece
tek bir e eklenmesine izin verir. Yukarda olduu gibi, eer bu metodu kullanarak bir
listeye yine bir liste eklemeye alrsanz, eklediiniz liste tek bir e olarak eklenecektir.
Yani yukardaki kodlar size yle bir kt verecektir:
[1, 3, 4, [10, 11, 12]]
Grdnz gibi, [10, 11, 12] listesi teki listeye tek bir liste halinde eklendi. te extend()
metodu bu tr durumlarda iinize yarayabilir. Mesela yukardaki rnei bir de extend()
metodunu kullanarak yazalm:
li1 = [1, 3, 4]
li2 = [10, 11, 12]
li1. extend(li2)
print(li1)
Grdnz gibi, extend() metodu tam da kelime anlamna uygun olarak listeyi yeni elerle
geniletti.
Hatrlarsanz append() metodunu anlatrken yle bir rnek vermitik:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
hepsi = iletim_sistemleri + platformlar
print(hepsi)
Esasnda, append() metodunu kullanmaya kyasla, burada + ilecini kullanmak sanki daha
pratikmi gibi grnyor. Bir de una bakn:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
iletim_sistemleri.extend(platformlar)
print(iletim_sistemleri)
440
26.1.3 insert()
Bildiiniz gibi, + ileci, append() ve extend() metotlar eleri listenin sonuna ekliyor. Peki
biz bir eyi listenin sonuna deil de, liste iinde baka bir konuma eklemek istersek ne
yapacaz? te bunun iin insert() adl baka bir metottan yararlanacaz.
insert kelimesi yerletirmek, sokmak gibi anlamlara gelir. insert() metodu da bu anlama
uygun olarak, eleri listenin istediimiz bir konumuna yerletirir. Dikkatlice inceleyin:
>>> liste = ["elma", "armut", "ilek"]
>>> [Link](0, "erik")
>>> print(liste)
['erik', 'elma', 'armut', 'ilek']
Grdnz gibi insert() metodu iki parametre alyor. lk parametre, enin hangi
konuma yerletirileceini, ikinci parametre ise yerletirilecek enin ne olduunu gsteriyor.
Yukardaki rnekte erik esini listenin 0. konumuna, yani listenin en bana yerletiriyoruz.
nsert() metodu zellikle dosya ilemlerinde iinize yarar. Diyelim ki elimizde ierii yle
olan [Link] adl bir dosya var:
Ahmet zkoparan
Mehmet Veli
Serdar Gzel
Zeynep Gz
Bizim amacmz, Ahmet zkoparan satrndan sonra Ferhat Yaz diye bir satr daha eklemek.
Yani dosyamz u hale getirmek istiyoruz:
Ahmet zkoparan
Ferhat Yaz
Mehmet Veli
Serdar Gzel
Zeynep Gz
Biz henz Pythonda dosya ilemlerinin nasl yaplacan renmedik. Ama hatrlarsanz
bundan nceki blmlerde birka yerde open() adl bir fonksiyondan bahsetmi ve bu
fonksiyonun dosya ilemlerinde kullanldn sylemitik. Mesela yukarda bahsettiimiz
[Link] adl dosyay amak iin open() fonksiyonunu u ekilde kullanabiliriz:
f = open("[Link]", "r")
ierik = [Link]()
Bu satr sayesinde dosya ieriini bir liste halinde alabildik. Eer yukardaki kodlara u
eklemeyi yaparsanz, dosya ieriini grebilirsiniz:
print(ierik)
['Ahmet zkoparan\n', 'Mehmet Veli\n', 'Serdar Gzel\n', 'Zeynep Gz\n', '\n']
Grdnz gibi, dosya ierii basit bir listeden ibaret. Dolaysyla listelerle yapabildiimiz
her eyi ierik adl deikenle de yapabiliriz. Yani bu listeye e ekleyebilir, listeden e
26.1. Listelerin Metotlar
441
Dediimiz gibi, [Link]() satr bize dosya ieriini bir liste olarak verdi. Amacmz
Ahmet zkoparan esinden sonra Ferhat Yaz esini eklemek. Bunun iin, liste
metotlarndan biri olan insert() metodunu kullanarak listenin 1. srasna Ferhat Yaz
esini ekledik. Burada Ferhat Yaz esine n adl satr ba karakterini de ilave ettiimize
dikkat edin. Bu eklemeyi neden yaptmz anlamak iin satr ba karakterini karmay
deneyebilirsiniz.
ierik adl deikenin deerini istediimiz biime getirdiimize gre bu listeyi tekrar
[Link] adl dosyaya yazabiliriz. Ama bunun iin ncelikle [Link] adl dosyay yazma
modunda amamz gerekiyor. Pythonda dosyalar ya okuma ya da yazma modunda alabilir.
Okuma modunda alan bir dosyaya yazlamaz. O yzden dosyamz bir de yazma modunda
amamz gerekiyor:
g = open("[Link]", "w")
open() fonksiyonunun ilk parametresi dosya adn gsterirken, ikinci parametresi dosyann
hangi modda alacan gsteriyor. Biz burada [Link] adl dosyay yazma modunda
atk. Buradaki w parametresi ngilizcede yazmak anlamna gelen write kelimesinin ilk
hardir. Biraz nce ise [Link] dosyasn r, yani okuma (read ) modunda amtk.
Dosyamz artk zerine yazmaya hazr. Dikkatlice bakn:
[Link](ierik)
Burada, biraz nce istediimiz biime getirdiimiz ierik adl listeyi doruda dosyaya yazdk.
Bu ilem iin writelines() adl zel bir metottan yararlandk. Bu metotlar birka blm
sonra ayrntl olarak inceleyeceiz. Biz imdilik sadece sonuca odaklanalm.
Yapmamz gereken son ilem, ak dosyalar kapatmak olmal:
[Link]()
[Link]()
442
3. Aldmz bu listenin 2.
"Ferhat Yaz\n"))
4. Listeyi istediimiz ekle getirdikten sonra bu defa dosyamz yazma modunda ayoruz
(g = open("[Link]", "w"))
5. Biraz nce dzenlediimiz listeyi dosyaya yazyoruz ([Link](ierik))
6. Son olarak da, hem yaptmz deiikliklerin etkin hale gelebilmesi hem de iletim
sisteminin programmza tahsis ettii kaynaklarn serbest kalmas iin dosyalarmz
kapatyoruz ([Link]() ve [Link]())
Burada insert() metodunun bize nasl kolaylk saladna dikkat edin. insert() metodu da
listelerin nemli metotlarndan biridir ve dediimiz gibi, zellikle dosyalar maniple ederken
epey iimize yarar.
26.1.4 remove()
Bu metot listeden e silmemizi salar. rnein:
>>> liste = ["elma", "armut", "ilek"]
>>> [Link]("elma")
>>> liste
['armut', 'ilek']
26.1.5 reverse()
Daha nce verdiimiz rneklerde, liste elerini ters evirmek iin dilimleme yntemini
kullanabileceimizi renmitik:
>>> meyveler = ["elma", "armut", "ilek", "kiraz"]
>>> meyveler[::-1]
['kiraz', 'ilek', 'armut', 'elma']
... veya:
443
>>> print(list(reversed(meyveler)))
['kiraz', 'ilek', 'armut', 'elma']
... ya da:
>>> for i in reversed(meyveler):
...
print(i)
...
kiraz
ilek
armut
elma
Grdnz gibi, Pythonda bir listeyi ters evirmenin pek ok yntemi var. Dilerseniz imdi
bu yntemlere bir tane daha ekleyelim.
Pythonda listelerin elerini ters evirmek iin yukardaki yntemlere ek olarak listelerin
reverse() metodunu da kullanabilirsiniz:
>>> liste = ["elma", "armut", "ilek"]
>>> [Link]()
>>> liste
['ilek', 'armut', 'elma']
htiyacnz olan ktnn trne ve ekline gre yukardaki yntemlerden herhangi birini tercih
edebilirsiniz.
26.1.6 pop()
Tpk remove() metodu gibi, bu metot da bir listeden e silmemizi salar:
>>> liste = ["elma", "armut", "ilek"]
>>> [Link]()
Ancak bu metot, remove() metodundan biraz farkl davranr. pop() metodunu kullanarak
bir liste esini sildiimizde, silinen e ekrana baslacaktr. Bu metot parametresiz olarak
kullanldnda listenin son esini listeden atar. Alternatif olarak, bu metodu bir parametre
ile birlikte de kullanabilirsiniz. rnein:
>>> [Link](0)
26.1.7 sort()
Yine listelerin nemli bir metodu ile kar karyayz. sort() adl bu nemli metot bir listenin
elerini belli bir lte gre sraya dizmemizi salar. Basit bir rnek verelim. Diyelim ki
elimizde yle bir liste var:
yeler = ['Ahmet', 'Mehmet', 'Ceylan', 'Seyhan', 'Mahmut', 'Zeynep',
'Abdullah', 'Kadir', 'Kemal', 'Kamil', 'Selin', 'Senem',
'Sinem', 'Tayfun', 'Tuna', 'Tolga']
444
Bu listedeki isimleri mesela alfabe srasna dizmek iin sort() metodunu kullanabiliriz:
>>> [Link]()
>>> print(yeler)
['Abdullah', 'Ahmet', 'Ceylan', 'Kadir', 'Kamil', 'Kemal', 'Mahmut',
'Mehmet', 'Selin', 'Senem', 'Seyhan', 'Sinem', 'Tayfun', 'Tolga',
'Tuna', 'Zeynep']
Bu metot elbette yalnzca hareri alfabe srasna dizmek iin deil saylar sralamak iin de
kullanlabilir:
>>> saylar = [1, 0, -1, 4, 10, 3, 6]
>>> [Link]()
>>> print(saylar)
[-1, 0, 1, 3, 4, 6, 10]
Grdnz gibi, sort() metodu eleri artan sralamaya tabi tutuyor. Yani eler a, b,
c veya 1, 2, 3 eklinde sralanyor. Bunun tersini yapmak da mmkndr. Yani istersek
Pythonn sralama ilemini c, b, a eklinde yapmasn da salayabiliriz. Bunun iin sort()
metodunun reverse parametresini kullanacaz:
>>> yeler = ['Ahmet', 'Mehmet', 'Ceylan', 'Seyhan', 'Mahmut', 'Zeynep',
'Abdullah', 'Kadir', 'Kemal', 'Kamil', 'Selin', 'Senem',
'Sinem', 'Tayfun', 'Tuna', 'Tolga']
>>> [Link](reverse=True)
Grdnz gibi sort() metodunun reverse adl bir parametresine verdiimiz True deeri
sayesinde liste elerini ters sraladk. Bu parametrenin ntanml deeri False tur. Yani
sort() metodu ntanml olarak eleri artra artra sralar. eleri azalta azalta sralamak
iin reverse parametresinin False olan ntanml deerini True yapmamz yeterli olacaktr.
Gelin isterseniz sort() metodunu kullanarak bir rnek daha verelim. Elimizde yle bir liste
olsun:
>>> isimler = ["Ahmet", "Ik", "smail", "idem", "Can", "ule"]
Grdnz gibi, kt pek beklediimiz gibi deil. Tpk karakter dizilerini anlatrken
rendiimiz sorted() fonksiyonunda olduu gibi, listelerin sort() metodu da Trke
karakterleri dzgn sralayamaz. Eer Trke karakterleri sralamamz gereken bir program
yazyorsak bizim sort() metodunun ileyiine mdahale etmemiz gerekir. Temel olarak,
sorted() fonksiyonunu anlatrken sylediklerimiz burada da geerlidir. Orada bahsettiimiz
locale modl burada da ou durumda iimizi halletmemizi salar. Ama sorted()
fonksiyonunu anlatrken de sylediimiz gibi, locale modl burada da i ve harerini
dzgn sralayamaz. Trke harerin tamamn dzgn sralayabilmek iin yle bir kod
yazabiliriz:
445
harfler = "abcdefghijklmnoprstuvyz"
evrim = {harf: [Link](harf) for harf in harfler}
isimler = ["ahmet", "k", "ismail", "idem", "can", "ule"]
[Link](key=lambda x: [Link](x[0]))
print(isimler)
Bu kodlarn bir ksmn anlayabiliyor, bir ksmn ise anlayamyor olabilirsiniz. nk burada
henz ilemediimiz konular var. Zaman geldiinde bu kodlarn tamamn anlayabilecek
duruma geleceksiniz. Siz imdilik sadece bu kodlardan ne karabildiinize bakn yeter.
Zaten bizim buradaki amacmz, sort() metodunun Trke hareri de dzgn bir ekilde
sralayabileceini gstermekten ibarettir.
Bu arada ufak bir uyar yapmadan gemeyelim: Yukardaki kodlar da esasnda Trke
kelimeleri tam anlamyla dzgn bir ekilde sralamak iin yeterli deil. Gml Fonksiyonlar
konusunu incelerken, yeri geldiinde bu konuya tekrar deinip, Trke kelimelerin nasl
doru, tam ve eksiksiz bir biimde sralanacan da tm ayrntlaryla inceleyeceiz.
26.1.8 index()
Karakter dizileri konusunu anlatrken bu veri tipinin index() adl bir metodu olduundan sz
etmitik hatrlarsanz. te liste veri tipinin de index() adnda ve karakter dizilerinin index()
metoduyla ayn ii yapan bir metodu bulunur. Bu metot bir liste esinin liste iindeki
konumunu syler bize:
>>> liste = ["elma", "armut", "ilek"]
>>> [Link]("elma")
0
Karakter dizilerinin index() metoduyla ilgili sylediimiz her ey listelerin index() metodu
iin de geerlidir.
26.1.9 count()
Karakter dizileri ile listelerin ortak metotlarndan biri de count() metodudur. Tpk karakter
dizilerinde olduu gibi, listelerin count() metodu da bir enin o veri tipi iinde ka kez
getiini syler:
>>> liste = ["elma", "armut", "elma", "ilek"]
>>> [Link]("elma")
2
Karakter dizilerinin count() metoduyla ilgili sylediimiz her ey listelerin count() metodu
iin de geerlidir.
446
26.1.10 copy()
Hatrlarsanz, geen blmde, listeleri, birbirlerini etkilemeyecek ekilde kopyalamak iin u
iki yntemi kullanmtk:
>>> liste1 = ["ahmet", "mehmet", "zlem"]
>>> liste2 = liste1[:]
ve:
>>> liste2 = list(liste1)
te ayn i iin yukardakilere ek olarak copy() adl bir metottan da yararlanabiliriz. Dikkatlice
bakn:
>>> liste2 = [Link]()
26.1.11 clear()
Listelerle ilgili olarak ele alacamz son metodun ad clear(). Bu metodun grevi bir listenin
ieriini silmektir.
Diyelim ki elimizde yle bir liste var:
>>> liste = [1, 2, 3, 5, 10, 20, 30, 45]
Bu metodun del szcnden farkl olduunu dikkat edin. clear() metodu listenin ieriini
boaltrken, del szc listeyi olduu gibi ortadan kaldrr.
447
26.2.1 index()
Listeler ve karakter dizileri konusunu anlatrken bu veri tiplerinin index() adl bir metodu
olduundan sz etmitik hatrlarsanz. te demet veri tipinin de index() adnda ve listelerle
karakter dizilerinin index() metoduyla ayn ii yapan bir metodu bulunur. Bu metot bir
demet esinin demet iindeki konumunu syler bize:
>>> demet = ("elma", "armut", "ilek")
>>> [Link]("elma")
0
26.2.2 count()
Karakter dizileri, listeler ve demetlerin ortak metotlarndan biri de count() metodudur. Tpk
karakter dizileri ve listelerde olduu gibi, demetlerin count() metodu da bir enin o veri tipi
iinde ka kez getiini syler:
>>> demet = ("elma", "armut", "elma", "ilek")
>>> [Link]("elma")
2
448
BLM 27
Sayma Sistemleri
Ama elbette dnya zerindeki tek sayma sistemi onlu sistem olmad gibi, saylar gstermek
iin kullanlabilecek rakamlar da yukardakilerle snrl deildir.
Nihayetinde rakam dediimiz eyler insan icad birtakm simgelerden ibarettir. Elbette
doada 2 veya 7 diye bir ey bulunmaz. Bizim yaygn olarak yukardaki ekilde gsterdiimiz
rakamlar Arap rakamlardr. Mesela Romallar yukardakiler yerine I, II, III, IV, V, VI, VII, VIII,
IX ve X gibi farkl simgeler kullanyordu... Neticede 2 ve II ayn kavrama iaret ediyor. Sadece
kullanlan simgeler birbirinden farkl, o kadar.
Onlu sayma sisteminde bir sayy oluturan rakamlar 10 un kuvvetleri olarak hesaplanr.
rnein 1980 saysn ele alalm. Bu sayy 10 un kuvvetlerini kullanarak u ekilde
hesaplayabiliriz:
>>> (0 * (10 ** 0)) + (8 * (10 ** 1)) + (9 * (10 ** 2)) + (1 * (10 ** 3))
1980
Grdnz gibi, saynn en sandaki basamak 10 un 0. kuvveti olacak ekilde, sola doru
kuvveti artrarak ilerliyoruz.
Gelelim teki sayma sistemlerine...
450
Bu sistemde 7 den byk bir sayy gstermek gerektiinde, tpk onlu sistemde olduu
gibi, simge listesinin en bana dnyoruz ve basamak saysn bir artrarak sembolleri
birletiriyoruz:
10, 11, 12, 13, 14, 15, 16, 17, 20, ..., 77, 100
Onlu sayma sistemi ile sekizli sayma sistemi arasndaki fark daha belirgin bir ekilde
grebilmek iin u kodlar yazalm:
say_sistemleri = ["onlu", "sekizli"]
print(("{:^5} "*len(say_sistemleri)).format(*say_sistemleri))
for i in range(17):
print("{0:^5} {0:^5o}".format(i))
sekizli
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
20
Grdnz gibi, onlu sistemde elimizde toplam on farkl simge olduu iin, elimizdeki
simgeleri kullanarak 10. sayya kadar ilerleyebiliyoruz. Bu noktadan sonra simge stoumuz
tkendii iin en baa dnp bir basamak artryoruz ve simgeleri birbiriyle birletirerek yeni
saylar elde ediyoruz.
Sekizli sistemde ise elimizde yalnzca sekiz farkl simge olduu iin, elimizdeki simgeleri
kullanarak ancak 8. sayya kadar gelebiliyoruz. teki saylar gsterebilmek iin bu noktadan
sonra baa dnp bir artrmamz ve simgeleri birbiriyle birletirerek yeni saylar elde etmemiz
gerekiyor.
Sekizli sayma sisteminde bir sayy oluturan rakamlar 8 in kuvvetleri olarak hesaplanr.
rnein sekizli sayma sistemindeki 3674 saysn ele alalm. Bu sayy 8 in kuvvetlerini
kullanarak u ekilde hesaplayabiliriz:
>>> (4 * (8 ** 0)) + (7 * (8 ** 1)) + (6 * (8 ** 2)) + (3 * (8 ** 3))
1980
451
Bu hesaplama eklini onlu sayma sisteminden hatrlyor olmalsnz. Grdnz gibi, sekizli
sistemdeki bir saynn her bir basaman 8 in kuvvetleri olarak hesapladmzda, bu saynn
onlu sistemdeki karln elde ediyoruz.
sekizli
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
20
on altl
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
10
Grdnz gibi, onlu sistemde birbirinden farkl toplam 10 adet rakam/simge varken, sekizli
sistemde toplam 8 farkl simge, on altl sistemde ise toplam 16 farkl simge var. Yani onlu
sistemde olas btn saylar eldeki 10 farkl simge ve bunlarn kombinasyonunun kullanlmas
yoluyla; sekizli sistemde 8 farkl simge ve bunlarn kombinasyonunun kullanlmas yoluyla;
on altl sistemde ise 16 farkl simge ve bunlarn kombinasyonunun kullanlmas yoluyla
gsteriliyor. Bu sebeple onlu sistemde 9 saysndan itibaren bir basamak artrlp simge
listesinin bana dnlrken, sekizli sistemde 7 saysndan itibaren; on altl sistemde ise f
saysndan itibaren baa dnlyor.
452
On altl sistemde 9 saysndan sonra gelen hareri yadrgam olabilirsiniz. Bu durumu yle
dnn: Say dediimiz eyler insan icad birtakm simgelerden ibarettir. Daha nce de
sylediimiz gibi, doada 2 veya 7 diye bir ey gremezsiniz...
te on altlk sistemdeki saylar gsterebilmek iin de birtakm simgelere ihtiya var. lk
on simge, onluk sayma sistemindekilerle ayn. Ancak 10 dan sonraki saylar gsterebilmek
iin elimizde baka simge yok. On altlk sistemi tasarlayanlar, bir tercih sonucu olarak, eksik
sembolleri alfabe hareriyle tamamlamay tercih etmiler. Alfabe hareri yerine pekala Roma
rakamlarn da tercih edebilirlerdi. Eer bu sistemi tasarlayanlar byle tercih etmi olsayd
bugn on altlk sistemi yle gsteriyor olabilirdik:
0
1
2
3
4
5
6
7
8
9
I
II
III
IV
V
VI
Bugn bu saylar bu ekilde kullanmyor olmamzn tek sebebi, sistemi tasarlayanlarn bunu
byle tercih etmemi olmasdr...
On altl sayma sisteminde bir sayy oluturan rakamlar 16 nn kuvvetleri olarak hesaplanr.
Peki ama bu sayma sistemindeki a, b, c, d, e ve f hareriyle nasl aritmetik ilem yapacaz?
rnein on altl sayma sistemindeki 7bc saysn ele alalm. Bu saynn onlu sistemdeki
karln 16 nn kuvvetlerini kullanarak hesaplayabiliriz hesaplamasna, ama peki yukarda
bahsettiimiz harer ne olacak? Yani yle bir ilem tabii ki mmkn deil:
>>> ((c * 16 ** 0)) + ((b * 16 ** 1)) + ((7 * 16 ** 2))
453
Demek ki on altl sistemdeki 7bc saysnn onlu sistemdeki karl 1980 mi.
sekizli
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
20
on altl
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
10
ikili
0
1
10
11
100
101
110
111
1000
1001
1010
1011
1100
1101
1110
1111
10000
Burada, onlu, sekizli ve on altl say sistemleri iin geerli olan durumun aynen ikili say
sistemi iin de geerli olduunu rahatlkla grebiliyoruz. kili say sistemindeki mevcut saylar
gsterebilmemiz iin toplam iki farkl simge var. Bunlar: 0 ve 1. kili say sisteminde 0
ve 1 diye saymaya balayp nc sayy sylememiz gerektiinde, elimizde 0 ve 1 den
baka simge olmad iin bir basamak artrp simge listesinin bana dnyoruz ve bylece
onluk dzendeki 2 saysn ikili dzende gsterebilmek iin 0 ve 1 den sonra 10 simgesini
kullanyoruz.
Bu sylediklerimizden sonra nternet zerinde ska karlatnz u szn anlamn
herhalde artk daha iyi anlyor olmalsnz:
454
Bu fonksiyonun kt olarak bir karakter dizisi verdiine dikkat edin. Bu karakter dizisinin
ilk iki karakteri (0b ), o saynn ikili sisteme ait bir say olduunu gsteren bir iarettir. Bu
bilgilerden yola karak, yukardaki karakter dizisinin gerek ikili ksmn almak iin u yntemi
kullanabilirsiniz:
>>> bin(2)[2:]
'10'
hex()
Bu fonksiyon, herhangi bir sayy alp, o saynn on altl sistemdeki karln verir:
455
>>> hex(10)
'Oxa'
Tpk bin() fonksiyonunda olduu gibi, hex() fonksiyonunun da kt olarak bir karakter dizisi
verdiine dikkat edin. Hatrlarsanz bin() fonksiyonunun ktsndaki ilk iki karakter (0b ),
o saynn ikili sisteme ait bir say olduunu gsteren bir iaret olarak kullanlyordu. hex()
fonksiyonunun ktsndaki ilk iki karakter de (0x ), o saynn on altl sisteme ait bir say
olduunu gsteriyor.
oct()
Bu fonksiyon, herhangi bir sayy alp, o saynn sekizli sistemdeki karln verir:
>>> oct(10)
'0o12'
Tpk bin() ve hex() fonksiyonlarnda olduu gibi, oct() fonksiyonunun da kt olarak bir
karakter dizisi verdiine dikkat edin. Hatrlarsanz bin() ve hex() fonksiyonlarnn ktsndaki
ilk iki karakter (0b ve 0x ), o saylarn hangi sisteme ait saylar olduunu gsteriyordu. Ayn
ekilde oct() fonksiyonunun ktsndaki ilk iki karakter de (0o ), o saynn sekizli sisteme ait
bir say olduunu gsteriyor.
int()
Aslnda biz bu fonksiyonu yakndan tanyoruz. Bildiiniz gibi bu fonksiyon herhangi bir say
veya say deerli karakter dizisini tam sayya (integer ) dntrmek iin kullanlyor. int()
fonksiyonunun imdiye kadar grdmz ilevi dnda bir ilevi daha bulunur: Biz bu
fonksiyonu kullanarak herhangi bir sayy onlu sistemdeki karlna dntrebiliriz:
>>> int('7bc', 16)
1980
Grdnz gibi, bu fonksiyonu kullanrken dikkat etmemiz gereken baz noktalar var.
lkin, eer int() fonksiyonunu yukardaki gibi bir dntrme ilemi iin kullanacaksak,
bu fonksiyona verdiimiz ilk parametrenin bir karakter dizisi olmas gerekiyor. Dikkat
etmemiz gereken ikinci nokta, int() fonksiyonuna verdiimiz ikinci parametrenin nitelii. Bu
parametre, dntrmek istediimiz saynn hangi tabanda olduunu gsteriyor. Yukardaki
rnee gre biz, on alt tabanndaki 7bc saysn on tabanna dntrmek istiyoruz.
Bir de u rneklere bakalm:
>>> int('1100', 2)
12
>>> int('1100', 16)
4352
lk rnekte, ikili sistemdeki 1100 saysn onlu sisteme eviriyoruz ve 12 saysn elde ediyoruz.
kinci rnekte ise on altl sistemdeki 1100 saysn onlu sisteme eviriyoruz ve 4352 saysn
456
elde ediyoruz.
Bu arada, yukarda bir saynn, karakter dizisi biimlendirme yntemleri kullanlarak ikili,
sekizli ve on altl dzene nasl evrileceini grdk. Bir sayy onlu dzene evirmek
iin ise sadece int() fonksiyonunu kullanabiliyoruz. Byle bir evirme ilemini karakter
dizisi biimlendirme yntemlerini kullanarak yapamyoruz. Ama elbette, eer baka bir
457
sayma sisteminden onlu sisteme evirdiiniz bir sayy herhangi bir karakter dizisi iinde
biimlendirmek isterseniz yle bir kod kullanabilirsiniz:
>>> n = '7bc'
>>> "{} saysnn onlu karl {:d} saysdr.".format(n, int(n, 16))
...veya:
>>> n = '7bc'
>>> "{} saysnn onlu karl {} saysdr.".format(n, int(n, 16))
Zira bildiiniz gibi, Pythonda onlu saylar temsil eden harf d hardir. Eer {} yaps
iinde herhangi bir harf kullanmazsanz yukardaki durumda Python {:d} yazmsnz gibi
davranacaktr.
458
(...)
255 11111111 ff
>>>
Grdnz gibi, onlu sistemde 255 eklinde, ikili sistemde ise 11111111 eklinde gsterilen
say on altl sistemde yalnzca ff eklinde gsterilebiliyor. Dolaysyla, kullanm asndan,
biz insanlar iin on altlk sayma sisteminin ikili sisteme kyasla ok daha pratik bir yntem
olduunu syleyebiliriz.
Ayrca on altl sistem, az alana ok veri sdrabilme zellii nedeniyle HTML renk
kodlarnn gsterilmesinde de tercih edilir. rnein beyaz rengi temsil etmek iin on altl
sistemdeki #FFFFFF ifadesini kullanmak rgb(255,255,255) ifadesini kullanmaya kyasla ok
daha mantkldr. Hatta #FFFFFF ifadesini #FFF eklinde ksaltma imkan dahi vardr.
459
BLM 28
Saylar
Geen blmde sayma sistemlerini ayrntl bir ekilde inceledik. Bu blmde ise yine
bununla balantl bir konu olan saylar konusunu ele alacaz. Esasnda biz saylarn ne
olduuna ve Pythonda bunlarn nasl kullanlacana dair tamamen bilgisiz deiliz. Buraya
gelene kadar, saylar konusunda epey ey syledik aslnda. Mesela biz Pythonda tr say
olduunu biliyoruz:
1. Tam Saylar (integers )
2. Kayan Noktal Saylar (oating point numbers veya ksaca oats )
3. Karmak Saylar (complex numbers )
Eer bir veri type(veri) sorgulamasna int cevab veriyorsa o veri bir tam saydr. Eer bir
veri type(veri) sorgulamasna oat cevab veriyorsa o veri bir kayan noktal saydr. Eer bir
veri type(veri) sorgulamasna complex cevabn veriyorsa o veri bir karmak saydr.
Mesela unlar birer tam saydr:
15, 4, 33
unlar birer kayan noktal saydr:
3.5, 6.6, 2.3
unlarsa birer karmak saydr:
3+3j, 5+2j, 19+10j
Ayrca imdiye kadar rendiklerimiz sayesinde bu saylarn eitli fonksiyonlar yardmyla
birbirlerine dntrlebileceini de biliyoruz:
Fonksiyon
int()
float()
complex()
Grevi
Bir veriyi tam sayya dntrr
Bir veriyi kayan noktal sayya dntrr
Bir veriyi karmak sayya dntrr
rnek
int(2)
float(2)
complex(2)
460
Bu listede imdilik bizi ilgilendiren tek bir metot var. Bu metodun ad bit_length().
bit_length()
Bilgisayarlar hakknda bilmemiz gereken en nemli bilgilerden biri udur: Bilgisayarlar ancak
ve ancak saylarla ilem yapabilir. Bilgisayarlarn ilem yapabildii saylar da onlu sistemdeki
saylar deil, ikili sistemdeki saylardr. Yani 0lar ve 1ler.
Bilgisayar terminolojisinde bu 0lar ve 1lerden oluan herbir basamaa bit ad verilir. Yani
ikili sayma sisteminde 0 ve 1 saylarndan herbiri 1 bittir. Mesela onlu sistemde 2 saysnn
ikili sistemdeki karl olan 10 says iki bitlik bir saydr. Onlu sistemdeki 100 saysnn ikili
sistemdeki karl olan 1100100 says ise yedi bitlik bir saydr.
Bu durumu daha net bir ekilde grebilmek iin u kodlar yazalm:
>>> for i in range(11):
...
print(i, bin(i)[2:], len(bin(i)[2:]), sep="\t")
...
0
0
1
1
1
1
2
10
2
3
11
2
4
100
3
5
101
3
6
110
3
7
111
3
8
1000
4
9
1001
4
10
1010
4
Burada ikinci stundaki saylar ilk stundaki saylarn ikili sistemdeki karlklardr. nc
stundaki saylar ise her bir saynn ka bit olduunu, yani bir bakma ikili sayma sisteminde
ka basamaa sahip olduunu gsteriyor.
te herhangi bir tam saynn ka bitlik bir yer kapladn renmek iin, tam saylarn
metotlarndan biri olan bit_length() metodundan yararlanacaz:
461
>>> say = 10
>>> say.bit_length()
4
Demek ki 10 says bellekte drt bitlik bir yer kaplyormu. Yani bu saynn ikili sistemdeki
karl olan 1010 says drt basamaktan oluuyormu.
Yukardaki rneklerden de rahatlkla karabileceiniz gibi, bit_length() metodu, ikili sayma
sistemindeki bir say zerine len() fonksiyonunun uygulanmas ile edeerdir. Yani:
>>> len(bin(10)[2:]) == (10).bit_length()
True
Bu arada u son rnekte bir ey dikkatinizi ekmi olmal: bit_length() metodunu dorudan
saylar zerine uygulayamyoruz. Yani:
>>> 10.bit_length()
File "<stdin>", line 1
10.bit_length()
^
SyntaxError: invalid syntax
Bu metodu saylarla birlikte kullanabilmek iin iki seeneimiz var: bit_length() metodunu
uygulamak istediimiz sayy nce bir deikene atayabiliriz:
>>> a = 10
>>> a.bit_length()
4
Bu durum, yani sayy parantez iinde gsterme zorunluluu, 10 saysnn sana bir nokta
iareti koyduumuzda, Pythonn bu sayy bir kayan noktal say olarak deerlendirmesinden
kaynaklanyor. Yani biz 10 yazp, bit_length() metodunu bu sayya balama amacyla
saynn sana bir nokta koyduumuz anda, Python bu saynn bir kayan noktal say olduunu
zannediyor. nk Python asndan, 10. says bir kayan noktal saydr. Bunu teyit edelim:
>>> type(10.)
<class 'float'>
Kayan noktal saylarn bit_length() adl bir metodu olmad iin de Pythonn bize bir hata
mesaj gstermekten baka yapabilecei bir ey kalmyor.
462
te as_integer_ratio()
is_integer()
Bir kayan noktal saynn ondalk ksmnda 0 harici bir saynn olup olmadn kontrol etmek
iin bu metodu kullanyoruz. rnein:
>>> (12.0).is_integer()
True
>>> (12.5).is_integer()
False
Grdnz gibi, karmak saylarn da birka tane metot ve nitelii var. Biz bunlar arasndan
imag ve real adl nitelikleri inceleyeceiz.
imag
Bir gerek bir de sanal ksmdan oluan saylara karmak saylar (complex ) ad verildiini
biliyorsunuz. rnein u bir karmak saydr:
12+4j
te imag adl nitelik, bize bir karmak saynn sanal ksmn verir:
463
>>> c = 12+4j
>>> [Link]
4.0
real
real adl nitelik bize bir karmak saynn gerek ksmn verir:
>>> c = 12+4j
>>> [Link]
12.0
464
28.2.1 abs()
Bu fonksiyon bize bir saynn mutlak deerini verir:
>>> abs(-2)
2
>>> abs(2)
2
28.2.2 divmod()
Bu fonksiyon, bir saynn bir sayya blnmesi ileminde blm ve kalan verir:
>>> divmod(10, 2)
(5, 0)
Bu fonksiyonun gerekletirdii blme ileminin bir taban blme ilemi olduuna zellikle
dikkatinizi ekmek istiyorum.
28.2.3 max()
Size yle bir soru sorduumu dnn: Acaba aadaki listede yer alan saylarn en by
katr?
[882388,
239479,
773607,
893126,
915106,
462902,
105779,
220075,
634295,
666182,
860937,
616293,
402324,
354050,
850804,
960182,
465
te byle bir soruyu zmek iin max() fonksiyonundan yararlanabilirsiniz. Yukardaki listeyi
saylar adl bir deikene atadmz varsayarsak, aadaki kod bize listedeki en byk sayy
verecektir:
>>> max(saylar)
Yukardaki rneklerde max() fonksiyonunu kullanarak bir dizi iindeki en byk sayy bulduk.
Peki bu fonksiyonu kullanarak bir dizi iindeki en uzun karakter dizisini bulabilir miyiz? Evet,
bulabiliriz.
Diyelim ki elimizde yle bir liste var:
isimler = ["ahmet", "mehmet", "necla", "sedat", "abdullah",
"gyaseddin", "sibel", "can", "necmettin", "sava", "zgr"]
print(max(isimler, key=len))
Bu kodlar, farkl sayma sistemleri arasndaki farklar daha net grmemizi salamt. Yalnz
burada dikkat ettiyseniz, say_sistemleri adl listeye her e ekleyiimizde, listedeki en
uzun deeri dikkate alarak karakter dizisi biimlendiricileri iindeki, eler arasnda ne
kadar boluk braklacan belirleyen saylar gncelliyorduk. Mesela yukardaki rnekte,
eler arasnda yeterince boluk brakabilmek iin bu sayy 9 olarak belirlemitik. te
imdi rendiimiz max() fonksiyonunu kullanarak bu saynn otomatik olarak belirlenmesini
salayabiliriz. Dikkatlice inceleyin:
466
28.2.4 min()
Bu fonksiyon, max() fonksiyonun yapt iin tam tersini yapar. Yani bu fonksiyonu kullanarak
bir dizi iindeki en kk sayy bulabilirsiniz:
>>> min(saylar)
28.2.5 sum()
Bu fonksiyon bir dizi iinde yer alan btn saylar birbiriyle toplar. rnein:
>>> a = [10, 20, 43, 45 , 77, 2, 0, 1]
>>> sum(a)
198
Eer bu fonksiyonun, toplama ilemini belli bir saynn zerine gerekletirmesini istiyorsanz
u kodu yazabilirsiniz:
>>> sum(a, 10)
208
sum() fonksiyonuna bu ekilde ikinci bir parametre verdiinizde, bu ikinci parametre toplam
deere eklenecektir.
467
BLM 29
Not: open() fonksiyonu dosya_ad ve kip dnda baka parametreler de alr. lerleyen
sayfalarda bu parametrelerden de sz edeceiz.
468
Mesela [Link] adl bir dosyay yazma kipinde amak iin yle bir komut kullanyoruz:
tahsilat_dosyas = open("tahsilat_dosyas.txt", "w")
Eer dosya adn dizin belirtmeden yazarsanz, oluturduunuz dosya, o anda hangi dizin
altnda bulunuyorsanz orada oluacaktr.
Ayrca dosyay barndran dizin adlarn yazarken, dizinleri ayrmak iin ters taksim (\ ) yerine
dz taksim (/ ) kullanmaya dikkat edin. Aksi halde, dizin ad oluturmaya alrken yanllkla
ka dizileri oluturabilirsiniz. Esasnda siz bu olguya hi yabanc deilsiniz. Zira ka
dizilerini anlatrken yle bir rnek verdiimizi hatrlyor olmalsnz:
print("C:\aylar\nisan\toplam masraf")
te eer bu rnekte olduu gibi ters taksim iaretleri ile oluturulmu dizin adlar
kullanrsanz programnz hata verecektir:
>>> open("C:\aylar\nisan\toplam masraf\[Link]", "w")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'C:\x07ylar\nisan\toplam masraf\[Link]'
Bunun sebebi, bildiiniz gibi, Pythonn \a, \n ve \t ifadelerini birer ka dizisi olarak
alglamasdr. Bu durumdan kaabilmek iin, dizin adlarn ters taksim iareti ile ayrmann
dnda, r adl ka dizisinden de yararlanabilirsiniz:
>>> open(r"C:\aylar\nisan\toplam masraf\[Link]", "w")
Bu ekilde, eer bilgisayarnzda C:\aylar\nisan\toplam masraf\ adl bir dizin varsa, o dizin
iinde [Link] adl bir dosya oluturulacaktr.
Bylece Python programlama dilinde bo bir dosyann nasl oluturulacan renmi olduk.
O halde gelin isterseniz imdi bu dosyann iini nasl dolduracamz renelim.
469
Python programlama dilinde, open() fonksiyonu ile yazma kipinde atmz bir dosyaya bir
veri yazabilmek iin dosyalarn write() adl metodundan yararlanacaz.
Siz aslnda bu metodun da nasl kullanlacan ok iyi biliyorsunuz:
[Link](yazlacak_eyler)
Eer dosyay atnzda bu bilgi yerine hl bo bir dosya gryorsanz, sebebi tamponda
tutulan verilerin henz dosyaya ilenmemi olmasdr.
Not: Bu konuyu print() fonksiyonunun ush adl parametresini incelerken rendiimizi
hatrlyor olmalsnz.
Eer durum byleyse, dosyanz kapatmanz gerekiyor. Bunu close() adl baka bir metotla
yapabildiimizi biliyorsunuz:
[Link]()
470
Bir dosyay open() fonksiyonu yardmyla aarken kip parametresi iin r harni kullanrsak,
Python o dosyay okuma yetkisiyle aacaktr. Yalnz burada yle bir zellik var: Eer bir
dosyay okuma kipinde aacaksanz, bu r harni hi belirtmeseniz de olur. Yani u komut
bilgisayarmzdaki [Link] adl dosyay okuma kipinde aacaktr:
fihrist = open("[Link]")
Dolaysyla bir dosyay aarken kip belirtmediimizde Python bizim o dosyay okuma kipinde
amak istediimizi varsayacaktr.
Hatrlarsanz, w kipiyle atmz bir dosyaya yazmak iin write() adl bir metottan
yararlanyorduk. r kipiyle atmz bir dosyay okumak iin ise read(), readline() ve
readlines() adl farkl metottan yararlanacaz.
Yukardaki metot da Pythonda dosya okuma ilemlerini gerekletirmemizi salar. Peki bu
metotlarn de ayn ii yapyorsa neden tek bir metot deil de farkl metot var?
Bu metotlarn de dosya okumaya yarasa da, verdikleri ktlar birbirinden farkldr. O
yzden farkl amalar iin farkl metodu kullanmanz gereken durumlarla karlaabilirsiniz.
Bu metotlar arasndaki fark anlamann en kolay yolu bu metodu srayla kullanp, ktlar
incelemektir.
ncelikle ierii u olan, [Link] adl bir dosyamzn olduunu varsayalm:
471
Grdnz gibi, read() metodu bize, dosyann btn ieriini bir karakter dizisi olarak
veriyor. Bir de una bakalm:
fihrist = open("[Link]")
print([Link]())
read() metodu bize dosya ieriinin tamamn veriyordu. Grdnz gibi readline()
metodu tek bir satr veriyor. Yani bu metot yardmyla dosyalar satr satr okuyabiliyoruz.
Bu metodun ileyi tarzn daha iyi grebilmek iin bu kodlar dosyaya yazp altrmak yerine
etkileimli kabuk zerinden de altrabilirsiniz:
>>> fihrist = open("[Link]", "r")
>>> print([Link]())
Ahmet zbudak : 0533 123 23 34
>>> print([Link]())
Mehmet Sln
: 0532 212 22 22
>>> print([Link]())
Sami Sam
: 0542 333 34 34
472
>>> print([Link]())
Grdnz gibi, bu defa karakter dizisi yerine bir liste ile karlayoruz. Demek ki read() ve
readline() metotlar kt olarak bize bir karakter dizisi verirken, readlines() metodu liste
veriyormu. Bunun neden nemli bir bilgi olduunu artk gayet iyi biliyor olmanz lazm. Zira
bir verinin tipi, o veriyle neler yapp neler yapamayacamz dorudan etkiler...
473
except...
Bu yntem gayet uygun ve iyi bir yntemdir. Ancak Python bize bu tr durumlar iin ok daha
pratik bir yntem sunar. Dikkatlice bakn:
with open("dosyaad", "r") as dosya:
print([Link]())
474
yerde bir ylan figr ile temsil\nedilmesi neredeyse bir gelenek halini
almtr.\n'
Burada open() fonksiyonunu kullanarak [Link] adl bir dosyay ap, read() metodu
yardmyla da bu dosyann ieriini okuduk. Bu noktada dosyay tekrar okumaya alrsak
elde edeceimiz ey bo bir karakter dizisi olacaktr:
>>> [Link]()
''
nk dosya bir kez tamamen okunduktan sonra imle otomatik olarak baa dnmyor.
Dosyay tekrar okumak istiyorsak, bunu baa bizim sarmamz lazm. te bunun iin seek()
metodunu kullanacaz:
>>> [Link](0)
Grdnz gibi seek() metodunu bir parametre ile birlikte kullandk. Bu metoda verdiimiz
parametre, dosya iinde kanc bayt konumuna gideceimizi gsteriyor. Biz burada 0
saysn kullanarak dosyann ilk baytna, yani en bana dnm olduk. Artk dosyay tekrar
okuyabiliriz:
>>> [Link]()
'Bu programlama dili Guido Van Rossum adl Hollandal bir
programc\ntarafndan 90l yllarn banda gelitirilmeye balanmtr.
ou insan,\nisminin Python olmasna aldanarak, bu programlama dilinin,
adn piton\nylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin\nad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty\nPython adl bir ngiliz komedi grubunun,
Monty Pythons Flying Circus adl\ngsterisinden esinlenerek adlandrmtr.
Ancak her ne kadar gerek byle olsa\nda, Python programlama dilinin pek ok
yerde bir ylan figr ile temsil\nedilmesi neredeyse bir gelenek halini
almtr.\n'
Eer o anda dosyann hangi bayt konumunda bulunduunuzu renmek isterseniz de tell()
adl baka bir metottan yararlanabilirsiniz. Bu metodu parametresiz olarak kullanyoruz:
>>> [Link]()
20
475
rnein yukarda verdiimiz [Link] adl dosyay bu kipte aalm ve dosyaya yeni bir girdi
ekleyelim:
with open("[Link]", "a") as f:
[Link]("Selin zden\t: 0212 222 22 22")
Grdnz gibi, dosyaya yeni eklediimiz girdiler otomatik olarak dosyann sonuna ilave
ediliyor. Burada u noktaya dikkat etmeniz lazm. Dosyann sonunda bir satr ba
karakterinin (\n ) bulunup bulunmamasna bal olarak, dosyaya eklediiniz yeni satrlar
dzgn bir ekilde bir alt satra geebilecei gibi, dosyann son satrnn yanna da eklenebilir.
Dolaysyla duruma gre yukardaki satr u ekilde yazmanz gerekebilir:
with open("[Link]", "a") as f:
[Link]("\nSelin zden\t: 0212 222 22 22")
Burada bir alt satra geebilmek iin Selin ifadesinden nce bir satr ba karakteri
eklediimize dikkat edin. Ayrca eer bu satrdan sonra bir baka satr daha ekleyecekseniz,
ilgili satrn sonuna da bir satr ba karakteri koymanz gerekebilir:
with open("[Link]", "a") as f:
[Link]("Selin zden\t: 0212 222 22 22\n")
Kar karya olduunuz duruma gre, satr ba karakterlerine ihtiyacnz olup olmadn ve
ihtiyacnz varsa bunlar nereye yerletireceinizi kendiniz deerlendirmelisiniz.
476
:
:
:
:
0533
0532
0542
0212
123
212
333
222
23
22
34
22
34
22
34
22
Dosya ierii bu. Eer bu dosyay a kipi ile atktan sonra dorudan write() metodunu
kullanarak bir ekleme yaparsak, yeni deer dosyann sonuna eklenecektir. Ama biz mesela u
veriyi:
Sedat Kz
: 0322 234 45 45
Ahmet zbudak : 0533 123 23 34 girdisinin hemen stne, yani dosyann sonuna deil de
en bana eklemek istersek ne yapacaz?
ncelikle u kodlar deneyelim:
with open("[Link]", "r") as f:
veri = [Link]()
[Link](0) #Dosyay baa saryoruz
[Link]("Sedat Kz\t: 0322 234 45 45\n"+veri)
Grdnz gibi, bu kez de dosyann okunamadna ilikin bir hata alyoruz. nk biz bu
kez de dosyay yazma kipinde atk. Ancak burada yle bir durum var. Bildiiniz gibi, bir
dosyay w kipi ile atmzda, Python bize hibir ey sormadan varolan ierii silecektir.
Burada da yukarda yazdmz kodlar yznden dosya ieriini kaybettik. Unutmayn, dosya
okuma-yazma ilemleri belli bir takm riskleri iinde barndrr. O yzden bu tr ilemleri
yaparken fazladan dikkat gstermeliyiz.
29.6. Dosyalarda Deiiklik Yapmak
477
Burada r+ adl yeni bir kip kullandmza dikkat edin. + iareti bir dosyay hem okuma
hem de yazma kipinde amamza yardmc olur. te bu iareti r kipiyle birlikte r+ eklinde
kullanarak dosyamz hem okuma hem de yazma kipinde amay baardk. Artk ilgili dosya
zerinde hem okuma hem de yazma ilemlerini ayn anda gerekletirebiliriz.
Yukardaki kodlarda ilk satrn ardndan yle bir kod yazdk:
veri = [Link]()
Bylece dosyann btn ieriini veri adl bir deikene atam olduk.
yapmazsak ne olur? Yani mesela yle bir kod yazarsak:
Peki bu ilemi
Bu ekilde Sedat Kz\t: 0322 234 45 45\n satr, dosyadaki ilk satr silip onun yerine
geecektir. nk [Link](0) ile dosyann bana dnp o noktaya, yani dosyann ilk satrna
bir veri ekledikten sonra Python br satrlar otomatik olarak bir alt satra kaydrmaz. Bunun
yerine ilk satrdaki verileri silip onun yerine, yeni eklenen satr getirir. Eer yapmak istediiniz
ey buysa ne l. Bu kodlar kullanabilirsiniz. Ama bizim istediimiz ey bu deil. O yzden
veri = [Link]() satrn kullanarak dosya ieriini bir deiken iinde depoluyoruz ve bylece
bu verileri kaybetmemi oluyoruz.
Bu satrn ardndan gelen [Link](0) satrnn ne ie yaradn biliyorsunuz. Biz yeni veriyi
dosyann en bana eklemek istediimiz iin, doal olarak bu kod yardmyla dosyann en
bana saryoruz. Bylece u kod:
[Link]("Sedat Kz\t: 0322 234 45 45\n"+veri)
Sedat Kz\t: 0322 234 45 45\n satrn dosyann en bana ekliyor. Ayrca burada, biraz nce
veri deikenine atadmz dosya ieriini de yeni eklediimiz satrn hemen arkasna ilave
ettiimize dikkat edin. Eer bunu yapmazsanz, elinizde sadece Sedat Kzn iletiim bilgilerini
barndran bir dosya olacaktr...
Bu kodlar bir dosyaya kaydedip altrdysanz, istediimiz ilemi baaryla yerine getirdiini
grmsnzdr. Peki ama bu kodlar nasl alyor?
Yukardaki kodlarda dikkatimizi eken pek ok zellik var. lk olarak gzmze arpan
ey, dosyay r+ kipinde am olmamz. Bu ekilde dosyay hem okuma hem de yazma
kipinde am oluyoruz. nk dosyada ayn anda hem okuma hem de yazma ilemleri
gerekletireceiz.
Daha sonra yle bir satr yazdk:
veri = [Link]()
Bu sayede dosyadaki btn verileri bir liste olarak alm olduk. Liste adl veri tipi ile ne
yapabiliyorsak, bu ekilde aldmz dosya ierii zerinde de ayn eyleri yapabiliriz. Bizim
amacmz bu listenin 2. srasna yeni bir satr eklemek. Bu ilemi listelerin insert() adl
metodu yardmyla rahatlkla yapabiliriz:
[Link](2, "Sedat Kz\t: 0322 234 45 45\n")
Bu ekilde liste zerinde istediimiz deiiklikleri yaptktan sonra tekrar dosyann bana
dnmemiz lazm. nk readlines() metoduyla dosyay bir kez tam olarak okuduktan sonra
imle o anda dosyann en sonunda bulunuyor. Eer dosyann en bana dnmeden herhangi
bir yazma ilemi gerekletirirsek, yazlan veriler dosyann sonuna eklenecektir. Bizim
yapmamz gereken ey dosyann en bana sarp, deitirilmi verilerin dosyaya yazlmasn
salamak olmal. Bunu da u satr yardmyla yapyoruz:
[Link](0)
imdiye kadar dosyaya yazma ilemleri iin write() adl bir metottan yararlanmtk. Burada
ise writelines() adl baka bir metot gryoruz. Peki bu iki metot arasndaki fark nedir?
write() metodu bir dosyaya yalnzca karakter dizilerini yazabilir. Bu metot yardmyla
dosyaya liste tipinde herhangi bir veri yazamazsnz. Eer mutlaka write() metodunu
29.6. Dosyalarda Deiiklik Yapmak
479
kullanmak isterseniz, liste zerinde bir for dngs kurmanz gerekir. O zaman yukardaki
kodlar yle yazmanz gerekir:
with open("[Link]", "r+") as f:
veri = [Link]()
[Link](2, "Sedat Kz\t: 0322 234 45 45\n")
[Link](0)
for e in veri:
[Link](e)
writelines() adl metot ise bize dosyaya liste tipinde verileri yazma imkan verir. Dolaysyla
herhangi bir dng kurmak zorunda kalmadan listeleri dosyalarmza yazabiliriz.
Bylece Pythonda dosyalarn herhangi bir yerine nasl yazabileceimizi renmi olduk. Bu
arada eer isteseydik yukardaki kodlar yle de yazabilirdik:
with open("[Link]", "r") as f:
veri = [Link]()
with open("[Link]", "w") as f:
[Link](2, "Sedat Kz\t: 0322 234 45 45\n")
[Link](veri)
Bir nceki kodlardan farkl olarak bu kodlarda dosyamz nce okuma kipinde ap verileri
veri adl bir deiken iinde sakladk. Ardndan ayn dosyay bir kez de yazma kipinde aarak,
gerekli deiiklikleri liste zerinde gerekletirdikten sonra btn verileri dosyaya yazdk.
Unutmayn, Pythonda herhangi bir ilemi pek ok farkl ekilde gerekletirebilirsiniz. Biz
yukarda olas yntemlerden bazlarn ele aldk. Zaten btn yntemleri tek tek gstermemiz
pek mmkn olmazd. Siz dosyalara ilikin bilgilerinizi ve farkl aralar kullanarak ayn
ilemleri ok daha farkl ekillerde de yapabilirsiniz. Yani kar karya olduunuz duruma
deerlendirip, yukardaki kodlardan uygun olann veya kendi bulduunuz bambaka bir
yntemi kullanabilirsiniz.
Bu arada, aslnda yukardaki kodlarda uyguladmz yntem biraz gvensiz. nk ayn
dosyay hem okuyup hem de bu dosyaya yeni veri ekliyoruz. Eer bu ilemlerin herhangi
bir aamasnda bir hata oluursa, btn deiiklikleri dosyaya ileyemeden dosya ieriini
tmden kaybedebiliriz. Bu tr risklere kar en uygun zm, okuma ve yazma ilemlerini ayr
dosyalar zerinde gerekletirmektir. Bunun nasl yaplacandan biraz sonra sz edeceiz.
Biz imdi baka bir konuya deinelim.
480
Kip
"r"
Aklamas
Bu ntanml kiptir. Bu kip dosyay okuma yetkisiyle aar. Ancak bu kipi
kullanabilmemiz iin, ilgili dosyann disk zerinde halihazrda var olmas gerekir.
Eer bu kipte almak istenen dosya mevcut deilse Python bize bir hata mesaj
gsterecektir. Dediimiz gibi, bu ntanml kiptir. Dolaysyla dosyay aarken
herhangi bir kip belirtmezsek Python dosyay bu kipte amak istediimizi
varsayacaktr.
"w" Bu kip dosyay yazma yetkisiyle aar. Eer belirttiiniz adda bir dosya zaten disk
zerinde varsa, Python hibir ey sormadan dosya ieriini silecektir. Eer
belirttiiniz adda bir dosya diskte yoksa, Python o adda bir dosyay otomatik olarak
oluturur.
"a" Bu kip dosyay yazma yetkisiyle aar. Eer dosya zaten disk zerinde mevcutsa
ieriinde herhangi bir deiiklik yaplmaz. Bu kipte atnz bir dosyaya eklediiniz
veriler varolan verilere ilave edilir. Eer belirttiiniz adda bir dosya yoksa Python
otomatik olarak o adda bir dosyay sizin iin oluturacaktr.
"x" Bu kip dosyay yazma yetkisiyle aar. Eer belirttiiniz adda bir dosya zaten disk
zerinde varsa, Python varolan dosyay silmek yerine size bir hata mesaj gsterir.
Zaten bu kipin w kipinden fark, varolan dosyalar silmemesidir. Eer belirttiiniz
adda bir dosya diskte yoksa, bu kip yardmyla o ada sahip bir dosya
oluturabilirsiniz.
"r+" Bu kip, bir dosyay hem yazma hem de okuma yetkisiyle aar. Bu kipi
kullanabilmeniz iin, belirttiiniz dosyann disk zerinde mevcut olmas gerekir.
"w+" Bu kip bir dosyay hem yazma hem de okuma yetkisiyle aar. Eer dosya mevcutsa
ierik silinir, eer dosya mevcut deilse oluturulur.
"a+" Bu kip bir dosyay hem yazma hem de okuma yetkisiyle aar. Eer dosya zaten disk
zerinde mevcutsa ieriinde herhangi bir deiiklik yaplmaz. Bu kipte atnz bir
dosyaya eklediiniz veriler varolan verilere ilave edilir. Eer belirttiiniz adda bir
dosya yoksa Python otomatik olarak o adda bir dosyay sizin iin oluturacaktr.
"x+" Bu kip dosyay hem okuma hem de yazma yetkisiyle aar. Eer belirttiiniz adda bir
dosya zaten disk zerinde varsa, Python varolan dosyay silmek yerine size bir hata
mesaj gsterir. Zaten bu kipin w+ kipinden fark, varolan dosyalar silmemesidir.
Eer belirttiiniz adda bir dosya diskte yoksa, bu kip yardmyla o ada sahip bir
dosya oluturup bu dosyay hem okuma hem de yazma yetkisiyle aabilirsiniz.
"rb" Bu kip, metin dosyalar ile ikili (binary ) dosyalar ayrt eden sistemlerde ikili
dosyalar okuma yetkisiyle amak iin kullanlr. r kipi iin sylenenler bu kip iin
de geerlidir.
"wb" Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar yazma
yetkisiyle amak iin kullanlr. w kipi iin sylenenler bu kip iin de geerlidir.
"ab" Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar yazma
yetkisiyle amak iin kullanlr. a kipi iin sylenenler bu kip iin de geerlidir.
"xb" Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar yazma
yetkisiyle amak iin kullanlr. x kipi iin sylenenler bu kip iin de geerlidir.
"rb+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. r+ kipi iin sylenenler bu
kip iin de geerlidir.
"wb+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. w+ kipi iin sylenenler bu
kip iin de geerlidir.
"ab+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. a+ kipi iin sylenenler bu
kip iin de geerlidir.
"xb+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. x+ kipi iin sylenenler bu
29.7. Dosyaya Erime Kipleri
481
kip iin de geerlidir.
Btn bu tabloya baktnzda ilk bakta sanki bir sr farkl eriim kipi olduunu dnm
olabilirsiniz. Ama aslnda tabloyu biraz daha incelerseniz, temel olarak r, w, a, x ve
b kiplerinin olduunu, geri kalan kiplerin ise bunlarn kombinasyonlarndan olutuunu
greceksiniz.
Daha nce de sylediimiz gibi, dosya ilemlerini pek ok farkl yntemle
gerekletirebilirsiniz. Yukardaki tabloyu dikkatlice inceleyerek, yapmak istediiniz ileme
uygun kipi rahatlkla seebilirsiniz.
Bu arada, yukardaki tabloda deindiimiz ikili (binary ) dosyalardan henz sz etmedik. Bir
sonraki blmde bu dosya trn de ele alacaz.
482
BLM 30
Dosyalara ilikin olarak bir nceki blmde anlattmz eylerin kafanza yatmas asndan
size u bilgiyi de verelim: Dosyalar da, tpk karakter dizileri ve listeler gibi, Python
programlama dilindeki veri tiplerinden biridir. Dolaysyla tpk karakter dizileri ve listeler
gibi, dosya (le ) adl bu veri tipinin de baz metotlar ve nitelikleri vardr. Gelin isterseniz bu
metot ve niteliklerin neler olduunu yle bir listeleyelim:
dosya = open("falanca_dosya.txt", "w")
print(*[metot for metot in dir(dosya) if not [Link]("_")], sep="\n")
Bu kodlar, dosya adl veri tipinin bizi ilgilendiren btn metotlarn alt alta ekrana basacaktr.
Eer yukardaki kodlar anlamakta zorluk ektiyseniz, bunlar yle de yazabilirsiniz:
dosya = open("falanca_dosya.txt", "w")
for metot in dir(dosya):
if not [Link]("_"):
print(metot, sep="\n")
Eer f adl bu dosya kapalysa True kts, aksa False kts verilecektir.
483
kts verir. Ama eer dosya yazma kipinde almsa bu metot bize False kts verecektir.
Bu metot
ngilizcede truncate kelimesi budamak, krpmak gibi anlamlara gelir. Bu metodun yapt i
de bu anlamyla uyumludur. Bu metodu temel olarak yle kullanyoruz:
>>> with open("[Link]", "r+") as f:
...
[Link]()
Bu kodlar, [Link] adl dosyann ilk 10 bayt dndaki btn verileri siler. Yani dosyay
yalnzca 10 baytlk bir boyuta sahip olacak ekilde krpar.
Gelin isterseniz bu metotla ilgili bir rnek verelim. Elimizdeki dosyann u ierie sahip
olduunu varsayalm:
Ahmet zbudak : 0533 123 23 34
Mehmet Sln : 0532 212 22 22
Sami Sam
: 0542 333 34 34
: 0532 212 22 22
: 0542 333 34 34
484
485
'r'
veya:
>>> [Link]
'cp1254' #Windows
486
BLM 31
Dosyalar ounlukla iki farkl snfa ayrlr: Metin dosyalar ve ikili dosyalar. Metin dosyalar
derken neyi kastettiimiz az ok anlalyor. Eer bir dosyay bir metin dzenleyici ile
atnzda herhangi bir dilde yazlm okunabilir bir metin gryorsanz, o dosya bir metin
dosyasdr. Mesela Notepad, Gedit, Kwrite veya benzeri metin dzenleyicileri kullanarak
oluturduunuz dosyalar birer metin dosyasdr. imdiye kadar verdiimiz btn rnekler
metin dosyalarn ieriyordu. Peki ikili (binary ) dosya ne demek?
kili dosyalar ise, metin dosyalarnn aksine, metin dzenleyicilerle alamayan, almaya
alldnda ise ounlukla anlamsz karakterler ieren bir dosya trdr. Resim dosyalar,
mzik dosyalar, video dosyalar, MS Oce dosyalar, LibreOce dosyalar, OpenOce
dosyalar, vb. ikili dosyalara rnektir.
nceki blmlerde de ifade ettiimiz gibi, bilgisayarlar yalnzca saylarla ilem yapabilir.
Bilgisayarlarn zerinde ilem yapabildii bu saylarn 0 ve 1 adl iki say olduunu biliyoruz.
Peki bu iki farkl sayy kullanarak neler yapabiliriz? Aslnda, bu iki farkl sayy kullanarak her
trl ilemi yapabiliriz: Basit veya karmak aritmetik hesaplamalar, metin dzenleme, resim
veya video dzenleme, web siteleri hazrlama, uzaya mekik gnderme... Btn bu ilemleri
sadece iki farkl say kullanarak yapabiliriz. Daha dorusu bilgisayarlar yapabilir.
Durum byle olmasna ramen, ilk bilgisayarlar yalnzca hesaplama ilemleri iin
kullanlyordu. Yani metin ieren ilemleri yapmak bilgisayarlarn deil, mesela daktilolarn
grevi olarak grlyordu. Bu durumu telefon teknolojisi ile kyaslayabilirsiniz. Bildiiniz gibi,
ilk telefonlar yalnzca iki kii arasndaki sesli iletiimi salamak iin kullanlyordu. Ama yeni
nesil telefonlar artk ikiden fazla kii arasndaki sesli ve grntl iletiimi salayabilmenin
yansra, nceleri birbirinden farkl cihazlarla gerekletirilen ilemleri artk tek bana yerine
getirebiliyor.
lk bilgisayarlarda ise metinlerin, daha dorusu karakterlerin grevi bir hayli snrlyd.
Bata da sylediimiz gibi, ounlukla dosyalar iki farkl snfa ayrlr: Metin dosyalar ve
ikili dosyalar. Ama iin asl sadece tek bir dosya tr vardr: kili dosyalar (binary les ).
Yani bilgisayarlar asndan btn dosyalar, ilerinde ne olursa olsun, birer ikili dosyadr ve
ilerinde sadece 0lar ve 1leri barndrr. te bu 0 ve 1lerin ne anlama geleceini, iletim
sistemleri ve bu sistemler zerine kurulu yazlmlar belirler. Eer bir dosya metin dosyasysa
bu dosyadaki 0 ve 1ler birer karakter/harf olarak yorumlanr. Ama eer dosya bir ikili
dosyaysa dosya iindeki 0 ve 1ler zel birtakm veriler olarak ele alnr ve bu verileri okuyan
yazlma gre deer kazanr. rnein eer ilgili dosya bir resim dosyasyla, bu dosya herhangi
bir resim grntleyici yazlm ile aldnda karmza bir resim kar. Eer ilgili dosya bir
video dosyasyla, bu dosya bir video grntleyici yazlm ile aldnda karmza bir video
kar. Bu olgudan bir sonraki blmde daha ayrntl olarak sz edeceiz. Biz imdilik iin
487
sadece pratiine younlaalm ve temel olarak iki farkl dosya eidi olduunu varsayalm:
Metin dosyalar ve ikili dosyalar.
Buraya gelene kadar hep metin dosyalarndan sz etmitik. imdi ise ikili dosyalardan sz
edeceiz.
Hatrlarsanz metin dosyalarn amak iin temel olarak yle bir komut kullanyorduk:
f = open(dosya_ad, 'r')
Bu ekilde bir metin dosyasn okuma kipinde am oluyoruz. Bir metin dosyasn deil de,
ikili bir dosyay amak iin ise u komutu kullanacaz:
f = open(dosya_ad, 'rb')
488
Pythonn bu dosyann bir ikili dosya olduu konusunda bilgilendirerek, dosyann dzgn bir
ekilde alp okunabilmesini salyoruz.
Gelin bu PDF belgesi zerinde biraz daha alalm.
PDF belgelerinde, o belge hakknda baz nemli bilgiler veren birtakm zel etiketler bulunur.
Bu etiketler unlardr:
Etiket
/Creator
/Producer
/Title
/Author
/Subject
/Keywords
/CreationDate
/ModDate
Anlam
Belgeyi oluturan yazlm
Belgeyi PDFe eviren yazlm
Belgenin bal
Belgenin yazar
Belgenin konusu
Belgenin anahtar kelimeleri
Belgenin oluturulma zaman
Belgenin deitirilme zaman
Bu etiketlerin tamam btn PDF dosyalarnda tanml deildir. Ama zellikle /Producer
etiketi her PDF dosyasnda bulunur.
imdi rnek olmas bakmndan elimize bir PDF dosyas alalm ve bunu gzelce okuyalm:
>>> f = open("[Link]", "rb")
>>> okunan = [Link]()
imdi de /Producer ifadesinin dosya iinde getii noktann sra numarasn bulalm.
Bildiiniz gibi, dosyalarn read() metodu bize bir karakter dizisi verir. Yine bildiiniz gibi,
karakter dizilerinin index() metodu yardmyla bir enin karakter dizisi iinde getii noktay
bulabiliyoruz. Yani:
>>> producer_index = [Link](b"/Producer")
489
Daha nce de dediimiz gibi, bilgisayarlar yalnzca saylar grr. Bu saynn hangi karaktere
karlk geldiini bulmak iin chr() fonksiyonundan yararlanabilirsiniz:
>>> chr(okunan[producer_index])
'/'
Hatta eer bu kt zerine split() metodunu uygularsak, kty daha kullanl bir hale
getirebiliriz:
>>> producer = okunan[producer_index:producer_index+50].split()
>>> producer
[b'/Producer', b'(Acrobat', b'Distiller', b'2.0', b'for', b'Macintosh)', b'/T']
Elbette bu yntem, bir PDF dosyasndan gerekli etiketleri almann en iyi yntemi deildir.
Ama henz Python bilgimiz bu kadarn yapmamza msaade ediyor. Ancak yine de, yukarda
rnek, bir ikili dosyadan nasl veri alnaca konusunda size iyi bir kir verecektir.
490
D8
FF
E0
4A
46
49
46
00
Ancak eer ilgili JPEG dosyas bir CANON fotograf makinesi ile oluturulmusa bu veri dizisi
yle de olabilir:
FF
D8
FF
E0
45
78
69
66
00
Burada soru iareti ile gsterdiimiz ksm, yani dosyann 5. ve 6. baytlar farkl
JPEG dosyalarnda birbirinden farkl olabilir. Dolaysyla bir JPEG dosyasn baka resim
dosyalarndan ayrabilmek iin dosyann ilk drt baytna bakmamz, sonraki iki bayt
atlamamz ve bunlardan sonra gelen be bayt kontrol etmemiz yeterli olacaktr.
Yukarda grdkleriniz birer on altl (hex ) saydr. Bunlar onlu dzende srasyla u saylara
karlk gelir:
255 216 255 224 ? ? 74 70 73 70 0
255 216 255 224 ? ? 45 78 69 66 0 #canon
491
Eer ilgili aralkta JFIF veya Exif baytlar yer alyorsa bu dosyann bir JPEG dosyas olduuna
karar veriyoruz.
Yukardaki kodlar elinizdeki bir JPEG dosyasna uygulayarak kendi kendinize pratik
yapabilirsiniz.
Mesela benim elimde [Link], [Link] ve [Link] adl farkl JPEG dosyas var:
dosyalar = ["[Link]", "[Link]", "[Link]"]
b'\xff\xd8\xff\xe0\x00\x10JFIF'
b'\xff\xd8\xff\xe1T\xaaExif'
b'\xff\xd8\xff\xe0\x00\x10JFIF'
Grdnz gibi bu ktlar yukarda JPEG dosyalarna ilikin olarak verdiimiz bayt dizilimi
ile uyuuyor. Mesela ilk dosyay ele alalm:
[Link]
b'\xff\xd8\xff\xe0\x00\x10JFIF'
492
Saylarn bandaki \x iaretleri bunlarn birer on altl say olduunu gsteren bir iarettir.
Dolaysyla yukardakileri daha net inceleyebilmek iin yle de yazabiliriz:
ff d8 ff e0 00 10 J F I F
b'\xff\xd8\xff\xe1T\xaaExif'
te dosyalarn trn ayrt etmek iin bu ktlardaki son drt bayt kontrol etmemiz yeterli
olacaktr:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("Evet {} adl dosya bir JPEG!".format(f))
else:
print("{} JPEG deil!".format(f))
da
[Link]
artnamade, [Link]
sayfasndaki bilgiye gre bir PNG dosyasnn ilk 8 bayt mutlaka aadaki deerleri ieriyor:
onlu deer
on altl deer
karakter deeri
137 80 78 71 13 10 26 10
89 50 4e 47 0d 0a 1a 0a
\211 P N G \r \n \032 \n
imdi elimize herhangi bir PNG dosyas alarak bu durumu teyit edelim:
>>> f = open("[Link]", "rb")
>>> okunan = [Link](8)
artnamede de sylendii gibi, bir PNG dosyasn teki trlerden ayrt edebilmek iin
dosyann ilk 8 baytna bakmamz yeterli olacaktr. O yzden biz de yukardaki kodlarda
sadece ilk 8 bayt okumakla yetindik.
Bakalm ilk 8 baytta neler varm:
>>> okunan
b'\x89PNG\r\n\x1a\n'
493
Bu deerin, artnamedeki karakter deeri ile ayn olup olmadn sorgulayarak herhangi bir
dosyann PNG olup olmadna karar verebilirsiniz:
>>> okunan == b"\211PNG\r\n\032\n"
True
Dolaysyla una benzer bir kod yazarak, farkl resim dosyalarnn trn tespit edebilirsiniz:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))
Bu kodlarda bir resim dosyasnn ilk 10 baytn okuduk. 7-11 aras baytlarn iinde JFIF veya
Exif baytlar varsa o dosyann bir JPEG olduuna; ilk 8 bayt b211PNGrn032n adl bayt
dizisine eitse de o dosyann bir PNG olduuna karar veriyoruz.
GIF
GIF
artnamesine
ulaabilirsiniz.
[Link]
adresinden
Bir dosyann GIF olup olmadna karar verebilmek iin ilk 3 baytn okumanz yeterli
olacaktr. Standart bir GIF dosyasnn ilk bayt G, I ve F karakterlerinden oluur.
Dosyann sonraki 3 bayt ise GIF in srm numarasn verir. 16.02.2016 itibariyle GIF
standardnn u srmleri bulunmaktadr:
1. 87a - Mays 1987
2. 89a - Temmuz 1989
Dolaysyla standart bir GIF dosyasnn ilk 6 bayt yledir:
GIF87a veya GIF89a
Eer bir dosyann GIF olup olmadn anlamak isterseniz dosyann ilk 3 veya 6 baytn
denetlemeniz yeterli olacaktr:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
elif okunan[:3] == b'GIF':
print("{} adl dosya bir GIF!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))
494
TIFF
TIFF artnamesine [Link] adresinden
ulaabilirsiniz. Bu artnameye gre bir TIFF dosyas unlardan herhangi biri ile balar:
1. II
2. MM
Dolaysyla, bir TIFF dosyasn tespit edebilmek iin dosyann ilk 2 baytna bakmanz yeterli
olacaktr:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
elif okunan[:3] == b'GIF':
print("{} adl dosya bir GIF!".format(f))
elif okunan[:2] in [b'II', b'MM']:
print("{} adl dosya bir TIFF!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))
BMP
Grdnz gibi ikili dosyalar, baytlarn zel bir ekilde dizildii ve zel bir ekilde
yorumland bir dosya trdr. Dolaysyla ikili dosyalarla alabilmek iin, ikili dosyann
bayt dizilimini yakndan tanmak gerekiyor.
495
BLM 32
496
Not: Bit kelimesi ngilizcede binary (ikili) ve digit (rakam) kelimelerinin birletirilmesi ile
retilmitir.
Bu bilgiye gre mesela 0 says bir bitlik bir say iken, 1001 says drt bitlik bir saydr.
letiimimizi eksiksiz bir biimde salayabilmemiz, yani gereken btn karakterleri temsil
edebilmemiz iin, sistemimizin 8 hanelik bir say kapasitesine sahip olmas, yani teknik bir
dille ifade etmek gerekirse sistemimizin 8 bitlik olmas herhalde yeterli olacaktr.
8 bitlik bir iletiim sisteminde 10 a kadar u ekilde sayabiliriz:
>>> for i in range(10):
...
print(bin(i)[2:].zfill(8))
...
00000000
00000001
00000010
00000011
00000100
00000101
00000110
00000111
00001000
00001001
Verici tarafndaki kii elindeki anahtar yardmyla farkl kuvvetlere sahip sinyalleri art arda
gndererek yukarda gsterildii gibi on farkl sayy alcya iletebilir. Sistemimizin 8 bitlik
olduunu dnrsek kar tarafa 0 says ile birlikte toplam 2 ** 8 = 256 farkl sinyal
gnderebiliriz:
>>> for i in range(256):
...
print(bin(i)[2:].zfill(8))
00000000
00000001
00000010
00000011
00000100
...
...
...
11111001
11111010
11111011
11111100
11111101
11111110
11111111
Grdnz gibi, bizim 8 bitlik bu sistemle gnderebileceimiz son sinyal, yani say 255 tir.
Bu sistemle bundan byk bir sayy gnderemeyiz. Bu durumu kendi gzlerinizle grmek
iin u kodlar altrn:
>>> for i in range(256):
...
print(bin(i)[2:], i.bit_length(), sep="\t")
Burada ilk stun 256 ya kadar olan saylarn ikili sistemdeki karlklarn, ikinci stun ise
bu saylarn bit uzunluunu gsteriyor. Bu kty incelediinizde de greceiniz gibi, 8 bit
497
uzunlua sahip son say 255 tir. 256 says ise 9 bit uzunlua sahiptir. Yani 256 says
mecburen bizim sistemimizin dndadr:
>>> bin(255)[2:]
'11111111'
>>> (255).bit_length()
8
>>> bin(256)[2:]
'100000000'
>>> (256).bit_length()
9
Dediimiz gibi, bu sistemde elimizde toplam 8 bit var. Yani bu sistemi kullanarak 0 dan 256 ya
kadar sayp, bu saylar alcya iletebiliriz.
Peki verici ile alc arasnda birtakm saylar gnderip alabilmek ne iimize yarar? Yani bu i
neden bu kadar nemli?
Bu sorularn cevabn birazdan vereceiz, ama ondan nce daha nemli bir konuya deinelim.
498
Bu arada, bunun 7 bitlik bir say olduuna dikkat edin. Dediimiz gibi, biz kontrol
mekanizmamz kurabilmek iin elimizdeki 8 bitlik kapasitenin 7 bitini kullanacaz. Bota
kalan 8. biti ise kontrol mekanizmasna tahsis edeceiz.
Ne diyorduk? Evet, biz kar tarafa 7 bitlik bir say olan 0110111 saysn gndermek istiyoruz.
Bu sayy gndermeden nce, iindeki 1 lerin miktarna bakarak bu saynn tek mi yoksa ift mi
olduuna karar verelim. Burada toplam be adet 1 says var. Yani bu say bir tek saydr. Eer
gndermek istediimiz say bir tek say ise, kar tarafa ulatnda da bir tek say olmaldr.
Biz bu sistem iin yle bir protokol tasarlayabiliriz:
Bu sistemde btn saylar kar tarafa bir tek say olarak iletilmelidir. Eer iletilen
saylar arasnda bir ift say varsa, o say hatal iletilmi veya iletim esnasnda
bozulmu demektir.
Peki biz iletilen btn saylarn bir tek say olmasn nasl salayacaz? te bu ilemi, boa
ayrdmz o 8. bit ile gerekletireceiz:
Eer kar tarafa iletilen bir say zaten tekse, o saynn bana 0 ekleyeceiz.
Bylece saynn teklik-iftlik durumu deimemi olacak. Ama eer iletilecek say
iftse, o saynn bana 1 ekleyeceiz. Bylece ift sayy, sistemimizin gerektirdii
ekilde, tek sayya evirmi olacaz.
rnek olarak 0110111 saysn verelim. Bu sayda toplam be adet 1 var. Yani bu say bir tek
say. Dolaysyla bu saynn bana bir adet 0 ekliyoruz:
0 0110111
Bylece saymzn teklik-iftlik durumu deimemi oluyor. Kar taraf bu sayy aldnda
1 lerin miktarna bakarak bu verinin doru iletildiinden emin oluyor.
Bir de u sayya bakalm:
1111011
Bu sayda toplam alt adet 1 says var. Yani bu say bir ift say. Bir saynn sistemimiz
tarafndan hatasz olarak kabul edilebilmesi iin bu saynn bir tek say olmas gerekiyor. Bu
yzden biz bu sayy tek sayya evirmek iin bana bir adet 1 say ekliyoruz:
1 1111011
Bylece saymzn iinde toplam yedi adet 1 says olmu ve bylece saymz tek sayya
dnm oluyor.
Teknik olarak ifade etmemiz gerekirse, yukarda yaptmz kontrol trne elik denetimi
(parity check ) ad verilir. Bu ilemi yapmamz salayan bite ise elik biti (parity bit ) denir.
ki tr elik denetimi bulunur:
1. Tek elik denetimi (odd parity check )
2. ift elik denetimi (even parity check )
Biz kendi sistemimizde hata kontrol mekanizmasn btn verilerin bir tek say olmas
gereklilii zerine kurduk. Yani burada bir tek elik denetimi gerekletirmi olduk. Elbette
btn verilerin bir ift say olmas gereklilii zerine de kurabilirdik bu sistemi. Yani isteseydik
ift elik denetimi de yapabilirdik. Bu tamamen bir tercih meselesidir. Bu tr sistemlerde
yaygn olarak tek elik denetimi kullanld iin biz de bunu tercih ettik.
Bu rneklerden de grdnz gibi, toplam 8 bitlik kapasitemizin 7 bitini veri aktarm iin,
kalan 1 bitini ise alnp verilen bu verilerin doruluunu denetlemek iin kullanyoruz. Elbette
32.2. Hata Kontrol
499
kullandmz hata kontrol mekanizmas epey zayf bir sistemdir. Ama, iletiim sistemleri
arasnda verilerin hatasz bir ekilde aktarlp aktarlamadn kontrol etmeye yarayan bir
sistem olan elik denetiminin, bugn bilgisayarn belleklerinde (RAM) dahi kullanlmaya
devam ettiini sylemeden gemeyelim...
karakter
a
e
i
m
q
u
y
C
G
K
O
S
W
say
1
101
1001
1101
10001
10101
11001
11101
100001
100101
101001
101101
110001
karakter
b
f
j
n
r
v
z
D
H
L
P
T
X
say
10
110
1010
1110
10010
10110
11010
11110
100010
100110
101010
101110
110010
karakter
c
g
k
o
s
w
A
E
I
M
Q
U
Y
say
11
111
1011
1111
10011
10111
11011
11111
100011
100111
101011
101111
110011
karakter
d
h
l
p
t
x
B
F
J
N
R
V
Z
Bu tabloda toplam 52 karakter ile 52 say birbiriyle eletirilmi durumda. Mesela vericiden
0 sinyali geldiinde bu tabloya gre biz bunu a har olarak yorumlayacaz. rnein kar
tarafa python mesajn iletmek iin srasyla u sinyalleri gndereceiz:
1111, 11000, 10011, 111, 1110, 1101
Grdnz gibi, elimizdeki 127 saynn 52sini harere ayrdk ve elimizde 75 tane daha say
kald. Eer isterseniz geri kalan bu saylar da birtakm baka karakterlere veya iaretlere
ayrarak, alc ve verici arasndaki btn iletiimin eksiksiz bir ekilde gereklemesini
salayabilirsiniz. rnein yle bir tablo oluturabilirsiniz:
500
say
0
100
1000
1100
10000
10100
11000
11100
100000
100100
101000
101100
110000
110100
111000
111100
1000000
1000100
1001000
1001100
1010000
1010100
1011000
1011100
1100000
karakter
0
4
8
c
g
k
o
s
w
A
E
I
M
Q
U
Y
#
+
/
=
[
_
}
n
say
1
101
1001
1101
10001
10101
11001
11101
100001
100101
101001
101101
110001
110101
111001
111101
1000001
1000101
1001001
1001101
1010001
1010101
1011001
1011101
1100001
karakter
1
5
9
d
h
l
p
t
x
B
F
J
N
R
V
Z
$
(
,
:
>
\
~
r
say
10
110
1010
1110
10010
10110
11010
11110
100010
100110
101010
101110
110010
110110
111010
111110
1000010
1000110
1001010
1001110
1010010
1010110
1011010
1011110
1100010
karakter
2
6
a
e
i
m
q
u
y
C
G
K
O
S
W
!
%
)
-
;
?
]
{
x0b
say
11
111
1011
1111
10011
10111
11011
11111
100011
100111
101011
101111
110011
110111
111011
111111
1000011
1000111
1001011
1001111
1010011
1010111
1011011
1011111
1100011
karakter
3
7
b
f
j
n
r
v
z
D
H
L
P
T
X
&
*
.
<
@
^
t
x0c
501
Mors alfabesinin bizim oluturduumuz sisteme mantk olarak ne kadar benzediine dikkat
edin. Bu sistemin benzeri biraz sonra gstereceimiz gibi, modern bilgisayarlarda da
kullanlmaktadr.
502
BLM 33
Bu blme gelinceye kadar Python programlama dilindeki karakter dizisi, liste ve dosya adl
veri tiplerine ilikin epey sz syledik. Artk bu veri tiplerine dair hemen hemen btn
ayrntlar biliyoruz. Ancak henz renmediimiz, ama programclk maceramz asndan
mutlaka renmemiz gereken ok nemli bir konu daha var. Bu nemli konunun ad, karakter
kodlama.
Bu blmde karakter kodlama adl hayati konuyu ilemenin yansra, son birka blmde
stnkr bir ekilde zerinden getiimiz, ama derinlemesine incelemeye pek frsat
bulamadmz btn konular da ele almaya alacaz. Bu konuyu bitirdikten sonra,
nceki konular alrken zihninizde olumu olabilecek boluklarn pek ounun dolduunu
farkedeceksiniz. Szn z, bu blmde hem yeni eyler syleyeceiz, hem de halihazrda
rendiimiz eylerin bir kez daha zerinden geerek bunlarn zihnimizde iyiden iyine
pekimesini salayacaz.
Hatrlarsanz nceki derslerimizde karakter dizilerinin encode() adl bir metodu olduundan
sz etmitik. Ayn ekilde, dosyalarn da encoding adl bir parametresi olduunu sylemitik.
Ayrca bu encoding konusu, ilk derslerimizde metin dzenleyici ayarlarn anlatrken de
karmza kmt. Orada, yazdmz programlarda zellikle Trke karakterlerin dzgn
grnebilmesi iin, kullandmz metin dzenleyicinin dil kodlamas (encoding ) ayarlarn
dzgn yapmamz gerektiini stne basa basa sylemitik. Biz u ana kadar bu konuyu
ayrntl olarak ele almam da olsak, siz imdiye kadar yazdnz programlarda Trke
karakterleri kullanrken halihazrda pek ok problemle karlam ve bu sorunlarn neden
kaynaklandn anlamakta zorlanm olabilirsiniz.
te bu blmde, o zaman henz bilgimiz yetersiz olduu iin ertelediimiz bu encoding
konusunu btn ayrntlaryla ele alacaz ve yazdmz programlarda Trke karakterleri
kullanrken neden sorunlarla karlatmz, bu sorunun temelinde neyin yattn anlamaya
alacaz.
O halde hi vakit kaybetmeden bu nemli konuyu incelemeye balayalm.
33.1 Giri
nceki blmlerde sk sk tekrar ettiimiz gibi, bilgisayar dediimiz ey, zerinden elektrik
geen devrelerden olumu bir sistemdir. Eer bir devrede elektrik yoksa o devrenin deeri
0 volt iken, o devreden elektrik getiinde devrenin deeri yaklak +5 volttur.
Grdnz gibi, ortada iki farkl deer var: 0 volt ve +5 volt. kili (binary ) sayma sisteminde
de iki deer bulunur: 0 ve 1. te biz bu 0 voltu ikili sistemde 0 ile, +5 voltu ise 1 ile temsil
503
ediyoruz. Yani devreden elektrik getiinde o devrenin deeri 1, elektrik gemediinde ise
0 olmu oluyor. Tabii bilgisayar asndan bakldnda devrede elektrik vardr veya yoktur.
Biz insanlar bu ikili durumu daha kolay bir ekilde maniple edebilmek iin farkl voltaj
durumlarndan her birine srasyla 0 ve 1 gibi bir ad veriyoruz. Yani iki farkl voltaj deerini
iki farkl say halinde kodlam oluyoruz...
Hatrlarsanz bir nceki blmde tasarladmz basit iletiim modelinde de ampuln lo k
vermesini salayan dk elektrik sinyallerini 0 ile, parlak k vermesini salayan yksek
elektrik sinyallerini ise 1 ile temsil etmitik. Bu temsil iine de teknik olarak kodlama
(encoding ) ad verildiini sylemitik. te bilgisayarlar asndan da benzer bir durum sz
konusudur. Bilgisayarlarda da 0 volt ve +5 volt deerleri srasyla ikili sayma sistemindeki 0
ve 1 saylar halinde kodlanabilir.
Szn z ilk bata yalnzca iki farkl elektrik sinyali vardr. Elbette bu elektrik sinyalleri
ile dorudan herhangi bir ilem yapamayz. Mesela elektrik sinyallerini birbiriyle toplayp,
birbirinden karamayz. Ama bu sinyalleri bir sayma sistemi ile temsil edersek (yani bu
sinyalleri o sayma sisteminde kodlarsak), bunlar kullanarak, rnein, aritmetik ilemleri
rahatlkla gerekletirebiliriz. Mesela 0 volt ile +5 voltu birbiriyle toplayamayz, ama 0 voltu
ikili sistemdeki 0 saysyla, +5 voltu ise ikili sistemdeki 1 saysyla kodladktan sonra bu ikili
saylar arasnda her trl aritmetik ilemi gerekletirebiliriz.
Bilgisayarlar yalnzca iki farkl voltaj durumundan anlad ve bu iki farkl voltaj durumu da ikili
sayma sistemindeki iki farkl say ile kolayca temsil edilebildii iin, ilk bilgisayarlar ounlukla
sadece hesap ilemlerinde kullanlyordu. Karakterlerin/harerin bilgisayar dnyasndaki
ilevi bir hayli kstlyd. Metin oluturma ii o zamanlarda daktilo ve benzeri aralarn grevi
olarak grlyordu. Bu durumu, telefon teknolojisi ile kyaslayabilirsiniz. lk telefonlar da
yalnzca iki kii arasndaki sesli iletiimi salamak gibi kstl bir amaca hizmet ediyordu. Bugn
ise, gemite pek ok farkl cihaza paylatrlm grevleri akll telefonlar araclyla tek elden
halledebiliyoruz.
Peki bir bilgisayar yalnzca elektrik sinyallerinden anlyorsa, biz mesela bilgisayarlar nasl
oluyor da metin girii iin kullanabiliyoruz?
Bu sorunun cevab aslnda ok ak: Birtakm elektrik sinyallerini, birtakm aritmetik ilemleri
gerekletirebilmek amacyla nasl birtakm saylar halinde kodlayabiliyorsak; birtakm saylar
da, birtakm metin ilemlerini gerekletirebilmek amacyla birtakm karakterler halinde
kodlayabiliriz.
Peki ama nasl?
Bir nceki blmde bahsettiimiz basit iletiim modeli araclyla bunun nasl yaplacan
anlatmtk. Tpk bizim basit iletiim sistemimizde olduu gibi, bilgisayarlar da yalnzca
elektrik sinyallerini grr. Tpk orada yaptmz gibi, bilgisayarlarda da hangi elektrik
sinyalinin hangi sayya; hangi saynn da hangi karaktere karlk geleceini belirleyebiliriz.
Daha dorusu, bilgisayarlarn grd bu elektrik sinyallerini saylara ve karakterlere
dntrebiliriz. Dardan girilen karakterleri de, bilgisayarlarn anlayabilmesi iin tam aksi
istikamette sayya, oradan da elektrik sinyallerine evirebiliriz. te bu dntrme ilemine
karakter kodlama (character encoding ) ad verilir.
Bu noktada yle bir soru akla geliyor: Tamam, saylar karakterlere, karakterleri de saylara
dntreceiz. Ama peki hangi saylar hangi karakterlere, hangi karakterleri de hangi
saylara dntreceiz? Yani mesela ikili sistemdeki 0 says hangi karaktere, 1 says hangi
karaktere, 10 says hangi karaktere karlk gelecek?
Siz aslnda bu sorunun cevabn da biliyorsunuz. Yine bir nceki blmde anlattmz
gibi, hangi saylarn hangi karakterlere karlk geleceini, saylarla karakterlerin eletirildii
504
33.1. Giri
505
33.2 ASCII
Bilgisayarlarn iki farkl elektrik sinyali ile altn, bu iki farkl sinyalin de 0 ve 1 saylar ile
temsil edildiini, bilgisayarla metin ilemleri yapabilmek iin ise bu saylarn belli karakterlerle
eletirilmesi gerektiini sylemitik.
Yukarda da bahsettiimiz gibi, uygarlk ve ilerleme asndan standartlama nemli bir
basamaktr. yle dnn: Biz bilgisayarlarn alma prensibinde iki farkl elektrik sinyali
olduunu biliyoruz. Biz insanlar olarak, ilerimizi daha kolay yapabilmek iin, bu sinyalleri
daha somut birer ara olan 0 ve 1 saylarna atamz. Eer devrede elektrik yoksa bu
durumu 0 ile, eer devrede elektrik varsa bu durumu 1 ile temsil ediyoruz. Esasnda bu
da bir uzlama gerektirir. Devrede elektrik yoksa bu durumu pekala 0 yerine 1 ile de temsil
edebilirdik... Eer elektrik sinyallerinin temsili zerinde byle bir uzlamazlk olsayd, her
eyden nce hangi sinyalin hangi sayya karlk gelecei konusunda da ortak bir karara
varmamz gerekirdi.
Elektriin var olmad durumu 0 yerine 1 ile temsil etmek akla pek yatkn olmad iin
uzlamada bir problem kmyor. Ama karakterler byle deildir. Onlarca (hatta yzlerce ve
binlerce) karakterin saylarla eletirilmesi gereken bir durumda, ortak bir eletirme dzeni
zerinde uzlama salamak hi de kolay bir i deildir. Zaten 1960l yllarn bana kadar da
byle bir uzlama salanabilmi deildi. Dediimiz gibi, her bilgisayar reticisi saylar farkl
karakterlerle eletiriyor, yani birbirlerinden tamamen farkl karakter kodlama sistemleri
kullanyordu.
te bu kargaay ortadan kaldrmak gayesiyle, Bob Bemer ve ekibi hangi saylarn hangi
karakterlere karlk geleceini belli bir standarda balayan bir tablo oluturdu. Bu standarda
ise American Standard Code for Information Interchange, yani Bilgi Alverii iin Standart
Amerikan Kodu veya ksaca ASCII ad verildi.
506
karakter
\x00
\x04
\x08
\x0c
\x10
\x14
\x18
\x1c
say
1
5
9
13
17
21
25
29
karakter
\x01
\x05
\t
\r
\x11
\x15
\x19
\x1d
say
2
6
10
14
18
22
26
30
karakter
\x02
\x06
\n
\x0e
\x12
\x16
\x1a
\x1e
say
3
7
11
15
19
23
27
31
karakter
\x03
\x07
\x0b
\x0f
\x13
\x17
\x1b
\x1f
507
Not: Bu arada, [Link] adresinden baktnz tablo ile yukardaki tablonun birbirinden
farkl olduunu zannedebilirsiniz ilk bakta. Ama aslnda arada herhangi bir fark yok. Yalnzca
iki tablonun karakterleri gsterim ekli birbirinden farkl. rnein [Link] tabloda
9 saysnn TAB (horizontal tab) adl bir karaktere atandn gryoruz. Yukardaki tabloda
ise 9 saysnn yannda \t adl ka dizisi var. Grdnz gibi, TAB (horizontal tab) ifadesi
ile \t ifadesi ayn karaktere atfta bulunuyor. Yalnzca bunlarn gsterimleri birbirinden farkl,
o kadar.
Aslnda bu karakter salatas arasnda bizim tandmz birka karakter de yok deil. Mesela 9.
sradaki \t esinin sekme oluturan ka dizisi olduunu syledik. Ayn ekilde, 10. sradaki
\n esinin satr bana geiren ka dizisi olduunu, 13. sradaki \r esinin ise satr
baa alan ka dizisi olduunu da biliyoruz. Bu tr karakterler baslamayan (non-printing )
karakterlerdir. Yani mesela ekranda grntlenebilen a, b, c, !, ?, = gibi karakterlerden
farkl olarak bu ilk 32 karakter ekranda grnmez. Bunlara ayn zamanda kontrol karakterleri
(control characters ) ad da verilir. nk bu karakterler ekranda grntlenmek yerine,
metnin akn kontrol eder. Bu karakterlerin ne ie yaradn u tabloyla tek tek gsterebiliriz
(tablo [Link] adresinden alntdr):
Say
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Karakter
bo
balk balangc
metin balangc
metin sonu
aktarm sonu
sorgu
bildirim
zil
geri al
yatay sekme
satr besleme/yeni satr
dikey sekme
form besleme/yeni sayfa
satr ba
dar kaydr
ieri kaydr
Say
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Karakter
veri balantsndan k
aygt denetimi 1
aygt denetimi 2
aygt denetimi 3
aygt denetimi 4
olumsuz bildirim
zaman uyumlu bota kalma
aktarm blou sonu
iptal
ortam sonu
deitir
k
dosya ayrcs
grup ayrcs
kayt ayrcs
birim ayrcs
Grdnz gibi, bunlar birer harf, say veya noktalama iareti deil. O yzden bu karakterler
ekranda grnmez. Ama bir metindeki veri, satr ve paragraf dzeninin nasl olacan, metnin
nerede balayp nerede biteceini ve nasl grneceini kontrol ettikleri iin nemlidirler.
Geri kalan saylar ise dorudan karakterlere, saylara ve noktalama iaretlerine tahsis
edilmitir:
508
say
32
36
40
44
48
52
56
60
64
68
72
76
80
84
88
92
96
100
104
108
112
116
120
124
karakter
$
(
,
0
4
8
<
@
D
H
L
P
T
X
\
d
h
l
p
t
x
|
say
33
37
41
45
49
53
57
61
65
69
73
77
81
85
89
93
97
101
105
109
113
117
121
125
karakter
!
%
)
-
1
5
9
=
A
E
I
M
Q
U
Y
]
a
e
i
m
q
u
y
}
say
34
38
42
46
50
54
58
62
66
70
74
78
82
86
90
94
98
102
106
110
114
118
122
126
karakter
&
*
.
2
6
:
>
B
F
J
N
R
V
Z
^
b
f
j
n
r
v
z
~
say
35
39
43
47
51
55
59
63
67
71
75
79
83
87
91
95
99
103
107
111
115
119
123
127
karakter
#
+
/
3
7
;
?
C
G
K
O
S
W
[
_
c
g
k
o
s
w
{
x7f
Merhaba irin Baba! adl karakter dizisinde geen har ASCII d bir karakterdir. Yani bu
harf ASCII ile temsil edilemez. O yzden byle bir kod yazp bu kodu altrdmzda Python
bize yle bir hata mesaj gsterecektir:
33.2. ASCII
509
Aynen anlattmz gibi, yukardaki hata mesaj da kodlar arasnda ASCII olmayan bir karakter
yer aldndan yaknyor...
ASCIInin her ne kadar yukarda bahsettiimiz eksiklikleri olsa da bu standart son derece
yaygndr ve piyasada bulunan pek ok sistemde kullanlmaya devam etmektedir. rnein
size kullanc ad ve parola soran hemen hemen btn sistemler bu ASCII tablosunu temel alr
veya bu tablodan etkilenmitir. O yzden ou yerde kullanc ad ve/veya parola belirlerken
Trke karakterleri kullanamazsnz. Hatta pek ok yaz tipinde yalnzca ASCII tablosunda yer
alan karakterlerin karl bulunur. Bu yzden, mesela blogunuzda kullanmak zere seip
beendiiniz ou yaz tipi , , , gibi hareri gstermeyebilir. Yukarda Merhaba
irin Baba! rneinde de gsterdiimiz gibi, Pythonn 2.x serisinde de ntanml olarak
ASCII kodlama biimi kullanlyordu. O yzden Pythonn 2.x srmlerinde Trke karakterleri
gsterebilmek iin daha fazla ilave ilem yapmak zorunda kalyorduk.
Szn z, eer yazdnz veya kendiniz yazmam da olsanz herhangi bir sebeple
kullanmakta olduunuz bir programda Trke karakterlere ilikin bir hata alyorsanz, bu
durumun en muhtemel sebebi, kullandnz programn veya sistemin, dorudan ASCIIyi
veya ASCIIye benzer baka bir sistemi temel alarak alyor olmasdr. ASCII tablosunda
grnen 128 karakter dnda kalan hibir karakter ASCII ile kodlanamayaca iin, zellikle
farkl dillerin kullanld bilgisayarlarda alan programlar kanlmaz olarak karakterlere
ilikin pek ok hata verecektir. rnein, karakter kodlamalarna ilikin olarak yukarda
bahsettiimiz ayrntlardan habersiz bir Amerikal programcnn yazd bir programa Trke
veri girdiinizde bu program bir anda tuhaf grnen hatalar verip kecektir...
510
Bu tabloya baktnzda batan 128e kadar olan karakterlerin standart ASCII tablosu ile ayn
olduunu greceksiniz. 128. karakterden itibaren ise Trkeye zg harer tanmlanr.
Mesela bu tabloda 128. karakter Trkedeki byk har iken, 159. karakter kk
hardir. Bu durumu u Python kodlar ile de teyit edebilirsiniz:
>>> "".encode("cp857")
b'\x80'
>>> "".encode("cp857")
b'\x9f'
Bu arada bu saylarn onaltl sayma dzenine gre olduunu biliyorsunuz. Onlu dzende
bunlarn karl srasyla udur:
>>> int("80", 16)
128
>>> int("9f", 16)
159
Burada karakter dizilerinin encode() adl metodunu kullandmza dikkat edin. Bu metot
yardmyla herhangi bir karakteri herhangi bir karakter kodlama sistemine gre kodlayabiliriz.
Mesela yukardaki iki rnekte ve harerini cp857 adl kod sayfasna gre kodladk ve
bunlarn bu kod sayfasnda hangi saylara karlk geldiini bulduk.
cp857 numaral kod sayfasnda ve hareri yer ald iin, biz bu hareri o kod sayfasna
gre kodlayabiliyoruz. Ama mesela ASCII kodlama sisteminde bu harer bulunmaz. O yzden
bu hareri ASCII sistemine gre kodlayamayz:
>>> "".encode("ascii")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xc7' in position
0: ordinal not in range(128)
Gerekten de onlu sistemde 199 saysna karlk gelen bu onaltl \xc7 says ASCIInin
kapsad say aralnn dnda kalmakta, bu yzden de ASCII kod zcs ile
kodlanamamaktadr.
Dediimiz gibi, Microsoft Trkiyeye gnderdii bilgisayarlarda 857 numaral kod sayfasn
tanmlyordu.
Ama mesela Arapa konuulan lkelere gnderdii bilgisayarlarda
ise, [Link] adresinden grebileceiniz 708
numaral kod sayfasn tanmlyordu. Bu kod sayfasn incelediinizde, 128 alt karakterlerin
standart ASCII ile ayn olduunu ancak 128 st karakterlerin Trke kod sayfasndaki
karakterlerden farkl olduunu greceksiniz. te 128 st karakterler btn dillerde
birbirinden farkldr.
Bu farklln ne sonu dourabileceini tahmin edebildiinizi
zannediyorum. Elbette, mesela kendi bilgisayarnzda yazdnz bir metni Arapa konuulan
33.2. ASCII
511
512
7
>>> (128).bit_length()
8
8 bitlik bir sistem olan Geniletilmi ASCII ise 0 ile 255 aras saylar temsil edebilir:
>>> bin(255)[2:]
'11111111'
Dolaysyla ASCIIde ve Geniletilmi ASCIIde 1 baytlk alana toplam 256 karakter sdrlabilir.
Eer daha fazla karakteri temsil etmek isterseniz 1 bayttan fazla bir alana ihtiya duyarsnz.
Bu arada, olas bir yanl anlamay nleyelim:
1 bayt olma durumu mesela dorudan a harnin kendisi ile ilgili bir ey deildir. Yani a
har 1 bayt ile gsterilebiliyorken, mesela har 1 bayt ile gsterilemiyorsa, bunun nedeni
harninin tuhaf bir harf olmas deildir! Eer ASCII gibi bir sistem Trkiyede tasarlanm
olsayd, herhalde har ilk 128 say arasnda kendine bir yer bulurdu. Mesela byle bir
sistemde muhtemelen x, w ve q hareri, Trk alfabesinde yer almadklar iin, darda
kalrd. O zaman da , , gibi harerin 1 bayt olduunu, x, w ve q gibi harerin ise 1
bayt olmadn sylerdik.
33.3 UNICODE
lk bilgisayarlarn ABD kl olmas nedeniyle, bilgisayarlar ounlukla ABDde retilip ABD
pazarna satlyordu. Bu nedenle ngilizce alfabeyi temel alan ASCII gibi bir sistem bu pazarn
karakter temsil ihtiyalarn %99 orannda karlyordu. Ancak bilgisayarlarn ABD dna
kmas ve ABD dnda da da yaylmaya balamasnn ardndan, ASCIInin yetersizlikleri de
iyice grnr olmaya balad. nk ASCII tablosunda, ngilizce dndaki dillerde bulunan
aksanl ve noktal harerin (, , , gibi) hibiri bulunmuyordu.
lk zamanlarda insanlar aksanl ve noktal hareri ASCII tablosundaki benzerleriyle
deitirerek kullanmaya raz olmulard ( yerine e; yerine a; yerine o; yerine c
gibi). Ancak bu zm Avrupa dillerini kullananlarn sorununu ksmen zyor da olsa,
Asya dillerindeki problemi zemez. nk ASCII tablosunu kullanarak ince ve Japonca gibi
dillerdeki karakterleri herhangi bir ekilde temsil etmeniz mmkn deildir.
Bu sknty ksmen de olsa giderebilmek iin, yukarda da bahsetmi olduumuz, 128-256
arasndaki boluktan yararlanlmaya baland. Dediimiz gibi, ASCII 7 bitlik bir sistem
olduu iin, 8 bitlik bilgisayarlarda fazladan 1 bitin bota kalmasna izin verir. te bu
1 bitlik boluk dnyann eitli lkeleri tarafndan kendi karakter ihtiyalarn karlamak
33.3. UNICODE
513
iin kullanld. Dolaysyla Almanlar 128-256 arasn farkl karakterlerle, Franszlar baka
karakterlerle, Yunanlar ise bambaka karakterlerle doldurdular.
Hatrlarsanz ASCIInin ortaya k sebebi bilgisayarlar arasnda veri alveriini
mmkn klmakt. ASCII Amerikadaki bilgisayarlar arasnda salkl bir veri alverii
gerekletirilmesini rahatlkla mmkn klyordu. Ama bilgisayarlarn dnyaya yaylmas
ile birlikte ilk bataki veri aktarm problemi tekrar ortaya kt. Bu defa da, mesela
Trkiyeden gnderilen bir metin (rnein bir [Link]) Almanyadaki bilgisayarlarda dzgn
grntlenemeyebiliyordu. rnein Windows-1254 (cp1254) numaral kod sayfas ile
kodlanm Trke bir metin, Almanyada Windows-1250 numaral kod sayfasnn tanml
olduu bir bilgisayarda, ayn saylarn her iki kod sayfasnda farkl karakterlere karlk
gelmesi nedeniyle dzgn grntlenemez.
Not:
Windows-1254 adl kod sayfas iin [Link]
adresine; Windows-1250 adl kod sayfas iin ise [Link]
adresine bakabilirsiniz.
te nasl 1960l yllarn banda Bob Bemer ve arkadalar bilgisayarlar arasnda salkl
bir veri iletiimi salamak iin kollar svayp ASCII gibi bir zm rettiyse, ASCII ve
Geniletilmi ASCII ile kodlanamayan karakterleri de kodlayp, uluslar arasnda ok geni apl
veri alveriine izin verebilmek amacyla Xerox irketinden Joe Becker, Apple irketinden ise
Lee Collins ve Mark Davis UNICODE adl bir zm zerinde ilk almalar balatt.
Peki tam olarak nedir bu UNICODE denen ey?
Aslnda Unicode da tpk ASCII gibi bir standarttr. Unicodeun bir proje olarak ortaya k
1987 ylna dayanr. Projenin amac, dnyadaki btn dillerde yer alan karakterlerin tek,
benzersiz ve doru bir biimde temsil edilebilmesidir. Yani bu projenin ortaya k gayesi,
ASCIInin yetersiz kald noktalar tela etmektir.
514
Unicode sisteminde her karakter tek ve benzersiz bir kod konumuna (code point ) karlk
gelir. Kod konumlar u formle gre gsterilir:
U+saynn_onaltl_deeri
Buradaki 0061 says onaltl bir saydr. Bunu onlu say sistemine evirebilirsiniz:
>>> int("61", 16)
97
bayt
bayt
bayt
bayt
kullanrsak
kullanrsak
kullanrsak
kullanrsak
toplam
toplam
toplam
toplam
2**8
2**16
2**24
2**32
=
=
=
=
256
65,536
16,777,216
4,294,967,296
33.3. UNICODE
515
Grne gre biz 4 baytlk bir sistem kullanrsak gelmi gemi btn karakterleri rahatlkla
temsil etmeye yetecek kadar alana sahip oluyoruz. Ancak burada yle bir durum var.
Bildiiniz gibi, 0 ile 256 aralndaki karakterler yalnzca 1 bayt ile temsil edilebiliyor. 256
ile 65,536 arasndaki karakterler iin ise 2 bayt yeter. Ayn ekilde 65,536 ile 16,777,216
aralndaki saylar iin de 3 bayt yeterli. Bu durumda eer biz btn karakterleri 4 bayt
ile temsil edecek olursak, korkun derece bir israfa dm oluruz. nk ASCII gibi bir
kodlama sisteminde yalnzca 1 bayt ile temsil edilebilecek bir karakterin kaplad alan bu
sistemle bou bouna 4 kat artm olacaktr.
Bu sorunun zm elbette sabit boyutlu karakter kodlama biimleri yerine deiken boyutlu
karakter kodlama biimleri kullanmaktr. te UNICODE sistemi iindeki UTF-8 adl kod
zc, karakterleri deiken sayda baytlar halinde kodlayabilir. UTF-8, UNICODE sistemi
iinde tanmlanm karakterleri kodlayabilmek iin 1 ile 4 bayt aras deerleri kullanr. Bylece
de bu kod zc UNICODE sistemi iinde tanmlanm btn karakterleri temsil edebilir.
Bu durumu bir rnek zerinden gstermeye alalm:
harfler = "abcdefghijklmnoprstuvyz"
for s in harfler:
print("{:<5}{:<15}{:<15}".format(s,
str([Link]("utf-8")),
len([Link]("utf-8"))))
d
e
f
g
i
j
k
l
m
n
o
p
r
s
t
u
v
y
z
516
b'a'
b'b'
b'c'
b'\xc3\xa7'
b'd'
b'e'
b'f'
b'g'
b'\xc4\x9f'
b'h'
b'\xc4\xb1'
b'i'
b'j'
b'k'
b'l'
b'm'
b'n'
b'o'
b'\xc3\xb6'
b'p'
b'r'
b's'
b'\xc5\x9f'
b't'
b'u'
b'\xc3\xbc'
b'v'
b'y'
b'z'
1
1
1
2
1
1
1
1
2
1
2
1
1
1
1
1
1
1
2
1
1
1
2
1
1
2
1
1
1
Burada, [Link]("utf-8") komutunun baytlar (bytes ) trnden bir veri tipi verdiine
dikkat edin (baytlar veri tipini bir sonraki blmde ayrntl olarak inceleyeceiz). Karakter
dizilerinin aksine baytlarn format() adl bir metodu bulunmaz. Bu yzden, bu veri
tipini format() metoduna gndermeden nce str() fonksiyonu yardmyla karakter dizisine
dntrmemiz gerekiyor.
Bu dntrme ilevini, alternatif olarak u ekilde de
yapabilirdik:
print("{:<5}{!s:<15}{:<15}".format(s,
[Link]("utf-8"),
len([Link]("utf-8"))))
Grdnz gibi, bu say 16 bitlik, yani 2 baytlk bir saydr. Bunu nasl teyit edeceinizi
biliyorsunuz:
>>> (50087).bit_length()
16
[Link] adresine
tablosunda harnin c3a7 saysyla eletirildiini greceksiniz.
gittiinizde
de
UTF-8
a har standart ASCII harerinden biri olduu iin Python dorudan bu harn kendisini
gsteriyor. Eer bu harn hangi sayya karlk geldiini grmek isterseniz u kodu
kullanabilirsiniz:
33.3. UNICODE
517
>>> ord("a")
97
Daha nce de sylediimiz gibi, UNICODE sistemi ASCII ile uyumludur. Yani ASCII sisteminde
tanmlanm bir harf hangi say deerine sahipse, UNICODE iindeki btn kod zcleri de
o harf iin ayn sayy kullanr. Yani mesela a har hem ASCIIde, hem UTF-8de 97 says ile
temsil edilir. Bu say 256dan kk olduu iin yalnzca 1 bayt ile temsil edilir. Ancak standart
ASCII dnda kalan karakterler, farkl kod zcler tarafndan farkl saylarla eletirilecektir.
Bununla ilgili yle bir alma yapabiliriz:
kod_zcler = ['UTF-8', 'cp1254', 'latin-1', 'ASCII']
harf = ''
for k in kod_zcler:
try:
print("'{}' karakteri {} ile {} olarak "
"ve {} saysyla temsil edilir.".format(harf, k,
[Link](k),
ord(harf)))
except UnicodeEncodeError:
print("'{}' karakteri {} ile temsil edilemez!".format(harf, k))
karakteri
karakteri
karakteri
karakteri
Bu ufak program kullanarak hangi karakterin hangi kod zc ile nasl temsil edildiini (veya
temsil edilip edilemediini) grebilirsiniz.
Anlam
Karakter temsil edilemiyorsa hata verilir
Temsil edilemeyen karakter grmezden gelinir
Temsil edilemeyen karakterin yerine bir ? iareti koyulur
Temsil edilemeyen karakter yerine XML karl koyulur
strict zaten ntanml deerdir. Dolaysyla eer errors parametresine herhangi bir deer
vermezsek Python sanki strict deerini vermiiz gibi davranacak ve ilgili karakter kodlamas
ile temsil edilemeyen bir karakter ile karlaldnda hata verecektir:
>>> "bu Trke bir cmledir.".encode("ascii")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in
position 4: ordinal not in range(128)
Burada ise replace deerini kullandk. Bylece temsil edilemeyen karakterlerin yerine birer
? iareti koyuldu:
>>> "bu Trke bir cmledir.".encode("ascii", errors="xmlcharrefreplace")
b'bu Türkçe bir cümledir.'
33.3. UNICODE
519
Burada biz open() fonksiyonunu iki farkl parametre ile birlikte kullandk. Ancak aslnda
belirtmemiz gereken nemli bir parametresi daha var bu fonksiyonun. te bu parametrenin
ad encoding dir.
Gelin imdi bu parametrenin ne olduuna ve nasl kullanldna bakalm:
encoding
Tahmin edebileceiniz gibi, encoding parametresi bir dosyann hangi kod zc ile
alacan belirtmemizi salar. Pythonda dosyalar ntanml olarak locale adl bir modln
getpreferredencoding() adl fonksiyonunun gsterdii kod zc ile alr. Siz de
dosyalarnzn varsaylan olarak hangi kod zc ile alacan renmek iin u komutlar
yazabilirsiniz:
>>> import locale
>>> [Link]()
Diyelim ki amak istediiniz dosya cp1254 adl kod zc ile kodlanm olsun. Eer siz bu
dosyay aarken cp1254 adl kod zcy deil de baka bir kod zcy yazarsanz elbette
dosyadaki karakterler dzgn grntlenemeyecektir.
rnein cp1254 ile kodlanm bir belgeyi UTF-8 ile amaya kalkrsanz veya siz hibir kod
zc belirtmediiniz halde kullandnz iletim sistemi ntanml olarak dosyalar amak
iin cp1254 harici bir kod zcy kullanyorsa, dosyay okuma esnasnda una benzer bir
hata alrsnz:
>>> f = open("[Link]", encoding="utf-8")
>>> [Link](50)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python33\lib\[Link]", line 300, in decode
(result, consumed) = self._buffer_decode(data, [Link], final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xde in position 79: invalid
continuation byte
520
Grdnz gibi, dosyamz bizim kullanmaya altmz kod zcden (UTF-8) farkl bir
kod zc ile (cp1254) kodlanm olduu iin, doal olarak karakterler doru saylarla
eletirilemiyor. Bu da kanlmaz olarak yukardaki hatann verilmesine sebep oluyor.
Aslnda siz bu hatay tanyorsunuz. encode() metodunu anlatrken bunun ne olduundan ve
bu hataya kar neler yapabileceinizden sz etmitik.
Hatrlarsanz bu tr hatalara kar ne tepki verileceini belirleyebilmek iin encode()
metodunda errors adl bir parametreyi kullanabiliyorduk. te open() fonksiyonunda da ayn
errors parametresi bulunur.
errors
Dediimiz gibi, bir dosyann doru grntlenebilmesi ve okunabilmesi iin, sahip olduu
kodlama biiminin doru olarak belirtilmesi gerekir. Ama okuyacanz dosyalarn hangi
kodlama sistemine sahip olduunu doru tahmin etmeniz her zaman mmkn olmayabilir.
Byle durumlarda, programnzn kmesini nlemek iin eitli stratejiler belirlemeniz
gerekir.
Bir nceki blmde verdiimiz rnekten de grdnz gibi, eer Python, almaya allan
dosyadaki karakterleri encoding parametresinde gsterilen kod zc ile zemezse
ntanml olarak bir hata mesaj retip programdan kacaktr. Ancak sizin istediiniz ey her
zaman bu olmayabilir. Mesela dosyadaki karakterler doru kodlanamasa bile programnzn
kmemesini tercih edebilirsiniz. te bunun iin errors parametresinden yararlanacaksnz.
Bu parametreyi encoding() metodundan hatrlyorsunuz. Bu parametre orada nasl
kullanlyorsa, open() fonksiyonunda da ayn ekilde kullanlr. Dikkatlice bakn:
>>> f = open(dosya_ad, encoding='utf-8', errors='strict')
33.3. UNICODE
521
33.4.1 repr()
nceleyeceimiz ilk fonksiyonun ad repr(). Esasnda biz bu fonksiyonu nceki derslerimizde
de birka rnekte kullanmtk.
Belki o zaman bu fonksiyonun ne ie yaradn
deneme-yanlma yoluyla anlam olabilirsiniz.
Eer henz bu fonksiyonun grevini
anlamadysanz da mesele deil. Bu blmde bu fonksiyonu ve ilevini ayrntl bir ekilde
anlatmaya alacaz.
Dilerseniz repr() fonksiyonunu anlatmaya bir rnek ile balayalm.
imdi Pythonn etkileimli kabuunu aarak u kodu yazn:
>>> "Python programlama dili"
Dikkat ettiyseniz, yukardaki kodlarn ktsnda karakter dizisi trnak iaretleri iinde
gsteriliyor. Eer bu karakter dizisini print() fonksiyonu iine yazarsanz o trnak iaretleri
kaybolacaktr:
>>> print("Python programlama dili")
Python programlama dili
522
Grdnz gibi, ilk kodun ktsnda satr ba karakteri (\n ) grnrken, ikinci kodun
ktsnda bu karakter grnmyor (ama ilevini yerine getiriyor. Yani satr bana geilmesini
salyor).
te bunun sebebi, ilk kodun Pythonn bak asn yanstrken, ikinci kodun bizim bak
amz yanstmasdr.
Peki bu bilgi bizim ne iimize yarar?
imdi yle bir rnek dnn:
Diyelim ki elimizde yle bir deiken var:
>>> a = "elma "
Grdnz gibi, bu ktya bakarak, a deikeninin tuttuu karakter dizisinin son tarafnda
bir adet boluk karakteri olduunu anlayamyoruz. Bu yzden bu deikeni yle bir program
iinde kullanmaya altmzda neden bozuk bir kt elde ettiimizi anlamak zor olabilir:
>>> print("{} kilo {} kald!".format(23, a))
23 kilo elma
kald!
Grdnz gibi, elma karakter dizisinin son tarafnda bir boluk olduu iin elma ile kald
kelimeleri arasnda gereksiz bir aklk meydana geldi.
Bu boluu print() ile gremiyoruz, ama bu deikeni print() olmadan yazdrdmzda o
boluk da grnr:
>>> a
'elma '
Daha nce de dediimiz gibi, banda print() olmayan ifadeler, bir dosyaya yazlp
altrldnda ktda grnmez. O halde biz yukardaki zellikten yazdmz programlarda
nasl yararlanacaz. te burada yardmmza repr() adl bir fonksiyon yetiecek. Bu
fonksiyonu yle kullanyoruz:
print(repr("karakter dizisi\n"))
523
'karakter dizisi\n'
Grdnz gibi hem trnak iaretleri, hem de satr ba karakteri ktda grnyor. Eer
repr() fonksiyonunu kullanmasaydk yle bir kt alacaktk:
karakter dizisi
Bildiiniz gibi, \n ka dizisi bir alt satra gememizi salyor. te r adl ka dizisi \n ka
dizisinin bu ilevini basklayarak, bizim \n ka dizisinin kendisini kt olarak verebilmemizi
salyor.
O halde bu noktada size yle bir soru sormama izin verin:
Acaba bir deikene atanm ka dizilerinin ilevini nasl basklayabiliriz?
elimizde yle bir deiken bulunuyor olsun:
Yani mesela
yeni_satr = "\n"
524
33.4.2 ascii()
ascii() fonksiyonu biraz nce rendiimiz repr() fonksiyonuna ok benzer. rnein:
>>> repr("asds")
"'asds'"
>>> ascii("asds")
"'asds'"
Bu iki fonksiyon, ASCII tablosunda yer almayan karakterlere kar tutumlar ynnden
birbirlerinden ayrlr. rnein:
>>> repr("")
"''"
>>> ascii("")
"'\\u0130'"
ascii() fonksiyonunun UNICODE kod konumlarn gsterme zelliinin bir benzerini daha
nce rendiimiz encode() metodu yardmyla da elde edebilirsiniz:
>>> "".encode("unicode_escape")
b'\\u20ac'
Ancak ascii() fonksiyonunun str tipinde, encode() metodunun ise bytes tipinde bir kt
verdiine dikkat edin.
33.4.3 ord()
Bu fonksiyon, bir karakterin say karln verir:
33.4. Konu ile ilgili Fonksiyonlar
525
>>> ord("\n")
10
>>> ord("")
8364
33.4.4 chr()
Bu fonksiyon, bir saynn karakter karln verir:
>>> chr(10)
'\n'
>>> chr(8364)
''
526
BLM 34
Bu blme gelinceye kadar veri tipi olarak karakter dizilerinden, listelerden ve dosyalardan
sz etmitik. Bu blmde ise Python programlama dilindeki iki veri tipinden daha sz
edeceiz. Birbirleriyle dorudan balantl olduklar iin bu blmde birlikte ele alacamz
bu veri tiplerinin ad baytlar(bytes ) ve bayt dizileri (bytearrays ).
Bu blmde yalnzca baytlar ve bayt dizileri adl veri tiplerinden sz etmeyeceiz. Bu iki yeni
veri tipini bilgi daarcmza eklemenin yansra, nceki blmlerde rendiimiz konular
zihnimizde pekitirmeye ve salamlatrmaya da devam edeceiz.
34.1 Giri
Bilgisayar teknolojisi ve bilimi asndan karakter tamamen soyut bir kavramdr. Son birka
blmdr stne basa basa tekrar ettiimiz gibi, karakter dediimiz ey, bilgisayarlarn
anlayabildii tek kavram olan saylara biz insanlarn atad birtakm iaretlerden ibarettir.
Dolaysyla bilgisayarlar asndan karakterler deil, ikili sayma dzenindeki birtakm saylar,
yani bitler ve baytlar vardr.
Teknik olarak 1 bit, ikili sayma sistemindeki her bir basamaa verilen isimdir. Zaten bit
kelimesinin de ngilizcede ikili basamak anlamna gelen binary digit ifadesinin ksaltmas
olduunu geen blmde renmitiniz.
rnein ikili sayma sistemindeki 0, bir bitlik bir say iken, 100 bitlik bir saydr. Bu bitlerin
8 tanesi bir araya gelince bayt denen birimi oluturur. Yani bayt, 8 adet bitten oluan bir
birimdir. Nasl bir dzinede 10, bir destede de 12 e olmasn biz insanlar tercih etmi ve
belirlemisek, bir baytta da 8 bit olmasn yine biz insanlar tercih etmi ve belirlemiizdir.
nceki derslerimizde de rendiimiz gibi, 8 adet bit, yani 1 bayt, Geniletilmi ASCII
sisteminde bir adet karakteri temsil etmek iin kullanlabilecek en byk birim olarak
tasarlanmtr. Yani Geniletilmi ASCII tablolarnn en sonundaki 255 numaral karakteri
temsil edebilmek iin 8 adet bit, yani toplam 1 bayt kullanmamz gerekir. Standart ASCII
sistemi ise 7 bitlik bir sistem olduu iin, bir adet karakteri temsil etmek iin kullanlabilecek
en byk birimin 7 bit olduunu biliyorsunuz. Dolaysyla ASCII sistemindeki son karaktere
karlk gelen 127. sayy temsil edebilmek iin toplam 7 bit yeterlidir.
Farkl bir sistem olan UTF-8 ise birden fazla bayt kullanarak ok sayda karakteri temsil etmeye
imkan tanr. UTF-8 ile, duruma gre 1, 2, 3 veya 4 bayt kullanarak, UNICODE sistemi iinde
tanmlanm btn karakterleri temsil edebilirsiniz. UTF-8, deiken boyutlu bir kodlama
sistemi olmas sayesinde, bir karakteri temsil edebilmek iin ka bayt gerekiyorsa, o karakteri
temsil etmek iin o kadar bayt kullanr. Ama mesela UTF-32 adl kod zc hangi karakter
527
olursa olsun hepsini 4 bayt (32 bit) ile temsil eder. Bu durumda aslnda tek baytla temsil
edilebilecek a, b, c gibi karakterler de bou bouna 4 bayt yer kaplam olur. Zaten UTF-8in
bu kadar yaygn ve gzde olmasnn nedeni de hem ok sayda karakteri kodlayabilmesi, hem
de bu ii yaparken tasarruu olmay baarabilmesidir.
Python programlama dilinde karakter dizileri UNICODE kod konumlar eklinde temsil
edilir. Dolaysyla str ad verilen veri tipi esasnda karakter dizilerini birtakm UNICODE kod
konumlar eklinde gsteren soyut bir yapdr. Yani biz Pythonda karakter dizileri zerinde
ilem yaparken aslnda baytlarla deil, UNICODE kod konumlar ile muhatap oluyoruz. Ancak
UNICODE kod konumlar da tamamen soyut kavramlardr. Bunlar bilgisayarn belleinde
bu ekilde temsil edemezsiniz ya da bu kod konumlarn herhangi bir a zerinden baka
bilgisayarlara iletemezsiniz. Bu kod konumlarn anlaml bir ekilde kullanabilmek iin
ncelikle bunlar bilgisayarlarn anlayabilecei bir biim olan baytlara evirmeniz gerekir.
nk dediimiz gibi bilgisayarlar yalnzca bitler ve baytlardan anlar. te kod zclerin
grevi de zaten bu kod konumlarn baytlara evirmektir.
Esasnda programclk maceranz boyunca genellikle metin ihtiyalarnz UNICODE kod
konumlar zerinden halledeceksiniz. Python sistemdeki ntanml kod zcy kullanarak
bu kod konumlarn alttan alta bayta evirip bellekte saklayacaktr. Ama eer yazdnz
programlarda herhangi bir ekilde dorudan baytlarla muhatap olmanz gerekirse str veri
tipini deil, bytes adl baka bir veri tipini kullanacaksnz. rnein ikili (binary ) dosyalar
zerinde eitli almalar yapacaksanz ve bu ikili dosyalara birtakm veriler girecekseniz,
gireceiniz bu veriler bytes tipinde olacaktr.
Btn bu sebeplerden tr, str ve bytes veri tipleri arasndaki fark anlamak, yazdnz
programlarn kararll ve salaml asndan byk nem tar. O anda elinizde olan
verinin hangi tipte olduunu bilmezseniz, bu verinin, programnzn almas esnasnda
size ne tr tuzaklar kurabileceini de kestiremezsiniz. rnein btn karakterlerin 1 bayt
olduunu ve bunlarn da yalnzca 0 ile 127 aras saylarla temsil edilebileceini zanneden
yazlmclarn tasarlad programlara Trke karakterler girdiinizde nasl bu programlar
patr patr dklyorsa, eer siz de baytlar ve karakterler arasndaki fark anlamazsanz sizin
yazdnz programlar da hi beklemediiniz bir anda tkezleyebilir.
rnein yazdnz bir programn bir aamasnda programa yalnzca tek karakterlik verilerin
girilmesi temeli zerinden bir ilem yaptnz dnn. Yani programnz iinde yapacanz
bir ilem, birden fazla karakter giriinin engellenmesini gerektiriyor olsun.
Bunun iin yle bir ey yazm olun:
a = "k"
if len(a) > 1:
print("Ltfen yalnzca tek bir karakter giriniz!")
else:
print("Teekkrler!")
Ben burada temsili olarak a adl bir deiken oluturdum ve rnek olmas asndan da bunun
deerini k olarak belirledim. Bu deerlerle programmz dzgn bir ekilde alr. nk a
deikeninin deeri tek bir karakter olan k har. Ama eer a deikeninin deeri mesela kz
gibi bir ey olsayd programmz Ltfen yalnzca tek bir karakter giriniz! uyars verecekti...
imdi bu a deikeninin sizin tarafnzdan belirlenmediini, bu deerin baka bir kaynaktan
geldiini dnn. Eer size bu deeri gnderen kaynak, bu deeri UNICODE kod konumu
olarak gnderiyorsa programnz dzgn alr. Ama peki ya gelen bu veri bayt olarak
geliyorsa ne olacak?
528
Yukarda verdiimiz rnein neden nemli olduunu, daha dorusu bu rnekle ne demek
istediimiz ve nereye varmaya altmz anlamam olabilirsiniz. Ama endie etmenize
hi gerek yok. Zira bu blmde yukarda sorduumuz sorunun cevabn derinlemesine ele
alacaz. Bu blmn sonuna vardmzda neler olup bittiini ve baytlarn neden bu kadar
nemli olduunu gayet iyi anlyor olacaksnz.
Burada kardiz adl deikenin deeri, bir baytlk bir karakter dizisidir. Bunu len() fonksiyonu
ile teyit edelim:
>>> len(kardiz)
1
Burada ise kardiz adl deikenin deerinin ka baytlk bir karakter dizisi olduu, yani bir
bakma len() fonksiyonunun ne kt verecei iletim sisteminden iletim sistemine farkllk
gsterir. Eer kullandnz iletim sistemi Windows ise muhtelemen len(kardiz) komutu
1 kts verecektir. Ama eer bu komutu GNU/Linux datmlarndan birinde veriyorsanz
alacanz kt byk ihtimalle 2 olacaktr.
Dediimiz gibi, Python2de str veri tipi bize bir dizi bayt verir. Dolaysyla bu veri tipinin iinde
tuttuu karakter dizisinin ka bayt ile gsterilecei, sistemdeki ntanml kod zcnn
hangisi olduuna baldr. Kullandnz iletim sisteminde ntanml kod zcnn hangisi
olduunu u komutla bulabilirsiniz:
>>> import locale
>>> [Link]()
529
>>> len("")
Bu komutu hangi iletim sisteminde verdiinize bal olarak yukardaki komuttan alacanz
kt farkl olacaktr. str tipi Python2de karakter dizilerini bayt olarak temsil eder. Bu temsilin
de hangi kurallara gre yaplaca kullanlan kod zcye baldr. Eer karakter dizileri
baytlara evrilirken cp1254 adl kod zc kullanlrsa, bu kod zc simgesini tek bayt
ile gsterilebildii iin yukardaki komut 1 kts verir. Ama UTF-8 adl kod zc simgesini
3 baytla gsterebildii iin yukardaki komutun kts da buna paralel olarak 3 olacaktr.
str veri tipi ile gsterilen bu karakter dizilerinin iindeki baytlara ulamak iin u yntemi
kullanabilirsiniz:
>>> ""[0]
'\xc5'
>>> ""[1]
'\x9f'
Grdnz gibi, str veri tipi gerekten de bize bir dizi bayt veriyor. Eer karakter dizilerini
baytlarna gre deil de sahip olduklar karakter saysna gre saymak isterseniz bunlar
UNICODE olarak tanmlanz gerekiyor:
>>> len(u'')
1
Python3 ile birlikte yukarda bahsettiimiz durumda baz deiiklikler oldu. Artk str veri tipi
UNICODE kod konumlarn dndryor. Dolaysyla artk her karakter dizisi, sahip olduklar
karakter saysna gre saylabiliyor:
>>> len("")
1
>>> len("")
1
te eer Python2deki str veri tipini elde etmek istiyorsanz, Python3te bytes adl yeni veri
tipini kullanmanz gerekiyor.
Bylece bo bir liste tanmlam olduk. Ayn ekilde karakter dizilerini de yle tanmlyorduk:
>>> kardiz = ''
Bu ekilde de bo bir karakter dizisi tanmlam olduk. te bo bir bayt tanmlamak iin de
u yapy kullanyoruz:
530
Grdnz gibi, gerekten de bayt tipinde bir veri tanmlamz. Nasl karakter dizileri str,
listeler list ifadesiyle gsteriliyorsa, baytlar da bytes ifadesi ile gsterilir.
Peki bu ekilde bir bayt veri tipi tanmlamak ne iimize yarar?
Hatrlarsanz bayt veri tipini ikili (binary ) dosyalar anlatrken de grmtk. Orada da
sylediimiz gibi, ikili dosyalar okuduunuzda elde edeceiniz ey karakter dizisi deil bayttr.
Ayn ekilde, ikili dosyalara da ancak baytlar yazabilirsiniz. Dolaysyla eer ikili dosyalarla
birtakm ilemler yapacaksanz bu bayt veri tipini youn olarak kullanacanzdan hi pheniz
olmasn. Yani bayt veri tipi kolayca grmezden gelebileceiniz gereksiz bir veri tipi deildir.
Ama ASCII dnda kalan karakterleri de bayta dntrmenin bir yolu var. Bunun iin
bytes() adl bir fonksiyondan yararlanacaz:
>>> b = bytes("", "utf-8")
Grdnz gibi, ilgili karakterin hangi kod zc ile kodlanacan belirterek, bayt tipinde
bir veri oluturabiliyoruz.
Tahmin edebileceiniz gibi, bytes() fonksiyonu, belirttiimiz kod zc ile kodlanamayan
karakterlerle karlalmas durumunda ne yaplacan belirlememizi salayan errors adl bir
parametreye de sahiptir:
>>> b = bytes("Frat", "ascii", errors="xmlcharrefreplace")
>>> b
b'Fırat'
531
>>> dir(bytes)
Listeye baktnzda bu metotlar karakter dizilerinin metotlar ile hemen hemen ayn
olduunu greceksiniz. Baytlarn metotlar arasnda olup da karakter dizilerinin metotlar
arasnda olmayan metotlar u ekilde elde edebilirsiniz:
>>> for i in dir(bytes):
...
if i not in dir(str):
...
print(i)
decode
fromhex
Grdnz gibi, decode() ve fromhex() adl metotlar baytlarda var, ama karakter dizilerinde
yok. O yzden biz de bu blmde yalnzca bu iki metodu incelemekle yetineceiz. nk teki
metotlar zaten karakter dizilerinden tanyorsunuz.
34.5.1 decode
Hatrlarsanz karakter dizilerinin encode() adl bir metodu vard. Bu metot yardmyla
karakter dizilerini belli bir kodlama biimine gre kodlayabiliyor, yani bunlar baytlara
evirebiliyorduk. Mesela harni UTF-8 ile kodlayalm:
>>> "".encode("utf-8")
b'\xc4\xb0'
te bu kodlama ilemini tersine evirebilmek, yani baytlar belli bir kodlama biimine gre
karakter dizilerine dntrebilmek iin decode() metodundan yararlanacaz:
>>> b"\xc4\xb0".decode("utf-8")
''
Grdnz gibi, cp1254 adl kod zc bu bayt zebiliyor, ama yanl zyor! nk
bu baytn gsterdii say cp1254 adl kod sayfasnda ye deil, baka bir karaktere karlk
532
geliyor. Aslnda baka iki karaktere, yani C4 ve B0 ile gsterilen ve karakterlerine karlk
geliyor... Bu durumu [Link] adresine gidip kendiniz de
grebilirsiniz.
Bu baytlar bir de ASCII ile zmeye alalm:
>>> b"\xc4\xb0".decode("ascii")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal
not in range(128)
Elbette, bu karakter 128den byk bir sayya karlk geldii iin ASCII tarafndan
zlemeyecektir.
34.5.2 fromhex
Bu metot, onaltl sayma sistemindeki bir saydan oluan bir karakter dizisini alp, bayta
dntrr. Bu metodu yle kullanyoruz:
>>> [Link]("c4b0")
b'\xc4\xb0'
Grdnz gibi, bu metot bir onaltl say olan c4b0 alp, bize bir bayt nesnesi veriyor.
b = b'PDF'
v = b'-1.7'
b = b + v
b
b'PDF-1.7'
Ama Python programlama dilinde bytes veri tipi dnda, baytlara ilikin ikinci veri tipi daha
bulunur. bytearray adl bu veri tipi, bytes veri tipinin aksine, zerinde deiiklik yaplabilen
bir veri tipidir.
Pythonda bytearray veri tipini u ekilde tanmlyoruz:
>>> pdf = bytearray(b'PDF-1.7')
Grdnz gibi, bir bayt dizisi tanmlayabilmek iin bytearray() adl bir fonksiyondan
faydalanyoruz.
533
534
19. lower
20. lstrip
21. maketrans
22. partition
23. replace
24. rnd
25. rindex
26. rjust
27. rpartition
28. rsplit
29. rstrip
30. split
31. splitlines
32. startswith
33. strip
34. swapcase
35. title
36. translate
37. upper
38. zll
535
BLM 35
Szlkler
u ana kadar Python programlama dilinde veri tipi olarak karakter dizilerini, saylar, listeleri,
demetleri ve dosyalar rendik. Yeni veri tipleri rendike Pythondaki hareket alanmzn
da genilediini siz de farketmisinizdir. Bu blmde yine Pythondaki nemli veri tiplerinden
birini inceleyeceiz. Bu defa inceleyeceimiz veri tipinin ad szlk. ngilizcede buna
dictionary diyorlar.
Szlkler de, tpk daha nceki derslerimizde rendiimiz karakter dizileri, saylar, listeler,
demetler ve dosyalar gibi programlama maceramz boyunca ilerimizi bir hayli kolaylatracak
ve hareket imkanmz geniletecek veri tiplerinden biridir.
teki veri tiplerinde olduu gibi, szlklerin de birtakm metotlar vardr. te bu blmde
hem genel olarak szlklerden sz edeceiz, hem de bu veri tipinin metotlarn en ince
ayrntsna kadar inceleyeceiz.
Szlk denen veri tipi Python programlama dilinin son derece kullanl ve ie yarar
aralarndan bir tanesidir.
Programlama alannda ilerledike, bu veri tipinin neler
yapabileceini grp aracanz rahatlkla syleyebilirim.
Esasnda biz daha nceki derslerimizin birinde szlk adl bu veri tipinden stnkr de olsa
sz etmitik. Yani aslnda bu veri tipiyle tanklmz eskiye dayanyor.
Hatrlayacaksnz, karakter dizilerinin [Link]() ve translate() adl metotlarn
anlatrken, Trkeye zg karakterleri ve bunlarn noktasz karlklarn ieren eviri_tablosu
adn verdiimiz yle bir deiken tanmlamtk:
eviri_tablosu = {"":
"":
"":
"":
"":
"":
"":
"":
"":
"":
"":
"":
"O",
"c",
"U",
"C",
"I",
"i",
"G",
"o",
"s",
"u",
"S",
"g"}
536
Hem eski bilgilerimize dayanarak, hem de yukarda anlattklarmzdan yola karak szlk veri
tipinin ne olduuna dair halihazrda kafamzda bir kir olumu olduunu syleyebiliriz.
Szlkler teki veri tiplerine kyasla biraz farkl bir grne sahip bir veri tipidir. Biz birazdan
szlklerin yapsn derinlemesine inceleyeceiz.
Ancak szlklerin yapsn incelemeye gemeden nce renmemiz gereken bir ey var.
Tpk teki veri tiplerinde olduu gibi, szlklerle de alabilmek iin ncelikle bu veri tipini
tanmlam olmamz gerekiyor. O yzden isterseniz szlklerin yapsndan sz etmeden nce
bir szl nasl tanmlayacamzdan bahsedelim.
Burada, ierii szlk veri tipi olan kelimeler adl bir deiken tanmladk. Grdnz gibi,
listelere benzer bir ekilde szlk veri tipi de iinde farkl veri tiplerini barndran, kapsayc
bir veri tipidir. Burada szlmz iki adet karakter dizisinden oluuyor.
Yukardaki szl nasl tanmladmza ok dikkat edin. Nasl ki listelerin ayrt edici zellii
keli parantezlerdi, szlklerin ayrt edici zellii de kme parantezleridir.
Esasnda szlk dediimiz ey en basit haliyle yle grnr:
>>> szlk = {}
Bu rnek bo bir szlktr. sterseniz yukardaki veri tipinin gerekten de bir szlk olduunu
kantlayalm:
>>> type(szlk)
<class 'dict'>
Python programlama diline zellikle yeni balayanlar, szlklerin grn nedeniyle bir
szlkteki e says konusunda tereddte kaplabilir, rnein yukardaki szln 2 eden
35.1. Szlk Tanmlamak
537
olutuu yanlgsna debilir. O halde bu noktada size yle bir soru sormama izin verin:
Acaba bu szlkte ka e var? Hemen bakalm:
>>> len(kelimeler)
1
Demek ki elimizdeki veri tipi bir adet eye sahip bir szlkm. Grdnz gibi, "kitap":
"book" ifadesi tek bana bir e durumundadr. Yani burada kitap karakter dizisini ayr,
book karakter dizisini ayr bir e olarak almyoruz. Bu ikisi tek bir szlk esi oluturuyor.
Hatrlarsanz, listelerde eleri birbirinden ayrmak iin virgl iaretlerinden yararlanyorduk.
Szlklerde de birden fazla eyi birbirinden ayrmak iin virgl iaretlerinden yararlanacaz:
>>> kelimeler = {"kitap": "book", "bilgisayar": "computer"}
Teknik olarak baktmzda bu kodlarda hibir problem yok. Ancak szlkleri byle saa doru
uzayacak ekilde tanmladmzda okunakll azaltm oluyoruz. Bu yzden yukardaki
szl yle yazmay tercih edebiliriz:
szlk = {"kitap"
:
"bilgisayar" :
"programlama":
"dil"
:
"defter"
:
"book",
"computer",
"programming",
"language",
"notebook"}
Bu ekilde szlkteki eler arasndaki iliki daha belirgin, yazdnz kodlar da daha okunakl
bir hale gelecektir.
Pythonda bir szlk oluturmann baka yollar da olmakla birlikte, en temel szlk
oluturma yntemi yukardaki rneklerde gsterdiimiz gibidir. Biz ilerleyen sayfalarda
szlk oluturmann farkl yntemlerini de ele alacaz. Ancak imdilik szlk tanmlama
konusunu burada noktalayp szlklerle ilgili nemli bir konuya daha deinelim.
538
"dil"
"defter"
: "language",
: "notebook"}
Bu szlkte birtakm Trke kelimeler ve bunlarn ngilizce karlklar var. imdi mesela bu
szlkteki kitap adl eye erielim:
print(szlk["kitap"])
Yukardaki rnekten anladmz gibi, szlk elerine erimek iin yle bir forml
kullanyoruz:
szlk[szlk_esinin_ad]
Ayn ekilde szlk deikeni iindeki bilgisayar esinin karln almak istersek yle bir
kod yazyoruz:
print(szlk["bilgisayar"])
"O",
"c",
"U",
"C",
"I",
"i",
"G",
"o",
"s",
"u",
"S",
"g"}
Mesela bu szlkteki esinin karln elde etmek iin yle bir kod yazdmz gayet
iyi hatrlyorsunuz:
print(eviri_tablosu[""])
Grdnz gibi szlkteki adl eyi parantez iinde belirttiimiz zaman, Python bize bu
enin karsndaki deeri veriyor. Dolaysyla szlk iinde esinin karl O har
olduu iin de ktmz O oldu.
Szln teki elerini ise u ekilde alabiliyoruz:
539
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
Ancak kod tekrarndan kanmak iin yukardaki kodlar u ekilde sadeletirme imkanmzn
da olduunu biliyorsunuz:
for i in eviri_tablosu:
print(eviri_tablosu[i])
Grdnz gibi, szlk iinde iki nokta st ste iaretinin sol tarafnda grnen eleri
keli parantez iinde yazarak, iki nokta st ste iaretinin sa tarafndaki deerleri elde
edebiliyoruz.
Eer bir szlk iinde bulunmayan bir eye erimeye alrsak Python bize KeyError tipinde
bir hata mesaj verecektir. Mesela yukardaki szl temel alacak olursak yle bir sorgu
hata verecektir:
>>> print(eviri_tablosu["Z"])
Traceback (most recent call last):
File "[Link]", line 14, in <module>
print(eviri_tablosu["Z"])
KeyError: 'Z'
Szlkte Z kayd bulunmad iin doal olarak Pythonn bize bir hata mesaj gstermekten
baka aresi kalmyor.
Szlkler ile ilgili epey bilgi edindik. Dilerseniz bu rendiklerimizi rnek bir uygulama
zerinde somutlatrmaya alalm. Mesela Pythondaki szlkleri kullanarak basit bir telefon
defteri uygulamas yazalm:
telefon_defteri = {"ahmet z" :
"mehmet su":
"seda naz" :
"eda ala" :
"0532
"0543
"0533
"0212
532
543
533
212
32
42
33
12
32",
42",
33",
12"}
Burada ncelikle isimler ve telefon numaralarndan oluan, szlk veri tipinde bir telefon
defteri oluturduk:
telefon_defteri = {"ahmet z" :
"mehmet su":
"seda naz" :
"eda ala" :
540
"0532
"0543
"0533
"0212
532
543
533
212
32
42
33
12
32",
42",
33",
12"}
Ardndan da telefon defterinde sorgulama yapacak olan kullancya gstereceimiz cevap iin
bir ablon oluturuyoruz:
cevap = "{} adl kiinin telefon numaras: {}"
Mesela kullanc ahmet z ismini sorgulamsa ona yle bir cevap vereceiz:
"ahmet z adl kiinin telefon numaras 0532 532 32 32"
Eer aranan isim telefon defterinde varsa, bir nceki admda tanmladmz cevap ablonuna
gre kullancy bilgilendiriyoruz. Ama eer eer isim defterde yoksa, programmz hata
veriyor. Bunu nlemek iin yle bir kod yazabilirsiniz:
telefon_defteri = {"ahmet z" :
"mehmet su":
"seda naz" :
"eda ala" :
"0532
"0543
"0533
"0212
532
543
533
212
32
42
33
12
32",
42",
33",
12"}
541
Burada iki nokta st ste iaretinden nce ve sonra birer tane karakter dizisi gryoruz.
Bu karakter dizileri kitap ve book. Dediimiz gibi, szlkler de tpk listeler gibi, farkl
veri tiplerinin bir araya gelmesi ile oluan birleik/kapsayc bir veri tipidir. Dolaysyla bir
szlk iinde sadece karakter dizilerini deil, baka veri tiplerini de grebilirsiniz. lerleyen
sayfalarda szlklere ilikin daha karmak rnekler verdiimizde szlklerin hangi veri
tiplerini ierebileceini de greceiz.
Ne dedik? Szlk iinde iki nokta st ste iaretinin solunda ve sanda kitap ve book adl
karakter dizileri var. Teknik olarak, iki nokta st ste iaretinin solundaki karakter dizisine
anahtar (key ), sandaki karakter dizisine ise deer (value ) ad verilir. Bu bilgilere bakarak
szlk iin yle bir tanm verebiliriz:
Szlkler; anahtar ve deer iftlerinin birbirleriyle eletirildii bir veri tipidir.
Dolaysyla szlkler bu anahtar ve deer iftleri arasnda birebir iliki kurar.
Mesela yukardaki rnekte kitap esi anahtar, book esi ise deerdir. te szlk
dediimiz ey, bu anahtar ve deer ifti arasnda birebir iliki kuran bir veri tipidir. Yani szlk
adl veri tipi, bir anahtar bir deerle eletirme grevi grr.
Szlklerin bu zelliini, szlk elerine eriirken gayet net bir ekilde grebiliyoruz.
Yukardaki rneklerde tanmladmz szlklerde sadece karakter dizilerini kullandk. Ama
aslnda szlkler farkl veri tiplerinden oluabilir. Mesela:
szlk = {"sfr":
"bir" :
"iki" :
""
:
"drt" :
"be" :
0,
1,
2,
3,
4,
5}
Burada szlk iinde hem saylar hem de karakter dizilerini kullandk. Ayn ekilde szlk
iinde listelere de yer verebiliriz:
szlk = {"Ahmet zkoparan": ["stanbul", "retmen", 34],
"Mehmet Yaz"
: ["Adana", "Mhendis", 40],
"Seda Bayrak"
: ["skenderun", "Doktor", 30]}
Mesela bu szlkte Seda Bayrak adl kiinin bilgilerine ulamak istersek yle bir kod
yazabiliriz:
print(szlk["Seda Bayrak"])
542
Grdnz gibi, szlk iinde Seda Bayrak adl enin karsndaki bilgi listesine
ulaabildik.
stersek szlkleri, ilerinde baka szlkleri barndracak ekilde de tanmlayabiliriz:
kiiler = {"Ahmet zkoparan": {"Memleket": "stanbul",
"Meslek" : "retmen",
"Ya"
: 34},
"Mehmet Yaz"
: {"Memleket": "Adana",
"Meslek" : "Mhendis",
"Ya"
: 40},
"Seda Bayrak"
: {"Memleket": "skenderun",
"Meslek" : "Doktor",
"Ya"
: 30}}
Burada bir liste iinde i ie gemi farkl liste ile kar karyayz. Mesela ilk listenin ilk
esi olan Ahmet adl eye erimek istersek yle bir kod yazmamz gerekiyor:
print(liste[0][0])
te i ie gemi szlklerin elerine ulamak iin de buna benzer bir kod yazmamz
gerekiyor. rnein kiiler adl szlkteki Mehmet Yaz adl kiinin yana ulamak istersek
yle bir ey yazacaz:
print(kiiler["Mehmet Yaz"]["Ya"])
Gelin isterseniz kiiler adl szl kullanarak basit bir irtibat listesi uygulamas yazalm.
Bylece szlklere elimizi altrm oluruz:
kiiler = {"Ahmet zkoparan": {"Memleket": "stanbul",
"Meslek" : "retmen",
"Ya"
: 34},
"Mehmet Yaz"
: {"Memleket": "Adana",
"Meslek" : "Mhendis",
"Ya"
: 40},
"Seda Bayrak"
: {"Memleket": "skenderun",
"Meslek" : "Doktor",
"Ya"
: 30}}
543
arama = input(isim)
ayrnt = input("Memleket/Meslek/Ya? ")
print(kiiler[arama][ayrnt])
Tpk bir nceki telefon defteri uygulamamz gibi, bu irtibat listesi uygulamas da gelitirilmeye
aktr. Ancak henz bu iki uygulamay gelitirmemizi salayacak bilgilerden yoksunuz. Bu
uygulamalar istediimiz kvama sokabilmek iin szlklere dair renmemiz gereken baka
eyler de var.
Szlklerin teki veri tiplerinden nemli bir fark, szlk iinde yer alan elerin herhangi bir
sralama mantna sahip olmamasdr. Yani szlkteki eler asndan sra diye bir kavram
yoktur.
rnein bir liste, demet veya karakter dizisi iindeki elere; bu elerin o liste, demet veya
karakter dizisi iindeki sralarna gre eriebilirsiniz:
>>> liste = ["Ahmet", "Mehmet", "Zeynep"]
>>> liste[0]
'Ahmet'
>>> liste[-1]
'Zeynep'
Grdnz gibi, szlkler zerinde sralamaya dayal bir sorgulama yapmaya altmzda
Python bize bir hata mesaj gsteriyor.
Bu durumun etkilerini urada da grebilirsiniz:
Dikkatlice bakn:
>>> szlk = {'a': '0', 'b': '1', 'c': '2'}
>>> szlk
{'a': '0', 'c': '2', 'b': '1'}
Bu kty iyi inceleyin. Greceiniz gibi, ktda grnen eler bizim szl tanmladmz
sradaki gibi deil. Biz szl a, b ve c eklinde sralayarak tanmladk, ama kt a, c
ve b eklinde oldu. O yzden szlkler zerinde alrken elerin srasna dayal herhangi
bir ilem yapmak hi mantkl deildir. nk szlkteki eleri tanmlarken kullandnz
sralama dzeninin ktda da aynen korunacann herhangi bir garantisi bulunmaz.
544
Bylece szle, anahtar Ahmet, deeri ise Adana olan bir e eklemi olduk.
Szlmzn son durumunu kontrol edelim:
>>> print(szlk)
{'Ahmet': 'Adana'}
Grdnz gibi, Ahmet esi szle eklendi. Artk bu eye normal yollardan ulaabiliriz:
>>> print(szlk["Ahmet"])
Adana
zellikle son ktya dikkatlice bakn. Szle en son Eda esini eklemitik. Ama szl
ekrana bastmzda bu enin szln sonuna deil ortasna bir yere yerletiini gryoruz.
Bu durumun, szlklerin srasz bir veri tipi olmasndan kaynaklandn biliyorsunuz.
Gelin pratik olmas asndan birka rnek daha verelim.
Elimizde yle bir szlk olsun:
>>> personel = {"Mehmet z": "AR-GE Mdr",
...
"Samet Sz": "Genel Direktr",
...
"Sedat Gn": "Proje Mdr"}
545
notlar["Ahmet"] = 45
notlar["Mehmet"] = 77
notlar["Seda"] = 98
notlar["Deniz"] = 95
notlar["Ege"] = 95
notlar["Zeynep"] = 100
Bu noktada szlklerin nemli bir zelliinden bahsetmemiz uygun olacak. Bir szle deer
olarak btn veri tiplerini verebiliriz. Yani:
>>>
>>>
>>>
>>>
>>>
szlk
szlk
szlk
szlk
szlk
=
=
=
=
=
{}
{'a':
{'a':
{'a':
{'a':
1}
(1,2,3)}
'kardiz'}
[1,2,3]}
Grdnz gibi, szlkler deer olarak her trl veri tipini kabul ediyor. Ama durum szlk
anahtarlar asndan byle deildir. Yani szlklere anahtar olarak her veri tipini atayamayz.
Bir deerin anahtar olabilmesi iin, o enin deitirilemeyen (immutable ) bir veri tipi
olmas gerekir. Pythonda imdiye kadar rendiimiz u veri tipleri deitirilemeyen veri
tipleridir:
1. Demetler
2. Saylar
3. Karakter Dizileri
u veri tipleri ise deitirilebilen veri tipleridir:
1. Listeler
546
2. Szlkler
Dolaysyla bir szle ancak u veri tiplerini ekleyebiliriz:
1. Demetler
2. Saylar
3. Karakter Dizileri
u kodlar dikkatlice inceleyin:
nce bo bir szlk oluturalm:
>>> szlk = {}
Yukardakiler, deitirilemeyen veri tipleri olduu iin szlklere anahtar olarak eklenebildi.
Bir de unlara bakalm:
Szlmze anahtar olarak bir liste eklemeye alalm:
>>> l = [1,2,3]
>>> szlk[l] = 'falanca'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
547
Szlmz bu.
deitirelim:
>>> notlar["Ahmet"] = 65
>>> print(notlar)
{'Seda': 98, 'Ege': 95, 'Mehmet': 77, 'Zeynep': 100, 'Deniz': 95, 'Ahmet': 65}
Amacmz bu harerin her birine bir numara vermek. Yani nihai olarak yle bir szlk elde
etmek istiyoruz:
{'':
'v':
'':
'u':
't':
'':
'':
'p':
's':
'r':
'':
'y':
'':
'z':
'e':
'd':
548
8,
26,
22,
24,
23,
18,
10,
19,
21,
20,
25,
27,
3,
28,
5,
4,
'g':
'f':
'a':
'c':
'b':
'm':
'l':
'o':
'n':
'i':
'h':
'k':
'j':
7,
6,
0,
2,
1,
15,
14,
17,
16,
11,
9,
13,
12}
veya:
>>> szlk = {}
>>> for i in range(len(harfler)):
...
szlk[harfler[i]] = i
Bir rnek daha verelim. Diyelim ki elinizde yle bir isim listesi var:
isimler = ["ahmet", "mehmet", "frat", "zeynep", "selma", "abdullah", "cem"]
Amacnz, bu isimleri ve her bir ismin ka harften olutuunu gsteren bir szlk elde etmek.
Yani nihai olarak yle bir ey olsun istiyorsunuz elinizde:
{'zeynep': 6,
'cem': 3,
'abdullah': 8,
'ahmet': 5,
'mehmet': 6,
'frat': 5,
'selma': 5}
Bildiiniz gibi szlkler, her biri birbirinden : iareti ile ayrlan birtakm anahtar-deer
iftlerinden oluuyor. te yukardaki szlk reteci yapsnda biz : iaretinin sol tarafna
isimler adl listedeki her bir eyi; sa tarafna da bu elerin uzunluklarn bir rpda
ekliyoruz.
35.6. Szlk reteleri (Dictionary Comprehensions )
549
BLM 36
Szlklerin Metotlar
Tpk teki veri tiplerinde olduu gibi, szlklerin de birtakm metotlar bulunur. Bu blmde
szlklerin u metotlarn inceleyeceiz:
1. clear()
2. copy()
3. fromkeys()
4. get()
5. items()
6. keys()
7. pop()
8. popitem()
9. setdefault()
10. update()
11. values()
lk olarak keys() metoduyla balayalm.
36.1 keys()
Szlkleri tarif ederken, szlklerin anahtar-deer iftlerinden oluan bir veri tipi olduunu
sylemitik. Bir szl normal yollardan ekrana yazdrrsanz size hem anahtarlar hem de
bunlara karlk gelen deerleri verecektir. Ama eer bir szln sadece anahtarlarn almak
isterseniz keys() metodundan yararlanabilirsiniz:
>>> szlk = {"a": 0,
...
"b": 1,
...
"c": 2,
...
"d": 3}
>>> print([Link]())
dict_keys(['b', 'c', 'a', 'd'])
550
Grdnz gibi, [Link]() komutu bize bir dict_keys nesnesi veriyor. Bu nesneyi
programnzda kullanabilmek iin isterseniz, bunu listeye, demete veya karakter dizisine
dntrebilirsiniz:
>>> liste = list([Link]())
>>> liste
['b', 'c', 'a', 'd']
>>> demet = tuple([Link]())
>>> demet
('b', 'c', 'a', 'd')
>>> kardiz = "".join([Link]())
>>> kardiz
'bcad'
Son rnekte szlk anahtarlarn karakter dizisine dntrmek iin str() fonksiyonunu
deil, karakter dizilerinin join() adl metodunu kullandmza dikkat edin. nk tuple()
ve list() fonksiyonlarnn aksine str() fonksiyonu, szlkteki anahtarlarn nasl bir lte
gre karakter dizisine evrileceine dair bir kural iermez. Zira siz bu szlk anahtarlarn
pek ok farkl ekilde karakter dizisine evirebilirsiniz. rnein eleri karakter dizisi iine
yerletirirken elerin arasna virgl koymak isteyebilirsiniz:
>>> kardiz = ', '.join([Link]())
>>> kardiz
'b, c, a, d'
36.2 values()
keys() metodu bir szln anahtarlarn veriyor. Bir szln deerlerini ise values()
metodu verir:
>>> szlk
{'b': 1, 'c': 2, 'a': 0, 'd': 3}
>>> print([Link]())
dict_values([1, 2, 0, 3])
Grdnz gibi, bu metottan bir dict_values nesnesi alyoruz. Tpk keys() metodunda
olduu gibi, values() metodunda da bu kty baka veri tiplerine dntrme imkanna
sahibiz:
>>> liste = list([Link]())
>>> liste
[1, 2, 0, 3]
36.2. values()
551
Bunun sebebi, szlkteki deerlerin int tipinde olmasdr. Bildiiniz gibi, sadece ayn tip
verileri birbiriyle birletirebiliriz. Eer birletirmek istediimiz veriler birbirinden farkl tipte
ise, bunlar birletirmeden nce bir dntrme ilemi yapmamz gerekir:
>>> kardiz = "".join([str(i) for i in [Link]()])
>>> kardiz
'1203'
Grdnz gibi, szlkteki deerlerin her birini, tek bir liste reteci iinde karakter dizisine
dntrdk ve ortaya kan listeyi karakter dizilerinin join() metodu yardmyla, elerin
arasnda hibir boluk brakmadan kardiz adl bir karakter dizisi iine yerletirdik. Elbette
eer isteseydik bu elerin her birinin arasna bir virgl de koyabilirdik:
>>> kardiz = ", ".join([str(i) for i in [Link]()])
>>> kardiz
'1, 2, 0, 3'
36.3 items()
Bu metot, bir szln hem anahtarlarn hem de deerlerini ayn anda almamz salar:
>>> [Link]()
dict_items([('a', 0), ('c', 2), ('b', 1)])
Grdnz gibi, tek bir liste iinde iki eli demetler halinde hem anahtarlar hem de
deerleri grebiliyoruz. Bu metot sklkla for dngleri ile birlikte kullanlarak bir szln
anahtar ve deerlerinin maniple edilebilmesini salar:
>>>
...
...
a =
c =
b =
552
36.4 get()
Bu metot szlklerin en kullanl metotlarndan biridir. Bu metot pek ok durumda iinizi bir
hayli kolaylatrr.
Diyelim ki yle bir program yazdk:
#!/usr/bin/env python3.0
ing_szlk = {"dil": "language", "bilgisayar": "computer", "masa": "table"}
sorgu = input("Ltfen anlamn renmek istediiniz kelimeyi yaznz:")
print(ing_szlk[sorgu])
Ama akas bu pek verimli bir yaklam saylmaz. Yukardaki yntem yerine szlklerin get()
metodundan faydalanabiliriz. Bakalm bunu nasl yapyoruz:
ing_szlk = {"dil": "language", "bilgisayar": "computer", "masa": "table"}
sorgu = input("Ltfen anlamn renmek istediiniz kelimeyi yaznz:")
print(ing_szlk.get(sorgu, "Bu kelime veritabanmzda yoktur!"))
Grdnz gibi, burada ok basit bir metot yardmyla btn dertlerimizi hallettik.
Szlklerin get() adl metodu, parantez iinde iki adet argman alr. Birinci argman
sorgulamak istediimiz szlk esidir. kinci argman ise bu enin szlkte bulunmad
durumda kullancya hangi mesajn gsterileceini belirtir. Buna gre, yukarda yaptmz
ey, nce sorgu deikenini szlkte aramak, eer bu e szlkte bulunamyorsa da
kullancya, Bu kelime veritabanmzda yoktur! cmlesini gstermekten ibarettir...
Gelin isterseniz bununla ilgili bir rnek daha yapalm.
Diyelim ki bir havadurumu program yazmak istiyoruz. Bu programda kullanc bir ehir ad
girecek. Program da girilen ehre ait havadurumu bilgilerini ekrana yazdracak. Bu program
klasik yntemle u ekilde yazabiliriz:
36.4. get()
553
#!/usr/bin/env python3
soru = input("ehrinizin adn tamam kk harf olacak ekilde yazn:")
if soru == "istanbul":
print("gk grltl ve saanak yal")
elif soru == "ankara":
print("ak ve gneli")
elif soru == "izmir":
print("bulutlu")
else:
print("Bu ehre ilikin havadurumu bilgisi bulunmamaktadr.")
Yukardaki, gayet geerli bir yntemdir. Ama biz istersek bu kodlar get metodu yardmyla
ok daha verimli ve sade bir hale getirebiliriz:
#!/usr/bin/env python3
soru = input("ehrinizin adn tamam kk harf olacak ekilde yazn:")
cevap = {"istanbul": "gk grltl ve saanak yal",
"ankara": "ak ve gneli", "izmir": "bulutlu"}
print([Link](soru, "Bu ehre ilikin havadurumu bilgisi bulunmamaktadr."))
36.5 clear()
Szlklerin, inceleyeceimiz ilk metodu clear(). Bu kelime ngilizcede temizlemek
anlamna gelir. Grevi szlkteki eleri temizlemektir. Yani ii dolu bir szl bu metot
yardmyla tamamen boaltabiliriz:
>>> lig = {"ampiyon": "Adana Demirspor", "ikinci": "Mersin dman Yurdu",
... "nc": "Adana Genlerbirlii"}
554
Grdnz gibi artk lig adl szlmz bombo. clear() metodunu kullanarak bu
szln btn elerini sildik. Ama tabii ki bu ekilde szl silmi olmadk. Bo da olsa
bellekte hl lig adl bir szlk duruyor. Eer siz ligi ortadan kaldrmak isterseniz del adl
bir paracktan yararlanmanz gerekir:
>>> del lig
Kontrol edelim:
>>> lig
NameError: name 'lig' is not defined
Grdnz gibi artk lig diye bir ey yok... Bu szl bellekten tamamen kaldrdk.
clear() adl metodun ne olduunu ve ne ie yaradn grdmze gre baka bir metoda
geebiliriz.
36.6 copy()
Diyelim ki elimizde yle bir szlk var:
>>> hava_durumu = {"stanbul": "yamurlu", "Adana": "gneli", ... "zmir": "bulutlu"}
555
>>> yedek_hava_durumu
{'stanbul': 'yamurlu', 'Adana': 'gneli', 'Mersin': 'sisli', 'zmir': 'bulutlu'}
Grdnz gibi bu defa szlklerin birinde yaplan deiiklik brn etkilemedi... copy
metodu saolsun!...
36.7 fromkeys()
fromkeys() metodu teki metotlardan biraz farkldr. Bu metot mevcut szlk zerinde
ilem yapmaz. fromkeys()in grevi yeni bir szlk oluturmaktr. Bu metot yeni bir szlk
olutururken listeler veya demetlerden yararlanr. yle ki:
>>> elemanlar = "Ahmet", "Mehmet", "Can"
>>> adresler = [Link](elemanlar, "Kadky")
>>> adresler
556
Grdnz gibi ncelikle elemanlar adl bir demet tanmladk. Daha sonra da adresler
adl bir szlk tanmlayarak, fromkeys() metodu yardmyla anahtar olarak elemanlar
demetindeki elerden oluan, deer olarak ise Kadky ieren bir szlk meydana
getirdik.
En bata tanmladmz elemanlar demeti liste de olabilirdi. Hatta tek bana bir karakter
dizisi dahi yazabilirdik oraya...
36.8 pop()
Bu metodu listelerden hatrlyoruz. Bu metot listelerle birlikte kullanldnda, listenin en son
esini silip, silinen eyi de ekrana basyordu. Eer bu metodu bir sra numaras ile birlikte
kullanrsak, listede o sra numarasna karlk gelen e siliniyor ve silinen bu e ekrana
baslyordu. Bu metodun szlklerdeki kullanm da az ok buna benzer. Ama burada fark
olarak, pop metodunu argmansz bir ekilde kullanamyoruz. Yani pop metodunun parantezi
iinde mutlaka bir szlk esi belirtmeliyiz:
>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("prasa", "fasulye"),
... "iecekler": ("su", "kola", "ayran")}
>>> [Link]("meyveler")
Bylelikle szlkte bulunmayan bir eyi silmeye altmzda Python bize bir hata mesaj
gstermek yerine, Silinecek e yok! eklinde daha anlaml bir mesaj verecektir...
36.9 popitem()
popitem() metodu da bir nceki blmde rendiimiz pop() metoduna benzer. Bu
iki metodun grevleri hemen hemen ayndr. Ancak pop() metodu parantez iinde bir
parametre alrken, popitem() metodunun parantezi bo, yani parametresiz olarak kullanlr.
Bu metot bir szlkten rastgele eler silmek iin kullanlr. Daha nce de pek ok kez
sylediimiz gibi, szlkler srasz veri tipleridir. Dolaysyla popitem() metodunun eleri
36.8. pop()
557
silerken kullanabilecei bir sra kavram yoktur. Bu yzden bu metot eleri rastgele silmeyi
tercih eder...
>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("prasa", "fasulye")}
>>> [Link]()
Bu komut szlkten rastgele bir anahtar, deerleriyle birlikte szlkten silecektir. Eer szlk
bosa bu metot bize bir hata mesaj gsterir.
36.10 setdefault()
Bu metot epey enteresan, ama bir o kadar da yararl bir aratr... Bu metodun ne ie yaradn
dorudan bir rnek zerinde grelim:
>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("prasa", "fasulye")}
>>> [Link]("iecekler", ("su", "kola"))
Bu komut yardmyla szlmz iinde iecekler adl bir anahtar oluturduk. Bu anahtarn
deeri ise (su, kola) oldu... Bir de una bakalm:
>>> [Link]("meyveler", ("erik", "ilek"))
('elma', 'armut')
Grdnz gibi, szlkte zaten meyveler adl bir anahtar bulunduu iin, Python ayn
ad tayan ama deerleri farkl olan yeni bir meyveler anahtar oluturmad. Demek ki
bu metot yardmyla bir szlk iinde arama yapabiliyor, eer aradmz anahtar szlkte
yoksa, setdefault() metodu iinde belirttiimiz zellikleri tayan yeni bir anahtar-deer ifti
oluturabiliyoruz.
36.11 update()
nceleyeceimiz son metot update() metodu... Bu metot yardmyla oluturduumuz
szlkleri yeni verilerle gncelleyeceiz. Diyelim ki elimizde yle bir szlk var:
>>> stok = {"elma": 5, "armut": 10, "peynir": 6, "sosis": 15}
Stoumuzda 5 adet elma, 10 adet armut, 6 kutu peynir, 15 adet de sosis var. Diyelim ki daha
sonraki zamanlarda bu stoa mal giri-k oldu ve stoun son hali yle:
>>> yeni_stok = {"elma": 3, "armut": 20, "peynir": 8, "sosis": 4, "sucuk": 6}
Yapmamz gereken ey, stoumuzu yeni bilgilere gre gncellemek olacaktr. te bu ilemi
update() metodu ile yapabiliriz:
>>> [Link](yeni_stok)
>>> print(stok)
{'peynir': 8, 'elma': 3, 'sucuk': 6, 'sosis': 4, 'armut': 20}
558
36.11. update()
559
BLM 37
Bu blmde Pythondaki iki veri tipini daha inceleyeceiz. nceleyeceimiz veri tiplerinin ad
kme ve dondurulmu kme.
zellikle kmeleri rendiimizde, bu veri tipinin kendine has birtakm zellikleri sayesinde
bunlarn kimi zaman hi tahmin bile edemeyeceimiz yerlerde iimize yaradn greceiz.
Normalde uzun uzun kod yazmay gerektiren durumlarda kmeleri kullanmak, bir-iki satrla
ilerimizi halletmemizi salayabilir.
Bu blmde kmeler dnda, bir de dondurulmu kmelerden sz edeceiz. Bu iki veri tipi
birbiriyle ilikilidir. O yzden bu iki veri tipini tek blmde ele alacaz.
sterseniz anlatmaya nce kmelerle balayalm.
37.1 Kmeler
Tpk listeler, demetler, karakter dizileri, saylar ve dosyalar gibi kmeler de Pythondaki veri
tiplerinden biridir. Adndan da az ok tahmin edebileceiniz gibi kmeler, matematikten
bildiimiz kme kavramyla sk skya balantldr. Bu veri tipi, matematikteki kmelerin
sahip olduu btn zellikleri tar. Yani matematikteki kmelerden bildiimiz kesiim,
birleim ve fark gibi zellikler Pythondaki kmeler iin de geerlidir.
Listeler, demetler ve szlklerin aksine kmelerin ayrt edici bir iareti yoktur.
oluturmak iin set() adl zel bir fonksiyondan yararlanyoruz.
Yukardaki bo veri tipinin bir kme olduunu nasl teyit edeceinizi biliyorsunuz:
>>> type(bo_kme)
<class 'set'>
560
Kme
Bylelikle, iinde e barndran ilk kmemizi baaryla oluturduk. Dikkat ederseniz, kme
olutururken listelerden faydalandk. Grdnz gibi set() fonksiyonu iindeki eler bir
liste iinde yer alyor. Dolaysyla yukardaki tanmlamay yle de yapabiliriz:
>>> liste = ["elma", "armut", "kebap"]
>>> kme = set(liste)
Bu daha temiz bir grnt oldu. Elbette kme tanmlamak iin mutlaka liste kullanmak
zorunda deiliz. stersek demetleri de kme haline getirebiliriz:
>>> demet = ("elma", "armut", "kebap")
>>> kme = set(demet)
Kullandmz karakter dizisinin byle uzun olmasna da gerek yok. Tek karakterlik dizilerden
bile kme oluturabiliriz:
>>> kardiz = "a"
>>> kme = set(kardiz)
Kme oluturmann son bir ynteminden daha sz edelim. En bata sylediimiz gibi, listeler,
demetler, szlkler ve karakter dizilerinin aksine kmelerin [ ], ( ), { }, gibi ayrt edici bir
iareti yoktur. Ama eer istersek szlkleri oluturmak iin kullandmz zel iaretleri kme
oluturmak iin de kullanabiliriz. Dikkatlice bakn:
>>> kme = {'Python', 'C++', 'Ruby', 'PHP'}
Grdnz gibi, aslnda szlklerin ayrt edici iareti olan ssl parantezleri kullanarak ve
eleri birbirinden virglle ayrarak da kme adl veri tipini elde edebiliyoruz. Teyit edelim
bunu:
>>> type(kme)
<class 'set'>
37.1. Kmeler
561
Bu arada, bir szl kmeye evirdiinizde, elbette szln yalnzca anahtarlar kmeye
eklenecektir. Szln deerleri ise byle bir ilemin sonucunda ortadan kaybolur.
Eer bir szl kmeye evirirken hem anahtarlar hem de deerleri korumak gibi bir
niyetiniz varsa yle bir ey yazabilirsiniz:
Szlmz u:
>>> bilgi = {"iletim sistemi": "GNU", "sistem ekirdei": "Linux",
... "datm": "Ubuntu GNU/Linux"}
Bu szlkteki anahtar-deer iftlerini bir kme iine, ift eli demetler olarak yerletirebiliriz:
>>> liste = [(anahtar, deer) for anahtar, deer in [Link]()]
>>> kme = set(liste)
Grdnz gibi, liste retelerini kullanarak nce bir liste oluturuyoruz. Bu liste her bir
anahtar ve deeri tek tek bir demet iine yerletiriyor. Daha sonra da bu listeyi set()
fonksiyonuna gndererek kmemizi oluturuyoruz.
562
Grdnz gibi, liste iinde birden fazla bulunan eler, Pythondaki kmeler yardmyla
teke indirilebiliyor.
rendiimiz bu bilgi sayesinde, daha nce grdmz count() metodunu da kullanarak,
yle bir kod yazabiliriz:
>>> liste = ["elma", "armut", "elma", "kiraz",
... "ilek", "kiraz", "elma", "kebap"]
>>> for i in set(liste):
...
print("{} listede {} kez geiyor!".format(i, [Link](i)))
kebap listede 1 kez geiyor!
elma listede 3 kez geiyor!
kiraz listede 2 kez geiyor!
armut listede 1 kez geiyor!
ilek listede 1 kez geiyor!
Burada set(liste) ifadesini kullanarak, liste elerini eiz ve benzersiz bir hale getirdik.
Kmelerin nemli bir zellii de, tpk szlkler gibi, herhangi bir ekilde e sras kavramna
sahip olmamasdr.
Dikkatlice bakn:
>>> arayz_takmlar = {'Tkinter', 'PyQT', 'PyGobject'}
>>> arayz_takmlar
{'PyGobject', 'PyQT', 'Tkinter'}
563
>>> arayz_takmlar[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing
Tpk hata mesajnda da sylendii gibi, kme adl veri tipi asndan e sras diye bir kavram
yoktur...
Esasnda tek bir kme pek bir ie yaramaz. Kmeler ancak birden fazla olduunda
bunlarla yararl iler yapabiliriz. nk kmelerin en nemli zellii, baka kmelerle
karlatrlabilme kabiliyetidir. Yani mesela kmelerin kesiimini, birleimini veya farkn
bulabilmek iin ncelikle elimizde birden fazla kme olmas gerekiyor. te biz de imdi bu
tr ilemleri nasl yapacamz reneceiz. O halde hi vakit kaybetmeden yolumuza devam
edelim.
Bu arada, buradaki random adl modle imdilik taklmayn. Birka blm sonra bu modl
inceleyeceiz. Biz imdilik random un da tpk sys ve os gibi bir modl olduunu ve rastgele
saylar retmemizi saladn bilelim yeter. Yukardaki kodlarda da bu modl 0 ile 10000
arasnda rstgele 1000 adet say retmemizi salad.
imdi amacmz bu liste iinde yer alan saylardan, deeri 100 den kk olanlar bulmak.
Bunun iin u kodlar kullanabiliriz:
import random
liste = [[Link](0, 10000) for i in range(1000)]
yzden_kk_saylar = [i for i in liste if i < 100]
print(yzden_kk_saylar)
Ancak ortaya kan listede ayn saylardan birka tane olabilir. te eer birbirinin ayn
olmayan saylardan olumu bir listeyi hzl ve pratik bir ekilde elde etmek istiyorsanz kme
retelerini kullanabilirsiniz:
import random
liste = [[Link](0, 10000) for i in range(1000)]
564
Grdnz gibi kmelerin epey metodu var. Bu arada if "__" not in i satrnda
_ yerine __ kullandmza dikkat edin.
Neden?
nk eer sadece _
kullanrsak symmetric_difference ve symmetric_difference_update metotlar ktmzda yer
almayacaktr.
37.1. Kmeler
565
Unutmadan syleyelim: Kmeler de, tpk listeler ve szlkler gibi, deitirilebilir bir veri
tipidir.
clear()
Kmelerle ilgili olarak inceleyeceimiz ilk metot clear(). Bu metodu daha nce szlkleri
alrken de grmtk. Szlklerde bu metodun grevi szln iini boaltmak idi. Burada
da ayn vazifeyi grr:
>>> km = set("adana")
>>> for i in km:
...
print(i)
...
a
d
n
>>> [Link]()
>>> km
set()
Burada nce km adl bir kme oluturduk. Daha sonra da clear() metodunu kullanarak bu
kmenin btn elerini sildik. Artk elimizde bo bir kme var.
copy()
Listeler ve szlkleri incelerken copy() adl bir metot renmitik. Bu metot ayn zamanda
kmelerle birlikte de kullanlabilir. stelik ilevi de ayndr:
>>> km = set("kahramanmara")
>>> yedek = [Link]()
>>> yedek
{'a', 'r', 'h', 'k', 'm', '', 'n'}
>>> km
{'a', 'h', 'k', 'm', 'n', 'r', ''}
Burada bir ey dikkatinizi ekmi olmal. km adl kmeyi yedek adyla kopyaladk, ama
bu iki kmenin ktlarna baktmz zaman e sralamasnn birbirinden farkl olduunu
gryoruz. Biliyorsunuz, tpk szlklerde olduu gibi, kmeler de srasz veri tipleridir. Bu
yzden, elde ettiimiz ktda eler rastgele diziliyor. Dolaysyla elere sralarna gre
eriemiyoruz. Aynen szlklerde olduu gibi...
add()
Kmelerden bahsederken, bunlarn deitirilebilir bir veri tipi olduunu sylemitik.
Dolaysyla kmeler, zerlerinde deiiklik yapmamza msaade eden metotlar da ierir.
rnein add() bu tr metotlardan biridir. Add kelimesi Trkede eklemek anlamna gelir.
Adndan da anlalaca gibi, bu metot yardmyla kmelerimize yeni eler ilave edebileceiz.
Hemen bunun nasl kullanldna bakalm:
566
Grdnz gibi, add() metodunu kullanarak, kmemize ilek adl yeni bir e ekledik.
Eer kmede zaten varolan bir e eklemeye alrsak kmede herhangi bir deiiklik
olmayacaktr. nk, daha nce de sylediimiz gibi, kmeler her bir eyi tek bir sayda
barndrr.
Eer bir kmeye birden fazla eyi ayn anda eklemek isterseniz for dngsnden
yararlanabilirsiniz:
>>> yeni = [1,2,3]
>>> for i in yeni:
...
[Link](i)
...
>>> kme
{1, 2, 3, 'elma', 'kebap', 'ilek', 'armut'}
Burada yeni adl listeyi kmeye for dngs ile ekledik. Ama bu ilemi yapmann baka bir
yolu daha vardr. Bu ilem iin Pythonda ayr bir metot bulunur. Bu metodun ad update()
metodudur. Sras gelince bu metodu da greceiz.
Bu arada, yeri gelmiken kmelerin nemli bir zelliinden daha sz edelim. Bir kmeye
herhangi bir e ekleyebilmemiz iin, o enin deitirilemeyen (immutable ) bir veri tipi
olmas gerekiyor. Bildiiniz gibi Pythondaki u veri tipleri deitirilemeyen veri tipleridir:
1. Demetler
2. Saylar
3. Karakter Dizileri
u veri tipleri ise deitirilebilen veri tipleridir:
1. Listeler
2. Szlkler
3. Kmeler
Dolaysyla bir kmeye ancak u veri tiplerini ekleyebiliriz:
1. Demetler
2. Saylar
3. Karakter Dizileri
u kodlar dikkatlice inceleyin:
nce bo bir kme oluturalm:
>>> kme = set()
37.1. Kmeler
567
>>> l = (1,2,3)
>>> [Link](l)
>>> kme
{(1, 2, 3)}
Grdnz gibi, tpk szlklerde olduu gibi, bir kmeye herhangi bir veri ekleyebilmemiz
iin o verinin deitirilemeyen bir veri tipi olmas gerekiyor.
568
difference()
Bu metot iki kmenin farkn almamz salar. rnein:
>>> k1 = set([1, 2, 3, 5])
>>> k2 = set([3, 4, 2, 10])
>>> [Link](k2)
{1, 5}
Demek ki k1in k2den fark buymu. Peki k2nin k1den farkn bulmak istersek ne yapacaz?
>>> [Link](k1)
{10, 4}
Grdnz gibi, birinci kullanmda, k1de bulunup k2de bulunmayan eleri elde ediyoruz.
kinci kullanmda ise bunun tam tersi. Yani ikinci kullanmda k2de bulunup k1de bulunmayan
eleri alyoruz.
sterseniz uzun uzun difference() metodunu kullanmak yerine sadece eksi (-) iaretini
kullanarak da ayn sonucu elde edebilirsiniz:
>>> k1 - k2
...veya...
>>> k2 - k1
Hayr, madem eksi iaretini kullanabiliyoruz, o halde art iaretini de kullanabiliriz! gibi bir
kir doru deildir.
difference_update()
Bu metot, difference() metodundan elde edilen sonuca gre bir kmenin gncellenmesini
salar. Yani? Hemen bir rnek verelim:
>>>
>>>
>>>
>>>
k1 = set([1, 2, 3])
k2 = set([1, 3, 5])
k1.difference_update(k2)
print(k1)
{2}
>>> print(k2)
{1, 3, 5}
Grdnz gibi, bu metot k1in k2den farkn ald ve bu fark kullanarak k1i yeniden
oluturdu. k1 ile k2 arasndaki tek fark 2 adl e idi. Dolaysyla difference_update()
metodunu uyguladmzda k1in elerinin silinip yerlerine 2 adl enin geldiini gryoruz.
37.1. Kmeler
569
discard()
Bir nceki blmde rendiimiz add() metodu yardmyla, nceden oluturduumuz bir
kmeye yeni eler ekleyebiliyorduk. Bu blmde reneceimiz discard() metodu ise
kmeden e silmemizi salayacak:
>>> hayvanlar = set(["kedi", "kpek", "at", "ku", "inek", "deve"])
>>> [Link]("kedi")
>>> print(hayvanlar)
{'ku', 'inek', 'deve', 'kpek', 'at'}
Eer kme iinde bulunmayan bir e silmeye alrsak hi bir ey olmaz. Yani hata mesaj
almayz:
>>> [Link]("ylan")
Burada etkileimli kabuk sessizce bir alt satra geecektir. Bu metodun en nemli zellii
budur. Yani olmayan bir eyi silmeye altmzda hata vermemesi.
remove()
Bu metot da bir nceki blmde grdmz discard() metoduyla ayn ilevi yerine getirir.
Eer bir kmeden e silmek istersek remove() metodunu da kullanabiliriz:
>>> [Link]("kpek")
Bu iki metot arasndaki bu fark nemli bir farktr. Bazen yazdnz programlarda, duruma
gre her iki zellie de ihtiyacnz olabilir.
intersection()
intersection kelimesi Trkede kesiim anlamna gelir. Adndan da anladmz gibi,
intersection() metodu bize iki kmenin kesiim kmesini verecektir:
>>> k1 = set([1, 2, 3, 4])
>>> k2 = set([1, 3, 5, 7])
>>> [Link](k2)
{1, 3}
570
Grdnz gibi, bu metot bize k1 ve k2nin kesiim kmesini veriyor. Dolaysyla bu iki kme
arasndaki ortak elemanlar bulmu oluyoruz.
Hatrlarsanz, difference() metodunu anlatrken, difference() kelimesi yerine - iaretini de
kullanabileceimiz, sylemitik. Benzer bir durum intersection() metodu iin de geerlidir.
ki kmenin kesiimini bulmak iin & iaretinden yararlanabiliriz:
>>> k1 & k2
{1, 3}
Python programclar genellikle uzun uzun intersection yazmak yerine & iaretini
kullanrlar...
sterseniz bu metot iin rnek bir program verelim. Bylece gerek hayatta bu metodu nasl
kullanabileceimizi grm oluruz:
tr = ""
parola = input("Sisteme giri iin bir parola belirleyin: ")
if set(tr) & set(parola):
print("Parolanzda Trke harfler kullanmayn!")
else:
print("Parolanz kabul edildi!")
Burada eer kullanc, parola belirlerken iinde Trke bir harf geen bir kelime yazarsa
programmz kendisini Trke harf kullanmamas konusunda uyaracaktr. Bu kodlarda
kmeleri nasl kullandmza dikkat edin. Programda asl ii yapan ksm u satrdr:
if set(tr) & set(parola):
print("Parolanzda Trke harfler kullanmayn!")
Burada kullancnn ilek adl kelimeyi girdiini varsayyoruz. Byle bir durumda set(tr)
ve set(parola) kmelerinin kesiim kmesi harni ierecek, dolaysyla da programmz
kullancya uyar mesaj gsterecektir. Eer kullancmz kalem gibi Trke harf iermeyen
bir kelime girerse:
37.1. Kmeler
571
>>> tr = ""
>>> parola = "kalem"
>>> set(tr) & set(parola)
set()
Grdnz gibi, elde ettiimiz kme bo. Dolaysyla byle bir durumda programmz
kullancya herhangi bir uyar mesaj gstermeyecektir.
intersection() metodunu pek ok yerde kullanabilirsiniz.
Hatta iki dosya arasndaki
benzerlikleri bulmak iin dahi bu metottan yararlanabilirsiniz. lerde dosya ilemleri
konusunu ilerken bu metottan nasl yararlanabileceimizi de anlatacaz.
intersection_update()
Hatrlarsanz difference_update() metodunu ilerken yle bir ey demitik:
Bu metot, difference() metodundan elde edilen sonuca gre bir kmenin gncellenmesini
salar.
te intersection_update metodu da buna ok benzer bir ilevi yerine getirir. Bu metodun
grevi, intersection() metodundan elde edilen sonuca gre bir kmenin gncellenmesini
salamaktr:
>>>
>>>
>>>
>>>
k1 = set([1, 2, 3])
k2 = set([1, 3, 5])
k1.intersection_update(k2)
print(k1)
{1, 3}
>>> print(k2)
{1, 3, 5}
Grdnz gibi, a ve b kmesinin kesiimi bo olmad iin, yani bu iki kme ortak en az bir
e barndrd iin, isdisjoint() metodu False kts veriyor. Burada temel olarak u soruyu
sormu oluyoruz:
572
Burada a ve b kmeleri ortak hi bir elemana sahip olmad iin Doru anlamna gelen True
ktsn elde ediyoruz.
issubset()
Bu metot yardmyla, bir kmenin btn elemanlarnn baka bir kme iinde yer alp yer
almadn sorgulayabiliriz. Yani bir kmenin, baka bir kmenin alt kmesi olup olmadn
bu metot yardmyla renebiliriz. Eer bir kme baka bir kmenin alt kmesi ise bu metot
bize True deerini verecek; eer deilse False ktsn verecektir:
>>> a = set([1, 2, 3])
>>> b = set([0, 1, 2, 3, 4, 5])
>>> [Link](b)
True
Bu rnekte True ktsn aldk, nk a kmesinin btn eleri b kmesi iinde yer alyor.
Yani a, bnin alt kmesidir.
issuperset()
Bu metot, bir nceki blmde grdmz issubset() metoduna benzer. Matematik
derslerinde grdmz kmeler konusunda hatrladnz b kmesi a kmesini kapsar
ifadesini bu metotla gsteriyoruz. nce bir nceki derste grdmz rnee bakalm:
>>> a = set([1, 2, 3])
>>> b = set([0, 1, 2, 3, 4, 5])
>>> [Link](b)
True
Buradan, a kmesi b kmesinin alt kmesidir, sonucuna ulayoruz. Bir de una bakalm:
>>> a = set([1, 2, 3])
>>> b = set([0, 1, 2, 3, 4, 5])
>>> [Link](a)
True
Burada ise, b kmesi a kmesini kapsar, sonucunu elde ediyoruz. Yani b kmesi a kmesinin
btn elemanlarn iinde barndryor.
37.1. Kmeler
573
union()
union() metodu iki kmenin birleimini almamz salar. Hemen bir rnek verelim:
>>> a = set([2, 4, 6, 8])
>>> b = set([1, 3, 5, 7])
>>> [Link](b)
{1, 2, 3, 4, 5, 6, 7, 8}
nceki blmlerde grdmz baz metotlarda olduu gibi, union() metodu da bir ksayola
sahiptir. union() metodu yerine | iaretini de kullanabiliriz:
>>> a | b
union() metodu yerine, bu metodun ksayolu olan | iareti Python programclar tarafndan
daha sk kullanlr.
update()
Hatrlarsanz add() metodunu anlatrken yle bir rnek vermitik:
>>> kme = set(["elma", "armut", "kebap"])
>>> yeni = [1, 2, 3]
>>> for i in yeni:
...
[Link](i)
...
>>> kme
{1, 2, 3, 'elma', 'armut', 'kebap'}
Grdnz gibi, for dngsn kullanmaya gerek kalmadan ayn sonucu elde edebildik.
symmetric_difference()
Daha nceki blmlerde difference() metodunu kullanarak iki kme arasndaki farkl eleri
bulmay renmitik. rnein elimizde yle iki kme var diyelim:
574
a = set([1,2, 5])
b = set([1,4, 5])
a.symmetric_difference_update(b)
print(a)
{2, 4}
37.1. Kmeler
575
Peki bu metot hangi lte gre kmeden e siliyor? Herhangi bir lt yok. Bu metot,
kme elerini tamamen rastgele siliyor.
Bylelikle Pythonda Listeler, Demetler, Szlkler ve Kmeler konusunu bitirmi olduk. Bu
konular sk sk tekrar etmek, hi olmazsa arada srada gz gezdirmek baz eylerin zihnimizde
yer etmesi asndan olduka nemlidir.
>>> dir(dondurulmu)
['__and__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__',
'__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__',
'__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__xor__', 'copy', 'difference', 'intersection',
'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']
Grdnz gibi, add(), remove(), update() gibi, deiiklik yapmaya ynelik metotlar listede
yok.
Dondurulmu kmeler ile normal kmeler arasnda ilev olarak hibir fark yoktur. Bu ikisi
arasndaki fark, listeler ile demetler arasndaki fark gibidir.
576
BLM 38
Fonksiyonlar
lk derslerimizden bu yana bir ey zellikle dikkatinizi ekmi olmal: lk andan itibaren hep
fonksiyon diye bir kavramdan sz ettik; stelik yazdmz kodlarda da bu fonksiyon denen
eyi bolca kullandk. Evet, belki bu kavram imdiye dek enine boyuna inceleme frsatmz hi
olmad, ama yine de adnn fonksiyon olduunu sylediimiz pek ok ara tandk bu noktaya
gelinceye kadar.
Herhalde, Fonksiyon denince aklnza ilk ne geliyor? diye bir soru sorsam, vereceiniz cevap
print() fonksiyonu olacaktr. Gerekten de bu fonksiyonu ilk derslerimizden bu yana o kadar
sk kullandk ki, fonksiyon denince aklnza ilk bu fonksiyonun gelmesi gayet doal.
Elbette rendiimiz tek fonksiyon print() deildi.
Bunun dnda type() diye bir
fonksiyondan da sz etmitik. print() kadar olmasa da, type() fonksiyonunu da yazdmz
kodlarda epey kullandk. print() ve type() dnda, fonksiyon olarak str(), int() ve
benzeri aralarla da tantk. Bunlarn dnda pek ok baka fonksiyon da Pythonla birlikte
hayatmza girdi.
te bu blmde, en batan bu yana sklkla szn ettiimiz, ama hibir zaman tam
anlamyla ele almadmz bu kavram daha iyi anlayabilmek iin, fonksiyon konusunu ayrntl
olarak ele alacaz. Bu blmde amacmz fonksiyonlar enine boyuna inceleyerek, okurun
bilgi daarcnda fonksiyonlara ilikin salam bir altyap oluturmaktr. Okur, bu blm
bitirdikten sonra fonksiyonlara ilikin olarak bilmesi gereken her eyi renmi olacak.
vb.)
4. Fonksiyonlar farkl sayda parametre alabilir. rnein print() fonksiyonu toplam 256
adet parametre alabilirken, input() fonksiyonu yalnzca tek bir parametre alr.
5. Fonksiyonlarn isimli ve isimsiz parametreleri vardr. print() fonksiyonundaki sep,
end ve le parametreleri isimli parametrelere rnekken, mesela print("Merhaba
Dnya!") kodunda Merhaba Dnya! parametresi isimsiz bir parametredir. Ayn ekilde
input("Adnz: ") gibi bir kodda Adnz: parametresi isimsiz bir parametredir.
6. Fonksiyonlarn, isimli ve isimsiz parametreleri dnda, bir de varsaylan deerli
parametreleri vardr. rnein print() fonksiyonunun sep, end ve le parametreleri
varsaylan deerli parametrelere birer rnektir. Eer bir parametrenin varsaylan bir
deeri varsa, o parametreye herhangi bir deer vermeden de fonksiyonu kullanabiliriz.
Python bu parametrelere, belirli deerleri ntanml olarak kendisi atayacaktr. Tabii
eer istersek, varsaylan deerli parametrelere kendimiz de baka birtakm deerler
verebiliriz.
Fonksiyon kavramnn tam olarak ne olduunu henz bilmiyor da olsak, imdiye
kadar rendiimiz fonksiyonlara bakarak fonksiyonlar hakknda yukardaki karmlar
yapabiliyoruz. Demek ki aslnda fonksiyonlar hakknda alttan alta pek ok ey renmiiz.
O halde, fonksiyonlar hakknda imdiden bildiklerimize gvenerek, fonksiyon kavramnn ne
olduundan ziyade ne ie yarad konusuna rahatlkla eilebiliriz. Zaten fonksiyonlarn ne
ie yaradn rendikten sonra, fonksiyonlarn ne olduunu da hemencecik anlayacaksnz.
Fonksiyonlarn ne ie yaradn en genel ve en kaba haliyle tarif etmek istersek yle bir
tanmlama yapabiliriz:
Fonksiyonlarn grevi, karmak ilemleri bir araya toplayarak, bu ilemleri
tek admda yapmamz salamaktr. Fonksiyonlar ou zaman, yapmak
istediimiz ilemler iin bir ablon vazifesi grr. Fonksiyonlar kullanarak,
bir veya birka admdan oluan ilemleri tek bir isim altnda toplayabiliriz.
Pythondaki fonksiyon kavram baka programlama dillerinde rutin veya
prosedr olarak adlandrlr. Gerekten de fonksiyonlar rutin olarak tekrar
edilen grevleri veya prosedrleri tek bir ad/at altnda toplayan aralardr.
Dilerseniz yukardaki soyut ifadeleri basit bir rnek zerinde somutlatrmaya alalm.
rnein print() fonksiyonunu ele alalm.
Bu fonksiyonun grevini biliyorsunuz: print() fonksiyonunun grevi, kullancnn girdii
parametreleri ekrana kt olarak vermektir. Her ne kadar print() fonksiyonunun grevini,
ekrana kt vermek olarak tanmlasak da, aslnda bu fonksiyon, ekrana kt vermenin
yansra, baka bir takm ilave ilemler de yapar. Yani bu fonksiyon, aslnda ald
parametreleri sadece ekrana kt olarak vermekle yetinmez. rnein u komutu inceleyelim:
>>> print("Frat", "zgl", "1980", "Adana")
Burada print() fonksiyonu toplam drt adet parametre alyor. Fonksiyonumuz, grevi
gerei, bu parametreleri ekrana kt olarak verecek. Bu komutu altrdmzda yle bir
kt alyoruz:
Frat zgl 1980 Adana
Dikkat ederseniz, burada salt bir ekrana kt verme ileminden fazlas var. Zira print()
fonksiyonu ald parametreleri u ekilde de ekrana verebilirdi:
578
Fratzgl1980Adana
Veya u ekilde:
F
r
a
t
z
g
l
1
9
8
0
A
d
a
n
a
Neticede bunlar da birer kt verme ilemidir. Ama dediimiz gibi, print() fonksiyonu ald
parametreleri sadece ekrana kt olarak vermekle yetinmiyor. Gelin isterseniz ne demek
istediimizi biraz daha aklayalm:
print() fonksiyonunun yukardaki komutu nasl algladn nceki derslerimizde
renmitik. Yukardaki komut Python tarafndan u ekilde alglanyor:
>>> print("Frat", "zgl", "1980", "Adana", sep=" ", end="\n",
... file=[Link], flush=False)
579
olduu gibi, input() fonksiyonu da aslnda alttan alta epey karmak ilemler gerekletirir.
Ama o karmak ilemlerin tek bir input() fonksiyonu iinde bir araya getirilmi
olmas sayesinde, sadece input() gibi basit bir komut vererek kullanclarmzla iletiime
geebiliyoruz.
Bu adan bakldnda fonksiyonlar deikenlere benzer. Bildiiniz gibi, her defasnda bir
deeri tekrar tekrar yazmak yerine bir deikene atayarak o deere kolayca eriebiliyoruz.
rnein:
>>> kurum = "Sosyal Sigortalar Kurumu"
Burada tanmladmz kurum adl deiken sayesinde, Sosyal Sigortalar Kurumu ifadesini
kullanmamz gereken her yerde sadece deiken adn kullanarak, deikenin tuttuu deere
ulaabiliyoruz. te fonksiyonlar da buna benzer bir ilev grr: rnein ekrana bir kt
vermemiz gereken her yerde, yukarda verdiimiz karmak admlar tek tek gerekletirmeye
almak yerine, bu karmak ve rutin admlar bir araya getiren print() gibi bir fonksiyondan
yararlanarak ilerimizi ok daha kolay bir ekilde halledebiliriz.
Bu anlattklarmz fonksiyonlarn ne ie yarad konusunda size bir kir vermi olabilir.
Dilerseniz bu anlattklarmz bir rnek araclyla biraz daha somutlatrmaya alalm:
Hatrlarsanz Kullancyla Veri Alverii balkl blmde yle bir rnek vermitik:
isim
soyisim
isis
ehir
=
=
=
=
"Frat"
"zgl"
"Ubuntu"
"stanbul"
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim)
soyisim)
isis)
ehir)
Frat
zgl
Ubuntu
stanbul
Bu program, belli deerleri kullanarak bir kayt oluturma ilemi gerekletiriyor. Mesela
yukardaki rnekte, Frat zgl adl ahsa ait isim, soyisim, iletim sistemi ve ehir bilgilerini
alarak, bu kii iin bir kayt oluturuyoruz.
Peki Frat zgl adl kiinin yansra, Mehmet ztaban adl baka bir kii iin de kayt
oluturmak istersek ne yapacaz?
Aklnza yle bir ey yazmak gelmi olabilir:
isim1
soyisim1
isis1
ehir1
=
=
=
=
"Frat"
"zgl"
"Ubuntu"
"stanbul"
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
580
isim1)
soyisim1)
isis1)
ehir1)
print("-"*30)
isim2
soyisim2
isis2
ehir2
=
=
=
=
"Mehmet"
"ztaban"
"Debian"
"Ankara"
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim2)
soyisim2)
isis2)
ehir2)
print("-"*30)
Programa her yeni kayt ekleniinde, her yeni kii iin benzer satrlar tekrar tekrar
yazabilirsiniz. Peki ama bu yntem sizce de ok skc deil mi? stelik bir o kadar da hataya
ak bir yntem. Muhtemelen ilk kayd ekledikten sonra, ikinci kayd eklerken birinci kayttaki
bilgileri kopyalayp, bu kopya zerinden ikinci kayd oluturuyorsunuz. Hatta muhtemelen
kopyalayp yaptrdktan sonra yeni kayd dzenlerken baz hatalar da yapyor ve dzgn
alan bir program elde edebilmek iin o hatalar dzeltmekle de urayorsunuz.
Btn bu ileri kolaylatracak bir zm olsa ve bizi ayn eyleri tekrar tekrar yazmaktan
kurtarsa sizce de ok gzel olmaz myd?
Mesela tpk print() fonksiyonu gibi,
kayt_olutur() adl bir fonksiyon olsa, biz sadece gerekli bilgileri bu fonksiyonun
parantezleri iine parametre olarak yazsak ve bu fonksiyon bize istediimiz bilgileri ieren
bir kayt olutursa ne ho olurdu, deil mi?
Yani rnein bahsettiimiz bu hayali
kayt_olutur() fonksiyonunu u ekilde kullanabilseydik...
kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")
581
Dediimiz gibi, byle bir ey yapmak Pythonla mmkndr. Ancak tabii ki kayt_olutur()
adl byle bir fonksiyonu kullanabilmenin belli n koullar var. Nasl say adl bir deikeni
kullanabilmek iin ncelikle bu ada sahip bir deiken tanmlam olmamz gerekiyorsa,
ayn ekilde kayt_olutur() adl bir fonksiyonu kullanabilmek iin de ncelikle bu ada
sahip bir fonksiyonu tanmlam olmamz gerekiyor. Zira mesela input() ve print() gibi
fonksiyonlar kullanabiliyor olmamz, Python gelitiricilerinin bu fonksiyonlar tanmlayp dilin
iine gmm olmalar sayesindedir.
te biz de kayt_olutur() adl fonksiyonu kullanabilmek iin bu ada sahip fonksiyonu
aadaki ekilde tanmlamalyz:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim)
soyisim)
isis)
ehir)
print("-"*30)
lk bakta bu kodlar size hibir ey ifade etmemi olabilir. Ama hi endie etmeyin. Biz
birazdan bu satrlarn ne anlama geldiini btn ayrntlaryla anlatacaz. Siz imdilik
anlamadnz ksmlar grmezden gelip okumaya devam edin.
Yukardaki kodlar yardmyla fonksiyonumuzu tanmlam olduk. Artk elimizde, tpk print()
veya input() gibi, kayt_olutur() adl ev yapm bir fonksiyon var. Dolaysyla bu
yeni fonksiyonumuzu, daha nce rendiimiz fonksiyonlar nasl kullanyorsak ayn ekilde
kullanabiliriz. Yani aadaki gibi komutlar yazabiliriz:
kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")
kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")
isim)
soyisim)
isis)
ehir)
print("-"*30)
582
Grdnz gibi, yukardaki yntem sayesinde kodlarmzdaki tekrar eden ksmlar ortadan
kalkt. Yukardaki fonksiyonun bize nasl bir kolaylk saladn daha net grebilmek iin,
fonksiyon kullanarak sadece u 11 satrla elde ettiimiz kty, fonksiyon kullanmadan elde
etmeyi deneyebilirsiniz:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim)
soyisim)
isis)
ehir)
print("-"*30)
kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")
kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")
kayt_olutur("lkay", "Kaya", "Mint", "Adana")
kayt_olutur("Seda", "Kara", "SuSe", "Erzurum")
Bu anlattklarmz size ok karmak gelmi olabilir. Ama endie etmenize hi gerek yok. Biraz
sonra, yukarda yazdmz kodlarn hepsini didik didik edeceiz. Ama ncelikle yukardaki
kod parasn yapsal olarak bir incelemenizi istiyorum. Fonksiyonu tanmladmz aadaki
kod parasna yle bir baktnzda neler gryorsunuz?
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim)
soyisim)
isis)
ehir)
print("-"*30)
kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")
583
Teknik olarak sylemek gerekirse, ilk paraya fonksiyon tanm (function denition ), ikinci
paraya ise fonksiyon ars (function call ) ad verilir. Dolaysyla bir fonksiyonun yaam
dngs iki aamadan oluur. Buna gre bir fonksiyon nce tanmlanr;
def kayt_olutur(parametre1, parametre2, parametre3, parametre4):
(...)
...sonra da arlr;
kayt_olutur(parametre1, parametre2, parametre3, parametre4)
Aslnda biz imdiye kadar grdmz print(), type(), open() vb. fonksiyonlarda bu
fonksiyon ars ksmyla zaten tanmtk. Zira u komut tam anlamyla bir fonksiyon
arsdr (yani bir fonksiyon arma ilemidir):
print("Frat", "zgl", "Adana", 32)
Grdnz gibi, yukardaki komutun yap olarak u komuttan hibir fark yok:
kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")
584
Bylece bir fonksiyonun yap olarak neye benzediini stnkr de olsa incelemi olduk.
Buraya kadar anlatlan ksmda baz noktalar anlamakta zorlanm olabilirsiniz. Eer yleyse
hi endielenmeyin. Bu gayet doal.
Gelin isterseniz imdi yukarda anlattklarmzn iini doldurmaya alalm.
Dedik ki, bir fonksiyonun ilk parasna fonksiyon tanm (function denition ) ad verilir. Bir
fonksiyonu tanmlamak iin def adl bir paracktan yararlanyoruz. rnein:
def bir_fonksiyon():
(...)
Burada def parac, tanmladmz eyin bir fonksiyon olduunu gsteriyor. bir_fonksiyon
ifadesi ise tanmladmz bu fonksiyonun addr. Fonksiyonu tanmladktan sonra, arrken
bu ad kullanacaz.
def bir_fonksiyon(): ifadesinin sonundaki iki nokta iaretinden de tahmin edebileceiniz
gibi, sonraki satra yazacamz kodlar girintili olacak. Yani mesela:
def selamla():
print("Elveda Zalim Dnya!")
Yukarda selamla() adl bir fonksiyon tanmlam olduk. Bu fonksiyonun grevi ekrana Elveda
Zalim Dnya! kts vermektir.
Bu noktada yle bir soru akla geliyor: Acaba fonksiyon gvdesindeki ksm iin ne kadarlk
bir girinti oluturacaz?
Girintilemeye ilikin olarak nceki derslerde bahsettiimiz btn kurallar burada da
geerlidir. Fonksiyon gvdesine, def ifadesinden itibaren 4 (drt) bolukluk bir girinti
veriyoruz. def ifadesinden itibaren girintili olarak yazdmz ksmn tamam o fonksiyonun
gvdesini oluturur ve btnyle o fonksiyona aittir.
Bu kodlarla yaptmz ey bir fonksiyon tanmlama ilemidir. Eer bu kodlar bir dosyaya
kaydedip altrrsak herhangi bir kt almayz. nk henz fonksiyonumuzu armadk.
Bu durumu print(), input() ve benzeri gml fonksiyonlara benzetebilirsiniz. Tpk
yukarda bizim yaptmz gibi, gml fonksiyonlar da Python gelitiricileri tarafndan bir
yerlerde tanmlanm vaziyette dururlar, ama biz bu fonksiyonlar yazdmz programlarda
arana kadar bu fonksiyonlar almaz.
Daha nce de dediimiz gibi, bir fonksiyonun yaam dngs iki aamadan oluur: Fonksiyon
tanm ve fonksiyon ars. Yukarda bu dngnn sadece fonksiyon tanm aamas
mevcut. Unutmayn, bir fonksiyon arlmadan asla almaz. Bir fonksiyonun alabilmesi
iin o fonksiyonun tanmlandktan sonra arlmas gerekir. rnein input() fonksiyonu
Pythonn derinliklerinde bir yerlerde tanmlanm vaziyette durur. Bu fonksiyon, biz onu
arana kadar, bulunduu yerde sessizce bekler. Ayn ekilde selamla() adl fonksiyon
da programmz iinde tanmlanm vaziyette, bizim onu aracamz an bekliyor. Bu
sylediklerimizi destekleyecek aklayc bilgileri biraz sonra vereceiz. Biz imdilik fonksiyon
tanm ksmn incelemeye devam edelim.
585
te burada fonksiyonumuzu arm olduk. Dikkat edin! Dediim gibi, iki nokta st ste
iaretinden sonraki satrda girintili olarak yazlan btn kodlar fonksiyona aittir. selamla()
satr ise fonksiyon tanmnn dnda yer alr. Bu satrla birlikte girintinin dna kld iin
artk fonksiyon tanmlama safhas sona ermi oldu.
Biz yukardaki rnekte, selamla() adl fonksiyonu tanmlar tanmlamaz armay tercih ettik.
Ama elbette siz bir fonksiyonu tanmlar tanmlamaz armak zorunda deilsiniz. Yazdnz
bir program iinde fonksiyonlarnz tanmladktan sonra, ihtiyacnza bal olarak, programn
herhangi baka bir yerinde fonksiyonlarnz arabilirsiniz.
Fonksiyonlarla ilgili sylediklerimizi toparlayacak olursak yle bir bilgi listesi ortaya
karabiliriz:
1. Pythonda kabaca iki tip fonksiyon bulunur. Bunlardan biri gml fonksiyonlar (builtin
functions ), teki ise zel fonksiyonlardr (custom functions ). Burada zel ifadesi,
kullancnn ihtiyalarna gre kullanc tarafndan zel olarak retilmi anlamna gelir.
2. Gml fonksiyonlar; Python gelitiricileri tarafndan tanmlanp dilin iine gmlm
olan print(), open(), type(), str(), int() vb. fonksiyonlardr. Bu fonksiyonlar
halihazrda tanmlanp hizmetimize sunulduu iin bunlar biz herhangi bir tanmlama
ilemi yapmadan dorudan kullanabiliriz.
3. zel fonksiyonlar ise, gml fonksiyonlarn aksine, Python gelitiricileri tarafndan
deil, bizim tarafmzdan tanmlanmtr. Bu fonksiyonlar dilin bir paras olmadndan,
bu fonksiyonlar kullanabilmek iin bunlar ncelikle tanmlamamz gerekir.
4. Pythonda bir fonksiyonun yaam dngs iki aamadan oluur: Tanmlanma ve
arlma.
5. Bir fonksiyonun arlabilmesi (yani kullanlabilmesi) iin mutlaka birisi tarafndan
tanmlanm olmas gerekir.
6. Fonksiyonu tanmlayan kii Python gelitiricileri olabilecei gibi, siz de olabilirsiniz. Ama
neticede ortada bir fonksiyon varsa, bir yerlerde o fonksiyonun tanm da vardr.
7. Fonksiyon tanmlamak iin def adl bir ifadeden yararlanyoruz. Bu ifadeden sonra,
tanmlayacamz fonksiyonun adn belirleyip iki nokta st ste iareti koyuyoruz. ki
nokta st ste iaretinden sonra gelen satrlar girintili olarak yazlyor. Daha nce
rendiimiz btn girintileme kurallar burada da geerlidir.
8. Fonksiyonun adn belirleyip iki nokta st ste koyduktan sonra, alt satrda girintili
olarak yazdmz btn kodlar fonksiyonun gvdesini oluturur. Doal olarak, bir
fonksiyonun gvdesindeki btn kodlar o fonksiyona aittir. Girintinin dna kld
anda fonksiyon tanm da sona erer.
586
Demek ki bu kodlarn altrld sistem Pythonn 3.3.0 srmnn kurulu olduu bir
GNU/Linux iletim sistemi imi...
587
imdiye kadarki
say = 12
kt = "{} saysnn karesi {} saysdr"
print([Link](say, say**2))
Gayet gzel. imdi yle bir durum hayal edin: Diyelim ki byk bir program iinde, farkl
farkl yerlerde yukardaki ilemi tekrar tekrar yapmak istiyorsunuz. Byle bir durumda yle
bir ey yazmanz gerekebilir:
say = 12
kt = "{} saysnn karesi {} saysdr"
print([Link](say, say**2))
####programla ilgili baka kodlar###
say = 15
print([Link](say, say**2))
###programla ilgili baka kodlar###
say = 29
print([Link](say, say**2))
Buradaki sorun, ayn eyleri tekrar tekrar yazmak zorunda kalmamzdr. Bu kk rnekte pek
belli olmuyor olabilir, ama zellikle byk programlarda ayn kodlarn program iinde srekli
olarak tekrarlanmas pek ok probleme yol aar. rnein kodlarda bir deiiklik yapmak
istediinizde, tekrarlanan ksmlar bulup hepsinin zerinde tek tek deiiklik yapmanz
gerekir. Mesela kt adl deikenin ieriini deitirmek isterseniz, yaptnz deiiklik
programnzn pek ok ksmn etkileyebilir. rnein, kt deikenini u ekle getirdiinizi
dnn:
kt = "{} saysnn karesi {}, karekk {} saysdr"
588
kare_bul() adl fonksiyonu bir kez tanmladktan sonra bu fonksiyonu programnz iinde
gereken her yerde arabilirsiniz:
kare_bul()
####programla ilgili baka kodlar###
kare_bul()
###programla ilgili baka kodlar###
kare_bul()
Grdnz gibi kare_bul() adl bu fonksiyon bizi pek ok zahmetten kurtaryor. Ancak
bu fonksiyonun bir sorunu var. Bu fonksiyon ekrana yalnzca 12 saysnn karesi 144
saysdr kts verebiliyor. Buradaki problem, fonksiyonun sadece 12 says zerinde ilem
yapabilmesi. yle bir dnnce, bu ktnn ne kadar anlamsz olduunu, aslnda yukardaki
fonksiyonun tamamen gereksiz bir i yaptn rahatlkla grebiliyoruz. Fonksiyonumuzun ad
kare_bul. Ama dediimiz gibi, fonksiyonumuz sadece 12 saysnn karesini syleyebiliyor.
Halbuki mantk olarak fonksiyonumuzun, btn saylarn karesini syleyebilmesini beklerdik.
Not:
Bu arada, grdnz gibi, yukardaki fonksiyon parametresiz bir fonksiyondur.
Dolaysyla bu fonksiyonu arrken parantez iinde herhangi bir deer belirtmiyoruz.
Fonksiyonumuzun gerek anlamda ilevli bir hale gelebilmesi iin sadece tek bir sayy deil,
btn saylar inceleyebiliyor olmas gerek. te fonksiyonumuza bu yetenei parametreler
araclyla kazandrabiliriz.
Dikkatlice bakn:
def kare_bul(say):
kt = "{} saysnn karesi {} saysdr"
print([Link](say, say**2))
589
Fonksiyona parametre olarak nasl bir isim verdiinizin nemi yoktur. Parantez iine
parametre olarak istediiniz kelimeyi yazabilirsiniz. nemli olan, parantez iinde fonksiyonun
ka parametre alacan gsteren bir iaret olmasdr. Mesela yukardaki fonksiyonu yle de
tanmlayabilirdik:
def kare_bul(i):
kt = "{} saysnn karesi {} saysdr"
print([Link](i, i**2))
...veya yle:
def kare_bul(osman):
kt = "{} saysnn karesi {} saysdr"
print([Link](osman, osman**2))
Elbette parametre ad olarak aklda kalc ve daha mantkl bir seim yapmak ilerinizi
kolaylatracaktr...
imdi de yukardaki fonksiyonu aralm:
kare_bul(9)
Fonksiyonu oluturan kodlarda herhangi bir deiiklik yapmak istediinizde sadece fonksiyon
tanmnn gvdesini deitirmeniz yeterli olacaktr. rnein:
def kare_bul(say):
kt = "{} saysnn karesi {}, karekk ise {} saysdr"
print([Link](say, say**2, say**0.5))
Elbette len() fonksiyonunu kullanarak! dediinizi duyar gibiyim. Gerekten de Pythonda bir
karakter dizisinin uzunluunu bulmann en iyi yolu len() fonksiyonunu kullanmaktr:
>>> len("istihza")
7
Peki ya Pythonda len() diye bir fonksiyon olmasayd ne yapacaktnz? Byle bir durumda,
karakter dizilerinin uzunluunu lmek iin sizin bir yntem icat etmeniz gerekecekti. Mesela
istihza kelimesinin ka karakterden olutuunu bulmak iin yle bir kod yazacaktnz:
c = 0
for s in "istihza":
c += 1
print(c)
Burada nce c adl bir deiken tanmlayp, bu deikenin deerini 0 yaptk. Bu deiken,
uzunluunu sorgulamak istediimiz kelimenin ka karakterden olutuu bilgisini saklayacak.
Ardndan bir for dngs tanmlyoruz. Bu dngde, istihza kelimesindeki her bir karakter
iin c deikeninin deerini 1 say artryoruz. Bylece dng sonunda c deikeni istihza
kelimesi iinde ka karakter olduu bilgisini tutmu oluyor.
Son olarak da c deikeninin nihai deerini ekrana yazdryoruz.
Bu kodlar altrdnzda 7 cevab alacaksnz. Demek ki istihza kelimesinde 7 karakter
varm. Peki istihza kelimesi yerine mesela Afyonkarahisar kelimesi iinde ka karakter
olduunu hesaplamak isterseniz ne yapacaksnz? Elbette yukardaki kodlar tekrar yazp,
istihza kelimesini Afyonkarahisar kelimesi ile deitireceksiniz. Bylece bu kelimenin ka
karakterden olutuunu bulmu olacaksnz. Sorgulamak istediiniz her kelime iin ayn
eyleri yapabilirsiniz...
Ne kadar verimsiz bir yntem, deil mi?
Halbuki hi bu tr eylerle uramaya gerek yok. Eer Python bize len() fonksiyonu gibi bir
fonksiyon vermemi olsayd, kendi len() fonksiyonumuzu icat edebilirdik. Dikkatlice bakn:
def uzunluk(e):
c = 0
for s in e:
c += 1
print(c)
Bylece ad uzunluk olan bir fonksiyon tanmlam olduk. Artk bir enin uzunluunu
hesaplamak istediimizde, btn o kodlar her defasnda tekrar tekrar yazmak yerine sadece
uzunluk() fonksiyonunu kullanabiliriz:
uzunluk("istihza")
uzunluk("Afyonkarahisar")
uzunluk("Tarm ve Kyileri Bakanl")
stelik bu fonksiyon yalnzca karakter dizilerinin deil teki veri tiplerinin de uzunluunu
hesaplayabilir:
liste = ["ahmet", "mehmet", "veli"]
uzunluk(liste)
Verdiimiz bu rnek bize hem gml fonksiyonlarn faydasn, hem de genel olarak
fonksiyonlarn ne ie yaradn aka gsteriyor. Buna gre, len() benzeri gml
38.4. Fonksiyonlar Ne e Yarar?
591
Burada kopyala() adl bir fonksiyon tanmladk. Bu fonksiyon toplam iki adet parametre
alyor: kaynak_dosya ve hedef_dizin. Grdnz gibi, bu iki parametre gerekten
de fonksiyon gvdesinde yaplan iin deiken elerini gsteriyor. Bu fonksiyonun
retecei kt, fonksiyonu aran kiinin bu iki parametreye verecei deerlere bal olarak
ekillenecek.
Bildiiniz gibi, parametrelere ne ad verdiinizin hibir nemi yok. Elbette parametrenin
grevine uygun bir isim vermeniz fonksiyonunuzun okunaklln artracaktr. Ama tabii ki
bu fonksiyonu pekala u parametrelerle de tanmlayabilirdik:
def kopyala(a, b):
kt = "{} adl dosya {} adl dizin iine kopyaland!"
print([Link](a, b))
Burada nemli olan, parametre grevi grecek iki adet kelime bulmak. Bu kelimelerin ne
olduunun nemi yok. Ama tabii ki kaynak_dosya ve hedef_dizin adlar, a ve b adlarna
kyasla, fonksiyondaki parametrelerin yapt ii ok daha iyi tarif ediyor.
Parametre ad belirleme kurallar deiken ad belirleme kurallaryla ayndr. Dolaysyla bir
deiken ad belirlerken neye dikkat ediyorsak, parametre ad belirlerken de ayn eye dikkat
etmeliyiz.
Gelin imdi isterseniz tanmladnz bu fonksiyonu aralm:
kopyala("[Link]", "/home/istihza/Desktop")
592
isim)
soyisim)
isis)
ehir)
print("-"*30)
Mesela yukardaki
593
Grdnz gibi, isim, soyisim ve teki bilgiler birbirine karm. te Pythonda, verili sras
nem tayan bu tr parametrelere sral parametreler (veya isimsiz parametreler) ad verilir.
isim)
soyisim)
isis)
ehir)
print("-"*30)
Bylece fonksiyon parametrelerini istediimiz sra ile kullanabiliriz. Ancak burada dikkat
etmemiz gereken baz noktalar var. Pythonda isimli bir parametrenin ardndan sral bir
parametre gelemez. Yani u kullanm yanltr:
kayt_olutur(soyisim="z", isim="Ahmet", "Debian", "Ankara")
594
Yani biz grmesek de aslnda her print() ars sep, end, le ve ush parametrelerini
de ieriyor. Biz bu zel parametreleri kullanmasak da, yazdmz kod dzgn bir ekilde
alr. Bunun nedeni, sep, end, le ve ush parametrelerinin ntanml olarak birtakm
deerlere sahip olmasdr. Yani biz bu parametrelere kendimiz bir deer atamazsak Python
bu parametrelere kendi belirledii baz ntanml deerleri atayacaktr. Dolaysyla, eer biz
baka bir deer yazmazsak, sep parametresi deerine, end parametresi n deerine, le
parametresi [Link] deerine, ush parametresi ise False deerine sahip olacaktr. te
bu tr parametrelere Pythonda varsaylan deerli parametreler ad verilir. Peki biz kendimiz
varsaylan deerli parametreler ieren fonksiyonlar nasl tanmlayabiliriz?
u rnee dikkatlice bakn:
def kur(kurulum_dizini="/usr/bin/"):
print("Program {} dizinine kuruldu!".format(kurulum_dizini))
Grdnz gibi, kur() fonksiyonunun kurulum_dizini adl bir parametresi var. Biz
fonksiyonu tanmlarken, bu parametreye bir varsaylan deer atadk (/usr/bin/ ). Bylece
kur() fonksiyonu parametresiz olarak arldnda bu varsaylan deer devreye girdi.
Eer biz bu deeri deitirmek istersek, mesela programmzn C:\Users\rat dizinine
kurulmasn istersek, kur() fonksiyonunu yle armalyz:
kur("C:\\Users\\firat")
kur() fonksiyonunu yukardaki gibi ardmzda Python bize yle bir kt verir:
Program C:\Users\firat dizinine kuruldu!
595
Bylece, kurulum_dizini parametresinin bool deeri False olursa kullanclarmza yle bir
uyar gsteriyoruz:
"Ltfen program hangi dizine kurmak istediinizi belirtin!"
596
Burada * iareti, eklendii parametreyi elerine ayryor. sep parametresi ise * iaretinin
birbirinden ayrd elerin arasna birer . karakteri ekliyor.
Bu iaretin etkilerini u rneklerde daha net grebilirsiniz:
>>> liste = ["Ahmet", "Mehmet", "Veli"]
>>> print(*liste)
Ahmet Mehmet Veli
>>> szlk = {"a": 1, "b": 2}
>>> print(*szlk)
a b
Grdnz gibi, * iareti herhangi bir eyi alp, bunu paralarna ayryor. te bu *
iaretini fonksiyon tanmlarken kullandmzda ise bu ilemin tam tersi gerekleiyor. Yani
fonksiyon tanmnda parametrenin soluna * getirdiimizde, bu fonksiyon arlrken verilen
argmanlar tek bir deiken iinde bir demet olarak toplanyor. Zaten bu konunun banda
verdiimiz u rnekte de bu durum aka grnyor:
def fonksiyon(*parametreler):
print(parametreler)
fonksiyon(1, 2, 3, 4, 5)
Aynen sylediimiz gibi, fonksiyon() adl fonksiyona argman olarak verdiimiz her bir
enin (1, 2, 3, 4, 5 ) tek bir demet iinde toplandn gryorsunuz.
Yldzl parametreler, tanmladnz fonksiyonun parametre saysn herhangi bir ekilde
snrlamak istemediiniz durumlarda ok iinize yarar.
38.5. Parametreler ve Argmanlar
597
* iareti ile birlikte kullanlacak parametrenin adn args yapmak bir zorunluluk olmamakla
birlikte, baka Python programclarnn kodlarnz daha kolay anlayabilmesi asndan bu
gelenei devam ettirmenizi tavsiye ederim. Yazdmz kodlarda Python programlama dilinin
geleneklerine bal kalmak ounlukla iyi bir alkanlktr.
isim)
soyisim)
isis)
ehir)
print("-"*30)
Bu fonksiyon bize toplam drt adet parametre kullanarak, isim, soyisim, iletim sistemi
ve ehir bilgilerinden meydana gelen bir kayt oluturma imkan salyor. Bu fonksiyonda
kullancnn girebilecei bilgiler snrl. Ama bir de yle bir fonksiyon yazdmz dnn:
def kayt_olutur(**bilgiler):
print("-"*30)
598
:
:
:
:
05333213232
Frat
stanbul
zgl
** iaretli parametreler pek ok farkl durumda iinize yarayabilir veya iinizi kolaylatrabilir.
Mesela * ve ** iaretlerini kullanarak yle bir program yazabilirsiniz:
def karlk_bul(*args, **kwargs):
for szck in args:
if szck in kwargs:
print("{} = {}".format(szck, kwargs[szck]))
else:
print("{} kelimesi szlkte yok!".format(szck))
szlk = {"kitap"
: "book",
"bilgisayar" : "computer",
"programlama": "programming"}
karlk_bul("kitap", "bilgisayar", "programlama", "fonksiyon", **szlk)
599
le ve ush adl parametreler olduunu biliyorsunuz. Yine bildiiniz gibi, sep parametresi
print() fonksiyonuna verilen isimsiz parametrelerin her birinin arasna hangi karakterin
geleceini; end parametresi ise bu parametrelerin en sonuna hangi karakterin geleceini
belirliyor. Bizim amacmz bu fonksiyona bir de start adnda isimli bir parametre ekleyerek
print() fonksiyonunun ilevini genileten baka bir fonksiyon yazmak. Bu yeni parametre,
karakter dizilerinin en bana hangi karakterin geleceini belirleyecek.
imdi bu amacmz gerekletirecek kodlarmz yazalm:
def bas(*args, start='', **kwargs):
for e in args:
print(start+e, **kwargs)
bas('e1', 'e2', 'e3', start="#.")
Eer elimizde **kwargs gibi bir imkan olmasayd yukardaki fonksiyonu u ekilde
tanmlamamz gerekirdi:
import sys
def bas(*args, start='', sep=' ', end='\n', file=[Link], flush=False):
for e in args:
print(start+e, sep=sep, end=end, file=file, flush=flush)
600
Fonksiyonu bu ekilde ardktan sonra, fonksiyon tanmnda yer alan input() fonksiyonu
sayesinde kullancya ismi sorulacak ve verdii cevap ekrana baslacaktr.
Yukardaki fonksiyonun tek ilevi kullancdan ald isim bilgisini ekrana basmaktr. Aldnz
bu veriyi baka yerlerde kullanamazsnz. Bu fonksiyonu ardnz anda kullancya ismi
sorulacak ve alnan cevap ekrana baslacaktr. Ancak siz, tanmladnz fonksiyonlarn tek
grevinin bir veriyi ekrana basmak olmasn istemeyebilirsiniz.
rnein yukardaki fonksiyon yardmyla kullancdan ismini aldktan sonra, bu isim bilgisini
baka bir karakter dizisi iinde kullanmak isteyebilirsiniz. Diyelim ki amacnz ismin_ne()
fonksiyonuyla aldnz ismi u karakter dizisi iine aadaki ekilde yerletirmek:
Merhaba Frat. Naslsn?
Bu ktnn ne anlama geldiini birazdan aklayacaz. Ama ncelikle baka bir konudan sz
edelim.
601
Biraz nce sylediimiz gibi, yukarda tanmladmz ismin_ne() adl fonksiyonun tek grevi
kullancdan ald isim bilgisini ekrana basmaktr. imdi bu fonksiyonu bir de yle
tanmlayalm:
def ismin_ne():
isim = input("ismin ne? ")
return isim
Ama eer, mesela yukardaki fonksiyonda isim deikenini basmak yerine dndrrsek iler
deiir:
def ismin_ne():
isim = input("ismin ne? ")
return isim
print("Merhaba {}. Naslsn?".format(ismin_ne()))
Grdnz gibi, istediimiz kty rahatlkla elde ettik. ismin_ne() adl fonksiyondan isim
deerini dndrm olmamz sayesinde bu deerle istediimiz ilemi gerekletirebiliyoruz.
602
Eer fonksiyondan deer dndrmek yerine bu deeri ekrana basmay tercih etseydik
yukardaki ilemi yapamazdk.
return deyimiyle ilgili son bir ey daha syleyelim...
Bu deyim, iinde bulunduu fonksiyonun alma srecini kesintiye uratr. Yani return
deyimini kullandnz satrdan sonra gelen hibir kod almaz. Basit bir rnek verelim:
def fonk():
print(3)
return
print(5)
fonk()
Burada eer fonksiyona parametre olarak eksi deerli bir say verilirse Python bize bir uyar
verecek ve fonksiyonun almasn durduracaktr.
Ancak programmz bu saylar retirken her saydan yalnzca bir adet retecek. Yani ayn
seride bir saydan birden fazla bulunamayacak.
Dilerseniz ncelikle kodlarmz grelim:
import random
def say_ret(balang=0, biti=500, adet=6):
saylar = set()
603
Grdnz gibi bu modln iinde epey ara var. Gelin isterseniz bu aralardan en sk
kullanlanlarn tanyalm.
rnein random modl iinde bulunan sample() adl fonksiyon herhangi bir dizi iinden
istediimiz sayda rastgele numune almamz salar:
>>> liste = ["ahmet", "mehmet", "sevgi", "sevim", "selin", "zeynep", "selim"]
>>> [Link](liste, 2)
['sevim', 'ahmet']
Grdnz gibi, yedi kiilik bir isim listesinden 2 adet rastgele numune aldk. Ayn ilemi
tekrarlayalm:
>>> [Link](liste, 2)
604
['sevgi', 'zeynep']
>>> [Link](liste, 5)
['selin', 'zeynep', 'ahmet', 'selim', 'mehmet']
Numune alma ilemi tamamen rastgeledir. Ayrca grdnz gibi, listeden istediimiz
sayda numune alabiliyoruz.
random modl iinde bulunan shuffle() adl baka bir fonksiyon, bir dizi iindeki elerin
srasn rastgele bir ekilde kartrmamz salar:
>>> liste = ["ahmet", "mehmet", "sevgi", "sevim",
... "selin", "zeynep", "selim"]
>>> [Link](liste)
shuffle() fonksiyonu liste elerini yine ayn liste iinde deitirdi. Deiiklii grmek iin
listeyi ekrana basabilirsiniz:
>>> liste
['selim', 'selin', 'ahmet', 'mehmet',
'sevim', 'sevgi', 'zeynep']
random modl iinde bulunan bir baka fonksiyon ise randrange() fonksiyonudur. Bu
fonksiyon, belli bir aralkta rastgele saylar retmemizi salar:
>>> [Link](0, 500)
156
Dilerseniz imdi
import random
def say_ret(balang=0, biti=500, adet=6):
saylar = set()
while len(saylar) < adet:
[Link]([Link](balang, biti))
return saylar
605
Buna gre, saylar deikeninin uzunluu 6 dan az olduu mddete bu deikene 0 ile
500 arasnda rastgele saylar eklemeye devam edeceiz. Bylelikle saylar deikeni iinde
birbirinden farkl toplam 6 say olmu olacak.
Fonksiyonun son satrnda ise u kodu gryoruz:
return saylar
Bu kod yardmyla, belirtilen miktardaki saylar tutan saylar adl deikeni fonksiyondan
dndryoruz. Yani fonksiyonumuz d dnyaya saylar adl bir deiken veriyor... Bu
deikeni bu ekilde dndrdkten sonra istediimiz gibi kullanabiliriz. Mesela:
for i in range(100):
print(say_ret())
Grdnz gibi, say_ret() fonksiyonunu kullanarak, her biri 6 eden oluan 100 adet
say listesi elde ettik. Biz yukarda bu fonksiyonu parametresiz olarak altrdmz iin,
Python balang, biti ve adet parametrelerinin ntanml deerlerini kulland (srasyla 0,
500 ve 6 ).
606
Eer ktnn kme parantezleri arasnda grnmesini istemiyorsanz elbette kty keynize
gre biimlendirebilirsiniz:
print(*say_ret(100, 1500, 20), sep='-')
Bu ekilde, 100 ile 1500 aras saylardan rastgele 20 adet seip her bir saynn arasna bir
tane - iareti yerletirdik:
352-1251-1366-1381-1350-330-203-842-269-285-816
-658-643-308-1174-152-594-522-1214-959
Bu kodlarda, fonksiyonun dnda x adl bir deiken var. Fonksiyonun iinde de yine x adn
tayan baka bir deiken var. Fonksiyonumuzun grevi bu x deikenini dndrmek.
Bu noktada size yle bir soru sormama izin verin: Acaba fonksiyon iinde tanmladmz x
deikeni, fonksiyon dndaki x deikeninin deerini deitiriyor mu? Bu sorunun cevabn
u kodlarla verelim:
x = 0
def fonk():
x = 1
return x
print('fonksiyon iindeki x: ', fonk())
print('fonksiyon dndaki x: ', x)
Grdnz gibi fonksiyon iindeki ve fonksiyon dndaki ayn adl deikenler birbirine
karmyor. Bunun sebebi, Pythondaki isim alan (namespace ) adl bir kavramdr.
Peki isim alan ne demek?
Pythonda deikenlerin, fonksiyonlarn ve daha sonra greceiniz gibi snarn bir kapsam
vardr. Bu kapsama Pythonda isim alan ad verilir. Dolaysyla Pythonda her nesnenin,
38.8. Fonksiyonlarn Kapsam ve global Deyimi
607
geerli ve etkin olduu bir isim alan bulunur. rnein yukardaki kodlarda fonksiyon
dndaki x deikeni ana isim alannda yer alan global bir deikendir. Fonksiyon iindeki
x deikeni ise fonk() deikeninin isim alan iinde yer alan lokal bir deikendir. Bu iki
deiken, adlar ayn da olsa, birbirlerinden farkl iki nesnedir.
Bir de u rneklere bakalm:
x = []
print('x\'in ilk hali:', x)
def deitir():
print('x\'i deitiriyoruz...')
[Link](1)
return x
deitir()
print('x\'in son hali: ', x)
Burada ise daha farkl bir durum sz konusu. Fonksiyon iinde append() metodunu
kullanarak yaptmz ekleme ilemi fonksiyon dndaki listeyi de etkiledi. Peki ama bu nasl
oluyor?
Python herhangi bir nesneye gndermede bulunduumuzda, yani o nesnenin deerini talep
ettiimizde aradmz nesneyi ilk nce mevcut isim alan iinde arar. Eer aranan nesneyi
mevcut isim alan iinde bulamazsa yukarya doru btn isim alanlarn tek tek kontrol eder.
Birka rnek verelim:
def fonk():
print(x)
fonk()
Bu hatann sebebi, x adl bir deikenin tanmlanmam olmasdr. Bu hatay gidermek iin
yle bir kod yazabiliriz:
x = 0
def fonk():
print(x)
fonk()
x = 0
def fonk():
x = 10
print(x)
fonk()
print(x)
Ama eer bir nesne deitirilemez bir nesne ise, o nesnenin deerini zaten normalde
de deitiremezsiniz. Deitirmi gibi yapmak iin ise o nesneyi yeniden tanmlamanz
gerektiini biliyorsunuz:
>>> isim = 'Frat'
>>> isim += ' zgl'
>>> print(isim)
Frat zgl
Burada yaptmz ey, karakter dizisinin deerini deitirmekten ziyade bu karakter dizisini
yeniden tanmlamaktr. nk bildiiniz gibi karakter dizileri deitirilemeyen veri tipleridir.
te karakter dizileri gibi deitirilemeyen nesneleri,
deitiremeyeceiniz gibi, yeniden tanmlayamazsnz da...
lokal
isim
alanlarnda
isim = 'Frat'
def fonk():
isim += ' zgl'
return isim
print(fonk())
609
Deitirilebilen bir veri tipi olan listeleri, fonksiyon iinde yeniden tanmlayamazsnz. Ancak
tabii isterseniz listeleri deiiklie uratabilirsiniz:
isim_listesi = []
def fonk():
isim_listesi.extend(['Frat zgl', 'Orun Kunek'])
return isim_listesi
print(fonk())
Bu kodlar dzgn bir ekilde alp, fonksiyon dndaki isim_listesi adl listeyi deiiklie
uratacaktr. Ancak u kodlar hata verecektir:
isim_listesi = []
def fonk():
isim_listesi += ['Frat zgl', 'Orun Kunek']
return isim_listesi
print(fonk())
te Python programlama dili bu tr durumlar iin zm olacak bir ara sunar bize. Bu aracn
ad global.
Gelin isterseniz bu global adl deyimin nasl kullanlacana bakalm nce...
u kodlarn hata vereceini biliyorsunuz:
isim = 'Frat'
def fonk():
isim += ' zgl'
return isim
print(fonk())
Burada fonk() adl fonksiyonun ilk satrnda yle bir kod gryoruz:
610
global isim
te bu satr, isim adl deikenin global alana tanmasn salyor. Bylece global alanda
bulunan isim adl deikeni deiiklie uratabiliyoruz.
global deyimi her ne kadar ilk bakta ok faydal bir aram gibi grnse de aslnda
programlarmzda genellikle bu deyimi kullanmaktan kanmamz iyi bir kir olacaktr. nk
bu deyim aslnda global alan kirletmemize neden oluyor. Global deikenlerin lokal
isim alanlarnda deiiklie uratlmas, eer dikkatsiz davranrsanz programlarnzn hatal
almasna yol aabilir.
611
BLM 39
Gml Fonksiyonlar
Bu blmde, daha nce de birka kez bahsettiimiz ve oka rneini grdmz bir
kavramdan sz edeceiz. Bu kavramn ad gml fonksiyonlar.
Esasnda biz buraya gelene kadar Pythonda pek ok gml fonksiyon grdk. Dolaysyla
aslnda grn olarak bunlarn neye benzediini biliyoruz.
rnein daha nceki
derslerimizde grdmz print() gml bir fonksiyondur. Ayn ekilde open(), type(),
len(), pow(), bin() ve imdiye kadar tantmz teki btn fonksiyonlar birer gml
fonksiyondur.
Gml fonksiyonlar ngilizcede builtin functions olarak adlandrlr. Bu fonksiyonlar
gerekten de dile gml vaziyettedirler. Bildiiniz gibi, bir fonksiyonu kullanabilmemiz iin
o fonksiyonu tanmlamamz gerekir. te gml fonksiyonlar, bizim tanmlamamza gerek
kalmadan, Python gelitiricileri tarafndan nceden tanmlanp dile gmlm ve hizmetimize
sunulmu faydal birtakm aralardr.
te bu blmde biz de bu gml fonksiyonlar tek tek ve ayrntl olarak inceleyeceiz.
Dediimiz gibi, bunlardan bir ksmn halihazrda grmtnz. Ama biz btnlk asndan,
nceden ele alm olduumuz bu fonksiyonlara da ksaca deinmeden gemeyeceiz.
Bylelikle hem yeni fonksiyonlar renmi olacaz hem de nceden rendiimiz
fonksiyonlarla birlikte yeni fonksiyonlar da derli toplu bir ekilde grme imkanmz olacak.
Bu blmde elbette birtakm fonksiyonlar salt art arda sralamakla yetinmeyeceiz.
Pythondaki gml fonksiyonlar incelerken bir yandan da Python programlama dilindeki
ok nemli baz kavramlar ele alacaz.
lk olarak abs() adl bir fonksiyonla balyoruz gml fonksiyonlar incelemeye...
39.1 abs()
ngilizcede mutlak anlamna gelen absolute adl bir kelime bulunur. te bu fonksiyonun
ad da bu kelimeden gelir. Fonksiyonumuzun grevi de isminin anlamna yakndr. abs()
fonksiyonunu bir saynn mutlak deerini elde etmek iin kullanyoruz.
Peki mutlak deer ne anlama geliyor. Esasnda siz bu kavrama matematik derslerinden
ainasnz. Ama bilmeyenler veya unutmu olanlar iin tekrar edelim. Mutlak deer bir
saynn 0 a olan uzakldr. rnein 20 saysnn 0 saysna olan uzakl 20dir. Dolaysyla
20 saysnn mutlak deeri 20dir. Ayn ekilde -20 saysnn da 0 saysna uzakl 20dir. Yani,
-20 saysnn da mutlak deeri 20dir.
te abs() fonksiyonu bize bir saynn mutlak deerinin ne olduunu syler:
612
>>> abs(-20)
20
>>> abs(20)
20
>>> abs(20.0)
20.0
Mutlak deer kavram yalnzca tamsaylar ve kayan noktal saylar iin deil, ayn zamanda
karmak saylar iin de geerlidir. Dolaysyla abs() fonksiyonunu kullanarak karmak
saylarn da mutlak deerini hesaplayabiliriz:
>>> abs(20+3j)
20.223748416156685
Grdnz gibi bu fonksiyon yalnzca tek bir parametre alyor ve bu parametrenin mutlak
deerini dndryor.
39.2 round()
round() fonksiyonu bir sayy belli ltlere gre yukar veya aa doru yuvarlamamz
salar. Basit birka rnek verelim:
>>> round(12.4)
12
>>> round(12.7)
13
Grdnz gibi bu fonksiyon, kayan noktal saylar en yakn tam sayya doru yuvarlyor.
Ancak burada dikkat etmemiz gereken bir nokta var.
u rnekleri bir inceleyelim:
>>> round(1.5)
2
>>> round(12.5)
12
Grdnz gibi, fonksiyonumuz 1.5 saysn yukar doru, 12.5 saysn ise aa doru
yuvarlad. Bunun sebebi, kayan noktal bir saynn st ve alt tam saylara olan uzaklnn
birbirine eit olduu durumlarda Pythonn ift sayya doru yuvarlama yapmay tercih
etmesidir. Mesela yukardaki rneklerde 1.5 says hem 1 saysna, hem de 2 saysna eit
uzaklkta bulunuyor. te Python bu durumda, bir ift say olan 2 saysna doru yuvarlamay
tercih edecektir.
39.2. round()
613
round() fonksiyonu toplam iki parametre alr. lk parametre, yuvarlanacak saynn kendisidir.
Yuvarlama hassasiyetini belirlemek iin ise ikinci bir parametreden yararlanabiliriz.
rnein 22 saysn 7 ye bldmzde normalde yle bir kt elde ederiz:
>>> 22/7
3.142857142857143
te biz round() fonksiyonuna ikinci bir parametre daha vererek, yuvarlama hassasiyetini
kontrol edebiliriz.
Aadaki rnekleri dikkatlice inceleyin:
>>> round(22/7)
3
>>> round(22/7, 0)
3.0
>>> round(22/7, 1)
3.1
>>> round(22/7, 2)
3.14
>>> round(22/7, 3)
3.143
>>> round(22/7, 4)
3.1429
39.3 all()
All kelimesi Trkede hepsi anlamna gelir. Bu fonksiyonun grevi de bu anlam artrr.
all() fonksiyonunun grevi, bir dizi iinde bulunan btn deerler True ise True deeri, eer
bu deerlerden herhangi biri False ise de False deeri dndrmektir.
rnein elimizde yle bir liste olduunu varsayalm:
614
Bildiiniz gibi, 0 hari btn saylarn bool deeri True dur. Yukardaki listede False deeri
verebilecek herhangi bir deer bulunmadndan, all() fonksiyonu bu liste iin True deerini
veriyor. Bir de una bakalm:
>>> liste = [0, 1, 2, 3, 4]
>>> all(liste)
False
Dediimiz gibi, all() fonksiyonu ancak dizi iindeki btn deerlerin bool deeri True ise
True kts verecektir.
Son bir rnek daha verelim:
>>> liste = ['ahmet', 'mehmet', '']
>>> all(liste)
False
Listede False deerine sahip bir bo karakter dizisi bulunduu iin all() fonksiyonu False
kts veriyor.
Bu fonksiyonu her trl kodun bool deerlerini test etmek iin kullanabilirsiniz. Mesela
bu fonksiyonu kullanarak, bir nesnenin listelenen zelliklerin hepsine sahip olup olmadn
denetleyebilirsiniz:
>>>
>>>
>>>
>>>
>>>
a = 3
t1 = a == 3
t2 = a < 4
t3 = a % 2 == 1
all([t1, t2, t3])
#say
#say
#say
#say
3 m?
4'ten kk m?
bir tek say m?
bu zelliklerin hepsine sahip mi?
True
Eer saymz bu zelliklerin birine bile sahip deilse, all() fonksiyonu False kts verecektir.
39.4 any()
Any kelimesi ngilizcede herhangi bir anlamna gelir. te any() fonksiyonunun grevi de,
bir dizi iindeki btn deerlerden en az biri True ise True kts vermektir.
rnein:
>>> liste = ['ahmet', 'mehmet', '']
>>> any(liste)
True
39.4. any()
615
any() fonksiyonunun True kts verebilmesi iin listede yalnzca bir adet True deerli e
olmas yeterlidir. Bu fonksiyonun False kts verebilmesi iin dizi iindeki btn elerin
bool deerinin False olmas gerekir:
>>> l = ['', 0, [], (), set(), dict()]
>>> any(l)
False
39.5 ascii()
Bu fonksiyon, bir nesnenin ekrana baslabilir halini verir bize. Dilerseniz bu fonksiyonun
yapt ii tanmlamak yerine bunu bir rnek zerinden anlatmaya alalm:
>>> a = 'istihza'
>>> print(ascii(a))
'istihza'
616
'\u015f'
'\u0131'
'k'
Burada listemiz ascii() fonksiyonuna parametre olarak verildikten sonra artk liste olma
zelliini yitirip bir karakter dizisi haline gelir. Bunu denetleyelim:
>>> print(type(temsil))
<class 'str'>
>>> temsil[0]
'['
Grdnz gibi, ascii() fonksiyonu listeyi alp, bunu ekrana baslabilir bir btn haline
getiriyor. Elbette bunun iin de, kendisine verilen parametreyi bir karakter dizisine
dntryor.
39.6 repr()
repr() fonksiyonunun yapt i, biraz nce grdmz ascii() fonksiyonunun yapt ie
ok benzer. Bu iki fonksiyon, ASCII olmayan karakterlere muameleleri asndan birbirinden
ayrlr.
Hatrlarsanz ascii() fonksiyonu ASCII olmayan karakterlerle karlatnda bunlarn
UNICODE (veya onaltlk) temsillerini gsteriyordu:
>>> ascii('eker')
"'\\u015feker'"
repr() fonksiyonu ise ASCII olmayan karakterlerle karlasa bile, bize kt olarak bunlarn
da karakter karlklarn gsterir:
>>> repr('eker')
"'eker'"
39.6. repr()
617
39.7 bool()
Bu fonksiyon bir nesnenin bool deerini verir:
>>> bool(0)
False
>>> bool(1)
True
>>> bool([])
False
39.8 bin()
Bu fonksiyon, bir saynn ikili dzendeki karln verir:
>>> bin(12)
'0b1100'
Bu fonksiyonun verdii ktnn bir say deil, karakter dizisi olduuna dikkat etmelisiniz.
39.9 bytes()
Bu fonksiyon bytes trnde nesneler oluturmak iin kullanlr. Bu fonksiyonu bayt adl veri
tipini incelerken ayrntl olarak ele almtk. Gelin isterseniz burada da bu fonksiyona yle
bir deinelim.
Dediimiz gibi, bytes() adl fonksiyon, bytes trnde veriler oluturmaya yarar. Bu fonksiyon
ilev olarak, daha nce rendiimiz list(), str(), int(), set(), dict() gibi fonksiyonlara
ok benzer. Tpk bu fonksiyonlar gibi, bytes() fonksiyonunun grevi de farkl veri tiplerini
bayt adl veri tipine dntrmektir.
Bu fonksiyon, kendisine verilen parametrelerin trne bal olarak birbirinden farkl sonular
ortaya karr. rnein eer bu fonksiyona parametre olarak bir tam say verecek olursanz,
bu fonksiyon size o tam say miktarnca bir bayt nesnesi verecektir. Gelin isterseniz bu
durumu rnekler zerinde gstermeye alalm:
>>> bytes(10)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Yukardaki komut bize, her bir esinin deeri 0 olan 10 baytlk bir veri dndrd:
>>> a = bytes(10)
>>> a
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
618
>>> a[0]
0
>>> a[1]
0
>>> a[2]
0
Dolaysyla, bytes() fonksiyonunun bir karakter dizisini bayta evirirken nasl davranmas
gerektiini anlayabilmesi iin, bayta dntrme ilemini hangi kod zc ile yapmak
istediimizi aka belirtmemiz gerekir:
>>> bytes('k', 'utf-8')
b'\xc4\xb1\xc5\x9f\xc4\xb1k'
>>> bytes('k', 'cp1254')
b'\xfd\xfe\xfdk'
39.9. bytes()
619
Grdnz gibi, bytes() fonksiyonuna parametre olarak bir karakter dizisi verebilmek iin,
bu karakter dizisi ile birlikte bir kod zc de belirtmemiz gerekiyor. Bylece bytes()
fonksiyonu kendisine verdiimiz karakter dizisini, belirttiimiz kod zcnn kurallarna
gre bayta dntryor.
Bu arada, ktda grnen b harerinin, elimizdeki verinin bir bayt olduunu gsteren bir
iaret olduunu biliyorsunuz.
Ayrca, bytes() fonksiyonuna verdiimiz ikinci parametrenin isminin encoding olduunu ve
bu parametreyi isimli bir parametre olarak da kullanabileceimizi belirtelim:
>>> bytes('istihza', encoding='ascii')
Bu noktada size yle bir soru soraym: Acaba bytes() fonksiyonuna ilk parametre olarak
verdiimiz karakter dizisi, ikinci parametrede belirttiimiz kod zc tarafndan tannmazsa
ne olur?
Cevab tahmin edebilirsiniz: Byle bir durumda elbette Python bize bir hata mesaj gsterir:
>>> bytes('eker', 'ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u015f' in position 0:
ordinal not in range(128)
... veya:
>>> bytes('', 'cp857')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python33\lib\encodings\[Link]", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position
0: character maps to <undefined>
har ASCII karakter kmesinde; iareti ise CP857 adl karakter kmesinde
tanmlanmam birer karakter olduu iin, ilgili kod zcler bu karakterleri zp bayta
dntremiyor. Yazdmz kodlarn bu tr durumlarda tamamen kmesini engellemek
iin, nceki derslerimizde de eitli vesilelerle renmi olduumuz errors adl bir
parametreden yararlanabiliriz:
>>> bytes('k', encoding='ascii', errors='replace')
b'???k'
>>> bytes('eker', encoding='ascii', errors='replace')
b'?eker'
>>> bytes('', encoding='cp857', errors='replace')
620
b'?'
>>> bytes('', encoding='cp857', errors='ignore')
b''
>>> bytes('', encoding='cp857', errors='xmlcharrefreplace')
b'€'
>>> bytes('eker', encoding='cp857', errors='xmlcharrefreplace')
b'\x9feker'
Bu yap iinde Python, 0 ile 128 aras saylar iin standart ASCII tablosunu, 128 ile 256 aras
saylar iin ise Latin-1 karakter kmesini temel alarak saylar birer bayta dntrecektir.
39.10 bytearray()
Bildiiniz gibi baytlar deitirilemeyen bir veri tipidir. Dolaysyla bir bayt veri tipi zerinde
herhangi bir deiiklik yapamayz. rnein bir baytn herhangi bir esini baka bir deerle
deitiremeyiz:
>>> a = bytes('istihza', 'ascii')
>>> a[0]
105
>>> a[0] = 106
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment
Ama eer hem baytlarla almak, hem de bu baytlarn zerinde deiiklik yapabilmek
isterseniz baytlar yerine bayt dizileri ile alabilirsiniz. te bunun iin bytearray() adl bir
fonksiyondan yararlanyoruz.
Yaptklar i bakmndan bytearray() ve bytes() fonksiyonlar birbirlerine ok benzer. Bu
ikisi arasndaki tek fark, bytearray() ile oluturulan veri tipinin, bytes() ile oluturulan veri
39.10. bytearray()
621
39.11 chr()
Bu fonksiyon, kendisine parametre olarak verilen bir tam saynn karakter karln
dndrr. rnein:
>>> chr(10)
'\n'
Bildiiniz gibi 10 saysnn karakter karl satr ba karakteridir. Bir de una bakalm:
>>> chr(65)
'A'
39.12 list()
Bu fonksiyon iki farkl ama iin kullanlabilir:
1. Liste tipinde bir veri oluturmak
2. Farkl veri tiplerini liste adl veri tipine dntrmek
Birinci ama iin bu fonksiyonu u ekilde kullanyoruz:
>>> l = list()
622
>>> list('istihza')
['i', 's', 't', 'i', 'h', 'z', 'a']
Bir szlk listeye dntrlrken, elbette szln anahtarlar dikkate alnacaktr. Eer siz
szln anahtarlarndan deil de deerlerinde bir liste oluturmak isterseniz yle bir kod
yazabilirsiniz:
>>> list([Link]())
[10, 100, 44]
39.13 set()
set() fonksiyonu list() fonksiyonuna ok benzer. Bu fonksiyon da tpk list() fonksiyonu
gibi, veri tipleri arasnda dntrme ilemleri gerekletirmek iin kullanlabilir. set()
fonksiyonunun grevi farkl veri tiplerini kmeye dntrmektir:
>>> k = set()
Burada bo bir kme oluturduk. imdi de mesela bir karakter dizisini kmeye dntrelim:
>>> i = 'istihza'
>>> set(i)
{'t', 's', 'z', 'a', 'i', 'h'}
39.14 tuple()
tuple() fonksiyonu da, tpk list(), set() ve benzerleri gibi bir dntrc fonksiyondur.
Bu fonksiyon farkl veri tiplerini demete dntrr:
>>> tuple('a')
('a',)
39.15 frozenset()
Bu fonksiyonu kullanarak farkl veri tiplerini dondurulmu kmeye dntrebilirsiniz:
39.13. set()
623
>>> s = set('istihza')
>>> df = frozenset(s)
>>> df
frozenset({'t', 's', 'a', 'z', 'i', 'h'})
39.16 complex()
Saylardan sz ederken, eer matematikle ok fazla ili dl deilseniz pek
karlamayacanz, karmak say adl bir say trnden de bahsetmitik. Karmak
saylar, bir gerek, bir de sanal ksmdan oluan saylardr.
Karmak saylar Pythonda complex ifadesiyle gsteriliyor. Mesela u bir karmak saydr:
>>> 12+0j
te eer herhangi bir sayy karmak sayya dntrmeniz gerekirse complex() adl bir
fonksiyondan yararlanabilirsiniz. rnein:
>>> complex(15)
(15+0j)
Byle bir kod yazdmzda, verdiimiz parametre karmak saynn gerek ksmn
oluturacak, sanal ksm ise 0 olarak kabul edilecektir. Elbette isterseniz sanal ksm kendiniz
de belirleyebilirsiniz:
>>> complex(15, 2)
(15+2j)
39.17 oat()
Bu fonksiyonu, saylar veya karakter dizilerini kayan noktal sayya dntrmek iin
kullanyoruz:
>>> float('134')
134.0
>>> float(12)
12.0
39.18 int()
Bu fonksiyon birka farkl ama iin kullanlabilir. int() fonksiyonunun en temel grevi, bir
karakter dizisi veya kayan noktal sayy (eer mmknse) tam sayya dntrmektir:
624
>>> int('10')
10
>>> int(12.4)
12
Bunun dnda bu fonksiyonu, herhangi bir sayma sisteminde temsil edilen bir sayy onlu
sayma sistemine dntrmek iin de kullanabiliriz. rnein:
>>> int('12', 8)
10
Burada, sekizli sayma sistemine ait say deerli bir karakter dizisi olan 12yi onlu sayma
sistemine dntrdk ve bylece 10 saysn elde ettik.
int() fonksiyonunu sayma sistemleri arasnda dntrme ilemlerinde kullanabilmek iin
ilk parametrenin bir karakter dizisi olmas gerektiine dikkat ediyoruz.
Bu arada, int(12, 8) komutununun 12 saysn sekizli sayma sistemine dntrmediine
dikkat edin. Bu komutun yapt i sekizli sayma sistemindeki 12 saysn onlu sayma
sistemine dntrmektir.
int() fonksiyonunun bu kullanmyla ilgili bir rnek daha verelim:
>>> int('4cf', 16)
1231
Burada da, onaltl sayma sistemine ait bir say olan 4cf yi onlu sayma sistemine evirdik
ve 1231 saysn elde ettik. 4cf saysn int() fonksiyonuna parametre olarak verirken
bunu karakter dizisi eklinde yazmay unutmuyoruz. Aksi halde Python bize bir hata mesaj
gsterecektir.
39.19 str()
Bu fonksiyonun, farkl veri tiplerini karakter dizisine dntrmek iin kullanldn
biliyorsunuz. rnein:
>>> str(12)
'12'
Burada 12 saysn bir karakter dizisine dntrdk. imdi de bir bayt karakter dizisine
dntrelim:
>>> bayt = b'istihza'
39.19. str()
625
Grdnz gibi, bir bayt karakter dizisine dntrmek iin str() fonksiyonuna
encoding adl bir parametre veriyoruz. Fonksiyonumuz, bu parametrede hangi kodlama
biimi belirtildiyse, baytlar bu kodlama biiminin kurallarna gre bir karakter dizisine
dntryor.
Tahmin edebileceiniz gibi, belirttiiniz kodlama biiminin herhangi bir bayt karakter dizisine
dntremedii durumlara kar bir errors parametresi de verebiliriz str() fonksiyonuna.
rnein elimizde bayt tipinde yle bir veri olduunu varsayalm:
>>> bayt = bytes('kadn', encoding='utf-8')
>>> print(bayt)
b'kad\xc4\xb1n'
ASCII adl kod zc, bkadn iindeki baytlardan birini tanyamad iin bize bir hata
mesaj gsterdi. Bildiiniz gibi ASCII 128den byk baytlar dntremez. te bu tr
durumlara kar errors parametresinden yararlanabilirsiniz:
>>> kardiz = str(bayt, encoding='ascii', errors='ignore')
>>> print(kardiz)
kadn
errors parametresine verdiimiz ignore deeri sayesinde Python bize hata mesaj gstermek
yerine, ASCII ile zlemeyen bayt grmezden geldi. errors parametresinin hangi deerleri
alabileceini nceki derslerimizden hatrlyor olmalsnz.
39.20 dict()
Bu fonksiyon, farkl veri tiplerinden szlkler retmemizi salar. rnein bu fonksiyonu
kullanarak bo bir szlk oluturabiliriz:
>>> s = dict()
dict() fonksiyonuna parametre olarak i ie gemi listeler veya demetler vererek de szlk
retebiliriz:
>>> eler = (['a', 1], ['b', 2], ['c', 3])
>>> dict(eler)
{'a': 1, 'b': 2, 'c': 3}
626
39.21 callable()
Bu fonksiyon, bir nesnenin arlabilir olup olmadn denetler. Peki hangi nesneler
arlabilir zelliktedir. Mesela fonksiyonlar arlabilir nesnelerdir. Deikenler ise
arlabilir nesneler deildir.
Birka rnek verelim bununla ilgili:
>>> callable(open)
True
Pythonn open() adl bir fonksiyonu olduu iin, doal olarak callable() fonksiyonu True
kts veriyor.
Bir de una bakalm:
>>> import sys
>>> callable([Link])
False
Burada da sys modl iindeki version adl nesnenin arlabilir zellikte olup olmadn
sorguladk. Daha nceki derslerimizde de grdnz gibi, sys modl iindeki version
adl ara bir fonksiyon deil, deikendir. Dolaysyla bu deiken callable([Link])
sorgusuna False yant verir.
39.22 ord()
Bu fonksiyon, bir karakterin karlk geldii ondalk sayy verir. rnein:
>>> ord('a')
97
>>> ord('')
305
39.23 oct()
Bu fonksiyon, bir sayy sekizli dzendeki karlna evirmemizi salar:
>>> oct(10)
'0o12'
39.24 hex()
Bu fonksiyon, bir sayy onaltl dzendeki karlna evirmemizi salar:
39.21. callable()
627
>>> hex(305)
'Ox131'
Yalnz hem oct() hem de hex() fonksiyonlarnda dikkat etmemiz gereken ey, bu
fonksiyonlarn parametre olarak bir say alp, kt olarak bir karakter dizisi veriyor olmasdr.
ngilizcede statement olarak adlandrlan deyimler ise ifadeleri de kapsayan daha geni bir
kavramdr. Buna gre btn ifadeler ayn zamanda birer deyimdir. Daha dorusu, ifadelerin
bir araya gelmesi ile deyimler oluturulabilir.
Deyimlere birka rnek verelim:
>>> a = 5
>>> if a:
...
print(a)
>>> for i in range(10):
...
print(i)
628
Python programlama dilinde deyimlerle ifadeleri ayrt etmenin kolay bir yolu da eval()
fonksiyonundan yararlanmaktr.
Eer deyim mi yoksa ifade mi olduundan emin
olamadnz bir eyi eval() fonksiyonuna parametre olarak verdiinizde hata almyorsanz
o parametre bir ifadedir. Eer hata alyorsanz o parametre bir deyimdir. nk eval()
fonksiyonuna parametre olarak yalnzca ifadeler verilebilir.
Birka rnek verelim:
>>> eval('a = 5')
File "<string>", line 1
a = 5
^
SyntaxError: invalid syntax
Grdnz gibi, eval() fonksiyonu bize bir hata mesaj verdi. nk a = 5 kodu bir
deyimdir. Unutmayn, Pythonda btn deer atama ilemleri birer deyimdir. Dolaysyla
eval() fonksiyonu bu deyimi parametre olarak alamaz.
Bir de una bakalm:
>>> eval('5 + 25')
30
Bu defa hata almadk. nk eval() fonksiyonuna, olmas gerektii gibi, parametre olarak
bir ifade verdik. Bildiiniz gibi, 5 + 25 kodu bir ifadedir.
Dediimiz gibi, eval() fonksiyonu deyimleri parametre olarak alamaz.
fonksiyonu alabilir:
Ama exec()
Bu ekilde, deeri 5 olan a adl bir deiken oluturmu olduk. sterseniz kontrol edelim:
>>> print(a)
5
Grdnz gibi, exec() fonksiyonu, mevcut isim alan iinde a adl bir deiken oluturdu.
Yalnz elbette mevcut isim alan iinde yeni deikenler ve yeni deerler olutururken dikkatli
olmamz gerektiini biliyorsunuz. Zira mesela yukardaki komutu vermeden nce mevcut isim
alannda zaten a adl bir deiken varsa, o deikenin deeri deiecektir:
>>> a = 20
Elimizde, deeri 20 olan a adl bir deiken var. imdi exec() fonksiyonu yardmyla a
deikeninin de iinde yer ald mevcut isim alanna mdahale ediyoruz:
>>> exec('a = 10')
Bu tr durumlarda, exec() ile oluturduunuz deikenleri global isim alanna deil de, farkl
bir isim alanna gndermeyi tercih edebilirsiniz. Peki ama bunu nasl yapacaz?
39.25. eval(), exec(), globals(), locals(), compile()
629
Python programlama dilinde isim alanlar szlk tipinde bir veridir. rnein global isim alan
basit bir szlkten ibarettir.
Global isim alann gsteren szlkte hangi anahtar ve deerlerin olduunu grmek iin
globals() adl bir fonksiyonu kullanabilirsiniz:
>>> globals()
globals adl bu szln ierii, o anda global isim alannda bulunan nesnelere gre farkllk
gsterecektir. rnein:
>>> x = 10
eklinde 10 deerine sahip bir x nesnesi tanmladktan sonra globals() fonksiyonunu tekrar
altrrsanz global isim alanna bu nesnenin de eklenmi olduunu grrsnz.
Dediimiz gibi, globals() fonksiyonundan dnen nesne bir szlktr. Bu szle, herhangi
bir szle veri ekler gibi deer de ekleyebilirsiniz:
>>> globals()['z'] = 23
Yalnz, Python programlama dili bize bu ekilde global isim alanna nesne ekleme imkan
verse de, biz mecbur deilsek bu yntemi kullanmaktan kanmalyz. nk bu ekilde
srad bir yntemle deiken tanmladmz iin aslnda global isim alann, nerden geldiini
kestirmenin g olduu deerlerle kirletmi oluyoruz.
Bildiiniz gibi, Pythonda global isim alan dnda bir de lokal isim alan bulunur. Lokal isim
alanlarnn, fonksiyonlara (ve ileride greceimiz gibi snara) ait bir isim alan olduunu
biliyorsunuz. te bu isim alanlarna ulamak iin de locals() adl bir fonksiyondan
yararlanacaz:
def fonksiyon(param1, param2):
x = 10
print(locals())
fonksiyon(10, 20)
Grdnz gibi, locals() fonksiyonu gerekten de bize fonksiyon() adl fonksiyon iindeki
lokal deerleri veriyor.
630
exec() fonksiyonu yardmyla a deikeninin de iinde yer ald mevcut isim alanna
mdahale edelim:
>>> exec('a = 3')
Dediimiz gibi, bu tr durumlarda, exec() ile oluturduunuz deikenleri global isim alan
yerine farkl bir isim alanna gndermeyi tercih etmemiz daha uygun olacaktr. Pythonda
isim alanlarnn basit bir szlk olduunu rendiimize gre, exec() ile oluturduumuz
deikenleri global isim alan yerine nasl farkl bir isim alanna gndereceimizi grebiliriz.
nce yeni bir isim alan oluturalm:
>>> ia = {}
39.26 copyright()
Bu fonksiyon yardmyla Pythonn telif haklarna ilikin bilgilere eriebilirsiniz:
>>> copyright()
Copyright (c) 2001-2012 Python Software Foundation.
All Rights Reserved.
Copyright (c) 2000 [Link].
All Rights Reserved.
Copyright (c) 1995-2001 Corporation for National Research Initiatives.
39.26. copyright()
631
39.27 credits()
Bu fonksiyon, Python programlama diline katkda bulunanlara teekkr ieren kk bir
metni ekrana kt olarak verir:
>>> credits()
Thanks to CWI, CNRI, [Link], Zope Corporation and a cast of thousands
for supporting Python development. See [Link] for more information.
39.28 license()
Bu fonksiyon yardmyla Pythonn lisansna ilikin epey ayrntl metinlere ulaabilirsiniz.
39.29 dir()
Eer dir() fonksiyonunu parametresiz olarak kullanrsak, mevcut isim alanndaki eleri bir
liste halinde elde ederiz:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__']
39.30 divmod()
Bu fonksiyonun ilevini bir rnek zerinden gstermeye alalm:
>>> divmod(10, 2)
(5, 0)
632
Grdnz gibi divmod(10, 2) komutu bize iki eli bir demet veriyor. Bu demetin ilk esi,
divmod() fonksiyonuna verilen ilk parametrenin ikinci parametreye blnmesi ileminin
sonucudur. Demetimizin ikinci esi ise, ilk parametrenin ikinci parametreye blnmesi
ileminden kalan saydr. Yani demetin ilk parametresi blme ileminin blm ksmn, ikinci
esi ise kalan ksmn verir.
Bu fonksiyonun blme ilemininin sonucunu tamsay cinsinden verdiine dikkat ediyoruz:
>>> divmod(10, 3)
(3, 1)
10 says 3 saysna blndnde tamsay cinsinden sonu 3 tr. Bu blme ileminin kalan
ise 1 dir.
39.31 enumerate()
ngilizcede enumerate kelimesi numaralandrmak anlamna gelir.
enumerate()
fonksiyonunun grevi de kelimenin bu anlamyla ayndr. Yani bu fonksiyonu kullanarak
nesneleri numaralandrabiliriz.
Bu fonksiyon bize bir enumerate nesnesi verir:
>>> enumerate('istihza')
<class 'enumerate'>
veya:
>>> [i for i in enumerate('istihza')]
[(0, 'i'), (1, 's'), (2, 't'), (3, 'i'), (4, 'h'), (5, 'z'), (6, 'a')]
for i in enumerate('istihza'):
print(i)
'i')
's')
't')
'i')
'h')
39.31. enumerate()
633
(5, 'z')
(6, 'a')
Grdnz gibi, enumerate nesnesi bize her koulda iki eli demetler veriyor.
demetlerin herbir esine nasl ulaabileceimizi de biliyor olmalsnz:
>>>
...
...
0.
1.
2.
3.
4.
5.
6.
Bu
rneklerden de grdnz gibi, enumerate() fonksiyonu bize bir dizi iindeki elerin
srasn ve enin kendisini ieren bir demet veriyor. Dikkat ettiyseniz, her zaman olduu
gibi, Python burada da saymaya 0dan balyor. Yani enumerate() fonksiyonunun rettii e
sralamasnda ilk enin sras 0 oluyor. Elbette eer isterseniz enumerate() fonksiyonunun
saymaya katan balayacan kendiniz de belirleyebilirsiniz:
>>>
...
...
1.
2.
3.
4.
5.
6.
7.
39.32 exit()
Bu fonksiyon, o anda alan programdan kmanz salar. Eer bu komutu etkileimli
kabukta verirseniz o anda ak olan oturum kapanacaktr.
39.33 help()
help() fonksiyonu gml fonksiyonlar iinde en faydal fonksiyonlarn banda gelir. Bu
fonksiyonu kullanarak Python programlama diline ait elere ilikin yardm belgelerine
ulaabiliriz. rnein:
>>> help(dir)
634
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at [Link]
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".
To get a list of available modules, keywords, or topics, type "modules",
"keywords", or "topics". Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".
help>
Bu ekranda, hakknda bilgi edinmek istediiniz eyi help> ibaresinden hemen sonra, boluk
brakmadan yazarak eye ilikin bilgilere ulaabilirsiniz:
help> dir
39.34 id()
Pythonda her nesnenin bir kimliinin olduunu biliyorsunuz. Kimlik ilelerini incelediimiz
konuda bundan bir miktar bahsetmi ve orada id() adl bir fonksiyondan sz etmitik.
Orada yle bir rnek vermitik:
>>> a = 50
>>> id(a)
505494576
>>> kardiz = "Elveda Zalim Dnya!"
>>> id(kardiz)
14461728
Orada sylediimiz ve yukardaki rneklerden de bir kez daha grdnz gibi, Pythondaki
her nesnenin kimlii eiz, tek ve benzersizdir.
39.34. id()
635
39.35 input()
Bu fonksiyonun ne ie yaradn gayet iyi biliyorsunuz. input() adl bu gml fonksiyonu
kullanarak kullanc ile veri alveriinde bulunabiliyoruz.
39.36 format()
Bu gml fonksiyonun grevi, daha nce karakter dizilerini ilerken, karakter dizilerinin
bir metodu olarak rendiimiz format() metodununa benzer bir ekilde, karakter dizilerini
biimlendirmektir. Ancak format() fonksiyonu, daha nce rendiimiz format() metoduna
gre daha dar kapsamldr. format() metodunu kullanarak olduka karmak karakter
dizisi biimlendirme ilemlerini gerekletirebiliriz, ama birazdan inceleyeceimiz format()
gml fonksiyonu yalnzca tek bir deeri biimlendirmek iin kullanlr.
Basit bir rnek verelim:
>>> format(12, '.2f')
12.00
Yukardaki ifadeyi daha nce grdmz format() metodu ile u ekilde yazabiliriz:
>>> '{:.2f}'.format(12)
'12.00'
39.37 lter()
Bu gml fonksiyon yardmyla dizi nitelii tayan nesneler iindeki eler zerinde belirli
bir lte gre bir szme ilemi uygulayabiliriz. Dilerseniz filter() fonksiyonunun grevini
bir rnek zerinden anlamaya alalm.
Diyelim ki elimizde yle bir liste var:
>>> [400, 176, 64, 175, 355, 13, 207, 298, 397, 386, 31, 120, 120, 236,
241, 123, 249, 364, 292, 153]
636
249
153
Hatta eer istersek liste retelerini kullanarak ayn ilemi daha ksa bir yoldan da
halledebiliriz:
>>> [i for i in l if i % 2 == 1]
[175, 355, 13, 207, 397, 31, 241, 123, 249, 153]
te Python, yukardaki ilemi yapabilmemiz iin bize nc bir yol daha sunar. Bu nc
yolun ad filter() fonksiyonudur. Dikkatlice bakn:
def tek(say):
return say % 2 == 1
print(*filter(tek, l))
Dilerseniz bu kodlar daha iyi anlayabilmek iin filter() fonksiyonuna biraz daha yakndan
bakalm...
filter() fonksiyonu toplam iki parametre alr. Bu parametrelerden ilki lt belirleyen
fonksiyon, ikincisi ise bu ltn uygulanaca edir. Yukardaki rnee baktmzda, tek()
adl fonksiyonun, l adl e zerine uygulandn gryoruz.
Yukardaki rnekte ilk olarak tek() adl bir fonksiyon tanmladk:
def tek(say):
return say % 2 == 1
Bu fonksiyonun grevi, kendisine parametre olarak verilen bir saynn tek say olup olmadn
sorgulamak. Eer verilen parametre bir tek say ise fonksiyonumuz True deerini, tek say
deilse False deerini dndrecektir. sterseniz fonksiyonumuzu test edelim:
print(tek(12))
12 says bir tek say olmad iin fonksiyonumuz bize False kts verir.
Bir de una bakalm:
print(tek(117))
117 says ise bir tek saydr. Bu nedenle fonksiyonumuz bize True deerini verecektir.
te biz bu fonksiyonu, filter() fonksiyonu yardmyla u liste zerine uygulayacaz:
l = [400, 176, 64, 175, 355, 13, 207, 298, 397, 386, 31,
120, 120, 236, 241, 123, 249, 364, 292, 153]
Dediimiz gibi, filter() fonksiyonu, dizi zellii tayan nesneler zerinde belli bir lte
gre ltreleme ilemi yapmamz salar. Biz de biraz nce tanmladmz tek() adl
fonksiyonu l adl bu listeye uygulayarak liste iindeki tek saylar ltreleyeceiz.
filter() fonksiyonunu altralm:
>>> filter(tek, l)
Burada filter() fonksiyonuna ilk parametre olarak tek() fonksiyonunu verdik. kinci
parametremiz ise bu fonksiyonu uygulayacamz l adl liste. Amacmz, l adl liste zerine
39.37. lter()
637
tek() fonksiyonunu uygulayarak, bu liste iindeki elerden True kts verenleri (yani tek
saylar) ayklamak.
imdi de yukardaki koddan aldmz ktya bakalm:
<filter object at 0x00F74F30>
veya:
>>> print(*filter(tek, l))
175 355 13 207 397 31 241 123 249 153
ya da:
>>> [i for i in filter(tek, l)]
[175, 355, 13, 207, 397, 31, 241, 123, 249, 153]
Grdnz gibi, gerekten de l adl liste iindeki btn tek saylar szld.
Gelin isterseniz filter() fonksiyonunu biraz daha iyi anlayabilmek iin basit bir alma
yapalm.
Elimizde bir snftaki rencilerin Matematik snavndan ald notlar ieren bir szlk var:
notlar = {'Ahmet'
'Sinan'
'Mehmet'
'Ceren'
'Selen'
'Cem'
'Can'
'Kezban'
'Hakan'
'Mahmut'
:
:
:
:
:
:
:
:
:
:
60,
50,
45,
87,
99,
98,
51,
100,
66,
80}
Buna gre mesela print(not_durumu(54)) gibi bir kod yazdmzda bu notun karlk geldii
D saysn alabiliyoruz. Peki biz bu notlar belli bir lte gre szmek, ayklamak istersek
ne yapabiliriz? rnein notu 70ten yukar olan rencileri listelemek istersek nasl bir kod
yazabiliriz?
te byle bir durumda filter() adl gml fonksiyonu kullanabiliriz:
638
notlar = {'Ahmet'
'Sinan'
'Mehmet'
'Ceren'
'Selen'
'Cem'
'Can'
'Kezban'
'Hakan'
'Mahmut'
:
:
:
:
:
:
:
:
:
:
60,
50,
45,
87,
99,
98,
51,
100,
66,
80}
def sz(n):
return n >= 70
print(*filter(sz, [Link]()))
Grdnz gibi, filter() fonksiyonu, sz() adl fonksiyon ile belirlediimiz lt notlar
adl szln deerleri zerine tek tek uygulamamz salyor.
39.38 hash()
Bu fonksiyon, belirli trdeki nesnelere bir karma deeri vermemizi salar. rnein:
>>> hash('istihza')
-840510580
>>> hash('python')
212829695
Ancak bu fonksiyonun rettii kt ayn nesne iin btn sistemlerde ayn olmayabilir.
Yani rnein yukardaki hash(istihza) komutu 32 bitlik ve 64 bitlik iletim sistemlerinde
birbirinden farkl sonular verebilir. Ayrca bu fonksiyonun rettii karma deerlerinin
birbiriyle akma ihtimali de yksektir. Dolaysyla bu fonksiyonu kullanarak, mesela parola
girileri iin karma deeri retmek doru olmaz.
39.39 isinstance()
Hatrlarsanz daha ilk derslerimizde rendiimiz type() adl bir fonksiyon vard.
fonksiyonu bir nesnenin hangi veri tipinde olduunu tespit etmek iin kullanyorduk:
Bu
>>> type('istihza')
<class 'str'>
te buna benzer ekilde, tip denetimi iin kullanabileceimiz bir fonksiyon daha var. Bu
fonksiyonun ad isinstance().
Bu fonksiyonu yle kullanyoruz:
39.38. hash()
639
Grdnz gibi istihza gerekten bir karakter dizisi (str) olduu iin komutumuz True
kts veriyor.
Bir de una bakalm:
>>> isinstance('istihza', list)
False
istihza bir liste (list) olmad iin komutumuz bu kez False kts verdi.
39.40 len()
Bu fonksiyon yardmyla nesnelerin uzunluklarn hesaplayabileceimizi biliyorsunuz:
>>> len('istihza')
7
>>> l = [1, 4, 5, 3, 2, 9, 10]
>>> len(l)
7
39.41 map()
Diyelim ki elimizde yle bir liste var:
>>> l = [1, 4, 5, 4, 2, 9, 10]
>>> for i in l:
...
i ** 2
...
1
16
25
16
4
81
100
Bylece, istediimiz gibi, btn elerin karesini bulmu olduk. Bu tr bir ilemi yapmann
bir baka yolu da map() adl bir gml fonksiyondan yararlanmaktr. Dikkatlice bakn:
>>> def karesi(n):
...
return n ** 2
...
640
Burada bir n saysnn karesini hesaplayan bir fonksiyon tanmladk. imdi bu fonksiyonu l
listesinin btn eleri zerine uygulayacaz:
>>> list(map(karesi, l))
[1, 16, 25, 16, 4, 81, 100]
39.42 max()
max() gml fonksiyonunun grevi, bir dizi iindeki en byk eyi vermektir. Bu fonksiyon
birka farkl parametre alr ve verdii kt, ald parametrelerin trne ve saysna bal
olarak deiiklik gsterebilir.
Bu fonksiyonu en basit u ekilde kullanabilirsiniz:
>>> max(1, 2, 3)
3
max() fonksiyonu yukarda gsterildii gibi birtakm isimsiz parametrelerle birlikte key adl
isimli bir parametre de alr. Bu parametre yardmyla max() fonksiyonunun en byk
kavramn hangi lte gre seeceini belirleyebiliriz. rnein:
>>> isimler = ['ahmet', 'can', 'mehmet', 'selin', 'abdullah', 'kezban']
>>> max(isimler, key=len)
'abdullah'
Amacmz bu liste iindeki isimler arasndan, en fazla harf ierenini bulmak. Bildiiniz gibi
Pythonda bir karakter dizisinin uzunluunu belirlemek iin len() adl bir fonksiyondan
yararlanyoruz. te aadaki kod yardmyla da max() fonksiyonunun en byk ltn
len() fonksiyonu zerinden deerlendirmesini salyoruz:
>>> max(isimler, key=len)
Bu arada key fonksiyonuna len() fonksiyonunu parantezsiz olarak verdiimize dikkat edin.
39.42. max()
641
Gelin isterseniz max() fonksiyonunu biraz daha iyi anlamak iin ufak bir alma yapalm.
Diyelim ki elimizde yle bir szlk var:
askerler = {'ahmet'
'mehmet'
'ali'
'cevat'
'berkay'
'mahmut'
:
:
:
:
:
:
'onba',
'temen',
'yzba',
'albay',
'stemen',
'binba'}
Bildiiniz gibi, max() fonksiyonu lt olarak saysal bykl gz nne alyor. Elbette
askeri rtbeleri byle bir lte gre sralamak pek mmkn deil. Ama eer yle bir
fonksiyon yazarsak iler deiir:
def en_yksek_rtbe(rtbe):
rtbeler = {'er'
'onba'
'avu'
'astemen'
'temen'
'stemen'
'yzba'
'binba'
'yarbay'
'albay'
:
:
:
:
:
:
:
:
:
:
0,
1,
2,
3,
4,
5,
6,
7,
8,
9}
return rtbeler[rtbe]
Burada, rtbelerin her birine bir say verdik. En kk rtbe en dk sayya, en yksek
rtbe ise en byk sayya sahip. Fonksiyonumuz bir adet parametre alyor. Bu parametrenin
ad rtbe. Yazdmz fonksiyon, kendisine parametre olarak verilecek rtbeyi rtbeler adl
szlkte arayp, bu rtbeye karlk gelen sayy dndrecek.
Bu bilgileri kullanarak kodlarmzn son halini dzenleyelim:
def en_yksek_rtbe(rtbe):
rtbeler = {'er'
'onba'
'avu'
'astemen'
'temen'
'stemen'
'yzba'
'binba'
'yarbay'
'albay'
:
:
:
:
:
:
:
:
:
:
0,
1,
2,
3,
4,
5,
6,
7,
8,
9}
return rtbeler[rtbe]
askerler = {'ahmet': 'onba',
'mehmet': 'temen',
'ali': 'yzba',
'cevat': 'albay',
'berkay': 'stemen',
'mahmut': 'binba'}
642
39.43 min()
min() fonksiyonu max() fonksiyonunun tam tersini yapar. Bildiiniz gibi max() fonksiyonu bir
dizi iindeki en byk eyi buluyordu. te min() fonksiyonu da bir dizi iindeki en kk
eyi bulur. Bu fonksiyonun kullanm max() ile ayndr.
39.44 open()
Bu fonksiyon herhangi bir dosyay amak veya oluturmak iin kullanlr. Eer dosyann
almas veya oluturulmas esnasnda bir hata ortaya karsa IOError trnde bir hata mesaj
verilir.
Bu fonksiyonun forml udur:
>>> open(dosya_adi, mode='r', buffering=-1, encoding=None,
...
errors=None, newline=None, closefd=True, opener=None)
Grdnz gibi, bu fonksiyon pek ok farkl parametre alabiliyor. Biz imdiye kadar bu
parametrelerin yalnzca en sk kullanlanlarn ilemitik. imdi ise geri kalan parametrelerin
ne ie yaradn da ele alacaz.
Yukardaki formlden de grebileceiniz gibi, open() fonksiyonunun ilk parametresi
dosya_adi dr. Yani amak veya oluturmak istediimiz dosya adn bu parametre ile
belirtiyoruz:
>>> open('falanca_dosya.txt')
Elbette eer amak istediiniz dosya, o anda iinde bulunduunuz dizinde deilse dosya ad
olarak, o dosyann tam adresini yazmanz gerekir. Mesela:
39.43. min()
643
>>> open('/home/istihza/Desktop/[Link]')
Bu arada, dosya adresini yazarken ters taksim yerine dz taksim iaretlerini kullanmak daha
doru olacaktr. Bu taksim tr hem Windowsta hem de GNU/Linuxta alr. Ancak eer
ters taksim iaretlerini kullanacaksanz, dosya yolu iindeki sinsi ka dizilerine kar dikkatli
olmalsnz:
>>> f = open('test\[Link]')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'test\[Link]'
Burada problemin [Link] adl dosyann ilk har ile, bundan nce gelen ters taksim
iaretinin birleerek tesadfen bir ka dizisi oluturmas olduunu biliyorsunuz. Bu tr
hatalara kar ters taksim yerine dz taksim iaretlerini kullanabileceiniz gibi r adl ka
dizisinden de yararlanabilirsiniz:
f = open(r'test\[Link]')
Anlam
Okuma kipidir. ntanml deer budur.
Yazma kipidir. Eer belirtilen adda dosya zaten varsa o dosya silinir.
Yeni bir dosya oluturulup yazma kipinde alr.
Dosya ekleme kipinde alr. Bu kip ile, varolan bir dosyann sonuna
eklemeler yaplabilir.
Dosyalar ikili kipte amak iin kullanlr.
Dosyalar metin kipinde amak iin kullanlr. ntanml deerdir.
Ayn dosya zerinde hem okuma hem de yazma ilemleri yaplmasn
salar.
644
14
>>> [Link]('ikinci satr\n')
13
>>> [Link]('aaa')
3
>>> [Link]('\n')
1
Burada her write() komutundan sonra [Link] adl dosyay ap bakarsanz, u durumu
grrsnz:
[Link](birinci satr\n) komutuyla dosyaya bir satrlk veri ekledik ve bu veri
dosyaya annda ilendi.
[Link](ikinci satr\n) komutuyla dosyaya bir satrlk baka bir veri daha ekledik
ve bu veri de dosyaya annda ilendi.
[Link](aaa) komutuyla eklenen veri satr deil. nk satr sonuna iaret eden satr
ba ka dizisini kullanmadk.
[Link](\n) komutuyla satr ba ka dizisini eklediimiz anda bir nceki karakter
dizisi (aaa) de dosyaya eklenecektir.
Ancak buffering parametresi bu 1 deerini yalnzca metin kipinde alabilir. Bu kstlamay da
aklmzn bir kenarna not edelim...
0 ve 1 dnda buffering parametresine 1den byk bir deer verdiinizde ise tampon
boyutunun ne kadar olacan kendiniz belirlemi olursunuz.
Yalnz ou durumda buffering parametresine herhangi bir zel deer atamanz
gerekmeyecektir. Bu parametreye herhangi bir deer atamadnzda, kullandnz iletim
sistemi tampona alma ilemlerininin nasl yrtleceine ve tampon boyutuna kendisi
karar verecektir. letim sisteminin sizin yerinize verdii bu karar da ounlukla istediiniz
ey olacaktr... Eer kendi sisteminizde ntanml tampon boyutunun ne olduunu merak
ediyorsanz u komutlar kullanabilirsiniz:
>>> import io
>>> io.DEFAULT_BUFFER_SIZE
39.44. open()
645
Bir dosyay aarken veya okurken herhangi bir karakter kodlama hatas ile karlatnzda
Pythonn ne tepki vermesi gerektiini ise errors adl parametre yardmyla belirleyebilirsiniz.
Eer bu parametreye strict deerini verirseniz karakter kodlama hatalar programnzn
ValueError trnde bir hata vererek almay kesmesine neden olacaktr. Bu parametreye
herhangi bir deer vermediinizde de Python sanki strict deerini vermisiniz gibi davranr.
Eer errors parametresine ignore deerini verirseniz kodlama hatalar grmezden gelinecek,
bu hataya sebep olan karakter silinecektir. Yalnz bu deerin veri kaybna yol ama ihtimalini
de gz nnde bulundurmalsnz.
Eer errors parametresine replace deerini verirseniz kodlama hatasna yol aan karater ?
veya ufffd karakterleri ile deitirilecektir.
open() fonksiyonunun kabul ettii bir baka parametre de newline adl parametredir. Peki
bu parametre ne ie yarar?
Windows ve GNU/Linux iletim sistemleri satr sonlarn birbirlerinden farkl ekilde gsterir.
GNU/Linuxta yazlm dosyalarda satr sonlar \n karakteri ile gsterilirken, Windowsta
yazlm dosyalarda satr sonunda \r\n karakterleri bulunur. Eer Windows ve GNU/Linux
sistemleri arasnda dosya alverii yapyorsanz kimi durumlarda bu farkllk eitli sorunlarn
ortaya kmasna yol aabilir. te dosyalarnzn hangi satr sonu karakterine sahip olacan
yukarda bahsettiimiz newline adl parametre ile belirleyebilirsiniz. rnein:
>>> f = open('dosya', newline='\n')
Bu ekilde dosyanz hangi iletim sisteminde olursa olsun satr sonlarnda \n karakterine
sahip olacaktr.
Dosyalarn metotlarn incelerseniz o listede fileno() adl bir metodun olduunu
greceksiniz. Bu metot, bize bir dosyann dosya tanmlaycsn (le descriptor ) verir. Dosya
tanmlayclar, dosyaya iaret eden pozitif tam saylardr. 0, 1 ve 2 saylar standart girdi,
standart kt ve standart hata dosyalarna ayrlm olduu iin, sizin atnz ve zerinde
ilem yaptnz dosyalarn tanmlayclar 2 saysndan byk olacaktr.
Bir rnek verelim:
>>> f = open('[Link]')
>>> [Link]()
3
te burada grdnz say, [Link] adl dosyann dosya tanmlaycsdr. Her dosyann dosya
tanmlaycs benzersizdir:
>>> g = open('[Link]')
>>> [Link]()
4
Pythonda bir dosyay open() fonksiyonuyla aarken dosya adn vermenin yansra, dosyann
tanmlaycsn da kullanabilirsiniz:
>>> z = open(4)
veya:
646
>>> z = open([Link]())
Bu sayede, eer isterseniz, elinizdeki dosyalarla daha ileri dzeyli ilemler yapabilirsiniz. Bir
rnek verelim.
Dediimiz gibi, bir dosyann tanmlaycs tek ve benzersizdir.
tanmlayclara sahip olmaz:
>>> a = open('[Link]')
>>> [Link]()
3
>>> b = open('[Link]')
>>> [Link]()
4
Bu ekilde b adl dosyann tanmlaycsn kullanarak, ayn dosyay bir de c adyla atk.
Ancak burada kullandmz closefd=False parametresine dikkat edin. Normalde dosyay
kapattmzda dosyann tanmlaycs serbest kalr ve baka bir dosya aldnda bu
tanmlayc yeni dosyaya atanr. Ama closefd parametresine False deeri verdiimizde dosya
kapansa bile, o dosyaya ait dosya tanmlaycs varolmaya devam edecektir.
39.45 pow()
Daha nceki derslerimizde pek ok kez rneklerini verdiimiz bu fonksiyon ngilizcedeki
power (kuvvet) kelimesinin ksaltmasndan oluur. Adnn anlamna uygun olarak, bu
fonksiyonu bir saynn kuvvetlerini hesaplamak iin kullanyoruz.
Bu fonksiyon en temel ekilde yle kullanlr:
>>> pow(2, 3)
8
39.45. pow()
647
>>> (2 ** 3) % 2
0
Ancak nceki derslerimizde de sylediimiz gibi, pow() fonksiyonu ounlukla yanlzca ilk iki
parametresi ile birlikte kullanlr:
>>> pow(12, 2)
144
39.46 print()
print() fonksiyonunu artk gayet iyi tanyoruz. Bu fonksiyonu, bildiiniz gibi, kullanclarmza
birtakm mesajlar gstermek iin kullanyoruz.
Kullanmn daha nce ayrntl bir ekilde anlatm olduumuz bu fonksiyonu u ekilde
formle edebiliriz:
print(deg1, deg2, deg3, ..., sep=' ', end='\n', file=[Link], flush=False)
Burada;
degx kt verilecek deerlerin ne olduunu belirtir. Buraya 256 adete
kadar deer yazabilirsiniz.
sep kt verilirken deerlerin arasna hangi karakterin yerletirileceini
belirtir. Bu deer ntanml olarak boluk karakteridir.
end kt verilecek son deerin ardndan hangi karakterin ilitirileceini
belirtir. Bu deer ntanml olarak satr ba (\n ) karakteridir.
le ktlarn hangi dosyaya yazlacan belirtir. ntanml olarak
bu parametrenin deeri [Link] tur. Yani print() fonksiyonu
ktlarn ntanml olarak standart kt konumuna gnderir.
ush Bildiiniz gibi, herhangi bir dosyaya yazma ilemi srasnda
dosyaya yazlacak deerler ncelikle tampona alnr.
lem
tamamlandktan sonra tampondaki bu deerler topluca dosyaya
aktarlr. te bu parametre, deerleri tampona almadan dorudan
dosyaya gnderebilmemizi salar. Bu parametrenin ntanml
deeri False tur. Yani deerler dosyaya yazlmadan nce ntanml
olarak ncelikle tampona gider. Ama eer biz bu parametrenin
deerini True olarak deitirirsek, deerler dorudan dosyaya
yazlr.
39.47 quit()
Bu fonksiyonu programdan kmak iin kullanyoruz. Eer bu fonksiyonu etkileimli kabukta
verecek olursanz etkileimli kabuk kapanacaktr.
648
39.48 range()
Bu fonksiyonu belli bir aralktaki saylar listelemek iin kullanyoruz. Yani mesela 0 ile 10
aras saylarn listesini almak istersek yle bir komut yazabiliriz:
>>> l = range(0, 10)
Ancak burada dikkat etmemiz gereken bir zellik var: Bu fonksiyon aslnda dorudan
herhangi bir say listesi oluturmaz. Yukarda l deikenine atadmz komutu ekrana
yazdrrsak bunu daha net grebilirsiniz:
>>> print(l)
range(0, 10)
Grdnz gibi, elimizdeki ey aslnda bir say listesi deil, bir range (aralk) nesnesidir.
Biz bu nesneyi istersek baka veri tiplerine dntrebiliriz. Mesela bunu bir listeye
dntrelim:
>>> list(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
39.48. range()
649
3
4
5
6
7
8
9
Burada 0 balang deeri, 10 ise biti deeridir. Buna gre oluturulacak saylar 0 ile 10
arasnda olacaktr. Yalnz burada retilecek say listesinde 0 saysnn dahil, 10 saysnn
ise hari olduunu unutmuyoruz. Yani bu komutun bize verecei ilk say 0 ; son say ise 9
olacaktr.
range() fonksiyonunda balang deerinin ntanml deeri 0 dr. Dolaysyla istersek biz
yukardaki komutu yle de yazabiliriz:
>>> range(10)
Bylece Python bizim range(0, 10) komutunu kastettiimizi varsayacaktr. Elbette eer
balang deerinin 0 dnda bir deer olmasn istiyorsanz bunu zellikle belirtmeniz
gerekir:
>>> range(10, 100)
Bu komut bize 10 ile (10 dahil) 100 aras (100 hari) saylar ieren bir range nesnesi
verecektir.
Yukarda verdiimiz formlden de greceiniz gibi, balang_deer ve biti_deer dnda
range() fonksiyonu nc bir parametre daha alabiliyor. Bu parametreye atlama_deeri
ad verdik. Bu parametreyi yle kullanyoruz:
>>> list(range(0, 10, 2))
[0, 2, 4, 6, 8]
650
39.49 reversed()
Diyelim ki elimizde yle bir liste var:
>>> isimler = ['ahmet', 'mehmet', 'veli', 'aye', 'idem', 'k']
Eer bu listedeki isimleri ters evirmek, yani yle bir liste elde etmek isterseniz:
['k', 'idem', 'aye', 'veli', 'mehmet', 'ahmet']
>>> isimler[::-1]
['k', 'idem', 'aye', 'veli', 'mehmet', 'ahmet']
Grdnz gibi, tpk range() fonksiyonunda olduu gibi, reversed() fonksiyonu da bize
rettii elerin kendisi yerine, bir nesne veriyor. Ama tabii ki bu bizim iin bir sorun deil.
Biz bu nesnenin ieriini nasl elde edebileceimizi gayet iyi biliyoruz:
>>> list(reversed(isimler))
['k', 'idem', 'aye', 'veli', 'mehmet', 'ahmet']
range() fonksiyonunu anlatrken szn ettiimiz ierik elde etme yntemlerini reversed()
fonksiyonuna da uygulayabilirsiniz.
39.50 sorted()
Bu metot, daha nceki derslerimizden de bildiiniz gibi, bir dizi iindeki eleri belirli bir
lte gre sraya dizmemizi salyor. Bununla ilgili ok basit bir rnek verelim:
>>> sorted('ahmet')
['a', 'e', 'h', 'm', 't']
Bu kodlar yardmyla ahmet adl karakter dizisi iindeki hareri alfabe srasna dizdik.
Elbette bu fonksiyonu sadece karakter dizileri zerine uygulamyoruz. sorted() adl
fonksiyon, dizi zellii tayan her trl nesne zerine uygulanabilir. Mesela demetlerin ve
listelerin bir dizi olduunu biliyoruz. Dolaysyla:
>>> sorted(('elma', 'armut', 'kiraz', 'badem'))
['armut', 'badem', 'elma', 'kiraz']
>>> sorted(['elma', 'armut', 'kiraz', 'badem'])
['armut', 'badem', 'elma', 'kiraz']
39.49. reversed()
651
sorted() fonksiyonuna hangi trde bir veri tipi verirseniz verin, aldnz kt her zaman bir
liste olacaktr. Bunu unutmayn.
Grdnz gibi, sorted() fonksiyonu nesneler zerinde bir sralama ilemi gerekletiriyor.
Ancak bu fonksiyonun bir problemi var.
Dikkatlice bakn:
>>> isimler = ['ahmet', 'idem', 'k', 'ebnem', 'zeynep', 'selin']
>>> sorted(isimler)
['ahmet', 'selin', 'zeynep', 'idem', 'k', 'ebnem']
Henz modlleri renmemi de olsak, bir modl kullanabilmek iin ncelikle o modl
ie aktarmamz gerektiini artk biliyorsunuz. Bu ilemi import adl bir komut yardmyla
yaptmz da biliyorsunuz.
imdi de yerelimizi (locale ) Trke olarak ayarlayalm:
>>> [Link](locale.LC_ALL, 'tr_TR') #GNU/Linux
>>> [Link](locale.LC_ALL, 'Turkish_Turkey.1254') #Windows
Bu ilemleri yaptktan sonra, sorted() fonksiyonunun key adl bir parametresini kullanarak
ve yine locale modlnn strxfrm() adl fonksiyonundan faydalanarak Trke karakterler
ieren listemizi sralamay deneyebiliriz:
>>> sorted(isimler, key=[Link])
['ahmet', 'idem', 'k', 'selin', 'ebnem', 'zeynep']
locale modl iinde bulunan strxfrm() adl fonksiyon, karakter dizilerinin, o anda etkin
yerel neyse, ona gre muamele grmesini salar. Biz yukarda yerelimizi Trke olarak
ayarladmz iin strxfrm() fonksiyonu, sorted() ile yaplan alfabe srasna dizme ileminin
Trkenin kurallarna gre yaplmasn salyor.
Ancak bu yntemin de sorunlu olduunu bir sre sonra kendiniz de farkedeceksiniz. Mesela
u rnei inceleyin:
>>> sorted('afgdhki', key=[Link])
['a', 'd', 'f', 'g', 'h', 'i', '', 'k']
Grdnz gibi, listede i har harnden nce geliyor. Ama aslnda bunun tersi olmalyd.
te byle bir durumda, kendi sralama mekanizmamz kendimiz icat etmeliyiz. Peki ama
nasl?
Bilgisayarlar farkl dillerdeki karakterleri her zaman doru sralayamasa da, saylar her zaman
doru sralar:
652
Burada Trk alfabesini oluturan hareri srasna gre dizdik. imdi bu harerin her birine
bir say vereceiz:
>>> evrim = {'a': 0, 'b': 1, 'c': 2, '': 3,
...
'e': 5, 'f': 6, 'g': 7, '': 8,
...
'': 10, 'i': 11, 'j': 12, 'k':
...
'l': 14, 'm': 15, 'n': 16, 'o':
...
'': 18, 'p': 19, 'r': 20, 's':
...
'': 22, 't': 23, 'u': 24, '':
...
'v': 26, 'y': 27, 'z': 28}
'd': 4,
'h': 9,
13,
17,
21,
25,
Yalnz byle her harfe karlk gelen sayy elle yazmak yorucu olacaktr. Bu ilemi daha kolay
bir ekilde yapabilmek iin farkl teknikleri kullanabilirsiniz. Mesela daha nce rendiimiz
szlk retelerinden yararlanabilirsiniz:
>>> evrim = {i: [Link](i) for i in harfler}
Bu ekilde harer deikeni iindeki herbir harn bir anahtar; bu harerin harer deikeni
iindeki srasn gsteren herbir saynn ise bir deer olduu bir szlk oluturmu olduk.
imdi isim listemizi alalm karmza:
isimler = ["ahmet", "k", "ismail",
"idem", "can", "ule"]
Ama biraz nce oluturduumuz evrim anahtarn kullanrsak durum bambaka olacaktr:
>>> sorted(isimler, key=lambda x: [Link](x[0]))
['ahmet', 'can', 'idem', 'k', 'ismail', 'ule']
Ancak aslnda burada da olduka sinsi bir problem var. Bu metot ile kelime listesini oluturan
kelimeleri yalnzca ilk harerine gre sralyoruz (x[0]). Peki ya ayn liste iinde ilk hareri
39.50. sorted()
653
ayn olup, sonraki harerde farkllaan kelimeler varsa ne olacak? Yani mesela bu metot
acaba ismail ve iskender kelimelerini doru bir ekilde sralayabilir mi? Bakalm:
harfler = "abcdefghijklmnoprstuvyz"
evrim = {i: [Link](i) for i in harfler}
isimler = ["ahmet", "k", "ismail", "idem",
"can", "ule", "iskender"]
print(sorted(isimler, key=lambda x: [Link](x[0])))
Grdnz gibi ismail ve iskender kelimeleri doru bir ekilde sralanmad; iskender
kelimesinin ismail kelimesinden nce gelmesi gerekiyordu...
Demek ki imdiye kadar kullandmz btn sralama yntemlerinin bir eksii varm. O
halde baka bir metot bulmaya alalm.
Dikkatlice bakn:
harfler = 'abcdefghijklmnoprstuvyz'
evrim = {i: [Link](i) for i in harfler}
def srala(kelime):
return ([[Link](kelime[i]) for i in range(len(kelime))])
isimler = ['ahmet', 'can', 'iskender', 'cigdem',
'ismet', 'ismail', 'ismit', 'idem',
'ismt', 'k', 'ule']
print(*sorted(isimler, key=srala), sep='\n')
Bu kod yardmyla kelime iinde geen herbir har evrim adl szlkte sorgulayarak, szlkte
ilgili harfe karlk gelen sayy buluyoruz.
654
Aslnda bu kodlar daha iyi anlayabilmek iin Pythondaki sorted() fonksiyonunun mantn
biraz daha derinlemesine incelememiz gerekiyor. Gelin imdi bu inceleme iini yapalm:
Diyelim ki elimizde yle bir liste var:
elemanlar = [('ahmet',
('mehmet',
('sevda',
('arzu',
('abdullah',
('ilknur',
('abdurrezzak',
33,
45,
24,
40,
30,
40,
40,
'karata'),
'arpabahi'),
'arsuz'),
'siverek'),
'payas'),
'kilis'),
'bolvadin')]
Bu liste, her biri isim, ya ve memleket bilgilerini ieren eli birer demetten oluuyor.
Eer biz bu liste zerine sorted() fonksiyonunu uygularsak:
print(*sorted(elemanlar), sep='\n')
Python elemanlar demetlerin ilk esine gre sralayacaktr. Yani isme gre.
Peki ya biz bu elemanlar yaa gre sralamak istersek ne yapacaz?
Bu amac gerekletirmek iin yle bir kod yazabiliriz:
def srala(liste):
return liste[1]
elemanlar = [('ahmet',
('mehmet',
('sevda',
('arzu',
('abdullah',
('ilknur',
('abdurrezzak',
33,
45,
24,
40,
30,
40,
40,
'karata'),
'arpabahi'),
'arsuz'),
'siverek'),
'payas'),
'kilis'),
'bolvadin')]
Grdnz gibi, elemanlar listesinin ikinci stununda deeri ayn olan eler var. Mesela
arzu, ilknur ve abdurrezzak 40 yanda. Python bu eleri sralarken, bunlarn listede
39.50. sorted()
655
getii sray dikkate alacaktr. Ama bazen biz sralamann byle olmasn istemeyebiliriz.
Mesela bizim istediimiz ey, deeri ayn olan eler iin nc stunun (veya birinci
stunun) dikkate alnmas olabilir. te bunun iin de srala() fonksiyonunu u ekilde
tanmlayabiliriz:
def srala(liste):
return (liste[1], liste[2])
Grdnz gibi burada srala() fonksiyonu bize iki eli bir demet dndryor.
Kodlarmz tam olarak yle grnecek:
def srala(liste):
return (liste[1], liste[2])
elemanlar = [('ahmet',
('mehmet',
('sevda',
('arzu',
('abdullah',
('ilknur',
('abdurrezzak',
33,
45,
24,
40,
30,
40,
40,
'karata'),
'arpabahi'),
'arsuz'),
'siverek'),
'payas'),
'kilis'),
'bolvadin')]
Kodlarmz byle yazdmzda Python listeyi ilk olarak ikinci stundaki ya deerlerine gre
sralar. Deeri ayn olan elerle karlatnda ise nc stundaki memleket deerlerine
bakar ve sralamay ona gre yapar.
Btn bu aklamalardan sonra yukardaki u kodlar daha iyi anlyor olmalsnz:
harfler = 'abcdefghijklmnoprstuvyz'
evrim = {i: [Link](i) for i in harfler}
def srala(kelime):
return ([[Link](kelime[i]) for i in range(len(kelime))])
isimler = ['ahmet', 'can', 'iskender', 'cigdem',
'ismet', 'ismail', 'ismit', 'idem',
'ismt', 'k', 'ule']
print(*sorted(isimler, key=srala), sep='\n')
Biz yine de her eyin iyiden iyine anlaldndan emin olmak iin durumu ksaca aklayalm.
ncelikle ilgili fonksiyonu nmze alalm:
def srala(kelime):
return ([[Link](kelime[i]) for i in range(len(kelime))])
Burada yaptmz ey biraz nce yaptmz eyle tamamen ayn aslnda. Tek fark, Pythonn
sralamada kullanmasn istediimiz eleri tek tek elle yazmak yerine, bunlar bir liste reteci
yardmyla otomatik olarak belirlemek.
Eer yukardaki kodlar yle yazsaydk:
def srala(kelime):
return ([Link](kelime[0]))
656
Bu durumda Python sralamada kelimelerin yalnzca ilk harerini dikkate alacakt. lk har
ayn olan kelimeleri ise bu yzden dzgn sralayamayacakt. Elbette Pythonn nce ilk harfe,
sonra ikinci harfe, sonra da nc harfe bakmasn salayabiliriz:
def srala(kelime):
return ([Link](kelime[0]), [Link](kelime[1]), [Link](kelime[2]))
Ancak bu yntemin uygulanabilir ve pratik olmad ortada. Kendi kendinize baz denemeler
yaparak bunu kendiniz de rahatlkla grebilirsiniz.
Pythonn, sralama yaparken kelimelerin nce ilk harerini, sonra ikinci, sonra nc, vb.
harerini karlatrmasn salamann en uygun yolu u olacaktr:
def srala(kelime):
return ([[Link](kelime[i]) for i in range(len(kelime))])
Grdnz gibi, burada kelimelerdeki harerin srasn tek tek elle yazmak yerine, bunu
bir for dngs iinde otomatik olarak yaptryoruz. Dolaysyla srala() fonksiyonuna
verilen parametrenin mesela ahmet olduu bir durumda yukardaki fonksiyon u demeti
dndryor:
def srala('ahmet'):
return ([Link]('ahmet'[0]),
[Link]('ahmet'[1]),
[Link]('ahmet'[2]),
[Link]('ahmet'[3]),
[Link]('ahmet'[4]))
Bylece Python, hangi uzunlukta bir isimle karlarsa karlasn, sralama ilemini dzgn
bir ekilde gerekletirebiliyor.
Bu blmde Pythonda sralama konusunu epey ayrntl bir ekilde ele aldk.
39.51 slice()
Bildiiniz gibi, birtakm elerden oluan bir nesnenin yalnzca belli ksmlarn ayrp alma
ilemine dilimleme ad veriliyor. rnein elimizde yle bir liste olduunu dnelim:
>>> l = ['ahmet', 'mehmet', 'aye', 'senem', 'salih']
5 eli bu listenin yalnzca ilk iki esini almak, yani dilimlemek iin u yapy kullanyoruz:
>>> l[0:2]
['ahmet', 'mehmet']
39.51. slice()
657
Ayn listenin, ilk eden itibaren sonuna kadar olan btn elerini almak iin ise unu
yazyoruz:
>>> l[1:]
Eer bu listeyi, elerini ikier ikier atlayarak dilimlemek istersek de u yolu takip ediyoruz:
>>> l[::2]
['ahmet', 'aye', 'salih']
Tahmin
39.52 sum()
Bu fonksiyonun temel grevi, bir dizi iindeki deerlerin toplamn bulmaktr. rnein:
>>> l = [1, 2, 3]
>>> sum(l)
6
658
Bu fonksiyon genellikle yukardaki gibi tek parametreyle kullanlr. Ama aslnda bu fonksiyon
ikinci bir parametre daha alr. Dikkatlice bakn:
>>> l = [1, 2, 3]
>>> sum(l, 10)
16
birinci
39.53 type()
type() fonksiyonunun grevi bir nesnenin hangi veri tipine ait olduunu sylemektir. Bu
fonksiyonu artk yakndan tanyorsunuz:
>>> type('elma')
<class 'str'>
39.54 zip()
Gelin isterseniz bu fonksiyonu bir rnek zerinden aklamaya alalm.
Diyelim ki elimizde yle iki farkl liste var:
>>> a1 = ['a', 'b', 'c']
>>> a2 = ['d', 'e', 'f']
Grdnz gibi, yukardaki kod bize bir zip nesnesi veriyor. Bu nesnenin elerine nasl
ulaabileceinizi biliyorsunuz:
>>> print(*zip(a1, a2))
('a', 'd') ('b', 'e') ('c', 'f')
>>> list(zip(a1, a2))
[('a', 'd'), ('b', 'e'), ('c', 'f')]
>>> for a, b in zip(a1, a2):
...
print(a, b)
...
a d
b e
c f
39.53. type()
659
Yukardaki ktlar incelediimizde, ilk listenin ilk esinin, ikinci listenin ilk esiyle; ilk
listenin ikinci esinin, ikinci listenin ikinci esiyle; ilk listenin nc esinin ise, ikinci
listenin nc esiyle eletiini gryoruz.
Bu zellikten pek ok farkl ekilde yararlanabilirsiniz. rnein:
>>> isimler = ['ahmet', 'mehmet', 'zeynep', 'ilker']
>>> yalar = [25, 40, 35, 20]
>>> for i, y in zip(isimler, yalar):
...
print('isim: {} / ya: {}'.format(i, y))
...
isim: ahmet / ya: 25
isim: mehmet / ya: 40
isim: zeynep / ya: 35
isim: ilker / ya: 20
Burada isimler ve yalar adl listelerin elerini zip() fonksiyonu yardmyla birbirleriyle
eletirdik.
39.55 vars()
Bu fonksiyon, mevcut isim alan iindeki metot, fonksiyon ve nitelikleri listeler. Eer bu
fonksiyonu parametresiz olarak kullanrsak, daha nce grdmz locals() fonksiyonuyla
ayn kty elde ederiz:
>>> vars()
{'__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__',
'__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__doc__': None}
Bu
Bu blmde
1. memoryview()
2. iter()
3. next()
4. object()
5. property()
6. staticmethod()
7. super()
8. getattr()
660
9. hasattr()
10. delattr()
11. classmethod()
12. issubclass()
13. setattr()
14. __import()
Bu fonksiyonlar, ilerleyen derslerle birlikte Python bilgimiz biraz daha arttnda ele alacaz.
39.55. vars()
661
BLM 40
Buraya gelinceye kadar fonksiyonlara ilikin epey sz syledik. Artk Python programlama
dilinde fonksiyonlara dair hemen her eyi bildiimizi rahatlkla syleyebiliriz. Zira bu noktaya
kadar hem fonksiyonlarn temel (ve orta dzey) zelliklerini rendik, hem de gml
fonksiyon kavramn ve gml fonksiyonlarn kendisini btn ayrntlaryla inceledik.
Dolaysyla yazdmz kodlarda fonksiyonlar olduka verimli bir ekilde kullanabilecek kadar
fonksiyon bilgisine sahibiz artk.
Dediimiz gibi, fonksiyonlara ilikin en temel bilgileri edindik. Ancak fonksiyonlara dair
henz bilmediimiz eyler de var. Ama artk Python programlama dilinde geldiimiz aamay
dikkate alarak ileriye doru bir adm daha atabilir, fonksiyonlara dair ileri dzey saylabilecek
konulardan da sz edebiliriz.
lk olarak lambda fonksiyonlarn ele alalm.
Peki ayn ilemi lambda fonksiyonlar yardmyla yapmak istersek nasl bir yol izleyeceiz?
Dikkatlice bakn:
>>> fonk = lambda param1, param2: param1 + param2
662
Burada sorted() fonksiyonunun key parametresi iinde kullandmz ifade bir lambda
fonksiyonudur:
lambda x: [Link](x[0])
Burada lambda fonksiyonu kullanmak yerine, srala() adl bir fonksiyon kullandk.
Eer yukarda lambda ile yazdmz rnei srala() fonksiyonu ile yazdmz rnekle
kyaslarsanz lambda fonksiyonlarnda hangi parann neye karlk geldiini veya ne anlama
sahip olduunu rahatlkla anlayabilirsiniz.
Gelin bir rnek daha verelim:
40.1. Lambda Fonksiyonlar
663
Diyelim ki bir saynn ift say olup olmadn denetleyen bir fonksiyon yazmak istiyorsunuz.
Bunun iin yle bir fonksiyon tanmlayabileceimizi biliyorsunuz:
def ift_mi(say):
return say % 2 == 0
Eer ift_mi() fonksiyonuna parametre olarak verilen bir say ift ise fonksiyonumuz True
kts verecektir:
print(ift_mi(100))
True
Baka bir rnek daha verelim. Diyelim ki bir liste iindeki btn saylarn karesini hesaplamak
istiyoruz. Elimizdeki liste u:
>>> l = [2, 5, 10, 23, 3, 6]
Bu listedeki saylarn her birinin karesini hesaplamak iin yle bir ey yazabiliriz:
>>> for i in l:
...
print(i**2)
4
25
100
529
9
36
664
Son rnekte verdiimiz lambdal kodu normal bir fonksiyon tanmlayarak yle de
yazabilirdik:
>>> def karesi(say):
...
return say ** 2
...
>>> print(*map(karesi, l))
4 25 100 529 9 36
Biz yukardaki rneklerde lambda fonksiyonunu tek bir parametre ile tanmladk. Ama elbette
lambda fonksiyonlarnn birden fazla parametre de alabileceini de biliyorsunuz.
rnein:
>>>
Burada lambda fonksiyonumuz toplam iki farkl parametre alyor: Bunlardan ilki ifade,
ikincisi ise birletirici. Fonksiyonumuzun gvdesinde ifade parametresine split() metodunu
uyguladktan sonra, elde ettiimiz paralar birletirici parametresinin deerini kullanarak
birbirleriyle birletiriyoruz. Yani:
>>> birletir('istanbul bykehir belediyesi', '-')
'istanbul-bykehir-belediyesi'
Eer ayn ilevi normal bir fonksiyon yardmyla elde etmek isteseydik yle bir ey
yazabilirdik:
>>> def birletir(ifade, birletirici):
...
return [Link]([Link]())
...
>>> birletir('istanbul bykehir belediyesi', '-')
'istanbul-bykehir-belediyesi'
665
Burada da lambda yerine isimli bir fonksiyon tanmlayp, command parametresine dorudan
bu fonksiyonu verdik.
Btn bu rneklerden grdnz gibi, lambda fonksiyonlar son derece pratik aralardr.
Normal, isimli fonksiyonlarla elde ettiimiz ilevsellii, lambda fonksiyonlar yardmyla ok
daha ksa bir ekilde elde edebiliriz. Ancak lambda fonksiyonlar normal fonksiyonlara gre
biraz daha okunaksz yaplardr. O yzden, eer lambda fonksiyonlarn kullanmaya mecbur
deilseniz, bunlarn yerine normal fonksiyonlar veya yerine gre liste retelerini tercih
edebilirsiniz.
666
def selamla(kim):
print('merhaba', kim)
Burada selamla() adl bir fonksiyon tanmladk. Grdnz gibi bu fonksiyon print() adl
baka bir fonksiyonu aryor. Burada srad bir ey yok. Dediimiz gibi, imdiye kadar
zaten hep byle fonksiyonlar grmtk.
Python fonksiyonlar, yukardaki rnekte de grdnz gibi, nasl baka fonksiyonlar
arabiliyorsa, ayn ekilde, istenirse, kendi kendilerini de arabilirler. te bu tr
fonksiyonlara Python programlama dilinde kendi kendilerini yineleyen, veya daha teknik bir
dille ifade etmek gerekirse zyinelemeli (recursive ) fonksiyonlar ad verilir.
ok basit bir rnek verelim. Diyelim ki, kendisine parametre olarak verilen bir karakter dizisi
iindeki karakterleri teker teker azaltarak ekrana basan bir fonksiyon yazmak istiyorsunuz.
Yani mesela elinizde istihza adl bir karakter dizisi var. Sizin amacnz bu karakter dizisini u
ekilde basan bir fonksiyon yazmak:
istihza
stihza
tihza
ihza
hza
za
a
Elbette bu ii yapacak bir fonksiyonu, daha nce rendiiniz dngler ve baka yaplar
yardmyla rahatlkla yazabilirsiniz.
Ama isterseniz ayn ii zyinelemeli fonksiyonlar
yardmyla da yapabilirsiniz.
imdi u kodlara dikkatlice bakn:
def azalt(s):
if len(s) < 1:
return s
else:
print(s)
return azalt(s[1:])
print(azalt('istihza'))
667
return azalt(s[1:])
Grdnz gibi, burada azalt() fonksiyonu iinde yine azalt() fonksiyonunu aryoruz.
Bylece fonksiyonumuz srekli olarak kendi kendini yineliyor. Yani ayn fonksiyonu tekrar
tekrar uyguluyor.
Peki ama bunu nasl yapyor?
Nasl bir durumla kar karya olduumuzu daha iyi anlamak iin yukardaki kodlar u ekilde
yazalm:
def azalt(s):
if len(s) < 1:
return s
else:
print(list(s))
return azalt(s[1:])
's',
't',
'i',
'h',
'z',
'a']
't',
'i',
'h',
'z',
'a']
Yukardaki ktnn ilk satrnda grdnz gibi, fonksiyon ilk arldnda listede istihza
karakter dizisini oluturan btn harer var. Yani fonksiyonumuz ilk almada parametre
olarak karakter dizisinin tamamn alyor. Ancak fonksiyonun her yineleniinde listedeki
harer birer birer dyor. Bylece zyinelemeli fonksiyonumuz parametre olarak karakter
dizisinin her defasnda bir eksiltilmi biimini alyor.
Yukardaki szn ettiimiz dmenin yn karakter dizisinin bandan sonuna doru. Yani
her defasnda, elde kalan karakter dizisinin ilk har dyor. Dme ynnn byle olmas
bizim kodlar yaz eklimizden kaynaklanyor. Eer bu kodlar yle yazsaydk:
def azalt(s):
if len(s) < 1:
return s
else:
print(list(s))
return azalt(s[:-1])
668
's',
's',
's',
's',
's',
't',
't',
't',
't',
't']
['i', 's']
['i']
harfinin
harfinin
harfinin
harfinin
harfinin
harfinin
harfinin
1.
2.
3.
4.
5.
6.
7.
almadaki
almadaki
almadaki
almadaki
almadaki
almadaki
almadaki
konumu:
konumu:
konumu:
konumu:
konumu:
konumu:
konumu:
6
5
4
3
2
1
0
Grdnz gibi istihza kelimesinin en sonunda bulunan a har her defasnda ba tarafa
doru ilerliyor.
Ayn ekilde, kodlar daha iyi anlayabilmek iin, fonksiyona parametre olarak verdiimiz
istihza kelimesinin her yinelemede ne kadar uzunlua sahip olduunu da takip edebilirsiniz:
def azalt(s):
if len(s) < 1:
return s
else:
print(len(s))
return azalt(s[:-1])
669
Daha sonra da bu yntemi zyinelemeli bir ekilde uyguladmzda, istihza karakter dizisinin
her defasnda daha kk bir paras bu yntemden etkileniyor:
azalt(s[1:])
Yani fonksiyonumuz ilk olarak istihza karakter dizisinin ilk har olan i harni dryor.
Sonra stihza kelimesinin ilk har olan s harni dryor. Ardndan tihza kelimesinin ilk
har olan t harni dryor ve kelime tkenene kadar bu ilemi devam ettiriyor.
Peki ama bunu nasl yapyor?
imdi yukardaki fonksiyondaki u ksma dikkatlice bakn:
if len(s) < 1:
return s
te if len(s) < 1:
blounun bulunduu bu kodlara dip nokta ad veriyoruz.
Fonksiyonumuzun yinelene yinelene (veya baka bir ifadeyle dibe ine ine) gelecei en son
nokta burasdr. Eer bu dip noktay belirtmezsek fonksiyonumuz, tpk dipsiz bir kuyuya
dm gibi, srekli daha derine inmeye alacak, sonunda da hata verecektir. Ne demek
istediimizi daha iyi anlamak iin kodlarmz yle yazalm:
def azalt(s):
print(s)
return azalt(s[1:])
Grdnz gibi burada herhangi bir dip nokta belirtmedik. Bu kodlar altrdmzda
Python bize yle bir hata mesaj verecek:
RuntimeError: maximum recursion depth exceeded
Yani:
almaZamanHatas: Azami zyineleme derinlii ald
670
Dediimiz gibi, zyinelemeli fonksiyonlar her yinelenite sorunun (yani zerinde ilem yaplan
parametrenin) biraz daha derinine iner. Ancak bu derine inmenin de bir snr vardr. Bu
snrn ne olduunu u kodlar yardmyla renebilirsiniz:
>>> import sys
>>> [Link]()
Burada, fonksiyon kendini yinelemeye balamadan hemen nce bir print() satr
yerletirerek s deikeninin durumunu takip ediyoruz:
print('zyineleme srecine girerken:', s)
Ayn ilemi bir de fonksiyonun kendini yinelemeye balamasnn hemen ardndan yapyoruz:
print('zyineleme srecinden karken:', s)
Grdnz gibi fonksiyon zyineleme srecine girerken drd her bir karakteri,
zyineleme srecinden karken yeniden dndryor. Bu, zyinelemeli fonksiyonlarn nemli
bir zelliidir. Mesela bu zellikten yararlanarak yle bir kod yazabilirsiniz:
def ters_evir(s):
if len(s) < 1:
return s
else:
ters_evir(s[1:])
671
print(s[0])
ters_evir('istihza')
lk bakta bu satrn nasl altn anlamak zor gelebilir. Ama aslnda son derece basit bir
mant var bu kodlarn. yle dnn: ters_evir() fonksiyonunu zyinelemeli olarak
ilettiimizde, yani u kodu yazdmzda:
return ters_evir(s[1:])
...dndrlecek son deer bo bir karakter dizisidir. te biz zyinelemeden klrken geri
dnen karakterlerin ilk harerini bu bo karakter dizisine ekliyoruz ve bylece girdiimiz
karakter dizisinin ters halini elde etmi oluyoruz.
672
Burada ayn i iin farkl bir yaklam benimsedik. lk olarak, dip noktasn u ekilde belirledik:
if not s:
return s
Bildiiniz gibi, bo veri tiplerinin bool deeri Falsetur. Dolaysyla zyineleme srasnda s
parametresinin uzunluunun 1in altna dmesi, s parametresinin iinin boaldn gsterir.
Yani o anda s parametresinin bool deeri False olur. Biz de yukarda bu durumdan
faydalandk.
Bir nceki kodlara gre bir baka farkllk da u satrda:
return s[-1] + ters_evir(s[:-1])
Burada benimsediimiz yaklamn z u: Bildiiniz gibi bir karakter dizisini ters evirmek
istediimizde ncelikle bu karakter dizisinin en son karakterini alp en baa yerletiririz. Yani
mesela elimizdeki karakter dizisi istihza ise, bu karakter dizisini ters evirmenin ilk adm
bunun en son karakteri olan a harni alp en baa koymaktr. Daha sonra da geri kalan
hareri tek tek tersten buna ekleriz:
dz: istihza
ters: a + z + h + i + t + s + i
zyinelemeli fonksiyonlara ilikin olarak yukarda tek bir rnek zerinde epey aklama
yaptk. Bu rnek ve aklamalar, zyinelemeli fonksiyonlarn nasl alt konusunda size
epey kir vermi olmal. Ancak elbette bu fonksiyonlar tek bir rnek yardmyla tamamen
anlayamam olabilirsiniz. O yzden gelin isterseniz bir rnek daha verelim. Mesela bu kez
de basit bir saya yapalm:
def saya(say, snr):
print(say)
if say == snr:
return 'bitti!'
else:
return saya(say+1, snr)
Not:
Bu fonksiyonun yapt ii elbette baka ekillerde ok daha kolay bir ekilde
halledebilirdik. Bu rnei burada vermemizin amac yalnzca zyinelemeli fonksiyonlarn
40.2. zyinelemeli (Recursive ) Fonksiyonlar
673
Bu bizim dip nokta adn verdiimiz ey. Fonksiyonumuz yalnzca bu noktaya kadar
yineleyecek, bu noktann ilerisine gemeyecektir. Yani say parametresinin deeri snr
parametresinin deerine ulatnda zyineleme ilemi de sona erecek. Eer byle bir
dip nokta belirtmezsek fonksiyonumuz sonsuza kadar kendini yinelemeye alacak, daha
nce szn ettiimiz zyineleme limiti nedeniyle de belli bir aamadan sonra hata verip
kecektir.
Sonraki satrlarda ise u kodlar gryoruz:
else:
return saya(say+1, snr)
Bu satrlar, bir nceki aamada belirttiimiz dip noktaya ulalana kadar fonksiyonumuzun
hangi ilemleri yapacan gsteriyor. Buna gre, fonksiyonun her yineleniinde say
parametresinin deerini 1 say artryoruz.
Fonksiyonumuzu saya(0, 100) gibi bir komutla altrdmz dnrsek, fonksiyonun
ilk almasnda 0 olan say deeri sonraki yinelemede 1, sonraki yinelemede 2, sonraki
yinelemede ise 3 olacak ve bu durum snr deer olan 100 e varlana kadar devam edecektir.
say parametresinin deeri 100 olduunda ise dip nokta olarak verdiimiz lt devreye
girecek ve fonksiyonun kendi kendisini yinelemesi ilemine son verilecektir.
Biz yukardaki rnekte yukarya doru sayan bir fonksiyon yazdk. Eer yukardan aaya
doru sayan bir saya yapmak isterseniz yukardaki fonksiyonu u ekle getirebilirsiniz:
def saya(say, snr):
print(say)
674
if say == snr:
return 'bitti!'
else:
return saya(say-1, snr)
print(saya(100, 0))
675
print(dz_liste_yap(l))
Fonksiyonumuzun temel alma prensibine gre liste iindeki btn eleri tek tek alp baka
bir liste iinde toplayacaz. Eer liste elemanlar zerinde ilerlerken karmza liste olmayan
bir eleman karsa bu eleman [liste] koduyla bir listeye dntreceiz.
nceki rneklerden farkl olarak, bu kez kodlarmzda iki farkl dip noktas kontrol gryoruz.
lkini yukarda akladk. kinci dip noktamz u:
elif not liste:
return []
Burada yaptmz ey u: Eer zyineleme esnasnda bo bir liste ile karlarsak, tekrar bo
bir liste dndryoruz. Peki ama neden?
Bildiiniz gibi bo bir listenin 0.
yapamayz:
eleman olmaz.
>>> a = []
>>> a[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
Grdnz gibi, bo bir liste zerinde indeksleme ilemi yapmaya kalktmzda hata
alyoruz. imdi durumu daha iyi anlayabilmek iin isterseniz yukardaki kodlar bir de ikinci
dip noktas kontrol olmadan yazmay deneyelim:
def dz_liste_yap(liste):
if not isinstance(liste, list):
return [liste]
else:
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
l = [1, 2, 3, [4, 5, 6], [7, 8, 9, [10, 11], 12], 13, 14]
print(dz_liste_yap(l))
676
Grdnz gibi, biraz nce bo bir liste zerinde indeksleme yapmaya altmzda
aldmz hatann ayns bu. nk kodlarmzn else blouna bakarsanz liste zerinde
indeksleme yaptmz grrsnz:
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
Elbette bo bir liste liste[0] veya liste[1:] gibi sorgulamalara IndexError tipinde bir hata
mesajyla cevap verecektir. te byle bir durumda hata almamak iin u kodlar yazyoruz:
elif not liste:
return []
Yani listenin ilk esine, geri kalan eleri teker teker ekliyoruz.
Gelin bir rnek daha verelim:
def topla(sayilar):
if len(sayilar) < 1:
return 0
else:
ilk, son = sayilar[0], sayilar[1:]
return ilk+topla(son)
Bu fonksiyonun grevi, kendisine liste olarak verilen saylar birbiriyle toplamak. Biz bu ii
baka yntemlerle de yapabileceimizi biliyoruz, ama bizim burada amacmz zyinelemeli
fonksiyonlar anlamak. O yzden saylar birbiriyle toplama ilemini bir de bu ekilde
yapmaya alacaz.
40.2. zyinelemeli (Recursive ) Fonksiyonlar
677
Buna gre sayilar adl listenin uzunluu 1in altna dnce 0 deerini dndryoruz. Burada
0 deerini dndrmemizin nedeni, listede e kalmadnda programmzn hata vermesini
nlemek. Eer 0 dnda baka bir say dndrrsek bu say toplama ileminin sonucuna etki
edecektir. Toplama ileminin sonucunu etkilemeyecek tek say 0 olduu iin biz de bu sayy
dndryoruz.
Taban noktaya varlncaya kadar yaplacak ilemler ise unlar:
ilk, son = sayilar[0], sayilar[1:]
return ilk+topla(son)
Burada amacmz, listenin ilk says ile listenin geri kalan elerini tek tek birbiriyle toplamak.
Bunun iin sayilar adl listenin ilk esini, listenin geri kalanndan ayryoruz ve ilk eyi ilk ;
geri kalan eleri ise son adl bir deikene gnderiyoruz:
ilk, son = sayilar[0], sayilar[1:]
Sonra da ilk eyi, geri kalan liste eleri ile tek tek topluyoruz. Bunun iin de topla()
fonksiyonunun kendisini son adl deiken iinde tutulan liste elerine zyinelemeli olarak
uyguluyoruz:
return ilk+topla(son)
Bylece liste iindeki btn elerin toplam deerini elde etmi oluyoruz.
Bu arada, yeri gelmiken Python programlama dilinin pratik bir zelliinden sz edelim.
Grdnz gibi saylarn ilk esini geri kalan elerden ayrmak iin yle bir kod yazdk:
ilk, son = sayilar[0], sayilar[1:]
Bylece sayilar deikenin ilk esi ilk deikeninde, geri kalan eleri ise son deikeninde
tutulacaktr. lerleyen derslerde Yrycler (Iterators ) konusunu ilerken bu yapdan daha
ayrntl bir ekilde sz edeceiz.
678
BLM 41
Modller
Bu blmde, geen derste ayrntl olarak incelediimiz Fonksiyonlar kadar nemli bir
konuyu ele alacaz. Bu nemli konunun ad modller.
Biz imdiye kadar modl konusunu hi ayrntl olarak ele almam olsak da esasnda siz
modl kavramna bsbtn yabanc saylmazsnz. Zira biz nceki derslerimizde zaman
zaman modllerden sz etmi, hatta yeri geldiinde bunlar kodlarmz iinde kullanmaktan
da ekinmemitik.
Bu konuya gelene
hatrlyorsunuzdur:
kadar,
eitli
blmlerde
modllerden
bahsettiimizi
sys
os
keyword
random
unicodedata
locale
te imdi, daha nce farkl blmlerde yle bir temas edip getiimiz modller konusunu
bu blmde derinlemesine incelemeye alacaz.
Bu rnekte, random adl modln iindeki randint() adl faydal bir fonksiyondan
yararlanarak 0 ile 10.000 saylar arasnda 1000 adet rastgele say ieren bir liste
679
oluturmutuk. Dolaysyla, yukardaki tanmda da belirttiimiz gibi, bir modl olan random,
rnekte bahsettiimiz ilevi kolaylkla yerine getirmemizi salayan bir fonksiyon barndryor.
Biz de bu fonksiyonu kullanarak amacmz rahatlkla yerine getirebiliyoruz.
random modlnn dnda, nceki derslerimizde yle bir deinip getiimiz, sys, os ve
locale gibi modllerin de eitli grevleri kolayca yerine getirmemizi salayan birtakm
aralar barndrdn grmtk.
in dorusu, modl denen ey Python programlama dilinin bel kemiidir. Eer modller
olmasayd, Python programlama dili hem ok kullansz bir dil olurdu, hem de modller
sayesinde ok kolay bir ekilde stesinden gelebildiimiz zorluklar iin her defasnda
kendimiz yeniden bir zm icat etmek zorunda kalrdk.
Belki bu iddial laf size u anda pek anlaml gelmemi olabilir. u ana kadar modllerle ilgili
rendikleriniz, henz zihninizde bu lafn iddiasn teyit etmiyor olabilir. Ama modllerin
neden bu kadar nemli olduunu birazdan ok daha net bir ekilde anlayacaksnz. imdilik
okumaya devam edin.
Hatrlarsanz bir nceki blmde Pythondaki fonksiyonlardan bahsetmitik.
Yine
hatrlarsanz o blmde pek ok rnek fonksiyon da tanmlamtk. Mesela kayt_olutur()
adl yle bir fonksiyon tanmladmz hatrlyor olmalsnz:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
isim)
soyisim)
isis)
ehir)
print("-"*30)
Bu fonksiyonu bir kez tanmladktan sonra, bu fonksiyonu ayn program iinde istediimiz
kadar kullanabiliyoruz. Yani kayt_olutur adl bir fonksiyon tanmlam olmamz sayesinde,
bu fonksiyonun gvdesinde belirttiimiz ilemleri her defasnda tekrar tekrar yapmak
zorunda kalmyoruz; btn bu ilemleri tek bir kayt_olutur ismine atam olduumuz
iin, bu fonksiyonun bize sunduu ileve ihtiya duyduumuz her yerde bu fonksiyonu
kullanabiliyoruz. rnein:
kayt_olutur('Frat', 'zgl', 'Debian', 'Arsuz')
Ya da:
kayt_olutur('Zerrin', 'Sz', 'Ubuntu', 'Bolvadin')
Eer
yukardaki
ilevsellii
bir
fonksiyon
olarak
tanmlam
kayt_olutur(Frat, zgl, Debian, Arsuz) kodunun verdii
etmek iin u kodlar yazmak zorunda kalacaktk:
olmasaydk,
kty elde
print("-"*30)
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
"Frat")
"zgl")
"Debian")
"Arsuz")
print("-"*30)
680
Burada isim, soyisim, iletim sistemi ve ehir bilgileri deitiinde de her defasnda ayn
eyleri uzun uzadya tekrar tekrar yazmamz gerekecekti:
print("-"*30)
print("isim
: ",
print("soyisim
: ",
print("iletim sistemi: ",
print("ehir
: ",
"Zerrin")
"Sz")
"Ubuntu")
"Bolvadin")
print("-"*30)
te modller de buna benzer bir vazife grr. Yani Pythonn fonksiyon sistemi nasl bize bir
ilevsellii ayn dosya iinde tekrar tekrar kullanma imkan veriyorsa, modl sistemi de bir
fonksiyonu farkl dosyalar ve programlar iinde tekrar tekrar kullanma imkan verir.
Dolaysyla, eer modl sistemi olmasayd, biz bir kez yazdmz (veya baka bir Python
programcs tarafndan yazlm) kayt_olutur() fonksiyonunu baka bir programda da
kullanmak istediimizde, bu fonksiyonu alp her defasnda yeni programa elle kopyalamak
zorunda kalrdk. Ama modl sistemi sayesinde, bir program iinde bulunan fonksiyonlar
(ve dier nitelikleri) baka Python programlar iine aktarabiliyoruz. Bylece bir Python
programndaki (veya modlndeki) ilevsellikten, baka bir Python programnda da
yararlanabiliyoruz. Dolaysyla modller sayesinde, bir kez yazdmz kodlar pek ok farkl
program iinde kullanma imkan elde ediyoruz. Bu da bizim;
Daha az kod yazmamz,
Bir kez yazdmz kodlar tekrar tekrar kullanabilmemizi,
Daha dzenli, daha derli toplu bir ekilde alabilmemizi
salyor.
te bu blmde, modllerin btn bu ilevleri nasl yerine getirdiini, modl denen eyden
nasl faydalanabileceimizi ve modllerin neden bu kadar nemli olduunu reneceiz.
Dilerseniz laf daha fazla dolandrmadan modller konusuna hzl bir giri yapalm.
681
modllerin
olduunu
Standart Ktphane iinde, Python ile programlama yaparken ilerinizi bir hayli
kolaylatracak pek ok modl bulacaksnz.
Bata da sylediimiz gibi, biz bu blme gelinceye kadar stnkr de olsa modllerden sz
etmitik. rnein nceki derslerimizde andmz sys, os, random ve benzeri modller hep
birer Standart Ktphane modldr. Dolaysyla bu modllerin sunduu ilevsellikten kendi
programlarmzda istediimiz her an yararlanabiliriz.
682
[Link] komutu, kullandnz iletim sistemine bal olarak farkl ktlar verir. Eer bu
komutu bir GNU/Linux datmnda veya bir Mac bilgisayarda verirsek yukardaki gibi posix
kts alrz. Ama eer ayn komutu Windowsta verirsek nt kts alrz. Dolaysyla os
modlnn name niteliini kullanarak, yazdmz bir programn hangi iletim sisteminde
altn denetleyebiliriz:
>>> if [Link] != 'nt':
...
print('Kusura bakmayn! Bu program yalnzca',
...
'Windows\'ta kullanabilirsiniz!')
... else:
...
print('Hogeldin Windows kullancs!')
Etkileimli kabukta yazdmz bu program gelin bir de bir metin dosyasna kaydedelim. Zira
biz henz modlleri renme aamasnda olduumuz iin imdilik bunlar etkileimli kabukta
test ediyor olsak da, gerek hayatta programlarmz etkileimli kabua deil, program
dosyalar iine yazacaz.
Yukardaki kodlar bir dosyaya kaydettiimizde programmz yle grnr:
import os
if [Link] != 'nt':
print('Kusura bakmayn! Bu program yalnzca',
'Windows\'ta kullanabilirsiniz!')
else:
print('Hogeldin Windows kullancs!')
683
Bylece modl iindeki bir nitelie erimi olduk. Yalnz burada asla unutmamamz gereken
ey, ncelikle kullanacamz modl import modl_ad komutuyla ie aktarmak olacaktr.
Modl ie aktarmazsak tabii ki o modldeki fonksiyon veya niteliklere de eriemeyiz. (Sk
yaplan bir hata olduu iin, bunu tekrar tekrar vurguluyoruz...)
Bu arada bir modl, her etkileimli kabuk oturumunda yalnzca bir kez ie aktarmak
yeterlidir. Yani siz etkileimli kabuu altrdktan sonra bir kez import os komutuyla modl
ie aktardktan sonra, o etkileimli kabuk oturumunu kapatana kadar, ayn modl tekrar ie
aktarmak zorunda kalmadan bu modln ieriini kullanabilirsiniz.
Ayn ekilde, eer bu kodlar etkileimli kabua deil de bir program dosyasna yazyorsanz,
import os komutunu dosyann bana bir kez yazdktan sonra ayn modl programn
ilerleyen ksmlarnda tekrar ie aktarmak zorunda kalmadan, o modlnn ieriinden
yararlanabilirsiniz.
Grdnz gibi, bir Standart Ktphane Modl olan os bize name adl ok kullanl bir
nitelik sunuyor. Eer os modl olmasayd, name adl niteliin sunduu ilevi kendimiz icat
etmek zorunda kalrdk.
Baka bir rnek daha verelim...
Diyelim ki yine bir program yazdnz. Programnzn almas iin, programnz kullanan
kiinin bilgisayarnda birtakm dizinler oluturmanz gerekiyor. te bu i iin de os
modlnden yararlanabilirsiniz.
Bu modl iindeki makedirs() fonksiyonunu kullanarak, o anda iinde bulunduunuz dizinde
yeni bir dizin oluturabilirsiniz:
>>> [Link]('DATA')
Bu komutu verdikten sonra, o anda altnda bulunduunuz dizinde DATA adl bir dizin
oluacaktr. Eer o anda hangi dizin altnda bulunduunuzu renmek isterseniz de yine
os modlnden faydalanabilirsiniz:
>>> [Link]()
os modlnn getcwd() fonksiyonu bize o anda hangi dizin altnda bulunduumuzu gsterir.
Bu komutun ktsnda hangi dizin adn gryorsanz, biraz nce makedirs() fonksiyonu ile
oluturduunuz DATA dizini de o dizin altnda olumutur...
Grdnz gibi, bir rpda os modlnn birka zelliinden birden yararlandk. Daha nce
de sylediimiz gibi, eer os modl olmasayd yukarda gerekletirdiimiz btn ilevleri
kendiniz icat etmek zorunda kalrdnz.
Bylece Pythondaki modllerin neye benzediini ve nasl kullanldn anlam olduk.
Modllerin faydal aralar olduu konusunda sizleri ikna edebilmi olduumuzu varsayarak
bir sonraki blme geelim.
684
veya:
>>> import os
>>> [Link] #letim sistemimizin adn verir
gibi...
Ancak Pythonda bir modl ie aktarmann tek yntemi bu deildir. Eer istersek modlleri
daha farkl ekillerde de ie aktarabiliriz.
Gelin imdi bu alternatif modl aktarma biimlerinin neler olduunu grelim.
import modl_ad as farkl_isim
Baz koullar, bir modl kendi adyla deil de baka bir isimle ie aktarmanz gerektirebilir.
Ya da siz bir modl kendi ad dnda bir adla ie aktarmann daha iyi bir kir olduunu
dnebilirsiniz.
Peki ama ne tr koullar bir modl farkl bir adla ie aktarmamz gerektirebilir veya biz
hangi sebeple bir modl farkl adla ie aktarmay isteyebiliriz?
Bu sorularn cevabn verebilmek iin, gelin isterseniz subprocess adl bir Standart Ktphane
modlnden yararlanalm. Hem bu vesileyle yeni bir modl de renmi oluruz...
Not:
subprocess modl, harici komutlar Python iinden altrabilmemizi salayan
olduka faydal bir aratr. Bu modl kullanarak Python programlarmz iinden, baka
programlar altrabiliriz.
Bir modln iindeki fonksiyon ve nitelikleri her kullanmak isteyiimizde, o fonksiyon veya
niteliin bana modl adn da eklememiz gerektiini artk gayet iyi biliyorsunuz. rnein
subprocess adl modl
>>> import subprocess
komutuyla ie aktardktan sonra, bu modl iindeki herhangi bir fonksiyon veya nitelii
kullanabilmenin birinci art, modl adn ilgili fonksiyon veya niteliin nne getirmektir.
Mesela biz subprocess modlnn call() adl fonksiyonunu kullanmak istersek, yle bir
kod yazmamz gerekir:
>>> [Link]('[Link]')
685
rnek olmas asndan baka bir modl daha ele alalm. Modlmzn ad webbrowser.
Not: webbrowser modl, bilgisayarmzda kurulu internet taraycsn kullanarak internet
sitelerini aabilmemizi salar.
Tpk subprocess gibi, webbrowser kelimesi de, her defasnda tekrar etmesi skc olabilecek
bir kelime. Dolaysyla dilerseniz bu modl import webbrowser yerine farkl bir isimle ie
aktarabilirsiniz. rnein:
>>> import webbrowser as br
veya:
>>> import webbrowser as web
Modl hangi adla ie aktaracanz tamamen size kalm. Diyelim ki bu modl web adyla
ie aktardk. Artk bu modln iindeki aralar web nekiyle kullanabiliriz:
>>> [Link]('[Link]')
Uyar:
Baz GNU/Linux datmlarnda websitesi adresini http nekiyle birlikte
belirtmeniz gerekebilir. rn. [Link]([Link]
Bu kod, bilgisayarmzdaki ntanml web taraycs hangisiyse onu altracak ve bizi,
parantez iinde gsterilen web sayfasna gtrecektir.
Eer biz webbrowser modln dorudan kendi adyla ie aktarsaydk:
>>> import webbrowser
Ama bu modl daha ksa bir adla ie aktarm olmamz sayesinde, bu modl gayet pratik
bir ekilde kullanma imkanna kavuuyoruz.
from modl_ad import isim1, isim2
imdiye kadar verdiimiz rneklerden de grdnz gibi, Standart Ktphane Modllerinin
iinde ok sayda fonksiyon ve nitelik bulunuyor. Mesela os modln ele alalm:
>>> import os
>>> dir(os)
686
687
Ayn ekilde, bir modl iinden belli nitelik ve fonksiyonlar da nasl ie aktaracanz
biliyorsunuz:
from os import path, listdir
veya:
from os import listdir as ld
gibi...
Bu rneklerde, os modl iinden path adl nitelii p adyla; listdir() fonksiyonunu ise ld
adyla ie aktardk. Bylece path niteliini p adyla; listdir() fonksiyonunu da ld adyla
kullanabiliriz.
Yalnz bu yntem ok sk kullanlmaz.
sonuncusuna geelim.
Bylece sys modl iindeki btn fonksiyon ve nitelikleri, balarna modl adn eklemeye
gerek olmadan kullanabiliriz:
>>> version
Ancak bu yntem pek tavsiye edilmez. nk bu ekilde, modl iindeki btn isimleri
kontrolsz bir ekilde mevcut ortama boaltm oluyoruz. Mesela eer modl bu ekilde ie
aktarlmadan nce version diye baka bir deiken tanmlamsanz, modl ie aktarldktan
sonra, nceden tanmladnz bu version deikeninin deeri kaybolacaktr:
>>> version = '1.0'
>>> print(version)
1.0
Bu ortama from sys import * komutuyla sys modlnn btn ieriini aktaralm:
>>> from sys import *
688
Ama bunun bir istisnas var. Bir modl yldzl olarak ie aktaracaksak, bu ilemi lokal etki
alanlar iinden gerekletiremeyiz. Yani mesela bir fonksiyonun lokal isim alan iinde yle
bir kod yazabiliriz:
def fonksiyon():
import os
Veya:
def fonksiyon():
import subprocess as sp
Bu kodlar bir dosyaya kaydedip altrdmzda una benzer bir hata alrz:
File "[Link]", line 1
def fonksiyon():
SyntaxError: import * only allowed at module level
Bunun anlam u: Yldzl ie aktarma ilemleri ancak modl seviyesinde, yani global isim
alannda gerekletirilebilir. Dolaysyla yukardaki ie aktarma ilemini ancak fonksiyonun
dnda gerekletirebiliriz:
from os import *
def fonksiyon():
pass
Veya:
def fonksiyon():
pass
689
from os import *
dir(os) komutunu kullanarak modln ieriini kontrol ettiinizde, o listede __le__ adl bir
niteliin olduunu greceksiniz. Bu nitelik Python ile yazlm tm modllerde bulunur. Bu
nitelii u ekilde kullanyoruz:
>>> os.__file__
`C:\Python35\lib\[Link]'
te buradan aldmz kt bize os modlnn kaynak dosyasnn nerede olduunu
gsteriyor. Hemen ktda grnen konuma gidelim ve [Link] dosyasn aalm.
690
Dosyay atnzda, gerekten de bu modln aslnda sradan bir Python program olduunu
greceksiniz. Dosyann ieriini incelediinizde, dir(os) komutuyla elde ettiimiz nitelik
ve fonksiyonlarn dosya iinde nasl tanmlandn grebilirsiniz. Mesela yeni dizinler
oluturmak iin [Link]() eklinde kullandmz makedirs fonksiyonunun [Link] iinde
tanmlanm alelade bir fonksiyon olduunu grebilirsiniz.
Ayn ekilde, nceki sayfalarda rneklerini verdiimiz webbrowser modl de,
bilgisayarmzdaki sradan bir Python programndan ibarettir. Bu modln nerede olduunu
da u komutla grebilirsiniz:
>>> import webbrowser
>>> webbrowser.__file__
Grdnz gibi, webbrowser modl de, tpk os modl gibi, bilgisayarmzdaki .py uzantl
bir dosyadan baka bir ey deil. sterseniz bu dosyann da iini ap inceleyebilirsiniz.
Yalnz u gerei de unutmamalyz: Pythondaki btn modller Python programlama dili
ile yazlmamtr. Baz modller C ile yazlmtr. Dolaysyla C ile yazlm bir modln
.py uzantl bir Python dosyas bulunmaz. Mesela sys byle bir modldr. Bu modl C
programlama dili ile yazld iin, kaytl bir .py dosyasna sahip deildir. Dolaysyla bu
modln bir __le__ nitelii de bulunmaz:
>>> import sys
>>> sys.__file__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'
Ama tabii ki, Pythondaki standart ktphane modllerinin ok byk blm Python ile
yazlmtr ve bu modllerin kaynak dosyalarn os ve webbrowser modllerini bulduunuz
dizinde grebilirsiniz. rnein nceki derslerimizde bahsi geen locale ve random gibi
modllerin kaynak dosyalarn da burada bulabilirsiniz.
Gelelim asl konumuz olan modl tanmlamaya...
Hatrlarsanz, Pythonda bir fonksiyon tanmlamak iin u sz dizimini kullanyorduk:
def fonksiyon_ad(parametreler):
fonksiyon_gvdesi
Ancak yukardaki rneklerden de rahatlkla grebileceiniz gibi, modller iin byle zel bir
sz dizimi yoktur. Yazdnz her Python program ayn zamanda potansiyel bir modldr.
O halde imdi gelin bir tane de kendimiz modl yazalm.
Mesela bir program dosyas oluturalm ve adn da [Link] koyalm. te bu program, ayn
zamanda bir Python modldr. Bu modln ad da szlktr. Dediimiz gibi, Pythonda
modller genellikle .py uzantsna sahiptir. Ancak bir modln ad sylenirken bu .py uzants
dikkate alnmaz. Bu yzden elinizdeki [Link] adl programn modl ad szlk olacaktr.
Grdnz gibi, modl tanmlamakta herhangi bir zel zorluk yok. Yazdmz her program,
otomatik olarak, ayn zamanda bir modl oluyor.
[Link] adl programmzn ierii yle olsun:
szlk = {"kitap"
: "book",
"bilgisayar" : "computer",
691
"programlama": "programming"}
def ara(szck):
hata = "{} kelimesi szlkte yok!"
return [Link](szck, [Link](szck))
Esasnda ktphane modlleriyle kendi yazdmz modller arasnda kullanm asndan pek
bir fark yoktur. Bu blmn banda grdmz ktphane modllerini nasl kullanyorsak,
kendi modllerimizi de yle kullanyoruz.
Ktphane modllerini anlatrken grdmz gibi, modl sistemi sayesinde, bir program
iinde bulunan fonksiyon (ve nitelikleri) baka Python programlar iine aktarabiliyoruz.
Bylece bir Python programndaki (veya modlndeki) ilevsellikten, baka bir Python
programnda da yararlanabiliyoruz.
imdi, eer bu [Link] dosyasn, mesela masastne kaydettiyseniz, masastnn
bulunduu konumda bir komut satr an ve Pythonn etkileimli kabuunu balatn. Tpk
ktphane modllerinde olduu gibi, etkileimli kabukta u komutu vererek szlk adl
modl ie aktarn:
>>> import szlk
Eer hibir ey olmadan bir alt satra geildiyse modlnz baaryla ie aktardnz demektir.
Eer No module named szlk gibi bir hata mesajyla karlayorsanz, muhtemelen Python
[Link] dosyasnn olduu dizinde balatamamsnzdr.
import szlk komutunun baarl olduunu varsayarak yolumuza devam edelim...
Peki neden ktphane modllerini her yerden ie aktarabilirken, kendi yazdmz modlleri
yalnzca bulunduklar dizin altnda ie aktarabiliyoruz?
Aslnda bunun cevab ok basit: Biz bir program dosyasnda veya komut satrnda import
modl_ad gibi bir komut verdiimizde Python modl_ad olarak belirttiimiz modl bulmak
iin bir arama ilemi gerekletirir. Elbette Python bu modl sabit diskin tamamnda
aramaz. Python, ie aktarmak istediimiz modl bulmak iin belli birtakm dizinlerin iini
kontrol eder. Peki Python modl dosyasn bulmak iin hangi dizinlerin iine bakar? Bu
sorunun cevabn bize sys modlnn path adl bir nitelii verecek. Hemen bakalm:
>>> import sys
>>> [Link]
te Python bir modl dosyasn ararken, import komutunun verildii dizin ile birlikte,
[Link] ktsnda grnen dizinlerin iine de bakar. Eer modl dosyasn bu dizinlerin
iinde bulursa modl baaryla ie aktarr, ama eer bulamazsa ImportError cinsinden bir
hata verir.
Peki eer biz kendi modllerimizi de her yerden ie aktarabilmek istersek ne yapmamz
gerekiyor?
Bunun iin iki seeneimiz var: Birincisi, modln yolunu [Link] listesine ekleyebiliriz.
kincisi, modlmz [Link] iinde grnen dizinlerden birine kopyalayabilir veya
tayabiliriz.
ncelikle birinci seenei ele alalm.
Grdnz gibi, [Link] komutunun kts aslnda basit bir listeden baka bir ey deildir.
Dolaysyla Pythonda liste adl veri tipi zerinde ne tr ilemler yapabiliyorsanz, [Link]
zerinde de ayn eyleri yapabilirsiniz.
Mesela, modl dosyasnn /home/istihza/programlar adl dizin iinde bulunduunu
varsayarsak, modl dosyasnn yolunu [Link] listesinin en sonuna u ekilde ekleyebiliriz:
[Link](r'/home/istihza/programlar')
Burada listelerin append() metodunu kullandmza dikkat edin. Dediimiz gibi, [Link]
aslnda basit bir listeden ibarettir. Dolaysyla bir listeye nasl e ekliyorsak, [Link] de
ayn ekilde e ekliyoruz.
Modl dosyasnn bulunduu /home/istihza/programlar yolunu
eklediimize gre, artk modlmz her yerden ie aktarabiliriz.
[Link]
listesine
Kendi yazdmz bir modl her yerden ie aktarabilmenin ikinci ynteminin, ilgili modl
dosyasn [Link] ktsnda grnen dizinlerden herhangi birine kopyalamak olduunu
sylemitik. Dolaysyla, [Link] ktsna bakp, modl dosyanz orada grnen dizinlerden
herhangi biri iine kopyalayabilirsiniz. Yaygn olarak tercih edilen konum, Python kurulum
dizini iindeki site-packages adl dizindir. Bu dizinin yerini u ekilde tespit edebilirsiniz:
>>> from distutils import sysconfig
>>> sysconfig.get_python_lib()
Modl dosyanz, bu komutlardan aldnz ktnn gsterdii dizin iine kopyaladktan sonra,
modlnz her yerden ie aktarabilirsiniz.
Bu konuyu kapatmadan nce [Link] ile ilgili nemli bir bilgi daha verelim. Python, ie
aktarmak istediimiz bir modl bulabilmek iin dizinleri ararken [Link] listesindeki dizin
693
adlarn soldan saa doru okur. Modl dosyasn bulduu anda da arama ilemini sona
erdirir ve modl ie aktarr. Diyelim ki [Link] ktmz yle:
['A', 'B', 'C']
Eer hem A, hem de B dizininde [Link] adl bir dosya varsa, Python A dizinindeki
szlk modln ie aktarr. nk [Link] ktsnda A dizini B dizininden nce
geliyor. Eer siz ie aktarma srasnda bir dizine ncelik vermek isterseniz o dizini append()
metoduyla [Link] listesinin sonuna eklemek yerine, insert() metoduyla listenin en bana
ekleyebilirsiniz:
>>> [Link](0, r'dizin/ad')
Grdnz gibi, nasl os modlnn iinde name, listdir() ve getcwd() gibi nitelik ve
fonksiyonlar varsa, kendi yazdmz szlk modl iinde de ara() adl bir fonksiyon ve
szlk adl bir nitelik var.
te biz bu fonksiyon ve nitelii kullanma imkanna sahibiz. Gelin birka deneme almas
yapalm:
>>> [Link]
694
>>> [Link]('kitap')
Bu modl ie aktaralm:
>>> import szlk
Gelin imdi
szlk = {"kitap"
: "book",
"bilgisayar" : "computer",
"programlama": "programming"}
def ara(szck):
hata = "{} kelimesi szlkte yok!"
return [Link](szck, [Link](szck))
def ekle(szck, anlam):
mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print([Link](szck))
Burada szlk modlne ekle() adl bir fonksiyon ilave ettik. Bu fonksiyon, szle yeni
kelimeler eklememizi salayacak. imdi tekrar modlmzn ieriini kontrol edelim:
>>> dir(szlk)
Ancak grdnz gibi, modle yeni eklediimiz ekle() fonksiyonu bu ktda grnmyor.
Bunun nedeni, etkileimli kabukta modl bir kez ie aktarldktan sonra, o modlde yaplan
deiikliklerin otomatik olarak etkinlemiyor oluudur. Yani deiikliklerin etkileimli kabukta
etkinleebilmesi iin o modl yeniden yklememiz lazm. Bunu iki ekilde yapabiliriz:
Birincisi, etkileimli kabuu kapatp yeniden atktan sonra import szlk komutuyla szlk
modln tekrar ie aktarabiliriz.
695
kincisi, importlib adl bir ktphane modlnden yararlanarak kendi modlmzn tekrar
yklenmesini salayabiliriz. Bu modl yle kullanyoruz:
>>> import importlib
>>> [Link](szlk)
Bu iki komutu verdikten sonra, szlk zerinde tekrar dir() fonksiyonunu uygularsak, yeni
eklediimiz ekle() fonksiyonunun ktya yansdn grrz:
>>> dir(szlk)
['__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__',
'ara', 'ekle', 'szlk']
Tpk nceki derslerimizde grdmz sys, os ve keyword modlleri gibi, importlib de bir
ktphane modldr. Bu modln bizim yukarda yazdmz szlk adl modlden fark,
Python gelitiricileri tarafndan yazlp dile entegre edilmi bir hazr modl olmasdr. Yani
szlk modln biz kendimiz yazdk, importlib modln ise Python gelitiricileri yazd.
kisi arasndaki tek fark bu.
Ne diyorduk? Evet, szlk adl modle ekle() adl yeni bir fonksiyon ilave ettik. Bu
fonksiyona da, tpk szlk niteliinde ve ara() fonksiyonunda olduu gibi, modl adn
kullanarak eriebiliriz:
>>> [Link]('araba', 'car')
araba kelimesi szle eklendi!
Szlmze, araba adl yeni bir kelimeyi, car karl ile birlikte ekledik. Hemen bunu
sorgulayalm:
>>> [Link]('araba')
'car'
696
Bu defa da modlmze sil() adl baka bir fonksiyon ekledik. Bu fonksiyon, szlkten e
silmemizi salayacak:
>>> [Link]('kitap')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'sil'
Grdnz gibi, bu kez bir hata mesaj aldk. Peki sizce neden? Elbette deiiklik yaptktan
sonra modl yeniden yklemediimizden... O halde nce modlmz yeniden ykleyelim:
>>> [Link](szlk)
Modl dosyasndan sil() adl fonksiyonu karalm. Yani modlmzn son hali yle olsun:
szlk = {"kitap"
: "book",
"bilgisayar" : "computer",
"programlama": "programming"}
def ara(szck):
hata = "{} kelimesi szlkte yok!"
return [Link](szck, [Link](szck))
def ekle(szck, anlam):
mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print([Link](szck))
697
Grdnz gibi, biz sil() fonksiyonunu karm olduumuz halde, dir(szlk) ktsnda
bu e grnmeye devam ediyor. stelik bu fonksiyon halen kullanlabilir durumda!
>>> [Link]('programlama')
programlama kelimesi szlkten silindi!
Ancak bu durumu rahatlkla grmezden gelebilirsiniz. Ama eer o enin orada olmas sizi
rahatsz ediyorsa, u komutla o eyi silebilirsiniz:
>>> del [Link]
Dediimiz gibi, modlden silinen eler, reload() ile yeniden yklendikten sonra dahi
kullanlr durumda kalmaya devam eder. Ama eer modl iinde varolan bir e zerinde
deiiklik yaparsanz o deiiklik, reload() sonras modln grnmne yansyacaktr. Yani
mesela, modlde halihazrda varolan sil() fonksiyonu zerinde bir deiiklik yaparsanz, bu
deiiklik reload() ile yeniden ykleme sonrasnda etkileimli kabua yansyacaktr.
Not: Pythonn 2.7.9 ve 3.4.0 srmlerinden itibaren, pip adl yazlm ntanml olarak
Python kurulumuyla birlikte geliyor. Dolaysyla Python2deki pipi kullanmak isterseniz pip2
komutunu, Python3teki pipi kullanmak isterseniz de pip3 komutunu kullanabilirsiniz.
rnein amacnz Django adl nc ahs modln kurmak ise bu modl u komut ile
kurabilirsiniz:
pip3 install django
Veya nce:
su -
Ardndan:
python3 [Link] install
699
imdi masastnde, ierii aadaki gibi olan, [Link] adl bir dosya oluturun:
def fonk1():
print('fonk1')
def fonk2():
print('fonk2')
def fonk3():
print('fonk3')
def fonk4():
print('fonk4')
def fonk5():
print('fonk5')
def _fonk6():
print('_fonk6')
def __fonk7():
print('__fonk7')
def fonk8_():
print('fonk8_')
Daha sonra, masastnn bulunduu konumda bir komut penceresi aarak Pythonn
etkileimli kabuunu altrn ve orada u komutu verip bu [Link] adl dosyay bir modl
olarak ie aktarn:
>>> import modl
Grdnz gibi, modl iinde tanmladmz btn fonksiyonlar bu listede var. Dolaysyla
bu fonksiyonlara u ekilde eriebiliyoruz:
>>> modl.fonk1()
fonk1
>>> modl.fonk2()
fonk2
>>> modl._fonk6()
_fonk6
>>> modl.__fonk7()
700
__fonk7
>>> modl.fonk8_()
fonk8_
Bu ekilde, istisnasz btn fonksiyonlara eriim yetkisi elde ettiimize dikkatinizi ekmek
isterim.
imdi etkileimli kabuu kapatp tekrar aalm ve bu kez modlmz u ekilde ie
aktaralm:
>>> from modl import *
Bu ekilde, ismi _ ile balayanlar hari btn fonksiyonlar, modl neki olmadan mevcut etki
alanna aktardmz biliyoruz.
Kontrol edelim:
>>> dir()
Grdnz gibi, gerekten de ismi _ ile balayanlar hari, btn fonksiyonlar, modl neki
olmadan kullanlmaya hazr bir ekilde mevcut etki alanmz iinde grnyor. Bunlar u
ekilde kullanabileceimizi biliyorsunuz:
>>> fonk4()
fonk4
>>> fonk8_()
fonk8_
Elbette, ismi _ ile balayan fonksiyonlar, dorudan isimlerini kullanarak ie aktarma imkanna
sahipsiniz:
>>> from modl import __fonk7
>>> from modl import _fonk6
701
Tabii ki, bu ekilde yldzl aktarmalarda (modln kendi varsaylan fonksiyonlar hari) hibir
fonksiyon ie aktarlmaz...
Bu kodlar, os, sys ve random modllerinin kesiim kmesini, yani her modlde ortak
olarak bulunan nitelikleri verecektir. Bu kodlar altrdmzda u kty alyoruz:
{'__doc__', '__package__', '__loader__', '__name__', '__spec__'}
Demek ki hem os hem sys hem de random modlnde ortak olarak bulunan nitelikler
bunlarm... Eer bu modln btn modlleri temsil etmiyor olabileceinden endie
ediyorsanz, bildiiniz baka modlleri de bu kodlara ekleyerek testinizin kapsamn
geniletebilirsiniz.
Mesela bu kodlara bir de subprocess modln ekleyelim:
import os, sys, random, subprocess
set_os = set(dir(os))
set_sys = set(dir(sys))
set_random = set(dir(random))
set_subprocess = set(dir(subprocess))
print(set_os & set_sys & set_random & set_subprocess)
702
Yalnz burada yle bir ey dikkatinizi ekmi olmal: Kesiim kmesini bulmak istediimiz
elere baka eler de eklemek istediimizde her defasnda birka farkl ilem yapmak
zorunda kalyoruz. Bu da hem kodlarmz hatalara ak hale getiriyor, hem de aslnda kolayca
halledebileceimiz bir ii gereksiz yere uzatmamza yol ayor.
Gelin bu kodlar biraz daha genel amal bir hale getirelim. Zira kodlarn yeniden kullanlabilir
zellikte olmas (code reusability ) programclkta aranan bir niteliktir:
modller = ['os', 'sys', 'random']
def kesiim_bul(modller):
kmeler = [set(dir(__import__(modl))) for modl in modller]
return [Link](*kmeler)
print(kesiim_bul(modller))
Eer bu kodlara yeni bir modl eklemek istersek, yapmamz gereken tek ey en bataki
modller listesini gncellemek olacaktr. Mesela bu listeye bir de subprocess modln
ekleyelim:
modller = ['os', 'sys', 'random', 'subprocess']
def kesiim_bul(modller):
kmeler = [set(dir(__import__(modl))) for modl in modller]
return [Link](*kmeler)
print(kesiim_bul(modller))
Grdnz gibi, bu kodlar iimizi epey kolaylatrd. Sadece tek bir noktada deiiklik
yaparak istediimiz sonucu elde ettik.
Bu arada, __import__() fonksiyonu hari, bu kodlardaki her eyi daha nceki derslerimizde
renmitik. Ama gelin isterseniz biz yine de bu kodlarn zerinden yle bir geelim.
Burada ilk yaptmz i, kullanmak istediimiz modl adlarn tutmas iin bir liste
tanmlamak:
modller = ['os', 'sys', 'random', 'subprocess']
Bu listede modl adlarnn birer karakter dizisi olarak gsterildiine dikkat edin. Zaten bu
modlleri henz ie aktarmadmz iin, bunlar dorudan trnaksz isimleriyle kullanamayz.
Daha sonra, asl ii yapacak olan kesiim_bul() adl fonksiyonumuzu tanmlyoruz:
def kesiim_bul(modller):
kmeler = [set(dir(__import__(modl))) for modl in modller]
return [Link](*kmeler)
Burada modller adl listedeki her e zerine srasyla __import() fonksiyonunu, dir()
fonksiyonunu ve set() fonksiyonunu uyguluyoruz. Daha sonra elde ettiimiz sonucu bir liste
reteci yardmyla liste haline getirip kmeler deikenine atyoruz.
Gelelim __import__() fonksiyonunun ne olduuna...
41.7. Modllerin zel Nitelikleri
703
Bir gml fonksiyon olan __import__() fonksiyonu, modl adlarn ieren karakter dizilerini
kullanarak, herhangi bir modl ie aktarmamz salayan bir aratr. Bu fonksiyonunu yle
kullanyoruz:
>>> __import__('os')
>>> __import__('sys')
Bu fonksiyonun parametre olarak bir karakter dizisi alyor olmasnn bize nasl bir esneklik
saladna dikkatinizi ekmek isterim. Bu fonksiyon sayesinde modl aktarma ilemini, kod
paralar iine programatik olarak yerletirebilme imkan elde ediyoruz. Yani, modl aktarma
ilemini mesela bir for dngs iine alamyorken:
>>> modller = ['os', 'sys', 'random']
>>> for modl in modller:
...
import modl
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ImportError: No module named 'modl'
Yalnz, __import__(os) gibi bir komut verdiimizde, os ismi dorudan kullanlabilir hale
gelmiyor. Yani:
>>> __import__('os')
704
__import__() fonksiyonu ok sk kullanacanz bir ara deildir. Ancak zellikle tek satrda
hem bir modl ie aktarmanz, hem de hemen ardndan baka ilemler yapmanz gereken
durumlarda bu fonksiyon iinize yarayabilir:
>>> open('[Link]', 'w').write('merhaba'); __import__('subprocess').call('[Link] [Link]')
Bu komut, kme1 ile kme2 adl kmelerin kesiimini bulacaktr. Eer bizim kodlarmzda
olduu gibi kme ismi belirtmeksizin birden fazla kmenin kesiimini bulmak isterseniz bu
metodu dorudan kme veri tipi (set ) zerine uygulayabilirsiniz:
>>> [Link](kme1, kme2)
Eer intersection() metoduna parametreleri bir liste iinden atamak isterseniz bu listeyi
yldz ileci yardmyla zmeniz gerekir:
>>> liste = [kme1, kme2, kme3]
>>> [Link](*liste)
lk olarak
705
Programs that import and use 'os' stand a better chance of being
portable between different platforms. Of course, they must then
only use functions that are defined by all platforms (e.g., unlink
and opendir), and leave all pathname manipulation to [Link]
(e.g., split and join).
"""
[Link] dosyas ile ayn konumda bulunan [Link] dosyasn atnzda, yukardaki
komutlardan aldnz ktnn [Link] dosyasnn en bandaki uzun karakter dizisi
olduunu greceksiniz.
eitli yazlmlar, bu belge dizilerini kullanarak, ilgili modle ilikin ksa klavuzlar oluturur.
Mesela Pythonn help() fonksiyonu bu belge dizilerinden yararlanr:
>>> help(os)
...eklinde tanmladnz karakter dizileri __doc__ nitelii ile arldnda yalnzca satr1
grntlenecektir. Eer bu satrn da kapsama alanna girmesini istiyorsak yukardaki
karakter dizilerini yle tanmlamalyz:
706
'''
satr1
satr2
satr3
'''
707
gibi bir komutla altrdmzda bize birtakm sorular sorulacak ve verdiimiz cevaplara gre
szlk zerinde baz ilemler yaplacaktr.
Hatrlarsanz, modller konusunu anlatmaya balarken, yazdmz btn programlarn
aslnda birer modl olduunu, dolaysyla bunlarn baka programlarn iine aktarlarak, sahip
olduklar ilevlerden baka programlarda da yararlananlabileceini sylemitik.
Yukardaki kodlar, komut satr zerinde bamsz bir program gibi altrabiliyoruz. Peki
acaba biz bu program dorudan altrmak deil de baka bir programn iine aktarp sahip
olduu ilevlerden yararlanmak istersek ne yapacaz?
te bunun iin __name__ adl bir nitelikten yararlanacaz.
Pythondaki herhangi bir modl ie aktardktan sonra bu modl zerine dir() fonksiyonunu
uygularsanz, istisnasz her modln __name__ adl bir nitelii olduunu grrsnz.
__name__ nitelii iki farkl deer alabilir: inde bulunduu modln ad veya "__main__" adl
zel bir deer.
Eer bir Python program baka bir program iinden modl olarak ie aktarlyorsa,
__name__ niteliinin deeri o modln ad olacaktr.
Eer bir Python program dorudan bamsz bir program olarak altrlyorsa,
__name__ niteliinin deeri bu defa "__main__" olacaktr.
Gelin isterseniz bu durumu bir rnek zerinde somutlatralm.
[Link] adl bir dosya oluturup iine sadece unu yazalm:
Mesela masastnde
print(__name__)
708
Grdnz gibi, programmz dorudan almaya balad. Ama biz bunu istemiyoruz. Biz
istiyoruz ki, [Link] bir modl olarak aktarldnda almaya balamasn. Ama biz onun
iindeki nitelikleri kullanabilelim.
Bunun iin [Link] dosyasnda u deiiklii yapacaz:
szlk = {"kitap"
: "book",
"bilgisayar" : "computer",
"programlama": "programming"}
def ara(szck):
hata = "{} kelimesi szlkte yok!"
print([Link](szck, [Link](szck)))
def ekle(szck, anlam):
mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print([Link](szck))
def sil(szck):
try:
[Link](szck)
except KeyError as err:
print(err, "kelimesi bulunamad!")
else:
print("{} kelimesi szlkten silindi!".format(szck))
#BURAYA DKKAT!!!
if __name__ == '__main__':
no = input('Yapmak istediiniz ilemin numarasn girin: ')
print('1. Szlkte kelime ara')
print('2. Szle kelime ekle')
print('3. Szlkten kelime sil')
if no == '1':
szck = input('Aradnz szck: ')
ara(szck)
elif no == '2':
szck = input('Ekleyeceiniz szck: ')
anlam = input('Eklediiniz szcn anlam: ')
ekle(szck, anlam)
elif no == '3':
szck = input('Sileceiniz szck: ')
sil(szck)
else:
print('Yanl ilem')
Grdnz gibi, ok basit bir if deyimi yardmyla dosyamzn bamsz bir program
olarak m altrldn yoksa bir modl olarak ie mi aktarldn kontrol ettik. Eer
__name__ niteliinin deeri __main__ ise, yani programmz bamsz olarak altrlyorsa
709
if blou iindeki kodlar iletiyoruz. Eer bu niteliin deeri baka bir ey ise (yani modln
ad ise), bu durumda programmz bir modl olarak ie aktarlyor demektir. Bu durumda if
blou iindeki kodlar altrmyoruz...
Her eyin yolunda olup olmadn kontrol etmek iin szlk modln ie aktaralm:
>>> import szlk
import webbrowser
ykleyici = webbrowser.__loader__
kaynak = ykleyici.get_data(webbrowser.__file__)
kaynak
710
import subprocess
ad = subprocess.__spec__.name
konumu = subprocess.__spec__.origin
ad
'subprocess'
>>> konumu
'C:\\Pythonxy\\lib\\[Link]'
Tpk __loader__ gibi, bu nitelik de gnlk olarak kullanacamz bir ara deil. Bu niteliin
iindeki aralarn sunduu bilgileri baka yollardan da elde edebileceimizi biliyorsunuz.
711
BLM 42
42.1 Giri
imdiye kadar Python programlama dili ile ilgili olarak grdmz konulardan rendiimiz
ok nemli bir bilgi var: Aslna bakarsak, bu programlama dilinin btn felsefesi, bir kez
yazlan kodlarn en verimli ekilde tekrar tekrar kullanlabilmesi, krine dayanyor.
imdi bir geriye dnp baktmzda, esasnda bu krin izlerini ta ilk derslerimize kadar
srebiliyoruz. Mesela deikenleri ele alalm. Deikenleri kullanmamzdaki temel gereke,
bir kez yazdmz bir kodu baka yerlerde rahata kullanabilmek. rnein, isim = Uzun
hsan Efendi gibi bir tanmlama yaptktan sonra, bu isim deikeni araclyla Uzun
hsan Efendi adl karakter dizisini her defasnda tekrar tekrar yazmak zorunda kalmadan,
kodlarmzn her yannda kullanabiliyoruz.
Ayn krin fonksiyonlar ve geen blmde incelediimiz modller iin de geerli olduunu
bariz bir ekilde grebilirsiniz. Gml fonksiyonlar, kendi tanmladmz fonksiyonlar,
hazr modller, nc ahs modlleri hep belli bir karmak sreci basitletirme, bir kez
tanmlanan bir prosedrn tekrar tekrar kullanlabilmesini salama amac gdyor.
te bu kir nesne tabanl programlama ve dolaysyla snf (class ) ad verilen zel bir veri tipi
iin de geerlidir. Bu blmde, bunun neden ve nasl byle olduunu btn ayrntlaryla ele
almaya alacaz.
Bu arada, ngilizcede Object Oriented Programming olarak ifade edilen programlama
yaklam, Trkede Nesne Tabanl Programlama, Nesne Ynelimli Programlama ya da
Nesneye Ynelik Programlama olarak karlk bulur. Biz bu karlklardan, ad Nesne Tabanl
Programlama olan tercih edeceiz.
Unutmadan, nesne tabanl programlamaya girmeden nce deinmemiz gereken bir ey
daha var. Eer rendiiniz ilk programlama dili Python ise, nesne tabanl programlamay
renmenin (aslnda yle olmad halde) zor olduunu dnebilir, bu konuyu biraz
712
42.2 Snar
Nesne tabanl programlamann temelinde, yukardaki giri blmnde de adn andmz
snf (class ) adl bir kavram bulunur. Bu blmde, bu temel kavram hakkyla ele almaya
alacaz.
Peki tam olarak nedir bu snf denen ey?
ok kaba ve olduka soyut bir ekilde tanmlayacak olursak, snar, nesne retmemizi
salayan veri tipleridir. te nesne tabanl programlama, adndan da anlalaca gibi,
nesneler (ve dolaysyla snar) temel alnarak gerekletirilen bir programlama faaliyetidir.
Hibir ey anlamadm! dediinizi duyar gibiyim. nk yukardaki tanm, nesne ne
demek, snf ne anlama geliyor gibi sorulara cevap vermiyor. Yani programclk asndan
nesne ve snf kelimelerini burada ne anlamda kullandmz, yukardaki tanma bakarak
kestiremiyoruz. Eer siz de bu kirdeyseniz okumaya devam edin...
42.2. Snar
713
Dzgn bir ekilde alan, gayet basit kodlardr bunlar. Ayrca amacmz da kusursuz bir
ekilde yerine getirir. stelik kodlardaki btn eler tek bir isim/etki alan (namespace,
scope ) iinde bulunduu iin, bunlara eriimde hibir zorluk ekmeyiz. Yani mesela
sesli_harer, saya, kelime, harf, mesaj deikenlerine kodlar iinde her yerden eriebiliriz.
Not: Eer isim/etki alan ile ilgili sylediimiz eyi anlamadysanz endie etmeyin. Birazdan
vereceimiz rnekle durumu daha net kavrayacaksnz.
Ancak bu kodlarn nemli bir dezavantaj, kodlarda benimsediimiz yaklamn genilemeye
pek msait olmamasdr.
Daha dorusu, yukardaki kodlara yeni kodlar ekledike
programmz karmak hale gelecek, kodlar anlamak zorlaacaktr.
Kod yapsn biraz olsun rahatlatmak iin baz nlemler alabiliriz. Mesela kullanc tarafndan
girilen kelimedeki bir harn sesli olup olmadn denetleyen kodlar bir fonksiyon iine
alarak, o ksm daha belirgin hale getirebiliriz:
sesli_harfler = 'aeiou'
saya = 0
kelime = input('Bir kelime girin: ')
def seslidir(harf):
return harf in sesli_harfler
for harf in kelime:
if seslidir(harf):
saya += 1
714
Burada, kontrol ettiimiz harn sesli_harer adl deiken iinde bulunup bulunmamasna
gre True veya False kts veren, seslidir() adl bir fonksiyon tanmladk. Eer kontrol
ettiimiz harf sesli_harer deikeni iinde geiyorsa, yani bu bir sesli harf ise, seslidir()
fonksiyonu True kts verecektir. Aksi durumda ise bu fonksiyondan False kts alacaz.
Bylece sesli harf kontrol yapmak istediimiz her yerde yalnzca seslidir() fonksiyonunu
kullanabileceiz. Bu da bize, bir kez yazdmz kodlar tekrar tekrar kullanma imkan verecek.
Eer yukardaki kodlar daha da genel amal bir hale getirmek istersek, sayac artran kodlar
da bir fonksiyon iine almay dnebiliriz:
sesli_harfler = 'aeiou'
saya = 0
kelime = input('Bir kelime girin: ')
def seslidir(harf):
return harf in sesli_harfler
def artr():
global saya
for harf in kelime:
if seslidir(harf):
saya += 1
return saya
mesaj = '{} kelimesinde {} sesli harf var.'
print([Link](kelime, artr()))
Hatrlarsanz, ilk bata yazdmz kodlarn en byk avantajnn, kodlarda geen btn
elerin tek bir isim/etki alannda bulunmas olduunu sylemitik. Bu sayede btn elere
her yerden eriebiliyorduk. Yukardaki kodlarda ise birden fazla isim/etki alan var:
1. sesli_harer, saya, kelime ve mesaj deikenlerinin bulunduu global isim/etki alan.
2. seslidir() fonksiyonunun lokal isim/etki alan.
3. artr() fonksiyonunun lokal isim/etki alan.
Bildiiniz gibi, global isim alannda bulunan deikenlere her yerden ulaabiliyoruz. Ancak
bunlar her yerden deitiremiyoruz. Yani mesela global isim alannda bulunan saya
deikeninin deerini, seslidir() fonksiyonu iinden grntleyebiliriz.
Bunu teyit edelim:
sesli_harfler = 'aeiou'
saya = 0
kelime = input('Bir kelime girin: ')
def seslidir(harf):
print('saya deikeninin deeri u anda: ', saya)
return harf in sesli_harfler
def artr():
global saya
715
Grdnz gibi, global isim alanndaki saya deikeninin deerini seslidir() fonksiyonu
iinde kullanabildik. Ama eer bu deiken zerinde deiiklik yapacaksak ilave admlar
atmak zorundayz. Dolaysyla, mesela artr() fonksiyonunun etki alanndan, global etki
alanndaki saya deikeni zerinde deiiklik yapabilmek iin global deyimini kullanmamz
gerekiyor. Bu ekilde, global isim alannda bulunan saya adl deikenin deerini
artrabiliyoruz.
Dikkat ederseniz, artr() fonksiyonunda iki tane global deiken var: saya ve kelime. Ama
biz bunlardan yalnzca saya deikenini global olarak belirledik. br global deikenimiz
kelime iin ise bu ilemi yapmadk. nk kelime adl deikeni deitirmek gibi bir niyetimiz
yok. Biz bu deikeni sadece kullanmakla yetiniyoruz. O yzden bu deikeni global olarak
belirlemek zorunda deiliz.
Ancak bildiiniz gibi, global deyimini kullanmak pek tavsiye edilen bir ey deil. Eer siz de
bu deyimi kullanmak istemezseniz, yukardaki kodlar u ekilde yazmay yeleyebilirsiniz:
sesli_harfler = 'aeiou'
saya = 0
kelime = input('Bir kelime girin: ')
def seslidir(harf):
return harf in sesli_harfler
def artr(saya):
for harf in kelime:
if seslidir(harf):
saya += 1
return saya
mesaj = '{} kelimesinde {} sesli harf var.'
print([Link](kelime, artr(saya)))
716
def artr(n):
for harf in kelime:
if seslidir(harf):
n += 1
return n
mesaj = '{} kelimesinde {} sesli harf var.'
print([Link](kelime, artr(saya)))
nemli olan, artr() fonksiyonunun, bizim global isim alanyla iletiim kurmamz salayacak
bir parametre almas. Bu parametrenin adnn ne olduunun bir nemi yok.
Yukardaki kodlarda birka deiiklik daha yaparak, bu kodlar iyice geniletilebilir hale
getirebiliriz:
sesli_harfler = 'aeiou'
saya = 0
def kelime_sor():
return input('Bir kelime girin: ')
def seslidir(harf):
return harf in sesli_harfler
def artr(saya, kelime):
for harf in kelime:
if seslidir(harf):
saya += 1
return saya
def ekrana_bas(kelime):
mesaj = "{} kelimesinde {} sesli harf var."
print([Link](kelime, artr(saya, kelime)))
def altr():
kelime = kelime_sor()
ekrana_bas(kelime)
altr()
717
718
sesli_harfler = 'aeiou'
saya = 0
def kelime_sor():
return input('Bir kelime girin: ')
def seslidir(harf):
return harf in sesli_harfler
def artr(saya, kelime):
for harf in kelime:
if seslidir(harf):
saya += 1
return saya
def ekrana_bas(kelime):
mesaj = "{} kelimesinde {} sesli harf var."
print([Link](kelime, artr(saya, kelime)))
def altr():
kelime = kelime_sor()
ekrana_bas(kelime)
if __name__ == '__main__':
altr()
Bu listede, sayac modlne ait btn nitelik ve fonksiyonlar grebiliyoruz. Bunlar, baka
modllerde olduu gibi kullanma imkanna sahibiz.
719
Modllerin ne kadar faydal aralar olabileceini bu rnek gayet net bir ekilde gsteriyor.
Eer ileride sesli hareri kullanmamz gerektiren baka bir program yazacak olursak, bu
hareri yeniden tanmlamak yerine, [Link] dosyasndan ie aktarabiliriz.
Btn bu rnekler sayesinde, snar daha iyi anlamamz salayacak altyapy oluturmu,
bir yandan da eski bilgilerimizi pekitirmi olduk. Dilerseniz, snar anlatmaya gemeden
nce, yukarda verdiimiz kodlar sn bir yap iinde nasl ifade edebileceimizi de grelim.
Elbette aadaki kodlar anlamanz u aamada sizden beklemiyoruz. Bu blmn sonuna
vardmzda, zihninizde her ey berraklam olacak. Siz imdilik sadece aadaki kodlara
bakn ve hem okunakllk hem de ynetilebilirlik bakmndan bu kodlarn bize ne gibi faydalar
salyor olabileceine dair kir yrtmeye aln. Anlamadnz ksmlar olursa bunlar gein
gitsin. Anladnz ksmlar ise yannza kr kalsn.
class HarfSayac:
def __init__(self):
self.sesli_harfler = 'aeiou'
[Link] = 0
def kelime_sor(self):
return input('Bir kelime girin: ')
def seslidir(self, harf):
return harf in self.sesli_harfler
def artr(self):
for harf in [Link]:
if [Link](harf):
[Link] += 1
return [Link]
def ekrana_bas(self):
mesaj = "{} kelimesinde {} sesli harf var."
sesli_harf_says = [Link]()
print([Link]([Link], sesli_harf_says))
def altr(self):
720
[Link] = self.kelime_sor()
self.ekrana_bas()
if __name__ == '__main__':
saya = HarfSayac()
[Link]()
Hakknda herhangi bir kre sahip olmadnz bir kod parasn anlamann en iyi yolu,
anlamadnz ksm kodlardan karp, kodlar bir de o ekilde altrmaktr. Mesela
yukardaki __init__, self ve class gibi elerin ismini deitirin, bunlar kodlardan karn veya
baka bir yere koyun. Elde ettiiniz sonular gzlemleyerek bu kodlar hakknda en azndan
bir kir sahibi olabilirsiniz.
Gelin isterseniz, henz yukardaki kodlar anlayabilecek kadar snf bilgisine sahip olmasak
da, bu kodlar yle bir stnkr gzden geirerek, bu kodlarn programclk deneyimimiz
asndan bize ne gibi bir katk sunuyor olabileceini anlamaya alalm.
Yukardaki kodlarda dikkatimizi eken ilk ey, bu kodlarn son derece derli toplu grnyor
olmasdr. yle ki, HarfSayac adl snf iindeki fonksiyonlar sanki ipe dizilir gibi dizilmi.
HarfSayac adl snf ile bu snf yaps iinde yer alan fonksiyonlar arasndaki iliki gayet net
bir ekilde grnyor. Eer ileride bu sayaca yeni bir ilev eklemek istersek, neyi nereye
yerletirmemiz gerektii ok ak. Mesela ilerde bu kodlara sesli harerle birlikte bir de sessiz
harf denetim ilevi eklemek istersek, gerekli deiiklikleri kolayca yapabiliriz:
class HarfSayac:
def __init__(self):
self.sesli_harfler = 'aeiou'
self.sessiz_harfler = 'bcdfghjklmnprstvyz'
self.saya_sesli = 0
self.saya_sessiz = 0
def kelime_sor(self):
return input('Bir kelime girin: ')
def seslidir(self, harf):
return harf in self.sesli_harfler
def sessizdir(self, harf):
return harf in self.sessiz_harfler
def artr(self):
for harf in [Link]:
if [Link](harf):
self.saya_sesli += 1
if [Link](harf):
self.saya_sessiz += 1
return (self.saya_sesli, self.saya_sessiz)
def ekrana_bas(self):
sesli, sessiz = [Link]()
mesaj = "{} kelimesinde {} sesli {} sessiz harf var."
print([Link]([Link], sesli, sessiz))
def altr(self):
[Link] = self.kelime_sor()
self.ekrana_bas()
721
if __name__ == '__main__':
saya = HarfSayac()
[Link]()
Ayrca sn kodlarda, farkl etki alanlar ile iletiim kurmak, snfsz kodlara kyasla daha
zahmetsizdir. Sn ve snfsz kodlarda fonksiyonlara verdiimiz parametreleri birbirleri ile
kyaslayarak bu durumu kendiniz de grebilirsiniz.
Sn yaplarn daha pek ok avantajl yn vardr. te biz bu blmde bunlar size tek tek
gstermeye alacaz.
Yukardaki, bo bir snf tanmdr. Hatrlarsanz fonksiyonlar tanmlamak iin def adl
bir ifadeden yararlanyorduk. te snar tanmlamak iin de class adl bir ifadeden
yararlanyoruz. Bu ifadenin ardndan gelen alan kelimesi ise bu snfn addr.
Eer arzu ederseniz, yukardaki snf u ekilde de tanmlayabilirsiniz:
class alan():
pass
Yani snf adndan sonra parantez kullanmayabileceiniz gibi, kullanabilirsiniz de. Her ikisi
de ayn kapya kar. Ayrca snf adlarnda, yukarda olduu gibi byk harf kullanmak ve
birden fazla kelimeden oluan snf adlarnn ilk harerini byk yazp bunlar birletirmek
adettendir. Yani:
class alanSnf():
pass
722
... veya:
class Asker():
pass
rendiimize
gre,
bu
snar
nasl
Burada unvan ve kabiliyetleri adl iki deiken tanmladk. Teknik dilde bu deikenlere snf
nitelii (class attribute ) ad verilir.
Biraz nce, snf tanmlamay renirken snf tanmlamann fonksiyon tanmlamaya ok
benzediini sylemitik. Gerekten de yledir. Ancak fonksiyonlarla snar arasnda (baka
farklarn dnda) ok nemli bir fark bulunur. Bildiiniz gibi, bir fonksiyonu tanmladktan
sonra, o fonksiyonun ilemeye balamas iin, o fonksiyonun mutlaka arlmas gerekir.
arlmayan fonksiyonlar almaz. Mesela yukardaki snfa benzeyen yle bir fonksiyon
tanmladmz dnn:
def alan():
kabiliyetleri = []
unvan = 'ii'
print(kabiliyetleri)
print(unvan)
Ancak snar farkldr. Bunu grmek iin yukardaki fonksiyonu bir snf haline getirelim:
723
class alan():
kabiliyetleri = []
unvan = 'ii'
print(kabiliyetleri)
print(unvan)
Eer snf niteliklerinin ne zaman alacan kendiniz kontrol etmek isterseniz, bu nitelikleri
snf dnda kullanabilirsiniz:
class alan():
kabiliyetleri = []
unvan = 'ii'
print([Link])
print([Link])
Burada alan() adl snfn niteliklerine nasl eritiimize dikkat edin. Grdnz gibi,
snf niteliklerine erimek iin dorudan snfn adn parantezsiz bir ekilde kullanyoruz.
Eer snf adlarn parantezli bir ekilde yazarsak baka bir ey yapm oluruz. Bundan biraz
sonra bahsedeceiz. Biz imdilik, snf niteliklerine erimek iin snf adlarn parantezsiz
kullanmamz gerektiini bilelim yeter.
Hatrlarsanz, bu blme balarken, nesne tabanl programlama yaklamnn, zellikle
birtakm ortak niteliklere ve davran ekillerine sahip gruplar tanmlamak gerektiinde son
derece kullanl olduunu sylemitik. Gelin isterseniz yukardaki alan() snfna birka
nitelik daha ekleyerek bu iddiamz destekleyelim:
class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''
Burada belli kabiliyetleri, unvan, maa, memleketi ve doum_tarihi olan bir alan() snf
tanmladk. Yani alan adl bir grubun ortak niteliklerini belirledik. Elbette her alann
memleketi ve doum tarihi farkl olaca iin snf iinde bu deikenlere belli bir deer
atamadk. Bunlarn birer karakter dizisi olacan belirten bir iaret olmas iin yalnzca
memleketi ve doum_tarihi adl birer bo karakter dizisi tanmladk.
Yukarda tanmladmz snf niteliklerine, dorudan snf adn kullanarak eriebileceimizi
biliyorsunuz:
724
print([Link])
print([Link])
print(alan.doum_tarihi)
Gayet gzel...
Ancak burada yle bir sorun var: Biz yukardaki gibi dorudan snf adn kullanarak elere
eritiimizde kodlarmz tek kullanmlk olmu oluyor. Yani bu ekilde ancak tek bir alan()
nesnesi (nesne kavramna ilerde deineceiz), dolaysyla da tek bir alan oluturma imkan
elde edebiliyoruz. Ama biz, mantken, snf iinde belirtilen zellikleri tayan, Ahmet,
Mehmet, Veli, Selim, Selin ve buna benzer, istediimiz sayda alan oluturabilmeliyiz. Peki
ama nasl?
Daha nce de sylediimiz gibi, snar belli birtakm ortak zelliklere sahip gruplar
tanmlamak iin biilmi kaftandr. Burada da, herbir alan iin ortak birtakm nitelikler
tanmlayan alan() adl bir snf oluturduk. Ancak elbette bu snfn bir ie yarayabilmesi
iin, biraz nce de deindiimiz gibi, bu snf temel alarak, bu snfta belirtilen nitelikleri
tayan birden fazla snf yesi meydana getirebilmemiz lazm.
imdi dikkatlice bakn:
class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''
ahmet = alan()
725
class Asker():
rtbesi = 'Er'
standart_tehizat = ['G3', 'kasatura', 'sng', 'el bombas']
gc = 60
birlii = ''
Burada da belli birtakm niteliklere sahip Asker() adl bir snf tanmladk.
niteliklerine dorudan snf adn kullanarak eriebileceimizi biliyorsunuz:
Bu snfn
[Link]
Asker.standart_tehizat
[Link]
[Link]
Ama bu snfn bir ie yarayabilmesi iin, bu snfa bir referans oluturmamz lazm, ki daha
sonra bu snfa bu referans zerinden atfta bulunabilelim. Yani bu snf arrken buna bir
isim vermeliyiz, ki bu isim zerinden snfa ve niteliklerine eriebilelim.
Mesela bu snfa daha sonra atfta bulunabilmek amacyla, bu snf iin mehmet adl bir
referans noktas oluturalm:
mehmet = Asker()
te, teknik olarak ifade etmemiz gerekirse, snar bir isme atama ilemine rnekleme (veya
rneklendirme) ad veriyoruz.
Burada ahmet ve mehmet, ait olduklar snarn birer sureti veya baka bir deyile
rneidir (instance ). mehmet in, Asker() adl snfn bir rnei, ahmet inse alan() adl
snfn bir rnei olmas demek, mehmet in ve ahmet in, ilgili snarn btn zelliklerini
tayan birer yesi olmas demektir.
Uyar:
Bu balamda rnek kelimesini misal anlamnda kullanmadmza zellikle
dikkatinizi ekmek isterim. Trkede rnek kelimesi ile karladmz instance kavram,
nesne tabanl programlamann nemli teknik kavramlarndan biridir.
Biz bir snf ardmzda (yani Asker() veya alan() komutunu verdiimizde), o snf
rneklemi oluyoruz. rneklediimiz snf bir deikene atadmzda ise o snfn bir rneini
karm, yani o snfn btn zelliklerini tayan bir ye meydana getirmi oluyoruz.
Bu arada, elbette bu teknik terimleri ezberlemek zorunda deilsiniz. Ancak nesne tabanl
programlamaya ilikin metinlerde bu terimlerle sk sk karlaacaksnz. Eer bu terimlerin
anlamn bilirseniz, okuduunuz ey zihninizde daha kolay yer edecek, aksi halde, srekli
ne demek olduunu bilmediiniz terimlerle karlamak renme motivasyonunuza zarar
verecektir.
Esasnda nesne tabanl programlamay rencilerin gznde zor klan ey, bu programlama
yaklamnn znden ziyade, ierdii terimlerdir. Gerekten de nesne tabanl programlama,
pek ok etrelli teknik kavram bnyesinde barndran bir sistemdir. Bu nedenle renciler
bu konuya ilikin bir eyler okurken, mulak kavramlarn arasnda kaybolup konunun
esasn gzden karabiliyor. Eer nesne tabanl programlamaya ilikin kavramlar hakkyla
anlarsanz, bu yaklama dair nemli bir engeli amsnz demektir.
te yandan, nesne tabanl programlamaya ilikin kavramlar anlamak sadece Trke okuyup
yazanlar iin deil, ayn zamanda ngilizce bilip ilgili makaleleri zgn dilinden okuyanlar iin
de zor olabilir. O yzden biz bu blmde, kavramlarn Trkeleri ile birlikte ngilizcelerini
726
de vererek, ngilizce bilenlerin zgn metinleri okurken konuyu daha iyi anlamalarn
salamaya alacaz. Dolaysyla, bir kavramdan bahsederken onun aslnn ne olduunu da
belirtmemiz, ngilizce bilip de konuyu daha ileri bir dzeyde aratrmak isteyenlere kolaylk
salayacaktr.
Ne diyorduk? Eer elimizde yle bir kod varsa:
class Sipari():
firma = ''
miktar = 0
sipari_tarihi = ''
teslim_tarihi = ''
stok_adedi = 0
jilet = Sipari()
Burada class, snf tanmlamamza yarayan bir edir. Tpk fonksiyonlardaki def gibi, snar
tanmlamak iin de class adl bir parac kullanyoruz.
Sipari ise, snfmzn ad oluyor. Biz snfmzn adn parantezli veya parantezsiz olarak
kullanma imkanna sahibiz.
Snfn gvdesinde tanmladmz u deikenler birer snf niteliidir (class atribute ):
firma = ''
miktar = 0
sipari_tarihi = ''
teslim_tarihi = ''
stok_adedi = 0
jilet = Sipari() komutunu verdiimizde ise, biraz nce tanmladmz snf rnekleyip
(instantiation ), bunu jilet adl bir rnee (instance ) atam oluyoruz. Yani jilet, Sipari() adl
snfn bir rnei olmu oluyor. Bir snftan istediimiz sayda rnek karabiliriz:
kalem = Sipari()
pergel = Sipari()
ikolata = Sipari()
Bu ekilde Sipari() snfn kez rneklemi, yani bu snfn btn zelliklerini tayan
farkl ye meydana getirmi oluyoruz.
Bu snf rneklerini kullanarak, ilgili snfn niteliklerine (attribute ) eriebiliriz:
kalem = Sipari()
[Link]
[Link]
kalem.sipari_tarihi
kalem.teslim_tarihi
kalem.stok_adedi
Bildiiniz gibi, eritiimiz bu nitelikler birer snf nitelii olduu iin, snf hi rneklemeden,
bu niteliklere dorudan snf ad zerinden de eriebilirdik:
[Link]
[Link]
Sipari.sipari_tarihi
727
Sipari.teslim_tarihi
Sipari.stok_adedi
zellikle, rneklenmesine gerek olmayan, yalnzca bir kez alacak snarda, snf
niteliklerine rnekler zerinden deil de dorudan snf ad zerinden erimek daha pratik
olabilir. Ancak yukarda olduu gibi, tek bir snftan, ortak niteliklere sahip birden fazla
ye oluturmamz gereken durumlarda snf bir rnee atayp, snf niteliklerine bu rnek
zerinden erimek ok daha akllca olacaktr. Ancak her koulda snarn niteliklerine
dorudan snf adlar zerinden erimek yerine rnekler zerinden erimeyi tercih etmenizin
de hibir sakncas olmadn bilin.
Gelin imdi yukarda rendiklerimizi kullanarak ufak tefek uygulama almalar yapalm.
Snfmz u olsun:
class Sipari():
firma = ''
miktar = 0
sipari_tarihi = ''
teslim_tarihi = ''
stok_adedi = 0
Bildiiniz gibi, ufak tefek kod almalar yapmak iin Pythonn etkileimli kabuu son derece
uygun bir ortamdr. O halde yukardaki snf [Link] adl bir dosyaya kaydedelim, bu
dosyann bulunduu konumda bir etkileimli kabuk ortam aalm ve [Link] dosyasn bir
modl olarak ie aktaralm:
>>> import sipari
Bylece sipari modl iindeki nitelik ve metotlara eriim saladk. Bunu teyit edelim:
>>> dir(sipari)
['Sipari', '__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__']
Sipari() adl snf listenin en banda grebilirsiniz. O halde gelin bu snf rnekleyerek
kullanlabilir hale getirelim:
>>> gofret = [Link]()
Elbette Sipari() adl snf sipari adl modl iinde bulunduundan, bu snfa sipari
nekiyle eriiyoruz. Tabii biz isteseydik modl u ekilde de ie aktarabilirdik:
>>> from sipari import Sipari
Ancak mevcut isim alann kirletmemek ve bu alan nereden geldii belli olmayan birtakm
nitelik ve metotlarla doldurmamak iin biz import modl_ad biimini tercih ediyoruz. Aksi
halde, bu kodlar okuyanlar, Sipari() adl snfn sipari adl bir modle ait olduunu
anlamayacak, bu snf ilk olarak mevcut dosya iinde bulmaya alacaklardr. Ama biz modl
adn snf adna eklediimizde modln nereden geldii gayet ak bir ekilde anlalabiliyor.
Bylece hem kodlar okuyan bakalarnn iini hem de birka ay sonra kendi kodlarmza
tekrar bakmak istediimizde kendi iimizi kolaylatrm oluyoruz.
728
Grdnz gibi, snf iinde tanmladmz btn snf nitelikleri (rma, miktar,
sipari_tarihi, stok_adedi ve teslim_tarihi ) bu liste iinde var.
Bu snf niteliklerinden, ad rma olan kullanarak sipariin hangi rmadan yaplacan
belirleyebiliriz:
>>> [Link] = 'z stihza ve erikleri Gda, Ticaret Anonim irketi'
Bylece, snf iindeki bir nitelie yeni bir deer atam olduk. sterseniz ipari miktarn da
belirleyelim:
>>> [Link] = 1000
teki snf niteliklerini de ihtiyacnza gre ayarlayabilir, hatta bu snfa yeni nitelikler de
ekleyebilirsiniz.
Gelin isterseniz pratik olmas bakmndan bir rnek daha verelim.
Elimizde yle bir snf olsun:
class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''
729
print([Link])
print([Link])
print([Link])
print([Link])
print([Link])
print(aye.doum_tarihi)
imdi burada bir duralm. nk burada ok sinsi bir sorunla kar karyayz. Dikkatlice
bakn.
alan() snf iin bir ahmet rnei oluturalm:
ahmet = alan()
Grdnz gibi, yalnzca ahmet rneine eklemek istediimiz prezantabl kabiliyeti selim
rneine de eklenmi. Ancak normal artlarda arzu edilen bir ey deildir bu. Zira bu durum
aslnda programmzdaki bir tasarm hatasna iaret eder. Peki ama bu durumun sebebi
nedir?
Hatrlarsanz, snf niteliklerinden bahsederken, bu niteliklerin nemli bir zelliinin, snf
arlmadan almaya balamalar olduunu sylemitik. Snf niteliklerinin bir baka nemli
zellii de, bu niteliklere atanan deerlerin ve eer yaplabiliyorsa bu deerler zerinde
sonradan yaplan deiikliklerin o snfn btn rneklerini etkiliyor olmasdr. Eer ilgili
snf nitelii; karakter dizisi, demet ve say gibi deitirilemeyen (immutable ) bir veri tipi
ise bu snf nitelii zerinde zaten deiiklik yapamazsnz. Yaptnz ey ancak ilgili snf
niteliini yeniden tanmlamak olacaktr. Ancak eer snf nitelii, liste, szlk ve kme gibi
deitirilebilir (mutable ) bir veri tipi ise bu nitelik zerinde yapacanz deiiklikler btn
snf rneklerine yansyacaktr. Yazdnz program asndan bu zellik arzu ettiiniz bir ey
olabilir veya olmayabilir. nemli olan, snf niteliklerinin bu zelliinin farknda olmanz
ve kodlarnz bu bilgi erevesinde yazmanzdr. Mesela yukardaki rnekte kabiliyetleri
listesine eklenen elerin btn rneklere yansmas istediimiz bir ey deil. Ama eer
snfmz yle olsayd:
730
class alan():
personel_listesi = []
Burada personel_listesi adl bir snf nitelii tanmladk. Eer bu listenin, personele eklenen
btn elemanlar barndrmasn planlyorsak bu listenin her rneklemede bymesi elbette
istediimiz bir ey olacaktr.
Peki o halde biz deerinin her rnekte ortak deil de her rnee zg olmasn istediimiz
nitelikleri nasl tanmlayacaz? Elbette snf nitelikleri yerine rnek nitelikleri denen baka bir
kavramdan yararlanarak...
rnek niteliklerini tanmlamak iin ise iki yardmc araca ihtiyacmz var:
fonksiyonu ve self.
__init__()
731
Bu kodlar altrdmz anda ekrana merhaba kts verilecektir. rnek nitelikleri ise
farkldr:
class alan():
def __init__(self):
[Link] = []
print([Link])
nk [Link] bir snf nitelii deil, bir rnek niteliidir. rnek niteliklerine
eriebilmek iin de ilgili snf mutlaka rneklememiz gerekir. Ayrca snf niteliklerinin
aksine, rnek niteliklerine snf adlar zerinden eriemeyiz. Yani [Link] adl rnek
niteliine erimeye ynelik yle bir giriim bizi hsrana uratacaktr:
[Link]
iin,
ahmet = alan()
ahmet = alan() kodu yardmyla, alan snfnn bir rneini kardk ve buna ahmet
adn verdik. te tam bu anda __init__() fonksiyonu almaya balad ve ahmet rnei
iin, kabiliyetleri adl bo bir rnek nitelii oluturdu.
Peki yukarda kodlarmz yazarken __init__() fonksiyonuna parametre olarak verdiimiz ve
kabiliyetleri listesinin banda kullandmz self kelimesi ne oluyor?
ncelikle bilmemiz gereken ey, self kelimesinin, Python programlama dilinin sz diziminin
gerektirdii bir e olduudur. Bu kelime, alan() adl snfn rneklerini temsil eder. Peki
self kelimesinin bir snfn rneklerini temsil ediyor olmas ne anlama geliyor?
Bildiiniz gibi, bir snfn rneini u ekilde karyoruz:
732
ahmet = alan()
Bu ahmet rneini kullanarak, alan() snfnn iindeki kabiliyetleri adl rnek niteliine
snf dndan eriebiliriz:
print([Link])
te self kelimesi, yukardaki kodda yer alan ahmet kelimesini temsil ediyor. Yani
[Link] eklinde bir kod yazabilmemizi salayan ey, __init__() fonksiyonu
iinde belirttiimiz self kelimesidir. Eer bu kelimeyi kullanmadan yle bir kod yazarsak:
class alan():
def __init__():
kabiliyetleri = []
Burada __init__() fonksiyonunda ilk parametre olarak self i belirttik. Ama kabiliyetleri
niteliinin bana self eklemedik. Dolaysyla yazdmz kodlar yine hata verdi. nk,
[Link] eklinde ifade ettiimiz kodlardaki ahmet kelimesini karlayacak
herhangi bir e snf iinde bulunmuyor...
Bu arada, rnek isimlerini (mesela ahmet ) yalnzca rnek niteliklerine erimek iin
kullanmyoruz. Bunlar ayn zamanda snf niteliklerine erimek iin de kullanabiliyoruz.
Dolaysyla eer yukardaki snf tanm iinde, [Link] adl rnek nitelii nin yansra
personel adl bir snf nitelii de bulunsayd:
class alan():
personel = ['personel']
def __init__(self):
[Link] = []
u kodlar yazdmzda:
ahmet = alan()
print([Link])
...o snf niteliine eriebilirdik. Ancak eer __init__() fonksiyonu altndaki kabiliyetleri
niteliine erimek istiyorsak, bu niteliin bana self kelimesini getirerek, bu nitelii bir rnek
nitelii haline getirmeli ve bylece, [Link] kodundaki ahmet kelimesini temsil
edecek bir eyi snf iinde oluturmalyz.
Bu sre tam olarak yle iler:
733
Biz [Link] eklinde bir komut verdiimizde, Python ilk olarak ilgili snfn
__init__() fonksiyonu iinde kabiliyetleri adl bir rnek nitelii arar. Elbette Pythonn
bu rnek niteliini bulabilmesi iin, __init__() fonksiyonu iinde, bu fonksiyonun ilk
parametresi ile ayn neki tayan bir niteliin yer almas gerekir. Yani eer __init__()
fonksiyonunun ilk parametresi self ise, Python bu fonksiyon iinde [Link] adl bir
rnek nitelii bulmaya alr. Eer bulamazsa, Python bu kez kabiliyetleri adl bir snf nitelii
arar. Eer onu da bulamazsa tabii ki hata verir...
Gelin isterseniz bu mekanizmay teyit edelim:
class alan():
kabiliyetleri = ['snf nitelii']
def __init__(self):
[Link] = ['rnek nitelii']
Grdnz gibi, burada ayn ad tayan bir snf nitelii ile bir rnek niteliimiz var.
Pythonda hem snf niteliklerine, hem de rnek niteliklerine rnek isimleri zerinden
eriebileceimizi sylemitik. Yani eer rneimizin ismi ahmet ise, hem kabiliyetleri adl
snf niteliine hem de [Link] adl rnek niteliine ayn ekilde eriiyoruz:
ahmet = alan()
print([Link])
Peki ama acaba yukardaki kodlar bize rnek niteliini mi verir, yoksa snf niteliini mi?
Byle bir durumda, yukarda bahsettiimiz mekanizma nedeniyle, [Link]
eklinde ifade ettiimiz rnek nitelii, kabiliyetleri adl snf niteliini glgeler. Bu yzden de
print([Link]) komutu, rnek niteliini, yani [Link] listesini verir.
Yukardaki kodlar altrarak siz de bu durumu teyit edebilirsiniz. Zira bu kodlar bize,
[Link] listesinin deeri olan rnek nitelii ktsn verecektir...
Peki ya siz snf nitelii olan kabiliyetleri listesine erimek isterseniz ne olacak?
te bunun iin, snf rneini deil de, snf adn kullanacaksnz:
class alan():
kabiliyetleri = ['snf nitelii']
def __init__(self):
[Link] = ['rnek nitelii']
#snf niteliine erimek iin
#snf adn kullanyoruz
print([Link])
#rnek niteliine erimek iin
#rnek adn kullanyoruz
ahmet = alan()
print([Link])
Ancak elbette, ayn ad tayan bir snf nitelii ile bir rnek niteliini ayn snf iinde
tanmlamak daha batan iyi bir kir deildir, ama yazdnz bir snf yanllkla ayn ada
sahip snf ve rnek nitelikleri tanmlamanz nedeniyle beklenmedik bir kt veriyorsa, siz
Pythonn bu zelliinden haberdar olduunuz iin, hatann nereden kaynaklandn kolayca
kestirebilirsiniz.
Szn ksas, Pythonn sz dizimi kurallar asndan, eer bir rnek nitelii tanmlyorsak, bu
734
niteliin bana bir self getirmemiz gerekir. Ayrca bu self kelimesini de, rnek niteliinin
bulunduu fonksiyonun parametre listesinde ilk sraya yerletirmi olmalyz. Unutmayn,
rnek nitelikleri sadece fonksiyonlar iinde tanmlanabilir. Fonksiyon dnda rnek nitelii
tanmlayamazsnz. Yani yle bir ey yazamazsnz:
class alan():
self.n = 0
def __init__(self):
[Link] = []
nk self kelimesi ancak ve ancak, iinde getii fonksiyonun parametre listesinde ilk srada
kullanldnda anlam kazanr.
Bu noktada size ok nemli bir bilgi verelim: Python snarnda rnek niteliklerini temsil
etmesi iin kullanacanz kelimenin self olmas art deildir. Bunun yerine istediiniz baka
bir kelimeyi kullanabilirsiniz. Mesela:
class alan():
def __init__(falanca):
[Link] = []
Dediimiz gibi, self kelimesi, bir snfn rneklerini temsil ediyor. Siz snf rneklerini
hangi kelimenin temsil edeceini kendiniz de belirleyebilirsiniz. Mesela yukardaki rnekte,
__init__() fonksiyonunun ilk parametresini falanca olarak belirleyerek, rnek niteliklerinin
falanca kelimesi ile temsil edilmesini salam olduk. Pythonda bu konuya ilikin kural udur:
Snf iindeki bir fonksiyonun ilk parametresi ne ise, o fonksiyon iindeki rnek niteliklerini
temsil eden kelime de odur. rnein, eer yle bir snf tanmlamsak:
class XY():
def __init__(a, b, c):
a.rnek_nitelii = []
Burada __init__() fonksiyonunun ilk parametresi a olduu iin, rnek niteliini temsil eden
kelime de a olur. Dolaysyla rnek_nitelii adl rnek niteliimizin bana da nek olarak bu
a kelimesini getiriyoruz.
__init__() fonksiyonunun ilk parametresi a olarak belirlendikten sonra, bu fonksiyon
iindeki btn rnek nitelikleri, nek olarak a kelimesini alacaktr:
class XY():
def __init__(a, b, c):
a.rnek_nitelii1 = []
a.rnek_nitelii2 = 23
a.rnek_nitelii3 = 'istihza'
ANCAK! Her ne sebeple olursa olsun, rnek niteliklerini temsil etmek iin self dnda bir
kelime kullanmayn. Python bu kelimeyi bize dayatmasa da, self kullanm Python topluluu
iinde ok gl ve sk skya yerlemi bir gelenektir. Bu gelenei kimse bozmaz. Siz de
bozmayn.
Szn z, tek bana self kelimesinin hibir anlamnn olmadn asla aklnzdan karmayn.
Bu kelimenin Python asndan bir anlam kazanabilmesi iin, ilgili fonksiyonun parametre
listesinde ilk srada belirtiliyor olmas lazm. Zaten bu yzden, dediimiz gibi, self kelimesinin
Python asndan bir zellii yoktur. Yani yle bir kod yazmamzn, Python sz dizimi
asndan hibir sakncas bulunmaz:
735
class alan():
def __init__(osman):
[Link] = []
nk Python, rnek niteliklerini temsil eden kelimenin ne olduuyla asla ilgilenmez. Python
iin nemli olan tek ey, temsil ii iin herhangi bir kelimenin belirlenmi olmasdr. Tabii,
biz, daha nce de srarla sylediimiz gibi, rnek niteliklerini self dnda bir kelime ile temsil
etmeye teebbs etmeyeceiz ve kodlarmz u ekilde yazmaktan amayacaz:
class alan():
def __init__(self):
[Link] = []
Biz bu snf iindeki kabiliyetleri listesine ekleme yaptmzda, bu durum o snfn btn
rneklerini etkiliyordu.
Yukardaki kodlar [Link] adl bir dosyaya kaydettiimizi varsayarsak:
>>>
>>>
>>>
>>>
import deneme
ahmet = [Link]()
[Link]('konukan')
[Link]
['konukan']
>>> mehmet = [Link]()
>>> print([Link])
['konukan']
import deneme
ahmet = [Link]()
[Link]('konukan')
[Link]
['konukan']
>>> mehmet = [Link]()
>>> print([Link])
[]
736
Grdnz gibi, ahmet rneine eklediimiz konukan esi, olmas gerektii gibi, mehmet
rneinde bulunmuyor. Birazdan bu konu zerine birka kelam daha edeceiz.
Snfmz tanmladk.
Gelin isterseniz bu kodlar aklamaya balamadan nce nasl
kullanacamz grelim.
Bildiiniz gibi, Python kodlarn test etmenin en iyi yolu, bunlar etkileimli kabuk zerinde
altrmaktr. zellikle bir program yazarken, tasarladnz snarn, fonksiyonlarn
ve teki elerin dzgn alp almadn test etmek iin etkileimli kabuu sklkla
kullanacaksnz.
O halde, yukardaki kodlar barndran dosyann bulunduu dizin altnda bir etkileimli kabuk
oturumu balatalm ve dosya adnn [Link] olduunu varsayarak kodlarmz bir modl
eklinde ie aktaralm:
>>> import alan
737
>>> 2 = [Link]('Mehmet')
Mehmet adl kii personele eklendi
Bu ekilde alan adl modl iindeki alan() adl snf srasyla Ahmet ve Mehmet
parametreleri ile ararak 1 ve 2 adl iki farkl snf rnei oluturmu olduk. Bu arada,
snfmz rneklediimiz anda __init__() fonksiyonunun devreye girdiine dikkat ediyoruz.
personele_ekle() adl fonksiyonu self.personele_ekle() eklinde __init__() fonksiyonu
iinden ardmz iin, snfmz rneklediimiz anda hem personelin kendisi personel
listesine eklendi, hem de bu kiinin personele eklendiine dair bir mesaj gsterildi.
Tanmladmz snfn niteliklerine, kardmz rnekler zerinden eriebiliriz:
>>> [Link]
'Ahmet'
>>> [Link]
'Mehmet'
738
Grdnz gibi, bir snf rneine eklediimiz kabiliyet teki snf rneklerine karmyor. Bu,
rnek niteliklerinin snf niteliklerinden nemli bir farkdr. Zira snf nitelikleri bir snfn btn
rnekleri tarafndan paylalr. Ama rnek nitelikleri her bir rnee zgdr. Bu zellikten
biraz sonra daha ayrntl olarak sz edeceiz. Biz imdilik okumaya devam edelim.
Snf rneklerimizin herhangi biri zerinden personel listesine de ulaabileceimizi biliyoruz:
>>> 1.personeli_grntle()
Personel listesi:
Mahmut
Mehmet
Gayet gzel...
Yukarda anlattklarmz snar hakknda size epey kir vermi olmal. Konuyu daha da
derinlemesine anlayabilmek iin, artk bu snf incelemeye geebiliriz.
Snfmz nmze alalm:
class alan():
personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
def personeli_grntle(self):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
Snf niteliklerinin zellii, o snfn btn rnekleri tarafndan paylalyor olmasdr. Yani
herhangi bir rnein bu nitelik zerinde yapt deiiklik, teki rneklere de yansyacaktr.
Hele bir de bu snf nitelii, listeler gibi deitirilebilir (mutable ) bir veri tipi ise, bu durum
hi de istemediiniz sonular dourabilir. Bununla ilgili bir rnei yukarda vermitik.
42.9. rnek Metotlar
739
Hatrlarsanz, kabiliyetleri adl, liste veri tipinde bir snf nitelii oluturduumuzda, bu listeye
eklediimiz eler, hi istemediimiz halde br rneklere de sirayet ediyordu. Elbette,
snf niteliklerinin bu zellii, o anda yapmaya altnz ey asndan gerekli bir durum
da olabilir. Mesela yukardaki kodlarda, listelerin ve snf niteliklerinin bu zellii bizim
amacmza hizmet ediyor. Yukardaki snf altrdmzda, eklenen her bir kiiyi bu personel
listesine ilave edeceiz. Dolaysyla bu nitelik zerinde yaplan deiikliklerin btn rneklere
yansmas bizim istediimiz bir ey.
Neyse... Laf daha fazla uzatmadan, kodlarmz aklamaya kaldmz yerden devam edelim...
Snfmz ve snf niteliimizi tanmladktan sonra __init__() adl zel fonksiyonumuzu
oluturuyoruz:
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
Burada snfmz Ahmet adl bir argmanla rneklediimize dikkatinizi ekmek isterim.
te bu argman, biraz nce __init__() fonksiyonunu tanmlarken belirttiimiz isim
parametresine karlk geliyor. Dolaysyla, bir snf arrken/rneklerken kullanacamz
argmanlar, bu __init__() fonksiyonunun parametreleri olarak tanmlyoruz.
Daha sonra bu isim parametresini, __init__() fonksiyonunun gvdesi iinde bir rnek
nitelii haline getiriyoruz:
[Link] = isim
Burada, personele_ekle() adl bir rnek metoduna (instance method ) atfta bulunuyoruz.
rnek metotlar, bir snfn rnekleri vastasyla arlabilen fonksiyonlardr.
Bu
fonksiyonlarn ilk parametresi her zaman self kelimesidir. Ayrca bu fonksiyonlara snf iinde
atfta bulunurken de yine self kelimesini kullanyoruz. Tpk yukardaki rnekte olduu gibi...
Bir rnek metodu olduunu sylediimiz personele_ekle() fonksiyonunu u ekilde
tanmladk:
740
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
Burada, bir snf nitelii olan personel deikenine nasl eritiimize ok dikkat etmenizi
istiyorum. Daha nce de sylediimiz gibi, snf niteliklerine snf dndayken rnekler
zerinden eriebiliyoruz. self kelimesi, bir snfn rneklerini temsil ettii iin, bir rnek
niteliine snf iinden erimemiz gerektiinde self kelimesini kullanabiliriz.
Snf niteliklerine, rnekler dnda, snf adyla da eriebileceinizi biliyorsunuz. Dolaysyla
isterseniz yukardaki kodlar yle de yazabilirdiniz:
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
Bir ncekinden farkl olarak, bu defa snf niteliine dorudan snf adn (alan ) kullanarak
eritik.
Ayrca bu fonksiyonda, bir rnek nitelii olan [Link] deikenine de eriebiliyor
olduumuza dikkat edin. Unutmayn, self snarn ok nemli bir esidir. Bu eyi
kullanarak hem rnek niteliklerine, hem snf niteliklerine, hem de rnek metotlarna
ulaabiliyoruz. Tanmladmz bu personele_ekle() adl rnek metodunu __init__()
fonksiyonu iinden self.personele_ekle() kodu ile (yani yine self kelimesini kullanarak)
ardmz hatrlyorsunuz.
personele_ekle() fonksiyonunun ardndan arka arkaya fonksiyon daha tanmladk:
def personeli_grntle(self):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
741
self.saya_sessiz = 0
def kelime_sor(self):
return input('Bir kelime girin: ')
def seslidir(self, harf):
return harf in self.sesli_harfler
def sessizdir(self, harf):
return harf in self.sessiz_harfler
def artr(self):
for harf in [Link]:
if [Link](harf):
self.saya_sesli += 1
if [Link](harf):
self.saya_sessiz += 1
return (self.saya_sesli, self.saya_sessiz)
def ekrana_bas(self):
sesli, sessiz = [Link]()
mesaj = "{} kelimesinde {} sesli {} sessiz harf var."
print([Link]([Link], sesli, sessiz))
def altr(self):
[Link] = self.kelime_sor()
self.ekrana_bas()
if __name__ == '__main__':
saya = HarfSayac()
[Link]()
Daha sonra, __init__() fonksiyonu iinde drt adet rnek nitelii tanmladk:
self.sesli_harfler = 'aeiou'
self.sessiz_harfler = 'bcdfghjklmnprstvyz'
self.saya_sesli = 0
self.saya_sessiz = 0
Bunlarn birer rnek nitelii olduunu, balarna getirdiimiz self kelimesinden anlyoruz.
nk bildiiniz gibi, self kelimesi, ilgili snfn rneklerini temsil ediyor. Bir snf iinde rnek
niteliklerine ve rnek metotlarna hep bu self kelimesi araclyla eriiyoruz.
Bu snf iinde, ilk parametreleri self olan u rnek metotlarn gryoruz:
742
def kelime_sor(self):
...
def seslidir(self, harf):
...
def sessizdir(self, harf):
...
def artr(self):
...
def ekrana_bas(self):
...
def altr(self):
...
Buna gre, eer programmz bamsz olarak altrlyorsa ncelikle HarfSayac() adl snf
rneklendiriyoruz:
saya = HarfSayac()
Daha sonra da saya rnei zerinden HarfSayac() adl snfn altr() metoduna
erierek programmz balatyoruz.
Bylece, Pythonda nesne tabanl programlama ve snara dair renmemiz gereken btn
temel bilgileri edinmi olduk. u ana kadar rendikleriniz sayesinde, etrafta greceiniz
sn kodlarn byk blmn anlayabilecek durumdasnz. Bir sonraki blmde, nesne
tabanl programlamann ayrntlarna inmeye balayacaz.
743
BLM 43
744
def personeli_grntle(self):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
745
Ancak kodlarn alma mant asndan burada bir tutarszlktan sz edebiliriz. Genel
olarak btn personele dair bilgi veren bir fonksiyona ahmet, mehmet, aye gibi bireysel
rnek deikenleri zerinden erimek kulaa sizce de biraz tuhaf gelmiyor mu? Neticede
bu fonksiyon, aslnda snfn herhangi bir rnei ile zellikle veya dorudan ilikili deil.
Yani bu fonksiyon tek tek snf rneklerini deil, genel olarak snfn btnn ilgilendiriyor.
Bu bakmdan, personel_saysn_grntle() fonksiyonunun rnek deikenlerinden
bamsz bir biimde kullanlabilmesi ok daha mantkl olacaktr.
Ayrca, bir rnek metodu olan personel_saysn_grntle() fonksiyonunu rneklerden
bamsz olarak kullanamadmz iin, bu metot yardmyla personel saysnn 0 olduu
bir durumu grntlememiz de mmkn olmuyor. nk bu fonksiyona eriebilmek iin
ncelikle snf en az bir kez rneklemi, yani snfn en az bir adet rneini karm olmamz
gerekiyor. Bu durum da kodlarmzn mant asndan son derece ciddi bir kstlamadr.
Yukarda sralanan gerekeler dorultusunda kodlar hem daha tutarl bir hale getirmek hem
de personel saysnn 0 olduu durumu gstermemizi engelleyen kstlamay aabilmek iin
yle bir ey deneyebilirsiniz:
def personel_saysn_grntle():
print(len([Link]))
class alan():
personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
def personeli_grntle(self):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
746
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
Burada personel saysn grntleyen fonksiyonu snftan ayrdk. Bylece u ekilde bir
kullanm mmkn olabildi:
>>> import alan
>>> alan.personel_saysn_grntle()
0
Grdnz gibi, bu ekilde kodlarmz biraz daha tutarl bir grnme kavutu. Ancak bu
ekilde, bariz bir biimde alan() snf ile ilikili olan personel_saysn_grntle()
fonksiyonunu snftan ayrm ve kod btnln bozmu olduk.
nk, her ne
kadar personel_saysn_grntle() fonksiyonu alan() snfnn herhangi bir rnei
ile ilikili olmasa da, anlam asndan bu fonksiyonun alan() snfna ait olduu
besbelli.
Ayrca, yukardaki kodlar barndran modln tamamn deil de, from
alan import alan gibi bir komutla yalnzca alan() snfn ie aktarrsak,
personel_saysn_grntle() fonksiyonu darda kalacaktr:
>>> from alan import alan
>>> dir()
747
Ancak bu da, her zaman tercih etmeyeceiniz bir kstlama olabilir. O halde bu kstlamay
amak iin gelin, ilgili fonksiyonu tekrar snf iine alalm:
class alan():
personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
def personel_saysn_grntle(self):
print(len([Link]))
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
def personeli_grntle(self):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
Yukardaki kodlarda ilgili fonksiyona bir rnek adyla deil de, snf adyla erimek iin ilk
etapta u kodu denemek aklnza gelmi olabilir:
>>> from alan import alan
>>> alan.personel_saysn_grntle()
748
Burada rnek_metodu() ile snf_metodu() arasndaki fark, ilkinde self, ikincisinde ise
cls kullanmamz. Ancak hatrlarsanz, self kelimesinin Python asndan bir zorunluluk
olmadn sylemitik. Tpk self gibi, aslnda cls kelimesi de Python asndan bir zorunluluk
deildir. Yani cls yerine de istediimiz kelimeyi kullanabilirdik. Bu metotlarda nemli olan,
parametre listesinin ilk srasn igal eden kelimenin ne olduudur. Dolaysyla yukardaki
rnekte Python asndan rnek_metodu() ile snf_metodu() arasnda hibir fark bulunmaz.
Python her iki metodu da birer rnek metodu olarak deerlendirir. Bu iki rnek metodu
arasndaki fark, ilkinde snf rneklerini temsil edecek kelimenin self, ikincisinde ise cls olarak
belirlenmi olmasdr. Python self veya cls kelimelerine zel bir nem atfetmez. Ama Python
topluluu iinde, rnek metotlar iin self, snf metotlar iin ise cls kullanmak ok gl bir
gelenektir.
Szn z, snf_metodu() fonksiyonunun ilk parametresini cls yapm olmamz bu
metodun bir snf metodu olabilmesi iin gereklidir, ama yeterli deildir. Pythonda bir snf
749
te Pythonda bir snf metodunu rnek metodundan ayran asl e, yukardaki rnekte
grdmz @classmethod ifadesidir. Pythonda isminin nnde @ iareti olan bu
tr elere bezeyici (decorator ) ad verilir. Grdnz gibi, @classmethod bezeyicisi,
yukardaki rnekte bir fonksiyonu snf metoduna dntrme ilevi gryor. lerleyen
derslerimizde bezeyicilerin baka zelliklerinden de sz edeceiz. Gelin isterseniz imdi
yukarda rendiimiz zellii alan() adl snfa uygulayalm:
class alan():
personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
@classmethod
def personel_saysn_grntle(cls):
print(len([Link]))
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
Yukarda
750
personel_saysn_grntle()
adl
fonksiyonun
yansra,
Grdnz gibi, snf metodumuza dorudan snf adn kullanarak eriebiliyoruz. Elbette bu
durum, snf metoduna rnek adlar zerinden de erimemize engel deil. Eer arzu edersek
personel_saysn_grntle() adl snf metodunu u ekilde de arabiliriz:
>>> aye.personel_saysn_grntle()
3
>>> ahmet.personel_saysn_grntle()
3
>>> mehmet.personel_saysn_grntle()
751
Ancak rnek metotlarna ve rnek niteliklerine atfta bulunmak iin rnek adlarn kullanmak,
snf metotlar ve snf niteliklerine atfta bulunmak iin ise snf adlarn tercih etmek daha
akllca olabilir.
personel_saysn_grntle()
fonksiyonu
iin
sylediimiz
personeli_grntle() fonksiyonu iin de aynen geerlidir.
bu
szler,
Szn z, snfn herhangi bir rneine bal olmayan bir ilem yapan, ama anlamsal olarak
da sna ilikili olduu iin snf dnda brakmak istemediiniz fonksiyonlar birer snf
metodu olarak tanmlayabilirsiniz.
Bu liste, her bir kitap iin, srasyla o kitabn ISBN numarasn, yazarn, ismini ve yaynevini
gsteren birer demetten oluuyor. Amacmz, bu listeden eitli ltlere gre sorgulama
yapabilen bir program yazmak. Yazdmz program; isbn, isim, eser ve yaynevi ltlerine
gre bu listeden veri alabilmemizi salayacak.
lk denememizi yapalm:
liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]
def sorgula(lt=None, deer=None):
for li in liste:
if not lt and not deer:
print(*li, sep=', ')
elif lt == 'isbn':
if deer == li[0]:
print(*li, sep=', ')
elif lt == 'yazar':
if deer == li[1]:
print(*li, sep=', ')
elif lt == 'eser':
if deer == li[2]:
print(*li, sep=', ')
752
elif lt == 'yaynevi':
if deer == li[3]:
print(*li, sep=', ')
Eer lt ve deer parametreleri iin herhangi bir deer belirtilmemise, yani bunlar None
olarak braklmsa, kitap listesinin tamamn, her bir e arasna birer virgl yerletirerek
ekrana basyoruz.
Eer sorgula() fonksiyonu arlrken lt parametresine isbn argman, deer
parametresine ise bir ISBN deeri verilmise u ilemi yapyoruz:
elif lt == 'isbn':
if deer == li[0]:
print(*li, sep=', ')
Burada yaptmz ey u: Eer lt isbn ise, fonksiyona verilen deer argmann, kitap
listesi iindeki her bir demetin ilk srasnda aryoruz. nk ISBN bilgileri demetlerin ilk
srasnda yer alyor. Eer bu koul salanrsa listenin ilgili ksmn ekrana basyoruz:
if deer == li[0]:
print(*li, sep=', ')
Her bir deer i, listenin ilgili srasnda aradmza dikkat edin. Yazar bilgisi demetlerin
ikinci srasnda yer ald iin li[1] i, ayn gerekeyle eser iin li[2] yi, yaynevi iin ise li[3]
sorguluyoruz.
Gelelim bu fonksiyonu nasl kullanacamza...
Her zaman sylediimiz gibi, Pythonn etkileimli kabuu mkemmel bir test ortamdr. O
halde imdi bu kodlar [Link] adl bir dosyaya kaydedelim ve dosyann bulunduu dizinde
43.3. Alternatif naclar
753
Tam da beklediimiz gibi, fonksiyon argmansz arldnda btn kitap listesini, her bir e
arasnda bir virgl olacak ekilde ekrana basyor.
imdi de mesela ISBN numarasna gre birka sorgu ilemi gerekletirelim:
>>> [Link]('isbn', '9789754060409')
9789754060409, Nietzsche, Byle Buyurdu Zerdt , Cem
>>> [Link]('isbn', '975872519X')
975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
>>> [Link]('isbn', '9789753424080')
9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis
Burada, sorgula() fonksiyonunun ilk parametresine argman olarak isbn deerini verdik.
Bylece programmz ISBN numarasna gre sorgu yapmak istediimizi anlad. Daha sonra
da ikinci argman olarak istediimiz bir ISBN numarasn yazdk ve sorgu ilemini tamamladk.
Bir de yaynevine gre sorgulama yapalm:
>>> [Link]('yaynevi', 'Metis')
9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis
>>> [Link]('yaynevi', 'thaki')
975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
>>> [Link]('yaynevi', 'Cem')
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem
754
if
if
if
if
deer
deer
deer
deer
==
==
==
==
li[0]],
li[1]],
li[2]],
li[3]]}
Burada btn if-else cmleciklerini birer liste retecine dntrp, d adl szln
anahtarlar olarak belirledik. Artk sorgulama ilemlerini bir if-else yaps iinde deil de,
bir szlk iinden gerekletireceiz.
Hangi parametrenin hangi listeyi aracan belirleyen szlmz yazdktan sonra,
szlklerin get() metodunu kullanarak, lt argmannn deerine gre szlkten veri
ekiyoruz. Eer szlkte bulunmayan bir lt deeri verilirse tm listeyi ekrana basyoruz.
Bu arada, eer d szl iindeki liste retelerinin birbirini tekrar eder bir yapda olmas sizi
rahatsz ediyorsa, bu ksm bir yardmc fonksiyon araclyla sadeletirebilirsiniz:
liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]
def bul(deer, sra):
return [li for li in liste if deer == li[sra]]
def sorgula(lt=None, deer=None):
d = {'isbn'
: bul(deer, 0),
'yazar'
: bul(deer, 1),
'eser'
: bul(deer, 2),
'yaynevi' : bul(deer, 3)}
for e in [Link](lt, liste):
print(*e, sep = ', ')
Burada btn liste retelerini tek bir bul() fonksiyonu iinde oluturarak, sorgula()
fonksiyonu iindeki d szlne gnderdik.
Bu kodlar da ayn ilk program rneinde olduu gibi kullanyoruz:
>>> import klist
>>> [Link]()
9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis
975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem
>>> [Link]('yazar', 'Nietzsche')
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem
>>> [Link]('eser', 'Sana Gl Bahesi Vadetmedim')
9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis
Yukardaki kodlar yazmann daha baka alternatieri de var. Mesela, eer arzu ederseniz,
755
Burada kitap listesini bir rnek nitelii olarak tanmlamak suretiyle snfn her yerinden
kullanlabilir hale getirdik.
Ardndan da bul() ve sorgula() adl fonksiyonlar, birer rnek metodu biiminde snf iine
yerletirdik.
Bu snf da u ekilde kullanabiliriz:
>>> import klist
>>> sorgu = [Link]()
>>> [Link]()
9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis
975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem
>>> [Link]('yazar', 'Evren')
975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
Elbette, bu rnekte, ilk yazdmz kodlar bir snf yaps iinde tarif etmenin bize pek bir
katks yok. Burada yaptmz ey esasnda btn kodlar Sorgu adl bir etki alan iine
tamaktan fazlas deil. Ama byle bir imkannzn da olduunu bilmeniz her halkarda sizin
iin faydal olacaktr.
Gelelim yukardaki kodlar yazmann son alternatine:
class Sorgu():
def __init__(self, deer=None, sra=None):
[Link] = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]
if not deer and not sra:
l = [Link]
else:
l = [li for li in [Link] if deer == li[sra]]
for i in l:
756
Burada da, her bir lt ayr birer snf metodu olarak tanmladk. Bylece bu ltleri
yapsal olarak birbirinden ayrm olduk. Yukardaki snf u ekilde kullanabiliriz:
nce modlmz ie aktaralm:
>>> from klist import Sorgu
Grdnz gibi, snf metodu yaklam, gayet temiz bir sorgu kodu retmemize imkan
tanyor.
Bir de yazara ve esere gre sorgulayalm:
>>> [Link]("Greenberg")
9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis
>>> [Link]("Postmodern Bir Kz Sevdim")
975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
Grdnz gibi, snf parametresiz olarak rneklediimizde btn listeyi elde ediyoruz.
te alternatif ina denen ilem tam olarak budur.
Yukardaki rnekte isbnden(),
yazardan(), eserden() ve yaynevinden() adl snf metotlar, Sorgu() adl snf alternatif
757
Burada tanmladmz Giri() snf, bir mteri numaras araclyla sisteme giri imkan
salyor:
>>> from sistem import Giri #kodlarmz [Link] dosyas iinde
>>> Giri()
Eer biz ayn zamanda bir parola ve TC Kimlik Numaras ile de giri imkan salamak istersek,
baka yntemlerin yansra, snf metotlarndan da yararlanabiliriz:
class Giri():
def __init__(self, mesaj='Mteri numaranz: '):
cevap = input(mesaj)
print('Hogeldiniz!')
@classmethod
def paroladan(cls):
mesaj = 'Ltfen parolanz giriniz: '
cls(mesaj)
@classmethod
def tcknden(cls):
mesaj = 'Ltfen TC kimlik numaranz giriniz: '
cls(mesaj)
veya:
>>> [Link]()
Snf metotlar iinde kullandmz cls(mesaj) satrlar, Giri() adl snf farkl bir parametre
ile armamz salyor. Grdnz gibi, bu snfn mesaj parametresinin ntanml deeri
Mteri numaranz: . Snfmz farkl bir ekilde arabilmek iin, cls(mesaj) kodlar
yardmyla snfn mesaj parametresini Ltfen parolanz giriniz: ve Ltfen TC kimlik
numaranz giriniz: deerleri ile yeniden altryoruz.
Daha nce de birka kez vurguladmz gibi, cls kelimesi Python asndan bir zorunluluk
deildir. Yani yukardaki snf mesela yle de yazabilirdik:
class Giri():
def __init__(self, mesaj='Mteri numaranz: '):
cevap = input(mesaj)
1
Aslnda burada ina edilen ey snftan ziyade nesnedir. Bu durumu ve nesne kavramn bir sonraki blmde
ayrntl olarak ele alacaz.
758
print('Hogeldiniz!')
@classmethod
def paroladan(snf):
mesaj = 'Ltfen parolanz giriniz: '
snf(mesaj)
@classmethod
def tcknden(snf):
mesaj = 'Ltfen TC kimlik numaranz giriniz: '
snf(mesaj)
Ancak, tpk self kelimesinde olduu gibi, cls de Python topluluu iinde son derece yerleik
bir gelenektir. Bu gelenei bozmak isteyeceinizi zannetmiyorum.
lk bakta snf metotlar size pek gerekli deilmi gibi gelebilir. Ama eer bu metotlarn
gerek dnyadaki kullanmna ilikin bir rnek verirsek belki kriniz deiir.
Snf metotlarnn kullanmna ilikin gzel bir rnei datetime modlnde grebilirsiniz.
Ayrca bkz.:
Aadaki rnei daha iyi anlayabilmek iin datetime Modl ve time Modl belgelerine
baknz.
Bir standart ktphane modl olan datetime n kaynak dosyasn aarsanz (kaynak
dosyann nerede olduunu nasl renebilirim diye soran arkadalara teesserimi
iletiyorum...), orada date snfnn yle yazldn greceksiniz:
class date:
__slots__ = '_year', '_month', '_day'
def __new__(cls, year, month=None, day=None):
if (isinstance(year, bytes) and len(year) == 4 and
1 <= year[2] <= 12 and month is None): # Month is sane
# Pickle support
self = object.__new__(cls)
self.__setstate(year)
return self
_check_date_fields(year, month, day)
self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
return self
@classmethod
def fromtimestamp(cls, t):
y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
return cls(y, m, d)
@classmethod
def today(cls):
t = _time.time()
return [Link](t)
@classmethod
def fromordinal(cls, n):
759
y, m, d = _ord2ymd(n)
return cls(y, m, d)
Bu ekilde, date snfna srasyla yl, ay ve gn bilgisi girerek bugn adl bir tarih nesnesi
oluturmu oluyoruz. Bu ekilde herhangi bir tarihi elle oluturabilirsiniz.
Eer amacnz bugnn tarihini oluturmaksa, yl, ay ve gn bilgilerini yukardaki gibi date
snfna elle girebileceiniz gibi, today() adl snf metodunu da kullanabilirsiniz:
>>> bugn = [Link]()
te bylece, date snfnn size sunduu bir alternatif inac (today()) vastasyla bugnn
tarihini otomatik olarak elde etmi oldunuz.
Ayn ekilde, eer elinizde bir zaman damgas varsa ve siz bu zaman damgasndan bir
tarih elde etmek istiyorsanz yine date snfnn sunduu bir baka alternatif inacdan
yararlanabilirsiniz:
>>> import time
>>> zaman_damgas = [Link]()
>>> bugn = [Link](zaman_damgas)
Eer elinizde tam say biimli bir Gregoryen tarih verisi varsa bu veriyi kullanarak da bir tarih
nesnesi elde edebilirsiniz:
>>> gregoryen = 735765
>>> bugn = [Link](gregoryen)
[Link](2015, 6, 16)
Uzun lafn ksas, alternatif inaclar, bir snftan nesne oluturmak iin bize alternatif yollar
sunan son derece faydal aralardr. Bu arada, eer bu blmde deindiimiz baz kavramlar
anlamakta zorlandysanz hi cannz skmayn. Bir sonraki blm iledikten sonra, burada
anlatlanlar kafanza ok daha salam bir ekilde yerlemi olacak.
760
Burada rnek_metodu(), self yardmyla rnek niteliklerine eriiyor. snf_metodu() ise cls
yardmyla snf niteliklerine eriiyor. Snf metodu tanmlamak iin ayrca @classmethod
bezeyicisini de kullanyoruz. te eer snf iinde tanmlayacanz fonksiyon herhangi bir
rnek ya da snf nitelii zerinde herhangi bir ilem yapmayacaksa yle bir ey yazabilirsiniz:
class Snf():
snf_nitelii = 0
def __init__(self, veri):
[Link] = veri
def rnek_metodu(self):
return [Link]
@classmethod
def snf_metodu(cls):
return cls.snf_nitelii
@staticmethod
def statik_metot():
print('merhaba statik metot!')
761
Burada Mat() adl bir snf tanmladk. Bu snf iinde iki adet statik metodumuz var: pi() ve
karekk(). Grdnz gibi, bu iki fonksiyon, rnek ve snf metotlarnn aksine ilk parametre
olarak self veya cls almyor. nk bu iki snfn da snf veya rnek nitelikleriyle herhangi bir
ii yok.
Statik metotlar hem rnekler hem de snf adlar zerinden kullanabiliriz.
Yukardaki kodlarn [Link] adl bir dosyada yer aldn varsayarsak:
>>> from mat import Mat
>>> m = Mat()
>>> [Link]() #rnek zerinden
3.142857142857143
>>> [Link](144) #rnek zerinden
12.0
>>> [Link]() #snf zerinden
3.142857142857143
>>> [Link](144) #snf zerinden
12.0
762
Burada bu iki fonksiyonu birer rnek metodu olarak tanmladk. Bu fonksiyonlar bu ekilde
tanmladmzda, bunlara rnekler zerinden eriebiliriz:
>>> from mat import Mat
>>> m = Mat()
>>> [Link]()
3.142857142857143
>>> [Link](144)
12.0
763
Grdnz gibi, kullanm asndan snf metotlar ile statik metotlar ayn. Ancak Mat()
snf iindeki fonksiyonlar birer snf metodu olarak tanmladmzda gereksiz yere cls
parametresi kullanm oluyoruz. Fonksiyon iinde herhangi bir yerde kullanlmad iin,
yukardaki rnekte cls parametresinin hibir amaca hizmet etmediine dikkat edin.
Statik metotlarn ok sk kullanlan aralar olmadn da belirterek yolumuza devam edelim.
Dipnotlar:
764
BLM 44
44.1 Nesneler
Geen blmlerden birinde snar tanmlarken, bunlarn, nesne retmemizi salayan bir
veri tipi olduuna dair mulak bir laf etmitik. te bu balk altnda, o tanm iinde geen ve
nesne tabanl programlamann temelini oluturan nesne kavram zerine eileceiz.
te bu kodlardaki snf = Snf() komutu ile bir nesne retmi olduk. Nesnemizin ad
da snf. Teknik olarak ifade edersek, snf rnei, Snf() adl snfn btn nitelik ve
765
metotlarn bnyesinde barndran bir nesnedir. Mesela yukardaki kodlarn [Link] adl bir
dosyada bulunduunu varsayarak yle bir deneme yapalm:
>>> import snf
>>> snf = [Link]()
Bu ekilde, kodlar ieren modl ie aktarm ve modl iindeki Snf() adl snf snf ad ile
rneklemi olduk. Yani yukardaki kodlar yardmyla snf adl bir nesne oluturduk. Bakalm
bu nesne hangi nitelik ve/veya metotlara sahipmi:
>>> dir(snf)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__']
Grdnz gibi, biz bo bir snf tanmlam olsak da, snf nesnesi ntanml olarak yine de
baz nitelik ve metotlara sahip. te Pythonda, yukardaki gibi birtakm nitelik ve metotlara
sahip olan bu tr elere nesne ad veriyoruz.
Bir de isterseniz yukardaki gibi bo bir snf tanmlamak yerine, snfmz iinde kendimiz
birtakm nitelik ve metotlar tanmlamay da deneyelim:
class Snf():
snf_nitelii = 'snf nitelii'
def __init__(self):
self.rnek_nitelii = 'rnek nitelii'
def rnek_metodu(self):
print('rnek metodu')
@classmethod
def snf_metodu(cls):
print('snf metodu')
@staticmethod
def statik_metot():
print('statik metot')
Grdnz gibi, kendi tanmladmz nitelik ve metotlar da snf adl nesne iine eklenmi...
766
te snf adl snf rneinin, yukarda gsterilen birtakm durum ve davranlara sahip
olmasndan yola karak, snf rneinin bir nesne olduunu sylyoruz.
Yukardaki aklamalarn, nesne kavram hakknda en azndan bir kir sahibi olmanz
saladn zannediyorum.
Grdnz gibi, nesne denen ey aslnda basit bir
isimlendirmeden ibarettir: Pythonda belli bir durumu/nitelii/metodu/davran olan
elemanlara/elere nesne (object ) ad veriyoruz. Peki o zaman, nesne denen ey basit bir
adlandrmadan ibaretse nesne tabanl programlamann etrafnda koparlan bunca yaygarann
sebebi nedir?
Nesne tabanl programlamay bu kadar zel ve nemli klan eyin ne olduunu anlamak iin
gelin nesnelere biraz daha yakndan bakalm.
767
if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
[Link](self)
def saldr_sonucunu_hesapla(self):
return [Link](0, 2)
def ka(self):
print('Kalyor...')
for i in range(10):
[Link](.3)
print('\n', flush=True)
print('Rakibiniz sizi yakalad')
def darbele(self, darbelenen):
[Link] += 1
[Link] -= 1
if ([Link] % 5) == 0:
[Link] -= 1
if [Link] < 1:
[Link] = 0
print('Oyunu {} kazand!'.format([Link]))
self.oyundan_k()
def oyundan_k(self):
print('klyor...')
[Link]()
##################################
# Oyuncular
siz = Oyuncu('Ahmet')
rakip = Oyuncu('Mehmet')
# Oyun balangc
while True:
print('u anda rakibinizle kar karyasnz.',
'Yapmak istediiniz hamle: ',
'Saldr: s',
'Ka:
k',
'k:
q', sep='\n')
hamle = input('\n> ')
if hamle == 's':
[Link](rakip)
print('Rakibinizin durumu')
rakip.mevcut_durumu_grntle()
print('Sizin durumunuz')
siz.mevcut_durumu_grntle()
if hamle == 'k':
[Link]()
if hamle == 'q':
768
siz.oyundan_k()
Komut satr zerinde alan basit bir oyundur bu. Dilerseniz bu kodlar incelemeye
balamadan nce, bir dosyaya kaydedip altrn. Karnza yle bir ekran gelecek:
u anda rakibinizle kar karyasnz.
Yapmak istediiniz hamle:
Saldr: s
Ka:
k
k:
q
>
Programmz bize burada farkl seenek sunuyor. Eer rakibimize saldrmak istiyorsak
klavyedeki s tuuna; rakibimizden kamak istiyorsak klavyedeki k tuuna; yok eer oyundan
kmak istiyorsak da klavyedeki q tuuna basacaz. Tercihinizi belirleyip neler olduunu
inceleyin ve oyunu iyice tanmaya aln.
Oyunu iyice anlayp tandktan sonra oyun kodlarn incelemeye geebiliriz.
Yukarda ilk olarak Oyuncu adl bir snf tanmladk:
class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
[Link] = isim
[Link] = 0
[Link] = can
[Link] = enerji
class kelimesinin snf tanmlamamz salayan bir ara, Oyuncu kelimesinin ise
tanmladmz snfn ad olduunu biliyoruz. Bu satrn hemen ardndan gelen __init__()
fonksiyonu, snfmz rneklendiinde neler olacan tanmladmz yerdir. Bu snfn,
rnekleme srasnda hangi parametreleri alacan da __init__() fonksiyonu iinde
belirliyoruz. Parametre listesinde grdmz ilk e, yani self, snfn o anki rneini
temsil ediyor. Pythonn szdizimi kurallar gereince bu kelimeyi oraya yazmamz gerektiini
biliyoruz.
Yukardaki fonksiyon, self dnda toplam parametre alyor: isim, can ve enerji. Bunlardan
ilki, yani isim parametresinin ntanml bir deeri yok. Dolaysyla snf arrken (yani
rneklerken) bu parametrenin deerini belirtmemiz gerekecek. teki iki parametre olan
can ve enerji ise birtakm ntanml deerlere sahip. Dolaysyla snf rneklendirirken
bu parametrelere farkl bir deer atamadmz srece, bu parametreler, listede belirtilen
deerleri tayacak.
Parametre olarak belirlediimiz deerleri snf iinde kullanabilmek iin, bunlar __init__()
fonksiyonunun gvdesinde birer rnek niteliine dntryoruz:
[Link] = isim
[Link] = 0
[Link] = can
[Link] = enerji
Burada ilave olarak bir de deeri 0 olan [Link] adl bir deiken tanmladk. Bu da
snfmzn rnek niteliklerinden biri olup, ilgili oyuncu (yani snfn o anki rnei) darbe aldka
bunun deeri ykselecektir.
Gelin isterseniz bu aamada snfmz rnekleyerek neler olup bittiini daha net anlamaya
769
alalm:
class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
[Link] = isim
[Link] = 0
[Link] = can
[Link] = enerji
#Snfmz rnekliyoruz
oyuncu = Oyuncu('Ahmet')
Bata da sylediimiz gibi, Oyuncu() snfn rnekleyerek meydana getireceiniz btn snf
rnekleri, yani nesneler, __init__() fonksiyonu iinde tanmladnz rnek niteliklerini
tayacaktr:
class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
[Link] = isim
[Link] = 0
[Link] = can
[Link] = enerji
oyuncu1
oyuncu2
oyuncu3
oyuncu4
=
=
=
=
Oyuncu('Ahmet')
Oyuncu('Mehmet')
Oyuncu('Veli')
Oyuncu('Aye')
Burada oyuncu1, oyuncu2, oyuncu3 ve oyuncu4 olmak zere drt farkl nesne oluturduk.
Bu nesnelerin hangi niteliklere sahip olacan ise Oyuncu() snfnn tanm iinde belirttik.
Yani snfmz tpk bir fabrika gibi alarak, bizim iin, ayn nitelikleri tayan drt farkl nesne
retti.
te nesne tabanl programlamann zn oluturan nesne budur. Bir nesnenin hangi
niteliklere sahip olacan belirleyen veri tipine snf (class ) derken, o snfn ortaya kard
rne ise nesne (object ) ad veriyoruz. Bunu una benzetebilirsiniz: Eer nsan bir snfsa,
Mahmut bu snfn bir rneidir. Dolaysyla Mahmut, nsan snfndan tremi bir nesnedir.
Ayn ekilde eer Kpek bir snfsa, Karaba da bu snfn bir rneidir. Yani Karaba,
Kpek snfndan tremi bir nesnedir. Mahmutun hangi zelliklere sahip olacan nsan
snfnn nasl tanmland, Karaban hangi zelliklere sahip olacan ise Kpek snfnn
nasl tanmland belirler. te ayn bunun gibi, Oyuncu() snfndan treyen nesnelerin hangi
zelliklere sahip olacan da Oyuncu() snfnn nasl tanmland belirler.
770
Bu fonksiyon, self dnda tek bir parametre alyor. Fonksiyonu altrrken kullanacamz
rakip parametresi, saldrnn kime kar (yani snf rneklerinden hangisine kar)
dzenleneceini belirleyecek.
Fonksiyon gvdesinde ilk olarak yle bir ksm gryoruz:
print('Bir saldr gerekletirdiniz.')
print('Saldr sryor. Bekleyiniz.')
for i in range(10):
[Link](.3)
print('.', end='', flush=True)
Burada saldrnn gerekletiine dair kullancy bilgilendirdikten sonra yle bir kod paras
yazdk:
for i in range(10):
[Link](.3)
print('.', end='', flush=True)
Bu kodlarda time adl bir standart ktphane modlnn sleep() adl bir metodundan
yararlandmz gryorsunuz. Elbette bu modl kullanabilmek iin ncelikle bu modl
44.3. Basit Bir Oyun
771
ie aktarm olmamz gerekiyor. Bu ilemi dosyann en banda import time satr yardmyla
gerekletirdiimizi grebilirsiniz.
Yukardaki satrlar, 3er milisaniye aralklarla, yan yana nokta iaretleri yerletirecektir.
Dilerseniz etkileimli kabukta bu kodlar u ekilde test edebilirsiniz:
>>> import time
>>> for i in range(10):
...
[Link](.3)
...
print('.', end='', flush=True)
Biraz nce time adl bir standart ktphane modln kullanmtk. imdi ise random adl
baka bir standart ktphane modln kullanyoruz. Elbette bu modl de kullanabilmek
iin ncelikle bu modl import random komutuyla ie aktarm olmamz gerekiyor. Bu
zorunluluu da, tpk time modlnde olduu gibi, dosyann en banda yerine getirmitik.
Yukarda random modln, 0 ile 2 aras rastgele saylar retmek iin kullandk.
[Link](0, 2) komutu her alnda 0, 1 ve 2 saylarndan birini rastgele
retecektir. Buradan elde ettiimiz sonucu sonu adl bir deikene atayarak saldr()
fonksiyonu iinde u ekilde kullanyoruz:
sonu = self.saldr_sonucunu_hesapla()
if sonu == 0:
print('\nSONU: kazanan taraf yok')
if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
[Link](rakip)
if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
[Link](self)
772
if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
[Link](rakip)
if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
[Link](self)
self i parantez iinde bir argman olarak kullanmak yerine, bu kelimeyi fonksiyon adnn
bana bir nek olarak takyoruz.
Ne diyorduk? Evet, saldr() fonksiyonu iinde darbele() adl bir fonksiyona atfta bulunduk.
Yani saldr sonucunda rakibimizi darbelediimizde ve rakibimizden darbe yediimizde
darbele() adl bir baka rnek metodunu ardk:
def darbele(self, darbelenen):
[Link] += 1
[Link] -= 1
if ([Link] % 5) == 0:
[Link] -= 1
if [Link] < 1:
[Link] = 0
print('Oyunu {} kazand!'.format([Link]))
self.oyundan_k()
Bu fonksiyon iinde, herhangi bir darbe alma durumunda oyuncunun darbe, can ve enerji
miktarlarnda meydana gelecek deiiklikleri tanmlyoruz.
Buna gre herhangi bir darbe alma durumunda aadaki ilemler gerekletirilecek:
Darbelenen oyuncunun darbe deeri 1 birim artacak:
[Link] += 1
773
Burada her 5 darbede 1 can kaybetme kriterini nasl belirlediimize dikkat edin. Bildiiniz
gibi, oyuncu darbe yedike darbe deikeninin deeri artyor. Bu deer 5 saysna ulatnda,
5 % 5 ileminin sonucu 0 olacaktr. Yani bu say 5e blndnde blme ileminden kalan
deer 0 olacaktr. 5in tm katlar iin (5, 10, 15, 20 gibi...) bu durum geerlidir. Eer darbe
deikenin ulat deer 5in kat deilse, bu say 5e tam blnmedii iin, blmeden kalan
deer 0 dnda bir say olur. Dolaysyla darbe deerinin ulat saynn 5e blnmesinden
kalan deerin 0 olup olmadn kontrol ederek oyuncunun 5 darbede 1 can kaybetmesini
salayabiliyoruz.
Oyuncunun can deeri 1in altna dtnde ise enerji deeri 0a inecek ve oyunu kimin
kazand ilan edildikten sonra oyun kapatlacak:
if [Link] < 1:
[Link] = 0
print('Oyunu {} kazand!'.format([Link]))
self.oyundan_k()
Gayet basit bir fonksiyon. Herhangi bir ekilde oyundan kmak gerektiinde sys modlnn
exit() fonksiyonunu kullanarak oyunu terk ediyoruz.
lerlemeden nce, darbele() fonksiyonunu kullandmz ksma tekrar bakalm:
sonu = self.saldr_sonucunu_hesapla()
if sonu == 0:
print('\nSONU: kazanan taraf yok')
if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
[Link](rakip)
if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
[Link](self)
Bildiiniz gibi, darbele() fonksiyonu, self dnda 1 adet parametre daha alyor. Bu
parametre, darbeyi hangi oyuncunun alacan gsteriyor. Yani darbeyi alan oyuncu biz
miyiz yoksa rakibimiz mi? te bunu tespit etmek iin darbelenen adl bir parametre
belirledik. Grdnz gibi, darbele() fonksiyonu saldr() adl baka bir fonksiyonun
iinden arlyor. saldr() fonksiyonu da rakip adl bir parametre alyor. te darbe alan
oyuncunun can ve enerji deerlerini yenilemek istediimizde bu parametreyi, darbele()
fonksiyonuna gnderiyoruz:
[Link](rakip)
Burada darbelenen oyuncu kar taraf. Yani rakibimiz darbe yemi. Eer darbelenen kii
kendimizsek, kendimize atfta bulunmak iin de self parametresini kullanyoruz:
[Link](self)
Pek ok kez sylediimiz gibi, self kelimesi mevcut snf rneini temsil eder. Dolaysyla
774
kendimize atfta bulunmak istediimiz durumlarda, yukarda olduu gibi self i kullanabiliriz.
Eer arzu ederseniz, darbele() fonksiyonunu yle de yazabilirsiniz:
def darbele(self):
[Link] += 1
[Link] -= 1
if ([Link] % 5) == 0:
[Link] -= 1
if [Link] < 1:
[Link] = 0
print('Oyunu {} kazand!'.format([Link]))
self.oyundan_k()
Burada darbelenen parametresini iptal ettik. Kimin durumunun yenileceini self in kim
olduu belirleyecek:
if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
[Link]()
if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
[Link]()
Grdnz gibi, eer rakibi darbeleyip onun can ve enerji durumunu yenilemek istiyorsak,
ilgili fonksiyonu [Link]() eklinde aryoruz. Kendimizin durumunu yenilemek
istediimizde ise [Link]() komutunu kullanyoruz.
Snfmz tanmladmza gre artk bu snf nasl kullanacamz incelemeye geebiliriz:
siz = Oyuncu('Ahmet')
rakip = Oyuncu('Mehmet')
Bu iki nesne, Oyuncu() snfnn btn niteliklerini tayor. Nesneleri olutururken, zorunlu
argman olan isim deerini mutlaka belirtmemiz gerektiini unutmuyoruz.
Daha sonra bir while dngs iinde, oyunumuzun kullanc tarafndan grntlenecek
ksmn kodluyoruz:
while True:
print('u anda rakibinizle kar karyasnz.',
'Yapmak istediiniz hamle: ',
'Saldr: s',
'Ka:
k',
'k:
q', sep='\n')
hamle = input('\n> ')
if hamle == 's':
[Link](rakip)
print('Rakibinizin durumu')
rakip.mevcut_durumu_grntle()
775
print('Sizin durumunuz')
siz.mevcut_durumu_grntle()
if hamle == 'k':
[Link]()
if hamle == 'q':
siz.oyundan_k()
Burada 3er milisaniyelik aralklarla \n ka dizisini kullanarak bir alt satra geiyoruz.
Kullancnn q tuuna basmas halinde ise oyundan derhal kyoruz:
if hamle == 'q':
siz.oyundan_k()
Bu rnek kodlar bize snar ve nesneler hakknda epey bilgi verdi. Ayrca bu kodlar sayesinde
nceki bilgilerimizi de pekitirmi olduk.
776
777
Hatta mesela 1 gibi alelade bir say bile, d dnyayla iletiim kurmasn ve d dnyann
kendisiyle iletiim kurabilmesini salayan pek ok nitelik ve metoda sahip bir nesnedir:
>>> dir(1)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__',
'__class__', '__delattr__', '__dir__', '__divmod__',
'__doc__', '__eq__', '__float__', '__floor__',
'__floordiv__', '__format__', '__ge__', '__getattribute__',
'__getnewargs__', '__gt__', '__hash__', '__index__',
'__init__', '__int__', '__invert__', '__le__', '__lshift__',
'__lt__', '__mod__', '__mul__', '__ne__', '__neg__',
'__new__', '__or__', '__pos__', '__pow__', '__radd__',
'__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__',
'__repr__', '__rfloordiv__', '__rlshift__', '__rmod__',
'__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__',
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__',
'__setattr__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__truediv__', '__trunc__', '__xor__',
'bit_length', 'conjugate', 'denominator', 'from_bytes',
'imag', 'numerator', 'real', 'to_bytes']
te konuya bu noktadan baktmzda, Pythonda her ey bir nesnedir. Yani Pythondaki her
eyle, sahip olduklar metotlar ve nitelikler araclyla etkileebilirsiniz.
Pythonn bu zelliini bilmek, muhatap olduunuz programlama dilini ve onun kabiliyetlerini
tanmak asndan nemlidir. Pythonda her eyin bir nesne olduunu anladnz anda, {a:
0, b: 1} gibi bir kodla yalnzca basit bir szlk tanmlamadnz, bunun arkaplannda,
bu szlkle etkileim kurmanz salayacak koca bir mekanizma bulunduunu bilirsiniz.
778
Yukardaki tanmlara gre, bu snfn birinci snf bir nesne olabilmesi iin baka bir fonksiyona
veya snfa parametre olarak atanabilmesi gerekiyor. Bakalm acaba gerekten yle mi?
print(Deneme())
779
780
BLM 45
Geen blmlerde, nesne tabanl programlamaya ilikin hem temel, hem orta, hem de ileri
dzey saylabilecek pek ok konuya deindik. imdiye kadar rendiklerimiz, nesne tabanl
programlama yaklam erevesinde yazlm retirken ynmz bulabilmemiz asndan
byk lde yeterlidir. Ancak daha nce de sylediimiz gibi, nesne tabanl programlama
ok geni kapsaml bir konudur ve iinde imdiye kadar adn bile anmadmz daha pek ok
kavram barndrr. te bu blmde, geen derslerimizde incelemeye frsat bulamadmz,
ancak nesne tabanl programlamay daha derinlemesine tanmak bakmndan bilmemizin iyi
olaca birtakm ileri dzey kavramlardan sz edeceiz.
Bu blmde inceleyeceimiz ilk konu snf yeleri.
781
class Snf():
snf_nitelii = 'snf nitelii'
def rnek_metodu(self):
print('rnek metodu')
@classmethod
def snf_metodu(cls):
print('snf metodu')
@staticmethod
def statik_metot():
print('statik metot')
Bu kodlarn [Link] adl bir dosya iinde yer aldn varsayarsak yle bir eyler yazabiliriz:
>>> import sinif
>>> s = [Link]()
>>> dir(s)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'statik_metot', 'snf_metodu', 'snf_nitelii', 'rnek_metodu']
782
kacan dndnz birtakm eler varsa bunlar darya kapatarak bir gizli ye haline
getirmek isteyebilirsiniz. Peki ama nasl?
Burada __gizli adl bir gizli snf nitelii tanmladk. Bu deikenin yalnzca ba tarafnda iki
adet alt izgi olduuna, ancak u tarafnda alt izgi bulunmadna dikkat edin. te Pythonda
ba tarafnda yukardaki gibi iki adet alt izgi olan, ancak u tarafnda alt izgi bulunmayan
(veya yalnzca tek bir alt izgi bulunan) btn eler birer gizli yedir. Darya kapal olan bu
gizli yelere, normal yntemleri kullanarak snf dndan eriemezsiniz.
sterseniz deneyelim:
>>> import sinif
>>> s = [Link]()
>>> s.__gizli
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Snf' object has no attribute '__gizli'
Bir de snf ad
>>> [Link].__gizli
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Snf' has no attribute '__gizli'
Bu ekilde de eriemedik. nk dediimiz gibi, banda ift alt izgi olan, ancak ucunda
herhangi bir izgi bulunmayan (veya tek bir alt izgi bulunan) bu gizli elere normal
yollardan eriemeyiz.
Dilerseniz gizli ye oluturma kurallarn yle bir netletirelim:
45.1. Snf yeleri
783
Bir yenin gizli olabilmesi iin banda en az iki adet, ucunda da en fazla bir adet alt izgi
bulunmaldr. Yani unlar birer gizli yedir:
>>>
>>>
>>>
>>>
__gizli = 'gizli'
__gizli_ = 'gizli'
__gizli_ye = 'gizli'
__gizli_ye_ = 'gizli'
Burada nemli bir noktaya dikkatinizi ekmek istiyorum: Gizli yeler yalnzca snf dna
kapaldr. Bu yelere snf iinden rahatlkla eriebiliriz. Mesela yukardaki rnekte bu
durumu gryorsunuz. __gizli adl deikene rnek_metodu() iinden normal bir ekilde
eriebiliyoruz:
def rnek_metodu(self):
print(self.__gizli)
print('rnek metodu')
Burada rnek_metodu(), __gizli adl gizli yeye erimemiz iin bize araclk etmi oluyor.
Peki ama bir insan neden bu ekilde birtakm gizli yeler tanmlamak istiyor olabilir?
Hatrlarsanz geen blmde yle bir rnek vermitik:
class alan():
personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
@classmethod
def personel_saysn_grntle(cls):
print(len([Link]))
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in [Link]:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
784
Zira biz, kodlarmzn yaps gerei, personel zerindeki ilemlerin yalnzca eitli
fonksiyonlar/metotlar araclyla yaplmasn istiyoruz.
Personele eleman ekleyecek kiilerin dorudan personel listesine erimesi, kodlarmzn
kullanm kurallarnn bir bakma ihlal edilmesi anlamna geliyor. nk biz personele eleman
ekleme ilemleri iin halihazrda ayr bir metot tanmlam durumdayz. Eer personele
adam eklenecekse, bu ilem dorudan personel listesi zerinden deil, personele_ekle()
adl rnek metodu zerinden gerekletirilmeli. Yukardaki kodlarda bu personele_ekle()
metodu dorudan snfn kendi __init__() metodu tarafndan kullanlyor. Dolaysyla
yukardaki snf kullanmann doru yolu, ilgili snf rneklemektir:
>>> from calisan import alan
>>> ahmet = alan('Ahmet')
Ayn ekilde personel listesini grntlemek iin de dorudan personel listesine erimeye
almayacaz. Yani yle bir ey yazmayacaz:
>>> [Link]
te yukardaki kodlarda yer alan personel listesinin usulsz bir ekilde kullanlmasn
nlemek amacyla bu listeyi bir gizli ye haline getirebilirsiniz:
class alan():
__personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.personele_ekle()
@classmethod
def personel_saysn_grntle(cls):
print(len(cls.__personel))
def personele_ekle(self):
785
self.__personel.append([Link])
print('{} adl kii personele eklendi'.format([Link]))
def personeli_grntle(self):
print('Personel listesi:')
for kii in self.__personel:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
Burada personel listesinin ba tarafna iki alt izgi ekleyerek bunu snf dndan, normal
yollarla eriilmez hale getirdik:
>>> alan.__personel
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'alan' has no attribute '__personel'
Grdnz gibi, aslnda snfmz iinde __personel adl bir nitelik olmasna ramen, Python
bu nitelie snf dndan eriilmesine izin vermiyor. Eer amacmz personel zerinde eitli
ilemler yapmaksa, bu i iin snfn bize sunduu metotlar kullanmamz gerekiyor:
>>> alan.personel_saysn_grntle()
te yandan, bu fonksiyon aleni bir ye olduu iin, buna dardan erimemizin nnde
herhangi bir engel yok:
>>> aye.personele_ekle()
'Aye adl kii personele eklendi'
Bu fonksiyon snf dndan arldnda, kendisini aran rnek adn personel listesine
tekrar ekleyecektir:
786
>>> alan.personeli_grntle()
Aye
Aye
Yani yukardaki komut Aye adl kiiyi personel listesine tekrar ekler. Dolaysyla bu
fonksiyona snf dndan eriilmesi son derece mantksz, son derece yanl ve hatta son
derece kafa kartrcdr. O yzden, herhangi bir sknt yaanmasn engellemek amacyla
bu fonksiyonu da bir gizli ye olarak tanmlayabiliriz:
class alan():
__personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.__personele_ekle()
@classmethod
def personel_saysn_grntle(cls):
print(len(cls.__personel))
def __personele_ekle(self):
self.__personel.append([Link])
print('{} adl kii personele eklendi'.format([Link]))
@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.__personel:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
nk
787
Pythonda gerek anlamda gizli ve darya tamamen kapal yeler bulunmaz. Peki bu ne
anlama geliyor?
Bu u anlama geliyor: Her ne kadar yukardaki rneklerde yeleri darya kapatmak iin
kullandmz alt izgi iaretleri ilgili deikeni gizlese de, bunu tamamen eriilmez hale
getirmez. Dediimiz gibi, Pythonda gerek anlamda da kapal snf yeleri bulunmad iin
biz bu yelere bir ekilde erime imkanna sahibiz. Peki ama nasl?
Python, kodlar iinde gizli bir ye ile karlatnda zel bir isim bulandrma (name
mangling ) ilemi gerekletirir ve ilgili gizli yenin grnn deitirir. Eer Pythonn
arkaplanda neler evirdiini bilirseniz, gizli yeye de eriebilirsiniz.
rnek snfmz yleydi:
class Snf():
__gizli = 'gizli'
def rnek_metodu(self):
print(self.__gizli)
print('rnek metodu')
@classmethod
def snf_metodu(cls):
print('snf metodu')
@staticmethod
def statik_metot():
print('statik metot')
Daha sonra, bu alt izginin sa tarafna bu gizli yeyi barndran snfn adn ilitirir:
_Snf
Dolaysyla _Snf__gizli kodunu kullanarak, __gizli adl yeye snf dndan eriebilirsiniz.
Pratik olmas bakmndan bir rnek daha verelim. Mesela u rnei ele alalm:
788
class alan():
__personel = []
def __init__(self, isim):
[Link] = isim
[Link] = []
self.__personele_ekle()
@classmethod
def personel_saysn_grntle(cls):
print(len(cls.__personel))
def __personele_ekle(self):
self.__personel.append([Link])
print('{} adl kii personele eklendi'.format([Link]))
@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.__personel:
print(kii)
def kabiliyet_ekle(self, kabiliyet):
[Link](kabiliyet)
def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format([Link]))
for kabiliyet in [Link]:
print(kabiliyet)
Burada __personele_ekle() adl fonksiyon bir gizli yedir. Dolaysyla buna dardan normal
yntemlerle eriemeyiz.
Bunu test etmek iin nce gerekli verileri oluturalm:
>>> from calisan import alan
>>> ahmet = alan('Ahmet')
Ahmet adl kii personele eklendi.
Grdnz gibi, Python bu yeye normal yollardan erimemize izin vermiyor. Ama biz
biliyoruz ki, Python bu yeyi gizlerken zel bir isim bulandrma ilemi gerekletiriyor. Bu
bulandrma ileminin nasl gerekletirildiini bildiimize gre gizli yeye eriebiliriz.
ncelikle rneimizin adn yazalm. Zira gizli yeye bu ad zerinden erieceiz:
>>> ahmet.
789
>>> ahmet._
Gayet baarl...
Yalnz buraya yle bir not delim: Her ne kadar Python bize gizli yelere erime
imkan sunsa da, bakasnn yazd kodlar kullanrken, o kodlardaki gizli yelere erimeye
almamak ou zaman iyi bir kirdir. Nihayetinde eer bir programc, bir snf yesini
gizlemise bunun bir nedeni vardr. Eer erimenizin istenmedii bir yeye eriirseniz
ve bunun sonucunda birtakm sorunlarla karlarsanz bu durum o program yazan
programcnn deil, tamamen sizin kabahatinizdir. Python programclarnn da sk sk
syledii gibi: Neticede hepimiz, doruyu yanl bilen, yetikin insanlarz.
iin yapmamz gereken tek ey bana bir adet alt izgi yerletirmektir. rnein:
class Falanca():
_yargizli = 'yargizli'
Buradaki _yargizli adl nitelie snf iinden veya dndan erimemizi engelleyen veya
zorlatran hibir mekanizma bulunmaz. Ama biz bir snf iinde tek alt izgi ile balayan
bir e grdmzde, bunun snfn i ileyiine ilikin bir ayrnt olduunu, snf dndan
bu eyi deitirmeye kalkmamamz gerektiini anlarz.
791
Peki eer kodlarmz kullananlar personel listesindeki bir kiinin ismini sonradan deitirmek
isterse ne yapacak?
Kodlarmz iinde, isim deiiklii yaplmasn salayan zel bir metot yok. Dolaysyla
kodlarmz kullananlar, dorudan isim adl rnek deikenine erierek isim deiikliini u
ekilde yapabilir:
>>> [Link] = 'Selim'
Ancak burada yle bir sorun var. Bu isim deiiklii personel listesine yansmad. Kontrol
edelim:
>>> alan.personeli_grntle()
Personel listesi:
Ahmet
Mehmet
class alan():
personel = []
def __init__(self, isim):
[Link] = isim
self.personele_ekle()
def personele_ekle(self):
[Link]([Link])
print('{} adl kii personele eklendi'.format([Link]))
@classmethod
def personeli_grntle(cls):
792
print('Personel listesi:')
for kii in [Link]:
print(kii)
def isim_deitir(self, yeni_isim):
kii = [Link]([Link])
[Link][kii] = yeni_isim
print('yeni isim:', yeni_isim)
Burada isim_deitir() adl yeni bir fonksiyon tanmladk. Artk kodlarmzdan istifade
edenler yalnzca bu yeni fonksiyonu kullanarak, personele nceden ekledikleri kiilerin ismini
kolayca deitirebilir:
>>>
>>>
>>>
>>>
>>>
Personel listesi:
Ahmet
Mehmet
Selim
>>> 1.isim_deitir('Emre')
yeni isim: Emre
>>> alan.personeli_grntle()
Personel listesi:
Emre
Mehmet
Selim
Grdnz gibi, kodlarmz gayet gzel alyor. Bu noktadan sonra, eer arzu ederseniz,
kullanclarnzn personel ve [Link] adl deikenlere dorudan erimesini engellemek iin
bunlar tek alt izgi veya ift alt izgi kullanarak gizleyebilirsiniz.
ift alt izgi ile:
class alan():
__personel = []
def __init__(self, isim):
self.__isim = isim
self.personele_ekle()
def personele_ekle(self):
self.__personel.append(self.__isim)
print('{} adl kii personele eklendi'.format(self.__isim))
@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.__personel:
print(kii)
793
personel ve [Link] adl nitelikleri ift alt izgi ile gizlediimizde Pythonn isim
bulandrma mekanizmasn ileteceini, tek alt izgi ile gizlediimizde ise bu mekanizmann
iletilmeyeceini biliyorsunuz.
Peki size yle bir soru soraym:
Acaba, personel listesindeki bir ismi, mesela yalnzca yle bir komut vererek deitiremez
miyiz?
>>> [Link] = 'Emre'
Elbette deitirebiliriz. Ancak bunun iin zel bir aratan yararlanmamz gerekir. Bu i iin
@property adl zel bir bezeyiciyi kullanacaz.
Dikkatlice bakn:
class alan():
_personel = []
def __init__(self, isim):
self._isim = isim
self.personele_ekle()
def personele_ekle(self):
self._personel.append(self._isim)
print('{} adl kii personele eklendi'.format(self._isim))
@classmethod
def personeli_grntle(cls):
794
print('Personel listesi:')
for kii in cls._personel:
print(kii)
@property
def isim(self):
return self._isim
@[Link]
def isim(self, yeni_isim):
kii = self._personel.index([Link])
self._personel[kii] = yeni_isim
print('yeni isim: ', yeni_isim)
Bu kodlar altrdnzda, tpk yukarda bahsettiimiz gibi, herhangi bir alann ismini
yalnzca u ekilde deitirebildiinizi greceksiniz:
>>> [Link] = 'Emre'
Burada nitelik bir snf nitelii, [Link] ise bir rnek niteliidir.
Buna karlk, bir snf iinde fonksiyon biiminde yer alan ve bir ilemi veya prosedr yerine
getiren elere ise metot ad veriyoruz. Mesela:
class Falanca():
def __init__(self):
pass
def rnek_fonk(self):
pass
@classmethod
def snf_fonk(cls):
pass
@staticmethod
795
def statik_fonk():
pass
Burada rnek_fonk() adl fonksiyon bir rnek metodu, snf_fonk() adl fonksiyon bir
snf metodu, statik_fonk() adl fonksiyon ise bir statik metottur. Metotlar ile niteliklerin
gerekletirebilecekleri ilemlerin karmaklnn birbirinden farkl olmasnn yansra, bunlar
arasnda kullanm asndan da farkllk vardr. Mesela Falanca() snf iindeki nitelik adl
snf niteliini u ekilde kullanyoruz:
>>> [Link]
>>> [Link] = 'yeni deer'
Ayn snf iindeki snf_fonk() adl snf metoduna ise yle eriiyoruz:
>>> Falanca.snf_fonk()
Niteliklerin aksine, metotlarda atama yoluyla deer deitirme gibi bir ey sz konusu
deildir. Yani una benzer bir ey yazamayz:
>>> Falanca.snf_fonk() = 'yeni deer'
Eer metot bir parametre alyorsa (yukardaki rneklerde metotlar parametre almyor), bu
parametreyi kullanarak metotla iletiim kurabiliriz. Mesela:
>>> Falanca.snf_fonk(yeni_deer)
Property kelimesi (attribute kelimesine benzer bir ekilde) ngilizcede zellik, nitelik gibi
anlamlara gelir. Kelime anlamna uygun olarak, @property bezeyicisinin yapt en temel
i, bir metodu, nitelik gibi kullanlabilecek hale getirmektir. ok basit bir rnek verelim:
class Program():
def __init__(self):
pass
def versiyon(self):
return '0.1'
Burada versiyon() adl bir rnek metodu tanmladk. Bu program yle kullanyoruz:
>>> program = Program()
>>> [Link]()
'0.1'
Burada versiyon() adl metodu @property bezeyicisi ile bezedik. Bylece bu metodu bir
nitelik haline getirmi olduk. Artk bunu yle kullanabiliriz:
796
Gnn birinde, data kelimesi yerine veri kelimesinin daha uygun olduunu dnerek,
data kelimesini veri olarak deitirmek istediinizi varsayalm. Bunun iin kodlarnzda u
deiiklii yapabilirsiniz:
class Program():
def __init__(self):
[Link] = 0
Ancak bu ekilde, programnz eskiden beri kullananlarn, sizin yazdnz bu program temel
alarak oluturduklar programlar bozmu oldunuz... nk eer bu programdan faydalanan
birisi, yazd kodda eski [Link] deikenini kullanmsa, yukardaki isim deiiklii
yznden program kullanlamaz hale gelecektir. te bunu nlemek iin @property
bezeyicisini kullanabilirsiniz.
Dikkatlice bakn:
class Program():
def __init__(self):
[Link] = 0
@property
def data(self):
return [Link]
Bu ekilde, [Link] niteliine yaplan btn arlar data() adl metot vastasyla [Link]
niteliine ynlendirilecek. Bylece bakalarnn bu program kullanarak yazd eski kodlar
bozmadan, programmzda istediimiz deiiklii yapm olduk. Yani programmzda geriye
dnk uyumluluu (backwards compatibility ) salam olduk.
Yukardaki kodlarda @property bezeyicisini kullanarak data() metodunu bir nitelie
dntrdmz iin artk yle bir kullanm mmkn:
45.2. @property Bezeyicisi
797
>>> p = Program()
>>> [Link]
0
>>> [Link]
0
Daha sonra herhangi bir sebepten tr buradaki [Link] niteliine eriimi kstlayp
bu nitelii zerinde deiiklik yaplamaz hale getirmek istersek @property bezeyicisinden
yararlanabiliriz:
798
class Program():
def __init__(self):
self._say = 0
@property
def say(self):
return self._say
Grdnz gibi, ncelikle [Link] adl nitelii, bana bir alt izgi getirerek normal eriime
kapatmak istediimizi belirttik. Bu kodlar grenler, say niteliinin yar-gizli bir ye olduunu
anlayp ona gre davranacak. Ayrca biraz sonra tanmlayacamz say() fonksiyonuyla
bu deikenin adnn birbirine karmamas iin de bir nlem alm olacaz. Pythonda bir
deikenin adn deitirmeden o deikene eriimi kontrol altna almak istediimizde tek alt
izgi kullanmak tercih edilen bir yntemdir.
Daha sonra da say() fonksiyonumuzu tanmlyoruz:
@property
def say(self):
return self._say
Bu say() fonksiyonunu @property ile bezediimiz iin, fonksiyon bir nitelie dnt ve
say deikenini salt okunur hale getirdi. Eer amacnz deikeni salt okunur hale getirmek
deilse @property ile bezediimiz fonksiyon iin bir setter parametresi tanmlayabilirsiniz.
Nasl m? Dikkatlice inceleyin:
class Program():
def __init__(self):
self._say = 0
@property
def say(self):
return self._say
@[Link]
def say(self, yeni_deer):
self._say = yeni_deer
return self._say
@property ile bezeyerek bir nitelik haline getirdiiniz fonksiyonu yazlabilir hale getirmek ve
bu yazma ileminin nasl olacan belirlemek iin zel bir .setter bezeyicisi ile bezenmi yeni
bir fonksiyon tanmlayabilirsiniz.
Biz yukarda, yine say adn tayan, .setter ile bezenmi bir fonksiyon daha tanmladk:
@[Link]
def say(self, yeni_deer):
self._say = yeni_deer
return self._say
Yukardaki kodlar altrdmzda, _say deikenine say ad ile normal bir ekilde eriip
istediimiz deiiklii yapabiliyoruz:
>>> p = Program()
>>> [Link]
0
799
>>> [Link] = 5
>>> [Link]
5
Grdnz gibi, artk say deikeni, kendisi iin bir .setter bezeyicisi tanmlam olmamz
sayesinde deiiklik kabul ediyor.
.setter bezeyicisini, bir nitelii yazlabilir hale getirmenin yansra, dorulama ilemleri iin de
kullanabilirsiniz.
Basit bir rnek verelim:
class Program():
def __init__(self):
self._say = 0
@property
def say(self):
return self._say
@[Link]
def say(self, yeni_deer):
if yeni_deer % 2 == 0:
self._say = yeni_deer
else:
print('ift deil!')
return [Link]
Bu arada, .setter dnda .deleter adl zel bir @property bezeyicisi daha bulunur. Bunu da
bir deeri silmek iin kullanyoruz:
class Program():
def __init__(self):
self._say = 0
@property
def say(self):
return self._say
@[Link]
def say(self, yeni_deer):
if yeni_deer % 2 == 0:
self._say = yeni_deer
else:
800
print('ift deil!')
return [Link]
@[Link]
def say(self):
del self._say
801
BLM 46
802
self.g = 100
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class i():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 70
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Ynetici():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 20
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
Burada asker, ii ve yneticinin her biri iin ayr bir snf tanmladk. Her snfn bir ismi,
rtbesi ve gc var. Ayrca her snf; hareket etme, puan kazanma ve puan kaybetme gibi
kabiliyetlere sahip.
Bu kodlarn [Link] adl bir dosyada bulunduunu varsayarsak, mesela bir asker
oluturmak iin yukardaki kodlar yle kullanabiliriz:
>>> import oyuncular
>>> asker1 = [Link]('Mehmet', 'er')
Asker() snfnn isim ve rtbe parametrelerini belirtmek suretiyle bir asker nesnesi
oluturduk. Tpk Pythonda grdmz baka nesneler gibi, bu nesne de eitli nitelik ve
metotlardan oluuyor:
>>> dir(asker1)
803
Ayn ekilde teki i() ve Ynetici() snarn da rnekleyip kullanabiliriz. Bu konuda bir
problem yok. Ancak yukardaki kodlar incelediinizde, ayn kodlarn srekli tekrarlandn
greceksiniz. Grdnz gibi, ayn nitelik ve metotlar her snf iin yeniden tanmlyoruz.
Bu durumun Pythonn mantalitesine aykr olduunu tahmin etmek hi zor deil. Peki acaba
yukardaki kodlar nasl daha Pythonvari hale getirebiliriz?
Bu noktada ilk olarak taban snardan sz etmemiz gerekiyor.
804
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class i():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 70
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Ynetici():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 20
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
Bu rnekte, Asker(), i() ve Ynetici() adl snarn ieriine baktmzda pek ok metot
ve niteliin aslnda birbiriyle ayn olduunu gryoruz. Gelin isterseniz btn snarda ortak
olan bu nitelik ve metotlar tek bir snf altnda toplayalm.
Asker(), i() ve Ynetici() snarnn, yazdmz programdaki oyuncular temsil ettiini
dnrsek, ortak nitelik ve metotlar barndran snfmz da Oyuncu() olarak adlandrmamz
mantksz olmayacaktr:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
805
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
te burada Oyuncu() adl snf, bir taban snf olarak adlandrlr. Taban snf denen ey,
birka farkl snfta ortak olan nitelik ve metotlar barndran bir snf trdr. ngilizcede
base class olarak adlandrlan taban snar, ayrca st snf (super class ) veya ebeveyn snf
(parent class ) olarak da adlandrlr. Biz bu makalede taban snf ismini tercih edeceiz.
Yukardaki Oyuncu() adl taban snf da, i(), Asker(), Ynetici() gibi snarn hepsinde
ortak olarak bulunacak nitelik ve metotlar barndracak. teki btn snar, ortak nitelik ve
metotlarn her defasnda tek tek yeniden tanmlamak yerine, Oyuncu() adl bu taban snftan
devralacak. Peki ama nasl? te bunu anlamak iin de alt snf adl bir kavrama deinmemiz
gerekiyor.
Burada Asker() snfn tanmlarken, bu snfn parantezleri iine Oyuncu() snfnn adn
yazdmza dikkat edin. te bu ekilde bir snfn parantezleri iinde baka bir snfn adn
belirtirsek, o snf, parantez iinde belirttiimiz snfn bir alt snf olmu olur. Yani mesela
yukardaki gibi Asker() snfnn parantezleri arasna Oyuncu() snfnn adn yazdmzda,
Asker() adl snf;
1. Oyuncu() adl snf miras alm,
806
rnek olmas asndan, Oyuncu() snfndan treyen (miras alan) birka alt snf daha
tanmlayalm:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Asker(Oyuncu):
pass
class i(Oyuncu):
pass
class Ynetici(Oyuncu):
pass
Tanmladmz bu i() ve Ynetici() snar da tpk Asker() snf gibi Oyuncu() adl
snftan miras ald iin, Oyuncu() snfnn sahip olduu tm nitelik ve metotlara sahiptirler.
Buraya kadar anlattklarmz zetleyecek olursak, u snf bir taban snftr:
class Oyuncu():
def __init__(self, isim, rtbe):
807
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
Bu taban snf, kendisinden treyecek alt snarn ortak nitelik ve metotlarn tanmlar.
u snar ise, yukardaki taban snftan treyen birer alt snftr:
class Asker(Oyuncu):
pass
class i(Oyuncu):
pass
class Ynetici(Oyuncu):
pass
Bu alt snar, Oyuncu() adl taban snfn btn nitelik ve metotlarn miras yoluyla devralr.
Yani Oyuncu() adl taban/ebeveyn/st snfn nitelik ve metotlarna, Asker(), i() ve
Ynetici() adl alt snardan eriebiliriz:
>>>
>>>
>>>
>>>
'hareket ediliyor...'
>>> ii1.puan_kaybet()
'puan kaybedildi'
>>> ynetici1.puan_kazan()
'puan kazanld'
te bu mekanizmaya miras alma (inheritance ) ad verilir. Miras alma mekanizmas, bir kez
yazlan kodlarn farkl yerlerde kullanlabilmesini salayan, bu bakmdan da programcy kod
tekrarna dmekten kurtaran olduka faydal bir aratr. lerleyen sayfalarda miras alma
mekanizmasnn baka faydalarn da greceiz.
Burada Asker() snf, miras ald Oyuncu() snfnn sanki bir kopyas gibidir. Dolaysyla
Oyuncu() snfnn btn nitelik ve metotlarna Asker() snf altndan da aynen eriebiliriz.
Yani yukardaki kod, Oyuncu() adl snfn btn nitelik ve metotlarnn Asker() snf
tarafndan miras alnmasn salar. Bu ekilde, Oyuncu() snf iinde hangi metot veya nitelik
nasl tanmlanmsa, Asker() snfna da o ekilde devredilir.
Taban snfmzn u ekilde tanmlandn biliyoruz:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
Dolaysyla bu taban snfta hangi nitelik ve metotlar hangi deerlere sahipse aadaki
Asker(), i() ve Ynetici() snar da o deerlere sahip olacaktr:
class Asker(Oyuncu):
pass
class i(Oyuncu):
pass
class Ynetici(Oyuncu):
pass
Ancak, dediimiz gibi, miras almada tek seenek btn metot ve nitelikleri olduu gibi alt
snara aktarmak deildir. Zaten yle olsayd miras alma mekanizmasnn pek bir anlam
olmazd. Biz miras aldmz snar zerinde, iinde bulunduumuz durumun gerektirdii
birtakm deiiklikleri yapabilmeliyiz ki bu mekanizmann ilgi ekici bir yan olsun.
809
Ayrca eer bir taban snf alt snara olduu gibi aktaracaksanz, taban snftan gelen
metot ve nitelikler zerinde herhangi bir deiiklik yapmayacaksanz ve alt snara da
herhangi bir nitelik ilave etmeyecekseniz, alt snar tanmlamak yerine dorudan taban
snfn rneklerinden yararlanmak daha akllca ve pratik bir tercih olabilir:
>>> asker = Oyuncu('Ahmet', 'Er')
>>> ii = Oyuncu('Mehmet', 'Usta')
>>> ynetici = Oyuncu('Selim', 'Mdr')
Burada asker, ii ve ynetici iin ayr ayr alt snar tanmlamak yerine, her biri iin dorudan
Oyuncu() snfn farkl isim ve rtbe deerleriyle rnekleyerek istediimiz eyi elde ettik.
lerleyen derslerde miras alma alternatierinden daha ayrntl bir ekilde sz edeceiz, ama
dilerseniz imdi konuyu daha fazla datmadan miras alnan metot ve niteliklerin alt snar
iinde nasl yeniden tanmlanacan, nasl deiiklie uratlacan ve alt snara nasl yeni
nitelik ve metotlar ekleneceini incelemeye geelim ve ilk rneklerimizi vermeye balayalm.
Hatrlarsanz bir nceki balkta yle bir kod yazmtk:
class Asker(Oyuncu):
pass
Burada Oyuncu() snfn btnyle alt snfa aktardk. Peki ya biz bir taban snf olduu
gibi miras almak yerine, baz nitelikleri zerinde deiiklik yaparak miras almak istersek ne
olacak? Mesela taban snf iinde self.g deeri 0. Biz bu deerin Asker(), i() ve
Ynetici() rnekleri iin birbirinden farkl olmasn isteyebiliriz. Veya taban snf olduu gibi
miras almakla birlikte, alt snardan herhangi birine ilave nitelik veya nitelikler eklemek de
isteyebiliriz. Diyelim ki biz Asker() snf iin, teki snardan farkl olarak, bir de memleket
nitelii tanmlamak istiyoruz. Peki bu durumda ne yapacaz?
te bunun iin Asker() snfn u ekilde yazabiliriz:
class Asker(Oyuncu):
memleket = 'Arpabahi'
Burada Asker() snfna memleket adl bir snf nitelii eklemi olduk. Dolaysyla Asker()
snf, Oyuncu() adl taban snftan miras alnan btn nitelik ve metotlarla birlikte bir de
memleket niteliine sahip olmu oldu:
>>> asker = Asker('Ahmet', 'binba')
>>> [Link]
'Ahmet'
>>> [Link]
'Arpabahi'
Elbette, bu nitelii br alt snarda tanmlamadmz iin bu nitelik yalnzca Asker() snfna
zgdr.
Ayn ekilde, bir taban snftan treyen bir alt snfa yeni bir snf metodu, rnek metodu veya
statik metot da ekleyebiliriz:
class Asker(Oyuncu):
memleket = 'Arpabahi'
810
def rnek_metodu(self):
pass
@classmethod
def snf_metodu(cls):
pass
@staticmethod
def statik_metot():
pass
Kural u: Eer alt snfa eklenen herhangi bir nitelik veya metot taban snfta zaten varsa, alt
snfa eklenen nitelik ve metotlar taban snftaki metot ve niteliklerin yerine geecektir. Yani
diyelim ki taban snfmz u:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
Eer taban snfta hareket_et() adl bir snf olmasayd, Asker() adl alt snf, taban snftan
miras alnan teki metot ve niteliklerle birlikte bir de hareket_et() adl yeni bir rnek
metoduna sahip olmu olacakt. Ancak taban snfta zaten hareket_et() adl bir rnek
metodu olduu iin, alt snfta tanmladmz ayn adl rnek metodu, taban snftaki metodun
yerine geip zerine yazyor.
Buraya kadar her ey tamam. Artk bir taban snfa ait metodu alt snfa miras yoluyla
aktarrken nasl yeniden tanmlayacamz rendik. Ayrca alt snara nasl yeni metot
ve nitelik ekleyeceimizi de biliyoruz. Ama mesela, [Link] ve [Link] deikenlerini
korurken, taban snf iinde 0 deeri ile gsterilen self.g deikenini Asker(), i() ve
Ynetici() snarnn her biri iinde nasl farkl bir deerle gstereceimizi bilmiyoruz. Yani
self.g deerini Asker() snf iinde 100, i() snf iinde 70, Ynetici() snf iinde
ise 50 ile gstermek istesek nasl bir yol takip etmemiz gerektii konusunda bir krimiz yok.
sterseniz u ana kadar bildiimiz yntemleri kullanarak bu amacmz gerekletirmeyi bir
deneyelim:
811
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 100
class i(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 70
class Ynetici(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 50
Burada taban snfn __init__() metodunu alt snarda yeniden tanmladk. Bu kodlar bu
ekilde yazp altrdmzda self.g deerinin herbir alt snf iin istediimiz deere sahip
olduunu grrz. Ancak burada yle bir sorun var. Bu kodlar bu ekilde yazarak [Link]
ve [Link] deikenlerinin deerini maalesef kaybettik...
__init__() metodunun parametre listesine isim ve rtbe parametrelerini yazdmz halde
bunlar kodlarmz iinde herhangi bir ekilde kullanmadmz iin, bu parametrelerin listede
grnyor olmas bir ey ifade etmiyor. Yani alt snarda tanmladmz __init__() metodu
bizden isim ve rtbe adl iki parametre bekliyor olsa da, bu parametrelerin deerini kodlar
iinde kullanmadmz iin bu parametrelere deer atamamz herhangi bir amaca hizmet
etmiyor.
Gelin bu sylediklerimizi kantlayalm:
>>> import oyuncular
>>> asker = [Link]('Ahmet', 'Er')
>>> [Link]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Asker' object has no attribute 'rtbe'
>>> [Link]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Asker' object has no attribute 'isim'
812
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 100
class i(Oyuncu):
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 70
class Ynetici(Oyuncu):
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 50
Burada [Link] ve [Link] deikenlerini herbir alt snf iin tekrar tanmladk. Bu kk
rnekte pek sorun olmayabilir, ama taban snfn __init__() metodunun iinde ok daha
karmak ilemlerin yapld durumlarda yukardaki yaklam hi de pratik olmayacaktr.
Ayrca eer miras alma ilemini, ieriini bilmediiniz veya baka bir dosyada bulunan bir
snftan yapyorsanz yukardaki yntem tamamen kullansz olacaktr. Ayrca ayn eyleri
tekrar tekrar yazmak miras alma mekanizmasnn ruhuna tamamen aykrdr. nk biz miras
alma ilemini zaten ayn eyleri tekrar tekrar yazmaktan kurtulmak iin yapyoruz.
Bu arada, yukarda yapmak istediimiz eyi ununla kartrmayn: Biz elbette taban snftaki
bir nitelii, rnekleme srasnda deitirme imkanna her koulda sahibiz. Yani taban ve alt
snarn yle tanmlanm olduunu varsayarsak:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Asker(Oyuncu):
pass
class i(Oyuncu):
pass
class Ynetici(Oyuncu):
pass
813
Ayn eyi teki i() ve Ynetici() snarnn rnekleri zerinde de yapabiliriz. Ama
bizim istediimiz bu deil. Biz, Asker() snfn rneklediimiz anda gc 100, i() snfn
rneklediimiz anda gc 70, Ynetici() snfn rneklediimiz anda ise gc 50 olsun
istiyoruz.
te tam bu noktada imdadmza yepyeni bir fonksiyon yetiecek. Bu yeni fonksiyonun ad
super().
46.5 super()
Hatrlarsanz, taban snardan ilk kez bahsederken, bunlara st snf da dendiini sylemitik.
st snf kavramnn ngilizcesi super class tr. te bu blmde inceleyeceimiz super()
fonksiyonunun ad da buradaki super, yani st kelimesinden gelir. Miras alnan st snfa
atfta bulunan super() fonksiyonu, miras aldmz bir st snfn nitelik ve metotlar zerinde
deiiklik yaparken, mevcut zellikleri de muhafaza edebilmemizi salar.
Bir nceki balkta verdiimiz rnek zerinden super() fonksiyonunu aklamaya alalm:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 100
Bu kodlarda, Oyuncu() adl taban snf miras alan Asker() snf, __init__() metodu iinde
self.g deerini yeniden tanmlyor. Ancak bu ekilde taban snfn __init__() metodu
silindii iin, [Link] ve [Link] deikenlerini kaybediyoruz. te bu sorunu, st snfa
atfta bulunan super() fonksiyonu ile zebiliriz.
Dikkatlice bakn:
814
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
super().__init__(isim, rtbe)
self.g = 100
te bu satrda super() fonksiyonu, tam da adnn anlamna uygun olarak, miras alnan st
snfn __init__() metodu iindeki kodlarn, miras alan alt snfn __init__() metodu iine
aktarlmasn salyor. Bylece hem taban snfn __init__() metodu iindeki [Link] ve
[Link] niteliklerini korumu, hem de self.g adl yeni bir nitelik ekleme imkan elde etmi
oluyoruz:
>>> asker = [Link]('Ahmet', 'Er')
>>> [Link]
'Ahmet'
>>> [Link]
'Er'
>>> asker.g
100
46.5. super()
815
super().__init__(isim, rtbe)
self.g = 20
Yldzl parametreleri nceki derslerimizden hatrlyor olmalsnz. Bildiiniz gibi, tek yldzl
parametreler bir fonksiyonun btn konumlu (positional ) argmanlarn, parametrelerin
parantez iinde getii sray dikkate alarak bir demet iinde toplar. te yukarda da bu
zellikten faydalanyoruz. Eer taban snfta isimli (keyword ) argmanlar da olsayd, o zaman
da ift yldzl argmanlar kullanabilirdik.
Tek ve ift yldzl argmanlar genellikle u ekilde gsterilir:
class Asker(Oyuncu):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.g = 100
Bylece konumlu argmanlar bir demet iinde, isimli argmanlar ise bir szlk iinde
toplam oluyoruz. Bu da bizi st (ya da taban) snfn parametre listesini alt snarda tekrar
etme derdinden kurtaryor.
Bu arada, miras alnan taban snfa atfta bulunan super() fonksiyonu, Python programlama
diline sonradan eklenmi bir zelliktir. Bu fonksiyon gelmeden nce taban snfa atfta
bulunabilmek iin dorudan o snfn adn kullanyorduk:
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
Oyuncu.__init__(self, isim, rtbe)
self.g = 100
veya:
class Asker(Oyuncu):
def __init__(self, *args):
Oyuncu.__init__(self, *args)
self.g = 100
816
Grdnz gibi, eski yntemde taban snfn adn iki kez kullanmamz gerekiyor. Ayrca
__init__() fonksiyonunun parametre listesinde ilk sraya yine self kelimesini de eklemek
zorunda kalyoruz.
sterseniz yukarda gsterdiimiz eski yntemi kullanmaya devam edebilirsiniz elbette. Ancak
super() fonksiyonunu kullanmak eski ynteme gre biraz daha pratiktir.
Yukardaki rneklerde super() fonksiyonunu __init__() metodu iinde kullandk. Ancak
elbette super() fonksiyonunu yalnzca __init__() fonksiyonu iinde kullanmak zorunda
deiliz. Bu fonksiyonu baka fonksiyonlar iinde de kullanabiliriz:
class Oyuncu():
def __init__(self, isim, rtbe):
[Link] = isim
[Link] = rtbe
self.g = 0
def hareket_et(self):
print('hareket ediliyor...')
def puan_kazan(self):
print('puan kazanld')
def puan_kaybet(self):
print('puan kaybedildi')
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
super().__init__(isim, rtbe)
self.g = 100
def hareket_et(self):
super().hareket_et()
print('hedefe ulald.')
Burada super().hareket_et() satryla taban snfn hareket_et() adl metodunu alt snfta
tanmladmz yeni hareket_et() metodu iinde altrarak, bu metodun kabiliyetlerini yeni
hareket_et() metoduna aktaryoruz.
veya:
46.6. object Snf
817
class Deneme:
pass
Snf tanmlarken parantez kullansak da olur kullanmasak da. Eer miras alacanz bir snf
yoksa parantezsiz yazm tercih edebilir, parantezli yazm tarzn ise baka bir snftan miras
aldnz durumlar iin saklayabilirsiniz:
class AltSnf(TabanSnf):
pass
Ancak sada solda incelediiniz Python kodlarnda bazen yle bir snf tanmlama ekli de
grrseniz armayn:
class Snf(object):
pass
Pythonn 3.x ncesi srmlerinde snar yeni ve eski tip olmak zere ikiye ayrlyordu. Bu
srmlerde eski tip snar yle tanmlanyordu:
class Snf:
pass
veya:
class Snf():
pass
Yani eski tip snar ntanml olarak herhangi bir taban snftan miras almazken, yeni
tip snarn object adl bir snftan miras almas gerekiyordu. Dolaysyla, tanmladnz
bir snfta object snfn miras almadnzda, yeni tip snarla birlikte gelen zelliklerden
yararlanamyordunuz. Mesela nceki derslerde rendiimiz @property bezeyicisi yeni tip
snarla gelen bir zelliktir. Eer Python 3 ncesi bir srm iin kod yazyorsanz ve eer
@property bezeyicisini kullanmak istiyorsanz tanmladnz snarda ak ak object snfn
miras almalsnz.
Python 3te ise btn snar yeni tip snftr. Dolaysyla object snfn miras alsanz da
almasanz da, tanmladnz btn snar ntanml olarak object snfn miras alacaktr.
Yani Python 3 asndan u tanmlama arasnda bir fark bulunmaz:
class Snf:
pass
class Snf():
pass
class Snf(object):
pass
Bunlarn hepsi de Python 3 asndan birer yeni tip snftr. Daha dorusu Python 3te btn
snar bir yeni tip snf olduu iin, yukardaki snf tanmlamalar hep ayn tipte snara
iaret eder. Python 2de ise ilk iki tanmlama eski tip snar gsterirken, yalnzca nc
tanmlama yeni tip snar gsterir.
818
819
BLM 47
GNU/Linux datmlarnda, datm gelitiren ekip genellikle Tkinter paketini Python paketinden ayrd
iin, Tkinteri ayrca kurmanz gerekebilir. Eer Pythonn etkileimli kabuunda import tkinter komutunu
verdiinizde bir hata mesaj alyorsanz [Link] adresinden yardm isteyin. Eer Windows
kullanyorsanz, byle bir probleminiz yok. Python kurduunuz anda Tkinter de emrinize amadedir.
820
Bu kodlar herhangi bir Python program gibi kaydedip altrdnzda bo bir pencerenin
aldn greceksiniz. te bylece siyah komut satrndan renkli grak arayze gei yapm
oldunuz. Hadi hayrl olsun!
Grdnz gibi, bu kodlarda snar kullanmadk. Dediimiz gibi, ilk etapta Tkinteri daha
iyi anlayabilmek iin sn yaplar yerine prosedrel bir yaklam benimseyeceiz.
Burada ncelikle Tkinter modln ie aktardmza dikkat edin:
import tkinter
821
Yukardaki kodlar yazdmzda, yani tkinter modlnn Tk() snfn rneklediimiz anda
aslnda penceremiz olutu. Ancak bu pencere rnekleme ile birlikte olumu olsa da,
Tkinterin i ileyii gerei, ana dng adl bir mekanizma almaya balamadan grnr
hale gelmez. te bu zel ana dng mekanizmasn altrmak ve bylece oluturduumuz
pencereyi grnr hale getirmek iin, Tk() snf rneklerinin mainloop() adl bir metodunu
altracaz:
[Link]()
Grdnz gibi, Tk() snfn pencere adyla rnekledikten sonra Tk() snfnn mainloop()
adl metoduna pencere rnei zerinden eritik.
Bu ana dng mekanizmasnn benzerlerini Tkinterin dndaki br grak arayz tasarm
aralarnda da greceksiniz.
Bu arada, yukardaki prosedrel rnekte bile, biz istemesek de snarla muhatap
olduumuza dikkatinizi ekmek isterim. nk kullandmz tkinter modlnn kendisi
halihazrda birtakm snardan oluuyor.
Dolaysyla bu modl ie aktardmzda,
kodlarmzn iine pek ok snf ister istemez dahil etmi oluyoruz. Esasnda srf bu durum
bile, grak arayzl programlarda neden nesne tabanl programlamann tercih edildiini
gayet gzel gsteriyor bize. Neticede, kullandmz harici kaynaklardan tr her ekilde
snarla ve nesne tabanl yaplarla ili dl olacamz iin, kendi yazdmz kodlarda da
nesne tabanl yaplardan kamamzn hibir gerekesi yok.
Neyse... Biz konumuza dnelim...
Yukarda Tkinter modln kullanarak bo bir pencere oluturduk. Gelin isterseniz bu bo
pencere zerinde birtakm deiiklikler yapalm.
ncelikle tkinter modlmz ie aktaralm:
import tkinter as tk
822
Kendi yazdmz snardaki nitelik ve metotlara nasl eriiyorsak, Tk() snfnn nitelik ve
metotlarna da ayn ekilde eritiimize dikkat edin. Neticede bizim yazdklarmz da snftr,
Tk() da snftr. Tk() snfnn bizimkilerden tek fark, Tk() snfnn Python gelitiricilerince
yazlm olmasdr. Yazarlar farkl olsa da btn snar ayn kurallara tabidir. Dolaysyla
ilgili snf kullanabilmek iin nce snfmz rnekliyoruz, ardndan da bu snf iinde tanml
olan nitelik ve metotlara noktal gsterim tekniini kullanarak ulayoruz. Burada da Tk()
snf rneklerinin geometry() metodunu kullanarak 200x200 yerine 200x70 boyutlarnda bir
pencere oluturduk:
[Link]('200x70')
Burada tkinter modlnn Tk() snfna ek olarak, ayn modln Label() ve Button() adl iki
snfn daha kullandk. Label() snf etiketler, Button() snf ise dmeler oluturmamz
salyor. Bu snarn rnekleri zerinde altrdmz pack() metodunu ise, etiket ve
dmeleri pencere zerine yerletirmek iin kullanyoruz.
Label() ve Button() snarnn text adl bir parametre aldn gryorsunuz.
parametrenin deeri, etiket veya dmenin zerinde ne yazacan gsteriyor.
Bu
Bu etiketi pencere zerine yerletirmek, yani grnr hale getirmek iin ise u komutu
kullanyoruz:
[Link]()
Bylece zerinde Tamam yazan ve tklandnda pencereyi kapatan bir dme oluturmu
oluyoruz. Dmenin zerine tklandnda ne olacan Button() snfnn command
parametresi araclyla belirledik. Bu parametreye, pencere rneinin destroy() metodunu
verdiimizde pencereye kapatma sinyali gnderilecektir. Yalnz bu metodu yazarken
parantez iaretlerini kullanmadmza dikkat edin. Eer metodu [Link]() eklinde
823
parantezli bir biimde yazarsak, kapatma komutu daha dmeye basmadan alacak ve bu
durumda dmemiz dzgn ilemeyecektir.
Tpk etikette olduu gibi, dmemizi de pencere zerine yerletirmek, yani grnr hale
getirmek iin pack() metodundan yararlanyoruz:
[Link]()
Bunun, Tk() snf ile mainloop() metodu arasndaki ilikiye benzediine dikkatinizi ekmek
isterim: Tpk pack() metoduna benzer bir ekilde, Tk() snf yardmyla da bir pencere
oluturduktan sonra, bu pencerenin grnr hale gelebilmesi iin mainloop() metodunu
altrmamz gerektiini hatrlyorsunuz.
Bu kodlarda Tkintere ilikin ayrntlardan ziyade, sn yaplar kodlarmza nasl dahil
ettiimize ve bunlar nasl kullandmza odaklanmanz istiyorum. Grdnz gibi, tkinter
modlnden ie aktardmz Tk(), Label() ve Button() gibi snarn metot ve niteliklerini,
mesela tpk karakter dizilerinin metot ve niteliklerini kullanr gibi kullanyoruz.
Yukardaki rnekte, tkinter modlnn snarn, kodlarmz iine prosedrel olarak dahil
ettik. Yani her snf, belli bir sraya gre kodlarmz iinde belirtip, bunlar adm adm
altrdk. Prosedrel programlamada kodlarn yazl sras ok nemlidir. Bunu kantlamak
iin ok basit bir rnek verelim:
import tkinter as tk
pencere = [Link]()
def k():
etiket['text'] = 'Elveda zalim dnya...'
dme['text'] = 'Bekleyin...'
dme['state'] = 'disabled'
[Link](2000, [Link])
etiket = [Link](text='Merhaba Zalim Dnya')
[Link]()
dme = [Link](text='k', command=k)
[Link]()
[Link]('WM_DELETE_WINDOW', k)
[Link]()
824
Buna gre,
Buna gre, dmeye basldnda, command parametresinin deeri olan k() fonksiyonu
almaya balayacak ve fonksiyon gvdesinde tanmladmz ilemler gerekleecek.
Bildiiniz gibi, bir program penceresinde, o program kapatmay salayacak dmelerin
yansra, bir de en st sa (veya sol) kede program penceresini kapatan bir X dmesi
bulunur. te bu X dmesine basldnda da pencere kapanmadan nce k()
fonksiyonunun almas iin u kodu yazyoruz:
[Link]('WM_DELETE_WINDOW', k)
825
[Link]('WM_DELETE_WINDOW', k)
[Link]()
826
[Link]()
[Link] = [Link](text='k', command=self.k)
[Link]()
def k(self):
[Link]['text'] = 'Elveda zalim dnya...'
[Link]['text'] = 'Bekleyin...'
[Link]['state'] = 'disabled'
[Link](2000, [Link])
pencere = Pencere()
[Link]()
Bu kodlarda grdnz btn satrlar anlayacak kadar nesne tabanl programlama bilgisine
sahipsiniz. Ama gelin biz yine de bu kodlar sizin iin tek tek ve tane tane aklayalm.
ncelikle tkinter modln tk adyla ie aktaryoruz:
import tkinter as tk
Burada ncelikle Tk() snfn miras aldmza dikkat edin. Bu sayede bu snfn iindeki btn
nitelik ve metotlar kendi uygulamamz iinden arabileceiz.
Penceremiz oluur olumaz pencere zerinde bir etiket ile bir dme olmasn planlyoruz.
Pencere oluur olumaz iletilecek kodlar tanmlamak iin bir __init__() metoduna
ihtiyacmz olduunu biliyorsunuz:
class Pencere([Link]):
def __init__(self):
...
Artk taban snfn __init__() metodunu kendi tanmladmz alt snfn __init__() metodu
iinden zelletirmeye balayabiliriz. ncelikle u satr yazyoruz:
[Link]('WM_DELETE_WINDOW', self.k)
827
Elbette zevkler ve renkler tartlmaz, ancak ben yukardaki kodlar, prosedrel kodlara gre
ok daha dzgn, dzenli, anlalr ve okunakl bulduumu, bu kodlara baktmda, program
oluturan paralarn prosedrel kodlara kyasla daha yerli yerinde olduunu dndm
sylemeden de gemeyeceim...
Eer siz aksini dnyorsanz sizi prosedrel yolu tercih etmekten alkoyan hibir eyin
olmadn da bilin. Ancak tabii ki bu, nesne tabanl programlamadan kaabileceiniz
anlamna da gelmiyor! Unutmayn, bu yaklam siz kullanmasanz da bakalar kullanyor.
Bu ekilde hem taban_snf1 hem de taban_snf2 de bulunan nitelik ve metotlar ayn anda
Snf adl snfa dahil olacaktr.
Ufak bir rnek verelim. Diyelim ki elimizde u snar var:
class c1:
sn1 = 'sn1'
def __init__(self):
self.n1 = 'n1'
print(self.n1)
def rn_metot1(self):
self.m1 = 'm1'
return self.m1
class c2:
sn2 = 'sn2'
828
def __init__(self):
self.n2 = 'n2'
print(self.n2)
def rn_metot2(self):
self.m2 = 'm2'
return self.m2
class c3:
sn3 = 'sn3'
def __init__(self):
self.n3 = 'n3'
print(self.n3)
def rn_metot3(self):
self.m3 = 'm3'
return self.m3
Burada farkl snf ve herbir snfn iinde de birer snf nitelii, birer __init__() metodu,
birer rnek nitelii ve birer rnek metodu gryoruz.
imdi bu snf birden taban snf olarak miras alan drdnc bir snf tanmlayalm:
class c4(c1, c2, c3):
pass
Burada, taban snf vazifesi grecek snarn adn c4 snfnn parantezleri arasna tek tek
yerletirdiimize dikkat edin. Bu ekilde c1, c2 ve c3 adl snar ayn anda miras alm
oluyoruz. te bu mekanizmaya Pythonda oklu miras alma (multiple inheritance ) ad
veriliyor.
Tek bir snf miras aldnzda hangi kurallar geerliyse, birden fazla snf miras aldnzda da
temel olarak ayn kurallar geerlidir. Ancak oklu miras almada birden fazla snf sz konusu
olduu iin, miras alnan snarn da kendi aralarnda veya baka snarla nitelik ve/veya
metot alverii yapmas halinde ortaya kabilecek beklenmedik durumlara kar dikkatli
olmalsnz. Ayrca oklu miras alma ilemi srasnda, ayn ad tayan metotlardan yalnzca
birinin miras alnacan da unutmayn.
rnein:
class c1:
sn1 = 'sn1'
def __init__(self):
self.n1 = 'n1'
print(self.n1)
def rn_metot1(self):
self.m1 = 'm1'
return self.m1
def ortak_metot(self):
[Link] = 'ortak metot_c1'
return [Link]
class c2:
829
sn2 = 'sn2'
def __init__(self):
self.n2 = 'n2'
print(self.n2)
def rn_metot2(self):
self.m2 = 'm2'
return self.m2
def ortak_metot(self):
[Link] = 'ortak metot_c2'
return [Link]
class c3:
sn3 = 'sn3'
def __init__(self):
self.n3 = 'n3'
print(self.n3)
def rn_metot3(self):
self.m3 = 'm3'
return self.m3
def ortak_metot(self):
[Link] = 'ortak metot_c3'
return [Link]
class c4(c1, c2, c3):
def __init__(self):
super().__init__()
Burada, ayn ad tayan __init__() ve ortak_metot() adl metotlardan yalnzca biri miras
alnacaktr. Bunlardan hangisinin miras alnacan az ok tahmin etmisinizdir. Evet, doru
bildiniz. Miras alma listesinde hangi snf nde geliyorsa onun metotlar miras alnacaktr:
s = c4()
print(s.ortak_metot())
Grdnz gibi, c4() snf nce c1 snfn miras ald iin hep c1 snfnn metotlar ncelik
kazanyor.
Eer snar class c4(c2, c3, c1): eklinde miras alsaydk, bu kez de c2 snfnn metotlar
ncelik kazanacakt.
Elbette, Pythonn sizin iin belirledii ncelik sras yerine kendi belirlediiniz ncelik srasn
da dayatabilirsiniz:
class c4(c1, c2, c3):
def __init__(self):
c2.__init__(self)
def ortak_metot(self):
return c3.ortak_metot(self)
Burada c2 snfnn __init__() metodu ile c3 snfnn ortak_metotuna miras ncelii verdik.
830
Burada ayn anda hem miras alma hem de dahil etme ynteminden yararlanyoruz. lk
nce Tk() snfn miras aldk. Bylece bu snfn nitelik ve metotlarna dorudan eriim elde
ettik. Etiket ve dme oluturmamz salayan Label() ve Button() snarn ise Pencere()
snfmz iine dahil ettik. Bylece bu snarn nitelik ve metotlarna srasyla [Link] ve
[Link] adlar altnda eriim kazandk.
Miras alma ve dahil etme yntemleri arasnda tercih yaparken genel yaklammz u olacak:
Eer yazdmz uygulama, bir baka snfn trevi ise, o snf miras alacaz. Ama eer bir
snf, yazdmz uygulamann bir paras ise o snf uygulamamza dahil edeceiz.
Yani mesela yukardaki rnekte temel olarak yaptmz ey bir uygulama penceresi
tasarlamaktr. Dolaysyla uygulama penceremiz, [Link]() snfnn dorudan bir trevidir.
O yzden bu snf miras almay tercih ediyoruz.
Pencere zerine etiket ve dme yerletirmemizi salayan Label() ve Button() snar ise,
uygulama penceresinin birer parasdr. Dolaysyla bu snar uygulamamz iine dahil
ediyoruz.
Yukarda anlattmz iki farkl iliki tr olma ilikisi (is-a relationship ) ve sahiplik ilikisi
(has-a relationship ) olarak adlandrlabilir. Olma ilikisinde, bir snf tekinin trevidir. Sahip
olma ilikisinde ise bir snf teki snfn parasdr. Eer iki snf arasnda olma ilikisi varsa
miras alma yntemini kullanyoruz. Ama eer iki snf arasnda sahiplik ilikisi varsa dahil
831
832
BLM 48
Nesne tabanl programlamaya ilikin bu son blmde nceki derslerde incelemeye frsat
bulamadmz ileri dzey konulardan sz edeceiz.
833
Bu snf rneklediinizde, bir nceki kodlarn aksine, ekrana merhaba snf yazs kt olarak
verilmeyecektir. te bunun sebebi, Pythonn ntanml __new__() metodunun zerine yazp,
o metodun ilevselliini ortadan kaldrm olmanzdr. Eer __new__() metodunun ntanml
davrann taklit etmek isterseniz yukardaki kodlar u ekilde yazmalsnz:
class Snf():
def __new__(cls, *args, **kwargs):
return object.__new__(cls, *args, **kwargs)
def __init__(self):
print('merhaba snf')
Burada yaptmz eyin aslnda temel olarak basit bir miras alma ileminden ibaret olduunu
gryor olmalsnz. Bildiiniz gibi, Pythondaki btn snar, eer baka bir snf miras
olarak almyorlarsa, otomatik olarak object snfn miras alrlar. Yani aslnda yukardaki snf
tanmn Python yle grr:
class Snf(object):
...
Burada object taban snf olmu oluyor. Bu taban snfn __new__() metodunun sahip olduu
ilevsellii Snf adl alt snfa aktarabilmek iin taban snf kendi __new__() metodumuz
iinde aryoruz:
class Snf():
def __new__(cls, *args, **kwargs):
return object.__new__(cls, *args, **kwargs)
te eer bir snfn ina edilme srecinin nasl ileyeceini kontrol etmek isterseniz bu
__new__() metodunun zerine yazarak metodu deiiklie uratabilirsiniz:
class Snf():
def __new__(cls, *args, **kwargs):
print('Yeni snf ina edilirken ltfen bekleyiniz...')
return object.__new__(cls, *args, **kwargs)
def __init__(self):
print('merhaba snf')
834
BLM 49
Paketler
835
>>> import os
>>> os.__path__
AttributeError: 'module' object has no attribute '__path__'
os bir modl olduu iin, __path__ niteliine sahip deildir. Bir de json paketine bakalm:
>>> import json
>>> json.__path__
json ise bir paket olduu iin, __path__ niteliine sahiptir. Birazdan bu niteliin ne ie
yaradn anlatacaz. Ama ondan nce renmeniz gereken baka eyler var.
Paketleri,
Standart Paketler
nc ahs Paketleri
Bu trlerin ne anlama geldiini isimlerine bakarak rahatlkla anlayabiliyoruz. Ama gelin
isterseniz bunlar ksaca gzden geirelim.
ncelikle standart paketlerden balayalm.
Eer sorguladnz eyin bir __path__ nitelii yoksa, paket sandnz o ey, aslnda bir paket
deildir. rnein:
>>> import subprocess
>>> subprocess.__path__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__path__'
836
nk, bildiiniz gibi, paketlerin aksine, modllerin __path__ adl bir nitelii bulunmaz.
subprocess de bir paket deil, modl olduu iin __path__ sorgusu hata verecektir.
Bir paketin __path__ niteliini sorguladnzda ktda hangi dizini gryorsanz, o
paketin bilgisayardaki konumu odur. Mesela yukarda adn andmz urllib paketinin
__path__ niteliini sorgulayp, karmza kan klasre gidelim.
Paket dizininin iini
atmzda karmza u dosyalar kacak:
[Link]
[Link]
[Link]
[Link]
[Link]
__init__.py
Daha nce de dediimiz gibi, paketler modllerden oluur. te urllib paketi de yukarda
ismini grdmz modllerin birleiminden oluuyor. Python kurulum dizini iindeki Lib
klasr altnda yer alan paketleri inceleyerek, hangi paketin hangi modllerden olutuunu
kendiniz de grebilirsiniz.
Elbette, eer bir GNU/Linux datm kullanyorsanz, bu komutu root haklaryla altrmanz
gerektiini sylememe herhalde gerek yok:
837
pip3 adl yazlm, sphinx paketinin btn dosyalarn PyPI sitesinden ekip otomatik olarak
bilgisayarmza kuracaktr.
Bir nc ahs paketini pip3 komutuyla kurmak yerine elle kurmay da tercih
edebilirsiniz. rnek olarak bu defa django paketini alalm. Bu paketin en son srmn
[Link] adresinden indirebilirsiniz. Ayrca
arzu ederseniz [Link] adresine urayarak bu modln resmi
websitesine de gzatabilirsiniz.
ndirdiiniz [Link] uzantl sktrlm dosyay atnzda karsnza pek ok dizin ve bu
dizinlerin iinde de pek ok Python dosyas kacak. Django, geni kapsaml nc ahs
paketlerine gzel bir rnektir.
Django paketini ap django-master adl dizinin iine girdiinizde, orada [Link] adl
bir dosya greceksiniz. te pip3 komutu yerine, bu dosyay kullanarak da bu paketi
bilgisayarmza kurabiliriz.
Dikkatlice bakn:
python3 [Link] install
Eer herhangi bir kt verilmeden alt satra geildiyse, bir nc ahs paketi olan
django yu bilgisayarnza baaryla kurmusunuz demektir. Bu nc ahs modln
nasl kullanacanz renmek iin internet zerindeki saysz makaleden ve kitaptan
yararlanabilirsiniz.
838
Veya bu modl iindeki bir nitelii veya metodu baka bir isim altnda da ie aktarabiliriz:
>>> from os import execv as exe
Gelelim paketlere...
Ancak os modlnn aksine, urllib paketini ie aktardmzda mevcut isim alanna herhangi
bir nitelik veya metot otomatik olarak aktarlmaz. rnein os modln ie aktardmzda
bu modln ieriinin, os neki altnda mevcut isim alanna dkldn biliyoruz:
>>> dir(os)
Grdnz gibi, modl ierii kullanlabilir durumda. Listedeki nitelik ve metotlara os neki
ile eriebiliriz:
>>> [Link]
>>> [Link]([Link]())
gibi...
Ancak import os komutunun aksine, import urllib komutu, paket ieriini otomatik olarak
mevcut isim alanna aktarmaz:
>>> import urllib
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__path__',
'__spec__']
Grdnz gibi listede yalnzca standart metot ve nitelikler var. Bu listede mesela paket
ieriinde olduunu bildiimiz [Link], [Link], [Link], [Link] ve [Link]
gibi modlleri gremiyoruz. Eer paket iinde bulunan belirli bir modl ie aktarmak
istiyorsak bunu ak ak belirtmeliyiz. Nasl m? Grelim...
839
>>> [Link]('[Link]
Bu ekilde urllib paketi iindeki request modlnden urlopen adl metodu dorudan ie
aktarm olduk. Dolaysyla bu metodu dmdz kullanabiliriz:
>>> urlopen('[Link]
Ancak, modller konusunu ilerken neksiz aktarmaya ilikin sylediklerimizin paketler iin
de geerli olduunu aklmzdan karmyoruz.
Bu ekilde urllib paketi iindeki request modlnn btn nitelik ve metotlarn dorudan
mevcut isim alanna aktarm olduk. Bu yntemin byk bir rahatlk sunmakla birlikte nemli
dezavantajlara da sahip olduunu gayet iyi bildiinizden eminim.
840
te bu ekilde basit bir dosya-dizin yaps oluturduumuzda, siparistakip adl bir Python
paketi meydana getirmi oluyoruz1 .
Gelin isterseniz, siparistakip dizininin gerekten bir paket olduunu teyit edelim.
ncelikle paketimizi ie aktaralm. Bunun iin siparistakip dizininin bulunduu klasrde u
komutu verelim:
1
Daha nce Pythonn 2.x srmlerini kullanm olanlar, bu yapnn bir paket oluturmak iin yeterli olmadn
dnebilir. nk Pythonn 2.x srmlerinde bir paket oluturabilmek iin, siparistakip dizininin iinde
__init__.py adl bir dosya daha oluturmamz gerekiyordu. Ancak Python3te bu zorunluluk ortadan kaldrld. Eer
bu sylediimiz eyin ne anlama geldiini bilmiyorsanz, bu uyary grmezden gelip yolunuza devam edebilirsiniz.
841
Grdnz gibi, listede __path__ adl bir nitelik var. Bu niteliin yalnzca paketlerde
bulunduunu biliyorsunuz. Demek ki siparistakip gerekten de bir Python paketiymi. Bunun
dnda, listede grdnz __package__ niteliini kullanarak da bir modln paket olup
olmadn kontrol edebilirsiniz:
>>> siparistakip.__package__
'siparistakip'
Eer test ettiimiz modl bir paketse, __package__ nitelii bize bir paket ad verecektir. Yok
eer test ettiimiz modl bir paket deil de alelade bir modlse, __package__ nitelii bo bir
karakter dizisi dndrecektir. Mesela os modlnn bir paket olmadn biliyoruz:
>>> import os
>>> os.__package__
''
Grdnz gibi, bu modln __package__ nitelii bo bir karakter dizisi. Ayrca bu modl bir
paket olmad iin, __path__ adl bir nitelik de barndrmyor:
>>> os.__path__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__path__'
842
+ altdizin
|__altmodul1.py
|__altmodul2.py
[Link] :
isim2 = 'modul2'
print(isim2)
[Link] :
isim3 = 'modul3'
print(isim3)
[Link] :
altisim1 = 'altmodul1'
print(altisim1)
[Link] :
altisim2 = 'altmodul2'
print(altisim2)
imdi paket adl dizinin bulunduu klasrde bir etkileimli kabuk oturumu aalm. Yalnz bu
oturumu paket dizinin iinde deil, bir st dizinde aacaksnz. Yani o anda bulunduunuz
dizinde dir veya ls komutu verdiinizde paket adl dizini gryor olmanz lazm... Eer dir
veya ls komutunun ktsnda altdizin adl dizini gryorsanz yanl yerdesiniz demektir.
Hemen bir st dizine gidin.
Bulunduumuz konumda u komutu verelim:
>>> import paket
Eer hibir kt almadan bir alt satra getiyseniz her ey yolunda demektir. Eer bir hata
mesaj gryorsanz, etkileimli kabuk oturumunu yanl konumda amsnzdr. Oturumu
doru konumda ap tekrar gelin...
Standart paketlerde ve nc ahs paketlerinde grdmz gibi, bir paketi yukardaki
ekilde ie aktardmzda, o pakete ait herhangi bir modl veya nitelik otomatik olarak ie
aktarlmyor. dir(paket) komutu verdiinizde yalnzca standart niteliklerin ie aktarldn
greceksiniz:
>>> dir(paket)
['__doc__', '__loader__', '__name__',
'__package__', '__path__', '__spec__']
Grdnz gibi, oluturduumuz paket, bir Python paketinin sahip olmas gereken btn
niteliklere sahip.
imdi bu paket iindeki modul1 adl modl ie aktaralm:
49.4. Kendi Oluturduumuz Paketler
843
Bylece modul1 adl modln iindeki deikenin deerini alm olduk. Paket iindeki teki
modlleri de ayn ekilde ie aktarabilirsiniz:
>>> from paket import modul2
modul2
>>> from paket import modul3
modul3
Grdnz gibi, paket iindeki modul1 modlnn isim1 niteliini baaryla aldk. rnek
olmas asndan tekileri de alalm:
>>> from paket.modul2 import isim2
modul2
>>> from paket.modul3 import isim3
modul3
Bu ekilde paket adl paketin altdizin adl alt dizinini ie aktarm olduk. Artk bu alt dizin
iindeki modllere ve onlarn niteliklerine eriebiliriz. Mesela paket adl paketin altdizin adl
alt dizini iindeki altmodul1 adl modln altisim1 niteliini alalm:
>>> [Link].altmodul1.altisim1
'altmodul1'
Grdnz gibi, altisim1 niteliine erimek iin uzun bir yol gitmemiz gerekiyor. Bu yolu
ksaltmak isterseniz modl u ekilde ie aktarabilirsiniz:
>>> from [Link] import altmodul1
844
>>> altmodul1.altisim1
'altmodul1'
Yani bu dosya ile ayn dizinde bulunan [Link] dosyasn, [Link] dosyas iinden
bir modl olarak ie aktaralm.
imdi, daha nce yaptmz gibi, paket adl dizinin bulunduu klasrde bir etkileimli kabuk
oturumu aalm ve u komutu yazalm:
>>> from [Link] import altmodul2
845
Bu hatann sebebi, Pythonn altmodul1 adl modl bulamyor olmasdr. Halbuki bu modl,
altmodul2 ile ayn dizinde bulunuyor. O halde acaba Python bu modl neden bulamyor?
Bunu anlamak iin yle bir deneme yapalm:
imdi [Link] ve [Link] dosyalarnn bulunduu konumda bir etkileimli kabuk
oturumu balatn ve u komutu verin:
>>> import altmodul2
Grdnz gibi, bu defa Python herhangi bir hata mesaj vermeden, impport altmodul1
komutuyla [Link] dosyas iinden ardmz altmodul1 modlnn ieriini
alabildi. Peki ama neden?
Bata da sylediimiz gibi, Python btn aktarma ilemlerini tek bir konumdan yapar.
Yani eer siz bir modl st dizinden ie aktardysanz, o st dizinin ad paket iindeki
btn aktarmalara nek olarak eklenecektir. Dolaysyla paket adl dizinin bulunduu
konumdan altdizin iindeki [Link] dosyasn ardnzda, [Link] iindeki
import altmodul1 komutu, [Link] dosyasn bulamayacaktr. Ama siz [Link]
dosyasn kendi dizini iinden ardnzda, import altmodul1 komutu, ayn dizin iindeki
[Link] dosyasn bulabilecektir.
Bu okuduklarnz ilk bakta size ok karmakm gibi gelebilir, ama aslnda biraz dikkat
ederseniz bu sistemin hi de yle karmak olmadn, aksine son derece mantkl olduunu
greceksiniz.
Durumu daha da netletirmek iin yle bir ey yapalm:
[Link] dosyasn ap, import altmodul1 komutunu yle yazalm:
from [Link] import altmodul1
Bu deiiklii kaydettikten sonra tekrar paket dizininin bulunduu konumda bir oturum ap
u komutu verelim:
>>> from [Link] import altmodul2
846
Bal e Aktarma
Dediimiz gibi, bir ie aktarma ileminin baarl olabilmesi, o ie aktarma ileminin yapld
konumun neresi olduuna ve paket iinde bulunan teki modllerdeki ie aktarmalarn
nasl yazldna baldr. Yani mesela normalde ayn konumda bulunan iki modl birbirini
yalnzca import modl_ad gibi bir komutla ie aktarabilecekken, eer bu modller st dizinin
bulunduu konumdan arlyorsa, ie aktarma baarsz olabilir. Bunun bir rneini yukarda
grmtk. altdizin iinde bulunan [Link] dosyasn, ayn dizindeki [Link]
dosyasndan ie aktarmak iin [Link] dosyasna import altmodul1 yazdmzda,
ana paket dizininin bulunduu konumdan altdizin iindeki [Link] dosyasn from
[Link] import altmodul2 gibi bir komut ile ie aktarma giriimimiz baarszla
uruyordu. Pythonn ilgili modl bulabilmesini salamak iin, [Link] dosyasna
import altmodul1 yazmak yerine from [Link] import altmodul1 yazmtk. te
ayn eyi bal ie aktarma (relative import ) denen bir mekanizma yardmyla da
gerekletirebiliriz.
Bu mekanizmada ie aktarma ilemi, ie aktaran modln bulunduu konuma gre
gerekleir. Bir rnek verelim...
[Link] dosyasna import altmodul1 veya from [Link] import altmodul1
yerine unu yazalm:
from . import altmodul1
Burada from kelimesinden sonra gelen nokta (.), ie aktaran modlle ayn dizine atfta
bulunuyor. Yani bu ekilde [Link] nin bulunduu dizine atfta bulunmu, bylece
bu dizinde bulunan altmodul1 adl modl ie aktarabilmi olduk. paket dizininden, hatta
altdizin dizininden yaplacak ie aktarma ilemleri bu komut sayesinde baarl olacaktr.
Dediimiz gibi, orada . iareti, ie aktaran modlle ayn dizini temsil ediyor. Eer oraya
yan yana iki nokta (..) koyacak olursanz, bir st dizine atfta bulunabilirsiniz. Mesela bir
st dizinde bulunan [Link] dosyasn [Link] veya [Link] dosyasndan ie
aktarmak isterseniz, bu dosyalarn herhangi birine u kodu yazabilirsiniz:
from .. import modul3
nokta yan yana koyduunuzda ise (...) iki st dizine atfta bulunmu olursunuz. Ancak bu
ekilde paketin dna kamayacanz da unutmayn. Yani mesela paket dizininin bulunduu
konuma gre bir st dizinde bulunan, yani paket dndaki [Link] adl bir modl u
ekilde ie aktaramazsnz:
from ... import falanca
Ama tabii eer paketinizin dizin yaps iki st dizine klmasna msaade ediyorsa yukardaki
komut alacaktr. Yani elinizdeki, aadakine benzer yapda bir pakette:
+ paket
|__ [Link]
|__ [Link]
|__ [Link]
+ altdizin
|__altmodul1.py
|__altmodul2.py
+ altaltdizin
|__altaltmodul1.py
|__altaltmodul2.py
847
848
Kullanc dizinini elde ettikten sonra, masastne giden yolu bulabilmek iin u komutu
kullanyoruz:
>>> masast = [Link](kullanc, 'Desktop')
Grdnz gibi, listelerin append() metodu yardmyla masastnn yolunu [Link] adl
listeye ekledik.
Artk masastnde bulunan paketleri rahatlkla her yerden ie aktarabiliriz.
Not: os modl hakknda daha geni bilgi iin os Modl balkl konuyu inceleyebilirsiniz.
sys modl hakknda bilgi iin ise sys Modl baln ziyaret edebilirsiniz.
849
BLM 50
Dzenli fadeler
Dzenli ifadeler Python programlama dilinin en etrelli konularndan biridir. yle ki,
dzenli ifadelerin Python iinde ayr bir dil olarak dnlmesi gerektiini syleyenler
dahi vardr. Ama btn zorluklarna ramen programlama deneyimimizin bir noktasnda
mutlaka karmza kacak olan bu yapy renmemizde byk fayda var. Dzenli ifadeleri
rendikten sonra, elle yaplmas saatler srecek bir ilemi saliseler iinde yapabildiinizi
grdnzde eminim dzenli ifadelerin ne byk bir nimet olduunu siz de anlayacaksnz.
Tabii her gzel ey gibi, dzenli ifadelerin nimetlerinden yararlanabilecek dzeye gelmek de
bir miktar kan, ter ve gzya istiyor.
Peki, dzenli ifadeleri kullanarak neler yapabiliriz? ok genel bir ifadeyle, bu yapy kullanarak
metinleri veya karakter dizilerini parmamzda oynatabiliriz. rnein bir web sitesinde
dank halde duran verileri bir rpda ayklayabiliriz. Bu veriler, mesela, toplu halde grmek
istediimiz web adreslerinin bir listesi olabilir. Bunun dnda, rnein, ok sayda belge
zerinde tek admda istediimiz deiiklikleri yapabiliriz.
Ancak genel bir kural olarak, dzenli ifadelerden kaabildiimiz mddete kamamz gerekir.
Eer Pythondaki karakter dizisi metotlar, o anda yapmak istediimiz ey iin yeterli
geliyorsa mutlaka o metotlar kullanmalyz. nk karakter dizisi metotlar, dzenli ifadelere
kyasla hem daha basit, hem de ok daha hzldr. Ama bir noktadan sonra karakter
dizilerini kullanarak yazdnz kodlar iyice karmaklamaya balamsa, kodlarn her taraf
if deyimleriyle dolmusa, hatta basit bir ilemi gerekletirmek iin yazdnz kod sayfa
snrlarn zorlamaya balamsa, ite o noktada artk dzenli ifadelerin dnyasna adm
atmanz gerekiyor olabilir. Ama bu durumda Jamie Zawinskinin u szn de aklnzdan
karmayn: Bazlar, bir sorunla kar karya kaldklarnda unu der: Evet, burada dzenli
ifadeleri kullanmam gerekiyor. te onlarn bir sorunu daha vardr artk...
Bata da sylediim gibi, dzenli ifadeler bize zorluklar unutturacak kadar byk kolaylklar
sunar. Emin olun yzlerce dosya zerinde tek tek elle deiiklik yapmaktan daha zor deildir
dzenli ifadeleri renip kullanmak... Hem zaten biz de bu sayfalarda bu sevimsiz konuyu
olabildiince sevimli hale getirmek iin elimizden gelen abay gstereceiz. Sizin de aba
gstermeniz, bol bol altrma yapmanz durumunda dzenli ifadeleri kavramak o kadar da
zorlayc olmayacaktr. Unutmayn, dzenli ifadeler ne kadar uratrc olsa da programcnn
en nemli silahlarndan biridir. Hatta dzenli ifadeleri rendikten sonra onsuz geen
yllarnza acyacaksnz.
imdi laf daha fazla uzatmadan iimize koyulalm.
850
Bata da sylediimiz gibi, dzenli ifadeler bir programcnn en nemli silahlarndan biridir.
u halde silahmzn zelliklerine bakalm. Yani bu yapnn bize sunduu aralar yle bir
listeleyelim. Etkileimli kabukta u kodu yazyoruz:
>>> dir(re)
Ne yazk ki, Pythonn yardm dosyalar hep ngilizce. Dolaysyla eer ngilizce bilmiyorsanz,
bu yardm dosyalar pek iinize yaramayacaktr. Bu arada yukardaki yardm blmnden
kmak iin klavyedeki q dmesine basmanz gerekir.
Varsayalm ki biz bu karakter dizisi iinde python kelimesi geip gemediini renmek
istiyoruz. Ve bunu da dzenli ifadeleri kullanarak yapmak istiyoruz. Dzenli ifadeleri
bu rnee uygulayabilmek iin yapmamz gereken ey, ncelikle bir dzenli ifade kalb
oluturup, daha sonra bu kalb yukardaki karakter dizisi ile karlatrmak. Biz btn bu
ilemleri match() metodunu kullanarak yapabiliriz:
851
>>> [Link]("python", a)
Burada, python eklinde bir dzenli ifade kalb oluturduk. Dzenli ifade kalplar match()
metodunun ilk argmandr (yani parantez iindeki ilk deer). kinci argmanmz ise (yani
parantez iindeki ikinci deer), hazrladmz kalb kendisiyle eletireceimiz karakter dizisi
olacaktr.
Klavyede ENTER tuuna bastktan sonra karmza yle bir kt gelecek:
<_sre.SRE_Match object; span=(0, 6), match='python'>
Bu kt, dzenli ifade kalbnn karakter dizisi ile eletii anlamna geliyor. Yani aradmz
ey, karakter dizisi iinde bulunmu.
Yukardaki ktda grdmz ifadeye Pythoncada eleme nesnesi (match object ) ad
veriliyor. nk match() metodu yardmyla yaptmz ey aslnda bir eletirme ilemidir
(match kelimesi ngilizcede elemek anlamna gelir). Biz burada python dzenli ifadesinin
a deikeniyle eleip elemediine bakyoruz.
Yani [Link]("python", a) ifadesi
araclyla python ifadesi ile a deikeninin tuttuu karakter dizisinin eleip elemediini
sorguluyoruz. Bizim rneimizde python a deikeninin tuttuu karakter dizisi ile eletii
iin bize bir eleme nesnesi dndrlyor.
Bu kt, dzenli ifade kalbnn karakter dizisi ile eletiini bildirmenin yansra, bize baka
birtakm bilgiler daha veriyor. Mesela bu ktdaki span parametresi, aradmz python
karakter dizisinin, a deikeninin 0. ila 6. karakterleri arasnda yer aldn sylyor bize.
Yani:
>>> a[0:6]
'python'
Ayrca yukardaki ktda grdmz match parametresi de bize eleen ifadenin python
olduu bilgisini veriyor.
Bir de u rnee bakalm:
>>> [Link]("Java", a)
Burada ENTER tuuna bastmzda hi bir kt almyoruz. Aslnda biz grmesek de Python
burada None kts veriyor. Eer yukardaki komutu yle yazarsak None ktsn biz de
grebiliriz:
>>> print([Link]("Java", a))
None
Grdnz gibi, ENTER tuuna bastktan sonra None kts geldi. Demek ki Java ifadesi,
a deikeninin tuttuu karakter dizisi ile elemiyormu. Buradan kardmz sonuca gre,
Python match() metodu yardmyla aradmz eyi eletirdii zaman bir eleme nesnesi
(match object ) dndryor. Eer eleme yoksa, o zaman da None deerini dndryor.
Biraz kafa kartrmak iin yle bir rnek verelim:
>>> a = "Python gl bir dildir"
>>> [Link]("gl", a)
852
Burada a deikeninde gl ifadesi getii halde match() metodu bize bir eleme
nesnesi dndrmedi. Peki ama neden?
Aslnda bu gayet normal. nk match() metodu bir karakter dizisinin sadece en bana
bakar. Yani Python gl bir dildir ifadesini tutan a deikenine [Link](gl, a) gibi bir
fonksiyon uyguladmzda, match() metodu a deikeninin yalnzca en bana bakaca ve a
deikeninin en banda gl yerine python olduu iin, match() metodu bize olumsuz
yant veriyor.
Aslnda match() metodunun yapt bu ii, karakter dizilerinin split() metodu yardmyla da
yapabiliriz:
>>> [Link]()[0] == "python"
True
Eer dzenli ifadelerden tek beklentiniz bir karakter dizisinin en bandaki veriyle eletirme
ilemi yapmaksa, split() veya startswith() metotlarn kullanmak daha mantkldr. nk
split() ve startswith() metotlar match() metodundan ok daha hzl alacaktr.
match() metodunu kullanarak bir ka rnek daha yapalm:
>>> sorgu = "1234567890"
>>> [Link]("1", sorgu)
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> [Link]("1234", sorgu)
<_sre.SRE_Match object; span=(0, 4), match='1234'>
>>> [Link]("124", sorgu)
853
8. Eer aradmz ey karakter dizisinin en banda yer almyorsa, match() metodu None
deeri dndrr.
Daha nce sylediimiz gibi, match() metodu ile bir eletirme ilemi yaptmzda, eer
eleme varsa Python bize bir eleme nesnesi dndrecektir. Dndrlen bu eleme
nesnesi bize span ve match parametreleri araclyla, eleen karakter dizisinin sorgu dizisi
iindeki yerini ve eleen dizinin ne olduu sylyor. span paramtresinin deerine span()
adl bir metot yardmyla eriebiliyoruz. rnein:
>>>
>>>
>>>
>>>
import re
sorgu = 'Bin kunduz'
eleme = [Link]('Bin', sorgu)
eleme
Ancak, match() metodu ile bulunan eyin ne olduunu eleme nesnesinin match
parametresine bakarak grebilsek de, bu deeri bir kod yardmyla alamyoruz. nk
eleme nesnelerinin span() metoduna benzeyen bir match() metodu bulunmaz.
Ama istersek tabii ki bulunan eyi de programatik olarak alma imknmz var. Bunun iin
group() adl bir baka metottan yararlanacaz:
>>> kardiz = "perl, python ve ruby yksek seviyeli dillerdir."
>>> eleme = [Link]("perl", kardiz)
>>> [Link]()
'perl'
Grdnz gibi, eleme deikeninin tipi bir eleme nesnesi (match object ). sterseniz bu
nesnenin metotlarna bir gz gezdirebiliriz:
>>> dir(eleme)
854
Peki, eletirmek istediimiz dzenli ifade kalb bulunamazsa ne olur? yle bir durumda
yukardaki kodlar hata verecektir. Hemen bakalm:
>>> nesne = [Link]("stanbul", iddia)
>>> [Link]()
Hata mesajmz:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
Byle bir hata, yazdnz bir programn kmesine neden olabilir. O yzden kodlarmz una
benzer bir ekilde yazmamz daha mantkl olacaktr:
>>> nesne = [Link]("stanbul", iddia)
>>> if nesne:
...
print("eleen ifade:", [Link]())
... else:
...
print("eleme baarsz!")
imdi isterseniz bu match() metoduna bir ara verip baka bir metodu inceleyelim.
Yukardaki kod, karakter dizisinin banda bir eleme bulamad iin bize None deeri
dndryordu. Ama eer ayn ilemi yle yaparsak, daha farkl bir sonu elde ederiz:
>>> a = "Python gl bir dildir"
>>> [Link]("gl", a)
<_sre.SRE_Match object; span=(7, 12), match='gl'>
855
grntleyebiliriz:
>>> kardiz = "Python gl bir dildir"
>>> nesne = [Link]("gl", kardiz)
>>> [Link]()
(7, 12)
>>> [Link]()
'gl'
imdiye kadar hep karakter dizileri zerinde altk. sterseniz biraz da listeler zerinde
rnekler verelim.
yle bir listemiz olsun:
>>> liste = ["elma", "armut", "kebap"]
>>> [Link]("kebap", liste)
Ne oldu? Hata aldnz, deil mi? Bu normal. nk dzenli ifadeler karakter dizileri zerinde
iler. Bunlar dorudan listeler zerinde ilem yapamaz. O yzden bizim Pythona biraz
yardmc olmamz gerekiyor:
>>> for i in liste::
...
nesne = [Link]("kebap", i)
...
if nesne:
...
print([Link]())
...
kebap
856
Grdnz gibi, metinde geen btn Python kelimelerini bir rpda liste olarak aldk.
Ayn ilemi search() metodunu kullanarak yapmak istersek yolu biraz uzatmamz gerekir:
>>> liste = [Link]()
>>> for i in liste:
...
nesne = [Link]("Python", i)
...
if nesne:
...
print([Link]())
...
Python
Python
Python
Python
857
Python
Python
Grdnz gibi, metinde geen btn Python kelimelerini search() metodunu kullanarak
bulmak iin ncelikle metin adl karakter dizisini, daha nce karakter dizilerini ilerken
grdmz split() metodu yardmyla bir liste haline getiriyoruz. Ardndan bu liste
zerinde bir for dngs kurarak search() ve group() metotlarn kullanarak btn Python
kelimelerini ayklyoruz. Eer karakter dizisini yukardaki ekilde listeye dntrmezsek yle
bir netice alrz:
>>> nesne = [Link]("Python", metin)
>>> print([Link]())
Python
50.2 Metakarakterler
imdiye kadar dzenli ifadelerle ilgili olarak verdiimiz rnekler sizi biraz artm olabilir.
Zor dediin bunlar myd? diye dnm olabilirsiniz. Haklsnz, zira zor dediim,
buraya kadar olan ksmda verdiim rneklerden ibaret deildir. Buraya kadar olan blmde
verdiim rnekler iin en temel ksmn gzler nne sermek iindi. imdiye kadar olan
blmde, mesela, python karakter dizisiyle eletirme yapmak iin python kelimesini
kullandk. Esasnda bu, dzenli ifadelerin en temel zelliidir. Yani python karakter dizisini
bir dzenli ifade sayacak olursak (ki zaten yledir), bu dzenli ifade en bata kendisiyle
eleecektir. Bu ne demek? yle ki: Eer aradnz ey python karakter dizisi ise,
kullanmanz gereken dzenli ifade de python olacaktr.
Diyoruz ki: Dzenli ifadeler en bata kendileriyle eleirler. Buradan u anlam kyor:
Demek ki bir de kendileriyle elemeyen dzenli ifadeler var. te bu durum, Pythondaki
dzenli ifadelere kiiliini kazandran eydir. Biraz sonra ne demek istediimizi daha ak
anlayacaksnz. Artk gerek anlamyla dzenli ifadelere giri yapyoruz!
ncelikle, elimizde aadaki gibi bir liste olduunu varsayalm:
>>> liste = ["zcan", "mehmet", "sleyman", "selim",
... "kemal", "zkan", "esra", "dndar", "esin",
... "esma", "zhan", "zlem"]
Diyelim ki, biz bu liste iinden zcan, zkan ve zhan elerini ayklamak/almak istiyoruz.
Bunu yapabilmek iin yeni bir bilgiye ihtiyacmz var: Metakarakterler.
Metakarakterler; kabaca, programlama dilleri iin zel anlam ifade eden sembollerdir.
rnein daha nce grdmz \n bir bakma bir metakarakterdir. nk \n sembol
Python iin zel bir anlam tar. Python bu sembol grd yerde yeni bir satra
geer. Yukarda kendisiyle elemeyen karakterler ifadesiyle kastettiimiz ey de ite bu
metakarakterlerdir. rnein, a har yalnzca kendisiyle eleir. Tpk istihza kelimesinin
yalnzca kendisiyle eleecei gibi... Ama mesela \t ifadesi kendisiyle elemez. Python bu
iareti grd yerde sekme (tab) dmesine baslm gibi tepki verecektir. te dzenli
ifadelerde de buna benzer metakarakterlerden yararlanacaz. Dzenli ifadeler iinde de,
zel anlam ifade eden pek ok sembol, yani metakarakter vardr. Bu metakarakterlerden biri
858
Bu kodu byle yazmamamz gerektiini artk biliyoruz. Aksi halde hata alrz. nk daha
nce de dediimiz gibi, dzenli ifadeler karakter dizileri zerinde ilem yapabilir. Listeler
zerinde deil. Dolaysyla komutumuzu u ekilde vermemiz gerekiyor:
>>> for i in liste:
...
nesne = [Link]("z[chk]an", i)
...
if nesne:
...
print([Link]())
Ancak, bu rnekte pek belli olmasa da, son yazdmz kod her zaman istediimiz sonucu
vermez. Mesela listemiz yle olsayd:
>>> liste = ["zcan demir", "mehmet", "sleyman",
... "selim", "kemal", "zkan nuri", "esra", "dndar",
... "esin", "esma", "zhan kamil", "zlem"]
Yukardaki kod bu liste zerine uygulandnda, sadece almak istediimiz ksm deil, ilgisiz
ksmlar da gelecektir.
Grdnz gibi, uygun kodlar kullanarak, zcan, zkan ve zhan elerini listeden
kolayca aykladk. Bize bu imkn veren ey ise [ ] adl metakarakter oldu. Aslnda [ ]
metakarakterinin ne ie yaradn az ok anlam olmalsnz. Ama biz yine de yle bir
bakalm bu metakaraktere:
[ ] adl metakarakter, yukarda verdiimiz listedeki z ile balayp, c, h veya k
harerinden herhangi biri ile devam eden ve an ile biten btn eleri ayklyor. Gelin
bununla ilgili bir rnek daha yapalm:
>>> for i in liste:
...
nesne = [Link]("es[mr]a",i)
...
if nesne:
...
print([Link]())
Grdnz gibi, es ile balayp, m veya r harerinden herhangi biriyle devam eden ve
sonunda da a har bulunan btn eleri aykladk. Bu da bize esma ve esra ktlarn
verdi...
Dediimiz gibi, metakarakterler programlama dilleri iin zel anlam ifade eden sembollerdir.
Normal karakterlerden farkl olarak, metakarakterlerle karlaan bir bilgisayar normalden
farkl bir tepki verecektir. Yukarda metakarakterlere rnek olarak \n ve \t ka dizilerini
vermitik. rnein Pythonda print(\n) gibi bir komut verdiimizde, Python ekrana \n
yazdrmak yerine bir alt satra geecektir. nk \n Python iin zel bir anlam tamaktadr.
Dzenli ifadelerde de birtakm metakarakterlerin kullanldn rendik. Bu metakarakterler,
dzenli ifadeleri dzenli ifade yapan eydir. Bunlar olmadan dzenli ifadelerle yararl bir i
yapmak mmkn olmaz. Bu giri blmnde dzenli ifadelerde kullanlan metakarakterlere
rnek olarak [ ] semboln verdik. Herhangi bir dzenli ifade iinde [ ] semboln gren
50.2. Metakarakterler
859
Python, dorudan doruya bu sembolle eleen bir karakter dizisi aramak yerine, zel bir
ilem gerekletirecektir. Yani [ ] sembol kendisiyle elemeyecektir...
Pythonda bulunan temel metakarakterleri topluca grelim:
[ ] . \* + ? { } ^ $ | ( )
Yukardaki rnekte, bir liste iinde geen zcan, zhan ve zkan elerini ayklyoruz.
Burada bu edeki farkl karakterleri (c, h ve k) keli parantez iinde nasl
belirttiimize dikkat edin. Python, keli parantez iinde grd btn karakterleri tek
tek liste elerine uyguluyor. nce z ile balayan btn eleri alyor, ardndan z
hecesinden sonra c haryle devam eden ve an hecesi ile biten eyi buluyor. Bylece
zcan esini bulmu oldu. Ayn ilemi, z hecesinden sonra h harni barndran ve an
hecesiyle biten eye uyguluyor. Bu ekilde ise zhan esini bulmu oldu. En son hedef
ise z ile balayp k har ile devam eden ve an ile biten e. Yani listedeki zkan esi...
En nihayetinde de elimizde zcan, zhan ve zkan eleri kalm oluyor.
Bir nceki blmde yine [ ] metakarakteriyle ilgili olarak u rnei de vermitik:
>>> for i in liste:
...
nesne = [Link]("es[mr]a",i)
...
if nesne:
...
print([Link]())
Bu rnein de zcan, zkan, zhan rneinden bir fark yok. Burada da Python keli
parantez iinde grd btn karakterleri tek tek liste elerine uygulayp, esma ve esra
elerini bize veriyor.
imdi bununla ilgili yeni bir rnek verelim
Diyelim ki elimizde yle bir liste var:
>>> a = ["23BH56","TY76Z","4Y7UZ","TYUDZ","34534"]
imdi u kodlar
>>> for i in a:
...
if [Link]("[0-9]",i):
...
print(i)
860
...
23BH56
4Y7UZ
34534
Burada parantez iinde kullandmz ifadeye dikkat edin. 0 ile 9 arasndaki btn eleri
ieren bir karakter dizisi tanmladk. Yani ksaca, iinde herhangi bir say barndran eleri
kapsama alanmza aldk. Burada ayrca search() yerine match() metodunu kullandmza
da dikkat edin. match() metodunu kullanmamzn nedeni, bu metodun bir karakter dizisinin
sadece en bana bakmas... Amacmz say ile balayan btn eleri ayklamak olduuna
gre, yukarda yazdmz kod, liste eleri iinde yer alan ve say ile balayan btn eleri
ayklayacaktr. Biz burada Pythona u emri vermi oluyoruz:
Bana say ile balayan btn eleri bul! nemli olan bu elerin sayyla balamasdr!
Sayyla balayan bu eler ister hare devam etsin, ister baka bir karakterle... Sen yeter
ki bana say ile balayan eleri bul!
Bu emri alan Python, hemen liste elerini gzden geirecek ve bize 23BH56, 4Y7UZ ve
34534 elerini verecektir. Dikkat ederseniz, Python bize listedeki TY76Z ve TYUDZ
elerini vermedi. nk TY76Z iinde saylar olsa da bunlar bizim ltmze uyacak
ekilde en bata yer almyor. TYUDZ esinde ise tek bir say bile yok...
imdi de isterseniz listedeki TY76Z esini nasl alabileceimize bakalm:
>>> for i in a:
...
if [Link]("[A-Z][A-Z][0-9]",i):
...
print(i)
Burada dikkat ederseniz dzenli ifademizin banda A-Z diye bir ey yazdk. Bu ifade
A ile Z hareri arasndaki btn karakterleri temsil ediyor. Biz burada yalnzca byk
hareri sorguladk. Eer kk hareri sorgulamak isteseydik A-Z yerine a-z diyecektik.
Dzenli ifademiz iinde geen birinci A-Z ifadesi aradmz karakter dizisi olan TY76Z
iindeki T harni, ikinci A-Z ifadesi Y harni, 0-9 ifadesi ise 7 saysn temsil ediyor.
Karakter dizisi iindeki geri kalan harer ve saylar otomatik olarak eletirilecektir. O yzden
onlar iin ayr bir ey yazmaya gerek yok. Yalnz bu sylediimiz son ey sizi aldatmasn.
Bu otomatik eletirme ilemi bizim u anda kar karya olduumuz karakter dizisi iin
geerlidir. Farkl nitelikteki karakter dizilerinin sz konusu olduu baka durumlarda iler
byle yrmeyebilir. Dzenli ifadeleri baarl bir ekilde kullanabilmenin ilk art, zerinde
ilem yaplacak karakter dizisini tanmaktr. Bizim rneimizde yukardaki gibi bir dzenli
ifade kalb oluturmak iimizi gryor. Ama baka durumlarda, duruma uygun baka
kalplar yazmak gerekebilir/gerekecektir. Dolaysyla, tek bir dzenli ifade kalbyla hayatn
gemeyeceini unutmamalyz.
imdi yukardaki kodu search() ve group() metotlarn kullanarak yazmay deneyin. Elde
ettiiniz sonular dikkatlice inceleyin. match() ve search() metotlarnn ne gibi farkllklara
sahip olduunu kavramaya aln... Sorunuz olursa bana nasl ulaacanz biliyorsunuz...
Bu arada, dzenli ifadelerle ilgili daha fazla ey rendiimizde yukardaki kodu ok daha
sade bir biimde yazabileceiz.
50.2.2 . (Nokta)
Bir nceki blmde [] adl metakarakteri incelemitik.
Bu blmde ise farkl bir
metakarakteri inceleyeceiz. nceleyeceimiz metakarakter: .
50.2. Metakarakterler
861
Bu metakarakter, yeni satr karakteri hari btn karakterleri temsil etmek iin kullanlr.
Mesela:
>>> for i in liste:
...
nesne = [Link]("es.a",i)
...
if nesne:
...
print([Link]())
...
esma
esra
Grdnz gibi, daha nce [] metakarakterini kullanarak yazdmz bir dzenli ifadeyi
bu kez farkl ekilde yazyoruz. Unutmayn, bir dzenli ifade birka farkl ekilde yazlabilir.
Biz bunlar iinde en basit ve en anlalr olann semeliyiz. Ayrca yukardaki kodu birka
farkl ekilde de yazabilirsiniz. Mesela u yazm da bizim durumumuzda geerli bir seenek
olacaktr:
>>> for i in liste:
...
if [Link]("es.a",i):
...
print(i)
Tabii ki biz, o anda zmek durumunda olduumuz soruna en uygun olan seenei tercih
etmeliyiz...
Yalnz, unutmamamz gereken ey, bu . adl metakarakterin sadece tek bir karakterin yerini
tutuyor olmasdr. Yani yle bir kullanm bize istediimiz sonucu vermez:
>>> liste = ["ahmet","kemal", "kamil", "mehmet"]
>>> for i in liste:
...
if [Link](".met",i):
...
print(i)
862
50.2.3 * (Yldz)
Bu metakarakter, kendinden nce gelen bir dzenli ifade kalbn sfr veya daha fazla sayda
eletirir. Tanm biraz kark olsa da rnek yardmyla bunu da anlayacaz:
>>> yeniliste = ["st", "sat", "saat", "saaat", "falanca"]
>>> for i in yeniliste:
...
if [Link]("sa*t",i):
...
print(i)
Burada * sembol kendinden nce gelen a karakterini sfr veya daha fazla sayda
eletiriyor. Yani mesela st iinde sfr adet a karakteri var. Dolaysyla bu karakter
yazdmz dzenli ifadeyle eleiyor. sat iinde bir adet a karakteri var. Dolaysyla bu da
eleiyor. saat ve saaat karakter dizilerinde srasyla iki ve adet a karakteri var. Tabii
ki bunlar da yazdmz dzenli ifadeyle eleiyor. Listemizin en son esi olan falancada da
ilk hecede bir adet a karakteri var. Ama bu edeki sorun, bunun s haryle balamamas.
nk biz yazdmz dzenli ifadede, aradmz eyin s har ile balamasn, sfr veya daha
fazla sayda a karakteri ile devam etmesini ve ardndan da t harnin gelmesini istemitik.
falanca esi bu koullar karlamad iin szgecimizin dnda kald.
Burada dikkat edeceimiz nokta, * metakarakterinin kendinden nce gelen yalnzca bir
karakterle ilgileniyor olmas... Yani bizim rneimizde * sembol sadece a harnin sfr
veya daha fazla sayda bulunup bulunmamasyla ilgileniyor. Bu ilgi, en bataki s harni
kapsamyor. s harnin de sfr veya daha fazla sayda elemesini istersek dzenli ifademizi
s*a*t veya [sa]*t biiminde yazmamz gerekir... Bu iki seenek iinde [sa]*t eklindeki
yazm tercih etmenizi tavsiye ederim. Burada, daha nce rendiimiz [ ] metakarakteri
yardmyla sa harerini nasl grupladmza dikkat edin...
imdi . metakarakterini anlatrken istediimiz sonucu alamadmz listeye dnelim. Orada
ahmet ve mehmet elerini listeden baaryla ayklayamamtk. O durumda bizim
baarsz olmamza neden olan kullanm yleydi:
>>> liste = ["ahmet", "kemal", "kamil", "mehmet"]
>>> for i in liste:
...
if [Link](".met",i):
...
print(i)
50.2. Metakarakterler
863
Ama artk elimizde * gibi bir ara olduuna gre imdi istediimiz eyi yapabiliriz. Yapmamz
gereken tek ey . sembolnden sonra * semboln getirmek:
>>> for i in liste:
...
if [Link](".*met", i):
...
print(i)
Grdnz gibi ahmet ve mehmet elerini bu kez baaryla aykladk. Bunu yapmamz
salayan ey de * adl metakarakter oldu... Burada Pythona u emri verdik: Bana kelime
banda herhangi bir karakteri (. sembol herhangi bir karakterin yerini tutuyor) sfr veya
daha fazla sayda ieren ve sonu da met ile biten btn eleri ver!
Bir nceki rneimizde a harnin sfr veya daha fazla sayda bulunup bulunmamasyla
ilgilenmitik. Bu son rneimizde ise herhangi bir harn/karakterin sfr veya daha fazla
sayda bulunup bulunmamasyla ilgilendik. Dolaysyla .*met eklinde yazdmz dzenli
ifade, ahmet, mehmet, muhammet, ismet, ksmet ve hatta tek bana met gibi
btn eleri kapsayacaktr. Ksaca ifade etmek gerekirse, sonu met ile biten her ey (met
ifadesinin kendisi de dhil olmak zere) kapsama alanmza girecektir. Bunu gnlk hayatta
nerede kullanabileceinizi hemen anlam olmalsnz. Mesela bir dizin iindeki btn mp3
dosyalarn bu dzenli ifade yardmyla listeleyebiliriz:
>>>
>>>
>>>
>>>
...
...
import os
import re
dizin = [Link]([Link]())
for i in dizin:
if [Link](".*mp3",i):
print(i)
Bu rnekte Python bize kt olarak None deerini vermiti. Yani herhangi bir eleme
bulamamt. nk dediimiz gibi, match() metodu bir karakter dizisinin yalnzca en bana
bakar. Ama geldiimiz u noktada artk bu kstlamay nasl kaldracanz biliyorsunuz:
>>> [Link](".*gl", a)
Ama match() metodunu bu ekilde zorlamak yerine performans asndan en doru yol bu
tr iler iin search() metodunu kullanmak olacaktr.
Bunu da getiimize gre artk yeni bir metakarakteri incelemeye balayabiliriz.
50.2.4 + (Art)
Bu metakarakter, bir nceki metakarakterimiz olan * ile benzerdir. Hatrlarsanz, *
metakarakteri kendisinden nceki sfr veya daha fazla sayda tekrar eden karakterleri
ayklyordu. + metakarakteri ise kendisinden nceki bir veya daha fazla sayda tekrar eden
karakterleri ayklar. Bildiiniz gibi, nceki rneklerimizden birinde ahmet ve mehmet
elerini u ekilde ayklamtk:
864
Burada u komutu vermi olduk: Bana sonu met ile biten btn eleri ver! Ama bana
met esini yalnz bana verme!
Ayn ilemi search() metodunu kullanarak da yapabileceimizi biliyorsunuz:
>>> for i in liste:
...
nesne = [Link](".+met",i)
...
if nesne:
...
[Link]()
...
ahmet
mehmet
Burada yazdmz dzenli ifadenin zellii nedeniyle st de kapsama alan iine giriyordu.
nk burada * sembol a karakterinin hi bulunmad durumlar da iine alyor. Ama
eer biz a karakteri en az bir kez gesin istiyorsak, dzenli ifademizi u ekilde yazmalyz:
>>> for i in yeniliste:
...
if [Link]("sa+t", i):
...
print(i)
Hatrlarsanz nceki derslerimizden birinde keli parantezi anlatrken yle bir rnek
vermitik:
>>> a = ["23BH56", "TY76Z", "4Y7UZ", "TYUDZ", "34534"]
>>> for i in a:
...
if [Link]("[A-Z][A-Z][0-9]",i):
...
print(i)
Burada amacmz sadece TY76Z esini almakt. Dikkat ederseniz, enin bandaki T ve
Y harerini bulmak iin iki kez [A-Z] yazdk. Ama artk + metakarakterini rendiimize
gre ayn ii daha basit bir ekilde yapabiliriz:
50.2. Metakarakterler
865
>>> for i in a:
...
if [Link]("[A-Z]+[0-9]",i):
...
print(i)
...
TY76Z
Burada [A-Z] dzenli ifade kalbn iki kez yazmak yerine bir kez yazp yanna da +
semboln koyarak, bu ifade kalbnn bir veya daha fazla sayda tekrar etmesini istediimizi
belirttik...
+ sembolnn ne i yaptn da anladmza gre, artk yeni bir metakarakteri incelemeye
balayabiliriz.
imdi de ?
Grdnz gibi, ?
adl metakarakterimiz, kendisinden nce gelen karakterin hi
bulunmad (yani sfr sayda olduu) ve bir adet bulunduu durumlar iine alyor. Bu
yzden de kt olarak bize sadece st ve sat elerini veriyor.
imdi bu metakarakteri kullanarak gerek hayatta karmza kabilecek bir rnek verelim.
Bu metakarakterin tanmna tekrar bakarsak, olsa da olur olmasa da olur diyebileceimiz
durumlar iin bu metakarakterin rahatlkla kullanlabileceini grrz. yle bir rnek
verelim: Diyelim ki bir metin zerinde arama yapacaksnz. Aradnz kelime uluslararas:
866
867
Bu say iftlerini deitirerek daha farkl sonular elde edebilirsiniz. Ayrca hangi say iftinin
daha nce rendiimiz ? metakarakteriyle ayn ii yaptn bulmaya aln...
50.2.7 ^ (apka)
^ sembolnn iki ilevi var. Birinci ilevi, bir karakter dizisinin en bandaki veriyi
sorgulamaktr. Yani aslnda match() metodunun varsaylan olarak yerine getirdii ilevi bu
metakarakter yardmyla aka belirterek yerine getirebiliyoruz. u rnee bakalm:
>>> a = ['23BH56', 'TY76Z', '4Y7UZ', 'TYUDZ',
... '34534', '1agAY54']
>>> for i in a:
...
if [Link]("[A-Z]+[0-9]",i):
...
print(i)
...
23BH56
TY76Z
4Y7UZ
1agAY54
Dikkat ederseniz, u son verdiimiz kod olduka hassas bir kt verdi bize. ktdaki btn
deerler, aynen dzenli ifademizde belirttiimiz gibi, yan yana bir veya daha fazla harf ieriyor
ve sonra da bir say ile devam ediyor. Bu farklln nedeni, ilk kodlarda print(i) ifadesini
kullanmamz. Bu durumun ktlarmz nasl deitirdiine dikkat edin. Bir de u rnee
bakalm:
>>> for i in a:
...
if [Link]("[A-Z]+[0-9]",i):
...
print(i)
...
TY76Z
Burada sadece TY76Z ktsn almamzn nedeni, match() metodunun karakter dizilerinin en
bana bakyor olmas. Ayn etkiyi search() metoduyla da elde etmek iin, balkta geen ^
(apka) sembolnden yararlanacaz:
>>> for i in a:
...
nesne = [Link]("^[A-Z]+[0-9]",i)
...
if nesne:
...
print([Link]())
...
TY7
Grdnz gibi, apka sembol olmadnda search() metodu karakter dizisinin bana
bakmakla yetinmiyor, ayn zamanda karakter dizisinin tamamn taryor. Biz yukardaki koda
bir ^ sembol ekleyerek, metodumuzun sadece karakter dizisinin en bana bakmasn
istedik. O da emrimize sadakatle uydu. Burada dikkatimizi ekmesi gereken baka bir nokta
da search() metodundaki ktnn krplm olmas. Dikkat ettiyseniz, search() metodu bize
enin tamamn vermedi. elerin yalnzca [A-Z]+[0-9] kalbna uyan ksmlarn kesip att
nmze. nk biz ona tersini sylemedik. Eer elerin tamamn istiyorsak bunu ak ak
belirtmemiz gerekir:
>>> for i in a:
...
nesne = [Link]("[A-Z]+[0-9].*",i)
...
if nesne:
...
print([Link]())
...
BH56
TY76Z
Y7UZ
AY54
50.2. Metakarakterler
869
2. En bataki say veya byk harften sonra kk harf GELMEMEL (Bu lt ^ iareti
salyor)
3. stelik bu kk harf gelmeme durumu bir veya daha fazla sayda tekrar etmeli... Yani
bataki say veya byk harften sonra ka tane olursa olsun asla kk harf gelmemeli
(Bu lt de + iareti salyor)
Bu ltlere uymayan tek e 1agAY54 olacaktr. Dolaysyla bu e ktda grnmeyecek...
Burada, ^ iaretinin nasl kullanldna ve kk hareri nasl darda braktna dikkat
edin. Unutmayalm, bu ^ iaretinin hari anlam sadece [] metakarakterinin iinde
kullanld zaman geerlidir.
50.2.8 $ (Dolar)
Bir nceki blmde ^ iaretinin, karakter dizilerinin en bana demir attn sylemitik.
Yani bu sembol arama/eletirme ileminin karakter dizisinin en bandan balamasn
salyordu. Bu sembol bir bakma karakter dizilerinin nasl balayacan belirliyordu. te
imdi greceimiz dolar iareti de ($) karakter dizilerinin nasl biteceini belirliyor. Bu soyut
aklamalar somut bir rnekle balayalm:
>>> liste = ["at", "katk", "fakat", "atk", "rahat",
... "mat", "yat", "sat", "satlk", "katlm"]
Grdnz gibi, elimizde on elik bir liste var. Diyelim ki biz bu listeden, at hecesiyle
biten kelimeleri ayklamak istiyoruz:
>>> for i in liste:
...
if [Link]("at$",i):
...
print(i)
...
at
fakat
rahat
mat
yat
sat
Grdnz gibi, ^ iareti bir karakter dizisinin nasl balayacan belirlerken, $ iareti
ayn karakter dizisinin nasl biteceini belirliyor. Hatta istersek bu metakarakterleri birlikte de
kullanabiliriz:
>>> for i in liste:
...
if [Link]("^at$",i):
...
print(i)
870
...
at
Sonu tam da beklediimiz gibi oldu. Verdiimiz dzenli ifade kalb ile at ile balayan ve
ayn ekilde biten karakter dizilerini aykladk. Bu da bize at ktsn verdi.
Python $ iaretinin zel anlamndan dolay, bizim sayyla biten bir karakter dizisi aradmz
zannedecek, dolaysyla da herhangi bir kt vermeyecektir. nk listemizde sayyla biten
bir karakter dizisi yok... Peki biz ne yapacaz? te bu noktada \ metakarakteri devreye
girecek... Hemen bakalm:
>>> for i in liste:
...
if [Link]("[0-9]+\$",i):
...
print(i)
...
10$
20$
50.2. Metakarakterler
871
atk
rahat
mat
yat
sat
50.2.11 ( ) (Parantez)
Bu metakarakter yardmyla dzenli ifade kalplarn gruplayacaz. Bu metakarakter bizim bir
karakter dizisinin istediimiz ksmlarn ayklamamzda ok byk kolaylklar salayacak.
Diyelim ki biz [Link] adresindeki btn
balklar ve bu balklara ait html dosyalarn bir liste halinde almak istiyoruz. Bunun iin
yle bir ey yazabiliriz:
import re
from [Link] import urlopen
url = "[Link]
f = urlopen(url)
regex = 'href=".+html">.+</a>'
for i in f:
nesne = [Link](regex, str(i, 'utf-8'))
if nesne:
print([Link]())
Burada yaptmz ey u:
1. ncelikle [Link] sayfasn urllib modl
yardmyla atk. Amacmz bu sayfadaki balklar ve bu balklara ait html dosyalarn
listelemek
2. Ardndan, btn sayfay taramak iin basit bir for dngs kurduk
3. Dzenli ifade kalbmz yle yazdk: <href=".+html">.+</a> nk bahsi geen
web sayfasndaki html uzantl dosyalar bu ekilde gsteriliyor. Bu durumu, web
taraycnzda [Link] sayfasn ap sayfa kaynan
grntleyerek teyit edebilirsiniz. (Firefoxta CTRL+Uya basarak sayfa kaynan
grebilirsiniz)
4. Yazdmz dzenli ifade kalb iinde dikkatimizi ekmesi gereken baz noktalar var:
Kalbn (.+html) ksmnda geen + metakarakteri kendisinden nce gelen dzenli
ifadenin bir veya daha fazla sayda tekrar eden elemelerini buluyor. Burada
+ metakarakterinden nce gelen dzenli ifade, kendisi de bir metakarakter olan
872
Hemen hemen amacmza ulatk saylr. Ama grdnz gibi ktmz biraz karmak.
Bunlar istediimiz gibi dzenleyebilsek iyi olurdu, deil mi? Mesela bu ktlar u ekilde
dzenleyebilmek ho olurdu:
Balk: ANA SAYFA; Balant: [Link]
50.2. Metakarakterler
873
print([Link]([Link](2),
[Link](1)))
Kodlarda yaptmz deiikliklere dikkat edin ve anlamaya aln. Baz noktalar gznze
karanlk grndyse hi endie etmeyin, nk bir sonraki blmde btn karanlk noktalar
tek tek aklayacaz. Burada en azndan, ( ) metakarakterini kullanarak dzenli ifadenin
baz blmlerini nasl grupladmza dikkat edin.
Bu arada, elbette [Link] sitesinde herhangi bir deiiklik olursa yukardaki kodlarn
istediiniz kty vermeyeceini bilmelisiniz. nk yazdmz dzenli ifade [Link]
sitesinin sayfa yapsyla sk skya balantldr.
Grdnz gibi, 0 indeksi eleen karakter dizisinin tamamn veriyor. Bir de una bakalm:
>>> [Link](1)
'python'
Burada 1 numaral grubun esi olan pythonu aldk. Gerisinin nasl olacan tahmin
edebilirsiniz:
>>> [Link](2)
'bir'
>>> [Link](3)
874
'programlama'
>>> [Link](4)
'dilidir'
Bu listede group() dnda bir de groups() adl bir metodun olduunu gryoruz. imdi
bunun ne i yaptna bakalm.
875
Yukardaki rnekte, bir say ile balayan, ardndan bir adet boluk karakteri ieren, sonra
da bir byk veya kk hare devam eden karakter dizilerini aykladk. Burada boluk
karakterini \s simgesi ile gsterdiimize dikkat edin.
876
\w zel dizisinin hangi karakterleri elediine dikkat edin. Bu zel dizi u ifadeyle ayn
anlama gelir:
[A-Za-z0-9_]
Dzenli ifadeler iindeki zel diziler genel olarak bunlardan ibarettir. Ama bir de bunlarn
byk hari versiyonlar vardr ki, nemli olduklar iin onlar da inceleyeceiz.
Grdnz gibi;
1. \s zel dizisi boluk karakterlerini avlyor
2. \d zel dizisi ondalk saylar avlyor
3. \w zel dizisi alfanmerik karakterleri ve _ karakterini avlyor
Dedik ki, bir de bunlarn byk hari versiyonlar vardr. te bu byk hari versiyonlar da
yukardaki dizilerin yapt iin tam tersini yapar. Yani:
1. \S zel dizisi boluk olmayan karakterleri avlar
2. \D zel dizisi ondalk say olmayan karakterleri avlar. Yani [^0-9] ile edeerdir.
3. \W zel dizisi alfanmerik olmayan karakterleri ve _ olmayan karakterleri avlar. Yani
[^A-Za-z0-9_] ile edeerdir.
\D ve \W dizilerinin yeterince anlalr olduunu zannediyorum. Burada sanrm sadece
S dizisi bir rnekle somutlatrlmay hakediyor:
>>> a =
>>> for
...
...
...
...
27Mart
Burada \S zel dizisinin listede belirtilen konumda boluk iermeyen eyi nasl bulduuna
dikkat edin.
imdi bu zel diziler iin genel bir rnek verip konuyu kapatalm...
Bilgisayarmzda u bilgileri ieren [Link] adl bir dosya olduunu varsayyoruz:
esra : istinye 05331233445 esma : levent 05322134344 sevgi : dudullu
05354445434 kemal : sanayi 05425455555 osman : tahtakale 02124334444
metin : taksim 02124344332 kezban : caddebostan 02163222122
Amacmz bu dosyada yer alan isim ve telefon numaralarn isim > telefon numaras eklinde
almak:
877
import re
dosya = open("[Link]")
for i in [Link]():
nesne = [Link]("(\w+)\s+:\s(\w+)\s+(\d+)",i)
if nesne:
print("{} > {}".format([Link](1), [Link](3)))
Burada formlmz u ekilde: Bir veya daha fazla karakter + bir veya daha fazla boluk
+ : iareti + bir adet boluk + bir veya daha fazla say
sterseniz bu blm ok basit bir soruyla kapatalm. Sorumuz u:
Elimizde u adresteki yn var: [Link]
Yapmanz gereken, bu yn iindeki gizli mesaj dzenli ifadeleri kullanarak bulmak...
Burada ncelikle dzenli ifade kalbmz derledik. Derleme ilemini nasl yaptmza dikkat
edin. Derlenecek dzenli ifade kalbn compile() metodunda parantez iinde belirtiyoruz.
Daha sonra search() metodunu kullanrken ise, [Link]() demek yerine, [Link]()
eklinde bir ifade kullanyoruz. Ayrca dikkat ederseniz [Link]() kullanmnda
parantez iinde sadece eleecek karakter dizisini kullandk (i). Eer derleme ilemi yapmam
olsaydk, hem bu karakter dizisini, hem de dzenli ifade kalbn yan yana kullanmamz
gerekecektir. Ama dzenli ifade kalbmz yukarda derleme ilemi esnasnda belirttiimiz
iin, bu kalb ikinci kez yazmamza gerek kalmad. Ayrca burada kullandmz dzenli ifade
kalbna da dikkat edin. Nasl bir ablon oturttuumuzu anlamaya aln. Grdnz gibi,
liste elerinde bulunan . iaretini eletirmek iin dzenli ifade kalb iinde \. ifadesini
878
kullandk. nk bildiiniz gibi, tek bana . iaretinin Python asndan zel bir anlam var.
Dolaysyla bu zel anlamdan kamak iin \ iaretini de kullanmamz gerekiyor.
879
Bu karakter dizisi iinde Python kelimesini temel alarak bir arama yapmak istiyorsak eer,
kullanacamz u kod istediimiz eyi yeterince yerine getiremeyecektir:
>>> print([Link]("Python.*", a).group())
Burada karakter dizimiz iinde geen btn krmz kelimelerini yeil kelimesiyle
deitirdik. Bunu yaparken de [Link] adl derleme seeneinden yararlandk.
Elbette sub() metoduyla daha karmak ilemler yaplabilir. Bu noktada yle bir hatrlatma
yapalm. Bu sub() metodu karakter dizilerinin replace() metoduna ok benzer. Ama tabii ki
sub() metodu hem kendi bana replace() metodundan ok daha gldr, hem de beraber
kullanlabilecek derleme seenekleri sayesinde replace() metodundan ok daha esnektir.
Ama tabii ki, eer yapmak istediiniz i replace() metoduyla halledilebiliyorsa en doru yol,
replace() metodunu kullanmaktr...
imdi bu sub() metodunu kullanarak biraz daha karmak bir ilem yapacaz. Aadaki
metne bakalm:
metin = """Karadeniz Erelisi denince akla ilk olarak kmr ve demir-elik
gelir. Kokusu ve tadyla dnyaya nam salm mehur Osmanl ilei ise ismini
880
Grdnz gibi, sub() metodu, argman olarak bir fonksiyon da alabiliyor. Yukardaki
kodlar biraz kark grnm olabilir. Tek tek aklayalm...
ncelikle u satra bakalm:
derle = [Link]("ile[k]", [Link])
Burada amacmz, metin iinde geen ilek ve ile kelimelerini bulmak. Neden ile?
nk ilek kelimesi bir sesli harften nce geldiinde sonundaki k har ye dnyor.
Bu seenekli yapy, daha nceki blmlerde grdmz [ ] adl metakarakter yardmyla
oluturduk. Dzenli ifade kalbmzn hem byk hareri hem de kk hareri ayn anda
bulmas iin [Link] seeneinden yararlandk.
881
Burada, daha sonra sub() metodu iinde kullanacamz fonksiyonu yazyoruz. Fonksiyonu,
def degistir(nesne) eklinde tanmladk. Burada nesne adl bir argman kullanmamzn
nedeni, fonksiyon iinde group() metodunu kullanacak olmamz. Bu metodu fonksiyon
iinde nesne adl argmana balayacaz. Bu fonksiyon, daha sonra yazacamz sub()
metodu tarafndan arldnda, yaptmz arama ilemi sonucunda ortaya kan eleme
nesnesi fonksiyona atanacaktr (eleme nesnesinin ne demek olduunu ilk blmlerden
hatrlyorsunuz).
te nesne adl bir argman kullanmamzn nedeni de, eleme
nesnelerinin bir metodu olan group() metodunu fonksiyon iinde kullanabilmek...
Bir sonraki satrda bir adet szlk gryoruz:
a = {"ile":"eri", "ile":"Eri", "ilek":"Erik", "ilek":"erik"}
Bu szl oluturmamzn nedeni, metin iinde geen btn ilek kelimelerini tek bir erik
kelimesiyle deitiremeyecek olmamz... nk ilek kelimesi metin iinde pek ok farkl
biimde geiyor. Bata da dediimiz gibi, yukardaki yol yerine metni birka kez kopyalayarak
ve her defasnda bir deiiklik yaparak da sorunu zebilirsiniz. (Mesela nce ilek
kelimelerini bulup bunlar erik ile deitirirsiniz. Daha sonra ile kelimelerini arayp
bunlar eri ile deitirirsiniz, vb...) Ama metni tekrar tekrar oluturmak pek performansl
bir yntem olmayacaktr. Bizim imdi kullandmz yntem metin kopyalama zorunluluunu
ortadan kaldryor. Bu szlk iinde ilek kelimesinin alaca ekilleri szlk iinde birer
anahtar olarak, erik kelimesinin alaca ekilleri ise birer deer olarak belirliyoruz.
Sonraki satrda iki metot birden var:
b = [Link]().split()
Burada, fonksiyonumuzun argman olarak vazife gren eleme nesnesine ait metotlardan
biri olan group() metodunu kullanyoruz.
Bylece derle = [Link]("ile[k]",
[Link]) satr yardmyla metin iinde bulduumuz btn ilek ve enilerini
alyoruz.
Karakter dizilerinin split() metodunu kullanmamzn nedeni ise group()
metodunun verdii kty liste haline getirip daha kolay maniple etmek. Burada for
i in b: print(i) komutunu verirseniz group() metodu yardmyla ne bulduumuzu
grebilirsiniz:
ile
ilek
ile
ilek
ile
ilek
ilek
ilek
ile
ilek
ilek
ilek
882
Burada, group() metodu yardmyla bulduumuz elemeler zerinde bir for dngs
oluturduk. Ardndan da return a[i] komutunu vererek a adl szlk iinde yer alan eleri
yazdryoruz. Bu arada, buradaki inin yukarda verdiimiz group() ktlarn temsil ettiine
dikkat edin. a[i] gibi bir komut verdiimizde aslnda srasyla u komutlar vermi oluyoruz:
a["ilek"]
a["ile"]
a["ilek"]
a["ile"]
a["ilek"]
a["ilek"]
a["ilek"]
a["ile"]
a["ilek"]
a["ilek"]
Bu komutlarn ktlar srasyla erik, eri, erik, Eri, erik, erik, erik, Eri, erik,
erik olacaktr. te bu return satr bir sonraki kod olan print([Link](degistir,metin))
ifadesinde etkinlik kazanacak. Bu son satrmz szlk elerini tek tek metne uygulayacak ve
mesela a["ilek"] komutu sayesinde metin iinde ilek grd yerde erik kelimesini
yaptracak ve bylece bize istediimiz ekilde deitirilmi bir metin verecektir...
Bu kodlarn biraz kark gibi grndn biliyorum, ama aslnda ok basit bir mant
var: group() metodu ile metin iinde aradmz kelimeleri ayklyor. Ardndan da a
szl iinde bunlar anahtar olarak kullanarak ilek ve eitleri yerine erik ve eitlerini
koyuyor...
Yukarda verdiimiz dzenli ifadeyi byle ufak bir metinde kullanmak ok anlaml olmayabilir.
Ama ok byk metinler zerinde ok eitli ve karmak deiiklikler yapmak istediinizde bu
kodlarn iinize yarayabileceini greceksiniz.
Yani:
import re
883
50.7 Sonu
Bylelikle dzenli ifadeler konusunu bitirmi olduk. Buradaki amacmz, size dzenli ifadeler
konusunda genel bir bak sunabilmekti. Bu yazlar okuduktan sonra kafanzda dzenli
ifadelerle ilgili kabataslak da olsa bir resim olutuysa bu yazlar amacna ulam demektir.
Elbette dzenli ifadeler burada anlattklarmzdan ibaret deildir. Bu konunun zerine
eildiinizde aslnda dzenli ifadelerin dipsiz bir kuyu gibi olduunu greceksiniz. Esasnda
en bata da dediimiz gibi, dzenli ifadeler apayr bir dil gibidir. Dorusu u ki, dzenli
ifadeler bal bana bamsz bir sistemdir. Hemen hemen btn programlama dilleri
yle ya da byle dzenli ifadeleri destekler. Pythonda dzenli ifadeleri bnyesine adapte
etmi dillerden biridir. Bizim dzenli ifadeler konusundaki yaklammz, her zaman bunlar
gerektiinde kullanmak olmaldr. Dediimiz gibi, eer yapmak istediiniz bir ilemi karakter
dizilerinin metotlar yardmyla yapabiliyorsanz dzenli ifadelere girimemek en iyisidir.
nk karakter dizisi metotlar hem daha hzldr hem de anlamas daha kolaydr.
884
BLM 51
51.1 Giri
Bu blmde, Pythondaki ileri dzey konulardan biri olan veritaban programlamay (database
programming ) inceleyeceiz. Dilerseniz ncelikle veritaban denen eyin ne olduunu
anlamaya alarak ie balayalm.
Esasnda veritaban, hibirimizin yabancs olduu bir kavram deil. Biz bu kelimeyi, teknik
anlamnn dnda, gnlk hayatta da ska kullanyoruz. Veritaban, herkesin bildii ve
kulland anlamyla, iinde veri barndran bir eydir. Gnlk kullanmda, hakikaten, iinde
veri barndran her eye veritaban dendiini duyarsnz.
Veritaban kelimesinin gnlk kullanmdaki anlam dnda bir de teknik anlam vardr. Bizi
esas ilgilendiren de zaten terimin teknik anlamdr. Mesela Vikipedide veritaban yle
tanmlanyor:
Bilgisayar terminolojisinde, sistematik eriim imkn olan, ynetilebilir,
gncellenebilir, tanabilir, birbirleri arasnda tanml ilikiler bulunabilen bilgiler
kmesidir. Bir baka tanm da, bir bilgisayarda sistematik ekilde saklanm,
programlarca ilenebilecek veri yndr.
Yukardaki tanm, veritabannn ne demek olduunu gayet iyi ifade ediyor. Ama esasnda
bizim veritaban tanm zerinde fazlaca durmamza gerek yok. Biz her zaman olduu gibi
iin teknik boyutuyla deil, taktik boyutuyla ilgilenmeyi tercih edeceiz. O halde yava yava
ie koyulmaya balayalm.
Pythonla
veritaban
programlama
ilemleri
iin
pek
ok
alternatimiz
var.
Pythonla hangi veritaban sistemlerini kullanabileceinizi grmek iin
[Link] adresindeki listeyi inceleyebilirsiniz. Biz
bunlar iinde, sadelii, basitlii ve kullanm kolayl nedeniyle Sqlite adl veritaban ynetim
sistemini ele alacaz.
885
Her eyden nce Sqlite Pythonun 2.5 srmlerinden bu yana bu dilin bir parasdr.
Dolaysyla eer kullandnz Python srm 2.5 veya st ise Sqlite Pythondaki
herhangi bir modl gibi ie aktarabilir ve kullanmaya balayabilirsiniz.
Sqlite herhangi bir yazlm veya sunucu kurulumu gerektirmez. Bu sayede, bu
modl kullanabilmek iin ncelikle bir sunucu yaplandrmanza da gerek yoktur.
Baz veritabanlarn kullanabilmek iin arka planda bir veritaban sunucusu altryor
olmanz gerekir. Sqliteta ise byle bir ey yapmazsnz.
Sqlite, teki pek ok veritaban alternatine gre basittir. Bu yzden Sqlite ok ksa bir
srede kavrayp kullanmaya balayabilirsiniz.
Sqlite zgr bir yazlmdr. Bu yazlmn batan aa btn kodlar kamuya aktr.
Dolaysyla Sqlite kodlarnn her zerresini istediiniz gibi kullanabilir, deiiklie
uratabilir, satabilir ve ticari olan/olmayan btn uygulamalarnzda gnl rahatlyla
kullanabilirsiniz.
Sqliten sade ve basit olmas sizi yanltmasn. Bu zelliklerine bakarak, Sqliten
yeteneksiz bir veritaban sistemi olduunu dnmeyin. Bugn Sqlite aktif olarak
kullanan pek ok byk ve tannm irket bulunur.
Mesela, Adobe, Apple,
Mozilla/Firefox, Google, Symbian ve Sun bu irketlerden bazlardr. Hatta GNOME
masast ortamnn sevilen mzik ve video alarlarndan Bansheede de veritaban
olarak Sqlite kullanldn syleyelim.
Yukardaki sebeplerden tr, veritaban konusunu Sqlite zerinden anlatacaz. O halde
hemen yola koyulalm.
Stun 2
Deer 2/1
Deer 2/2
Deer 2/3
Deer 2/4
Stun 3
Deer 3/1
Deer 3/2
Deer 3/3
Deer 3/4
Stun 4
Deer 4/1
Deer 4/2
Deer 4/3
Deer 4/4
Stun 5
Deer 5/1
Deer 5/2
Deer 5/3
Deer 5/4
Sqlite iinde oluturulan yukardakine benzer her tablonun bir de ismi vardr. Daha dorusu,
Sqlite ile bir tablo olutururken, bu tabloya bir de ad vermemiz gerekir. Mesela yukardaki
tabloya deerler adn verdiimizi varsayabilirsiniz.
Sqlite ile alrken veriler zerinde yapacamz ilemleri, yukardaki tablonun adn ve bu
tablodaki stunlar kullanarak gerekletireceiz. Bu yzden Sqliten yapsn anlamak byk
nem tar. Grdnz gibi, bu veritaban sisteminin yapsn anlamak da yle zor bir i
deildir.
886
51.4.1 Sqlitebrowser
Sqlitebrowser,
Sqlite veritabanlarnn ieriini grak bir arayz araclyla
grntleyebilmemizi salayan bir program. Bu program sayesinde, veritaban zerinde
yaptnz almann doru sonu verip vermediini teyit edebilir, elinizdeki veritabannn
ieriinde hangi verilerin olduunu ak seik grebilirsiniz.
Bu program indirmek iin ziyaret etmemiz gereken adres [Link]
Eer siz bir Windows kullancs iseniz, sitedeki .exe dosyasn indirip, program herhangi bir
Windows program gibi kurabilirsiniz.
GNU/Linux kullanclarnn nnde ise her zaman olduu gibi birka farkl seenek var.
ncelikle, bu program ou GNU/Linux datmnn paket deposunda zaten bulunur.
Dolaysyla bu program datmnzn paket deposu araclyla rahatlkla kurabilirsiniz.
Mesela Ubuntu kullananlar u komutla program kurabilir:
sudo apt-get install sqlitebrowser
Bamllklar kurduktan sonra, indirdiiniz .[Link] dosyasn aadaki komut yardmyla an:
tar zxvf [Link]
Ben burada indirdiiniz program srmnn 3.7.0 olduunu varsaydm. Sizin indirdiiniz
srm farklysa yukardaki komutu o srme gre vereceksiniz.
Daha sonra u komutu vererek, atnz klasrn iine girin:
cd sqlitebrowser-3.7.0
887
make
sudo make install
Pythonda Sqlite veritaban sistemine ait modl sqlite3 adn tar. Bu yzden, bu modl ie
aktarmak iin import sqlite3 ifadesini kullanmamz gerekiyor. Eer bu isim size ok uzun
geliyorsa veya modl adnda saylarn ve harerin birlikte bulunmas nedeniyle hem say hem
de harf girmeyi bir angarya olarak gryorsanz elbette sqlite3 modln farkl bir adla da
ie aktarabileceinizi biliyorsunuz. Mesela:
888
Veya:
>>> import sqlite3 as lite
Bylece sqlite3 modln sql veya lite adyla ie aktarm olduk. Ancak ben konuyu
anlatrken, okur asndan kafa karklna sebep olmamak iin, modl import sqlite3
eklinde ie aktarmz gibi davranacam.
Gelelim bu modl yardmyla nasl veritaban oluturulacana...
Bunun iin sqlite3
modlnn connect() adl metodundan yararlanacaz. Bu metodu u ekilde kullanyoruz:
>>> vt = [Link]('veritaban_ad')
Eer bu komutu verdiiniz dizin iinde [Link] adl bir veritaban yoksa, bu ada sahip
bir veritaban oluturulacaktr.
Bu arada, biz veritaban dosyasnn uzants olarak .sqlite setik. Ama eer siz isterseniz
kendinize uygun baka bir uzant da belirleyebilirsiniz. Veritaban dosyasnn uzantsnn ne
olmas gerektii konusunda kesin kurallar bulunmaz. .sqlite uzantsnn yerine, .sqlite3, .db
veya .db3 gibi uzantlar tercih edenler de vardr. Hatta eer siz isterseniz veritabannzn
uzantsn .osman olarak dahi belirleyebilirsiniz. Bu konuda herhangi bir kstlama bulunmaz.
Yukardaki rnekte [Link] adn verdiimiz bir veritaban dosyasna, connect()
metodu yardmyla balandk. Elbette isteseydik connect() metoduna argman olarak tam
dosya yolu da verebilirdik:
>>> import sqlite3
>>> vt = [Link]('/home/istihza/[Link]') #GNU/Linux
>>> vt = [Link]('c:/users/fozgul/desktop/[Link]') #Windows
Bu komut yardmyla sabit disk zerinde bir Sqlite veritaban dosyas oluturmu oluyoruz.
Ancak isterseniz sqlite3 ile geici bir veritaban da oluturabilirsiniz:
>>> vt = [Link](':memory:')
Oluturduunuz bu geici veritaban sabit disk zerinde deil RAM (bellek) zerinde alr.
Veritabann kapattnz anda da bu geici veritaban silinir. Eer arzu ederseniz, RAM
zerinde deil, disk zerinde de geici veritabanlar oluturabilirsiniz. Bunun iin de yle
bir komut kullanyoruz:
>>> vt = [Link]('')
Grdnz gibi, disk zerinde geici bir veritaban oluturmak iin bo bir karakter dizisi
kullandk. Tpk :memory: kullanmnda olduu gibi, bo karakter dizisiyle oluturulan geici
veritabanlar da veritaban balantsnn kesilmesiyle birlikte ortadan kalkacaktr.
Geici veritaban oluturmak, zellikle eitli testler veya denemeler yaptnz durumlarda
iinize yarar. Sonradan nasl olsa sileceiniz, srf test amal tuttuunuz bir veritabann
disk zerinde oluturmak yerine RAM zerinde oluturmay tercih edebilirsiniz. Ayrca, geici
51.5. Yeni Bir Veritaban Oluturmak
889
veritabanlar sayesinde, yazdnz bir kodu test ederken bir hatayla karlarsanz sorunun
veritaban iinde varolan verilerden deil, yazdnz koddan kaynaklandndan da emin
olabilirsiniz. nk, dediimiz gibi, programn her yeniden alnda veritaban batan
oluturulacaktr.
Dikkatinizi ekmek istediim bir nokta da udur: Grdnz gibi Sqlite, veritabann o
anda iinde bulunduunuz dizin iinde oluturuyor. Mesela MySQL kullanyor olsaydnz,
oluturulan veritabanlarnn nceden tanmlanm bir dizin iine atldn grecektiniz.
rnein GNU/Linux sistemlerinde, MySQL veritabanlar /var/lib/mysql gibi bir dizinin iinde
tutulur.
Eer bu komutu verdiiniz dizin iinde [Link] adl bir veritaban yoksa, bu ada sahip
bir veritaban oluturulur. Eer zaten bu adla bir veritaban dosyanz varsa, sqlite3 bu
veritabanna balanacaktr. Dolaysyla Sqliteta hem yeni bir veritaban oluturmak hem de
mevcut bir veritabanna balanmak iin birbiriyle tamamen ayn kodlar kullanyoruz.
Mesela biraz nce [Link] adresinden indirdiimiz
[Link] adl veritabanna balanalm.
Bu dosyann bulunduu konumda bir Python etkileimli kabuk oturumu atmz
varsayarsak:
>>> vt = [Link]('[Link]')
mleci oluturduktan sonra artk nmz iyice alyor. Bylece, yukarda oluturduumuz
im nesnesinin execute() metodunu kullanarak SQL komutlarn altrabileceiz. Nasl m?
Hemen bakalm.
890
imdi de yeni bir veritaban dosyas oluturalm (veya varolan bir veritaban dosyasna
balanalm):
>>> vt = [Link]('[Link]')
Hatrlarsanz, Sqlite veritaban sisteminin tablo benzeri bir yapya sahip olduunu ve bu
sistemdeki her tablonun da bir isminin bulunduunu sylemitik. te burada yaptmz ey,
adres_defteri adl bir tablo oluturup, bu tabloya isim ve soyisim adl iki stun eklemekten
ibarettir. Yani aslnda yle bir ey oluturmu oluyoruz:
isim
soyisim
891
Ayrca, execute() metoduna parametre olarak verilen SQL komutlarnn alelade birer
karakter dizisi olduuna da dikkatinizi ekmek isterim. Bunlar Pythondaki karakter dizilerinin
btn zelliklerini tar. Mesela bu karakter dizisini execute() metoduna gndermeden nce
bir deikene atayabilirsiniz:
import sqlite3
vt = [Link]('[Link]')
im = [Link]()
sql = """CREATE TABLE 'personel dosyasi'
('personel ismi', 'personel soyismi', memleket)"""
[Link](sql)
Bu hata mesajn almanz gayet normal. Bunun stesinden nasl geleceinizi renmek iin
okumaya devam edin...
Bu kodlar ilk kez altrdnzda, mevcut dizin altnda [Link] adl bir veritaban dosyas
oluturulacak ve bu veritaban iinde isim, soyisim ve memleket balkl stunlara sahip,
personel adl bir tablo meydana getirilecektir.
Ancak ayn kodlar ikinci kez altrdnzda yle bir hata mesaj ile karlaacaksnz:
[Link]: table personel already exists
Buradaki sorun, [Link] dosyas iinde personel adl bir tablonun zaten bulunuyor
olmasdr. Bir veritaban zerinde ilem yaparken, ayn ada sahip iki tablo oluturamayz.
Bu hatay nlemek iin artl tablo oluturma ynteminden yararlanacaz. Bunun iin
kullanacamz SQL komutu udur: CREATE TABLE IF NOT EXISTS.
rneimizi bu yeni bilgiye gre tekrar yazalm:
892
import sqlite3
vt = [Link]('[Link]')
im = [Link]()
sorgu = """CREATE TABLE IF NOT EXISTS personel
(isim, soyisim, memleket)"""
[Link](sorgu)
Uyar: Bu kodlar altrdktan sonra, eer veritabannn ieriini Sqlitebrowser ile kontrol
ettiyseniz verilerin veritabanna ilenmediini greceksiniz. Endie etmeyin; birazdan
bunun neden byle olduunu aklayacaz.
Burada INSERT INTO tablo_ad VALUES adl yeni bir SQL komutu daha reniyoruz. CREATE
TABLE ifadesi Trkede TABLO OLUTUR anlamna geliyor. INSERT INTO ise ... NE
YERLETR anlamna gelir. Yukardaki karakter dizisi iinde grnen VALUES ise DEERLER
demektir. Yani aslnda yukardaki karakter dizisi u anlama gelir: personel NE Frat,
zgl ve Adana DEERLERN YERLETR. Yani yle bir tablo olutur :
isim
Frat
soyisim
zgl
memleket
Adana
Buraya kadar gayet gzel gidiyoruz. sterseniz imdi derin bir nefes alp, u ana kadar
yaptmz eyleri bir gzden geirelim:
ncelikle sqlite3 modln ie aktardk. Bu modln nimetlerinden yararlanabilmek
iin bunu yapmamz gerekiyordu. sqlite3 kelimesini her defasnda yazmak bize
893
angarya gibi gelebilecei iin bu modl farkl bir adla ie aktarmay tercih edebiliriz.
Mesela import sqlite3 as sql veya import sqlite3 as lite gibi...
sqlite3 modln ie aktardktan sonra bir veritabanna balanmamz veya
elimizde bir veritaban yoksa yeni bir veritaban oluturmamz gerekiyor.
Bunun iin connect() adl bir fonksiyondan yararlanyoruz.
Bu fonksiyonu,
[Link](veritaban_ad) eklinde kullanyoruz.
Eer iinde
bulunduumuz dizinde, veritaban_ad adl bir veritaban varsa Sqlite bu veritabanna
balanr. Eer bu adda bir veritaban yoksa, alma dizini altnda bu ada sahip yeni
bir veritaban oluturulur. zellikle deneme amal ilemler yapmamz gerektiinde,
sabit disk zerinde bir veritaban oluturmak yerine RAM stnde geici bir veritaban
ile almay da tercih edebiliriz. Bunun iin yukardaki komutu yle yazyoruz:
[Link](:memory:). Bu komutla RAM zerinde oluturduumuz veritaban,
balant kesildii anda ortadan kalkacaktr.
Veritabanmz oluturduktan veya varolan bir veritabanna balandktan sonra
yapmamz gereken ey bir imle oluturmak olacaktr. Daha sonra bu imlece ait
metotlardan yararlanarak nemli iler yapabileceiz. Sqliteta bir imle oluturabilmek
iin [Link]() gibi bir komut kullanyoruz. Tabii ben burada oluturduunuz
veritabanna db adn verdiinizi varsayyorum.
mlecimizi de oluturduktan sonra nmz iyice alm oldu. imdi dir(im) gibi
bir komut kullanarak imlecin metotlarnn ne olduunu inceleyebilirsiniz. Tabii ben
burada imlece im adn verdiinizi varsaydm. Grdnz gibi, listede execute()
adl bir metot da var. Artk imlecin bu execute() metodunu kullanarak SQL komutlarn
iletebiliriz.
Yukarda adet SQL komutu rendik. Bunlardan ilki CREATE TABLE. Bu komut
veritaban iinde bir tablo oluturmamz salyor.
kinci komutumuz CREATE
TABLE IF NOT EXISTS. Bu komut da bir tabloyu eer yoksa oluturmamz salyor.
nc komutumuz ise INSERT INTO ... VALUES .... Bu komut, oluturduumuz
tabloya ierik eklememizi salyor. Bunlar una benzer bir ekilde kullandmz
hatrlyorsunuz:
[Link]("CREATE TABLE personel (isim, soyisim, memleket)")
[Link]("INSERT INTO personel VALUES ('Frat', 'zgl', 'Adana')")
Burada bir ey dikkatinizi ekmi olmal. SQL komutlarn yazmaya balarken ift trnakla
baladk. Dolaysyla karakter dizisini yazarken i taraftaki Frat, zgl ve Adana deerlerini
yazmak iin tek trnak kullanmamz gerekti. Karakter dizileri iindeki manevra alannz
geniletmek iin, SQL komutlarn trnak iinde yazmay da tercih edebilirsiniz. Bylece
karakter dizisi iindeki tek ve ift trnaklar daha rahat bir ekilde kullanabilirsiniz. Yani:
[Link]("""CREATE TABLE personel (isim, soyisim, memleket)""")
[Link]("""INSERT INTO personel VALUES ("Frat", "zgl", "Adana")""")
Ayrca trnak kullanmanz sayesinde, uzun satrlar gerektiinde blerek ok daha okunakl
kodlar da yazabileceinizi biliyorsunuz.
894
Grdnz gibi, commit() imlecin deil, balant nesnesinin (yani burada vt deikeninin)
bir metodudur. imdi bu satr da betiimize ekleyelim:
import sqlite3
vt = [Link]("[Link]")
im = [Link]()
[Link]("""CREATE TABLE IF NOT EXISTS
personel (isim, soyisim, sehir, eposta)""")
[Link]("""INSERT INTO personel VALUES
("Orun", "Kunek", "Adana", "okunek@[Link]")""")
[Link]()
Bu son satr da ekledikten sonra Sqlite veritaban iinde yle bir tablo oluturmu olduk:
isim
Orun
soyisim
Kunek
ehir
Adana
eposta
okunek@[Link]
Eer [Link]() satrn yazmazsak, veritaban, tablo ve stun balklar oluturulur, ama
stunlarn ierii veritabanna ilenmez.
895
import sqlite3
vt = [Link]("[Link]")
im = [Link]()
[Link]("""CREATE TABLE IF NOT EXISTS
personel (isim, soyisim, sehir, eposta)""")
[Link]("""INSERT INTO personel VALUES
("Orun", "Kunek", "Adana", "okunek@[Link]")""")
[Link]()
[Link]()
Burada btn ilemleri bitirdikten sonra veritabann kapatmak iin, close() adl bir metottan
yararlandk:
[Link]()
Bu ekilde, veritabannn ilk ald andan itibaren, iletim sisteminin devreye soktuu
kaynaklar serbest brakm oluyoruz. Esasnda programmz kapandnda, ak olan btn
Sqlite veritabanlar da otomatik olarak kapanr. Ama yine de bu ilemi elle yapmak her zaman
iyi bir kirdir.
Eer zerinde ilem yaptnz veritabannn her ey bittikten sonra otomatik olarak
kapanmasn garantilemek isterseniz, daha nce rendiimiz with szcn
kullanabilirsiniz:
import sqlite3
with [Link]('[Link]') as vt:
im = [Link]()
[Link]("""CREATE TABLE IF NOT EXISTS personel
(isim, soyisim, memleket)""")
[Link]("""INSERT INTO personel VALUES
('Frat', 'zgl', 'Adana')""")
[Link]()
Bu ekilde with szcn kullanarak bir veritaban balants atmzda, btn iler
bittikten sonra Python bizim iin balanty otomatik olarak sonlandracaktr.
Ancak ou durumda veritabanna girilecek veriler harici kaynaklardan gelecektir. Basit bir
rnek verelim:
896
import sqlite3
with [Link]('[Link]') as vt:
im = [Link]()
veriler = [('Frat', 'zgl', 'Adana'),
('Ahmet', 'Sz', 'Bolvadin'),
('Veli', 'Gz', 'skenderun'),
('Mehmet', 'z', 'Kilis')]
[Link]("""CREATE TABLE IF NOT EXISTS personel
(isim, soyisim, memleket)""")
for veri in veriler:
[Link]("""INSERT INTO personel VALUES
(?, ?, ?)""", veri)
[Link]()
Burada veritabanna ilenecek veriler, veriler adl bir deikenden geliyor. Bu deiken
iindeki verileri veritabanna nasl yerletirdiimize dikkat edin:
for veri in veriler:
[Link]("""INSERT INTO personel VALUES
(?, ?, ?)""", veri)
Ayrca her bir stunun (isim, soyisim, memleket) altna gelecek her bir deer iin (mesela
srasyla Frat, zgl, Adana) bir adet ? iareti yerletirdiimizi de gzden karmayn.
897
[Link]()
miktar
45
ilk_odeme_tarihi
23 Ocak 2010
son_odeme_tarihi
30 Ocak 2010
Bilmediimiz ise bu veritabanndan nasl veri
Burada zel bir SQL komutu olan SELECT veri FROM tablo_ad komutundan faydalandk.
Burada joker karakterlerden biri olan * iaretini kullandmza dikkat edin. SELECT * FROM
faturalar ifadesi u anlama gelir: faturalar adl tablodaki btn eleri se!
Burada SELECT kelimesi SEMEK demektir. FROM ise ...DEN/...DAN anlam verir.
Yani SELECT FROM faturalar dediimizde faturalardan se demi oluyoruz. Burada
kullandmz * iareti de her ey anlamna geldii iin, SELECT * FROM faturalar ifadesi
faturalardan her eyi se gibi bir anlama gelmi oluyor.
Verileri setiimize gre, artk setiimiz bu verileri nasl alacamza bakabiliriz. Bunun
iin de fetchone(), fetchall() veya fetchmany() adl metotlardan ya da for dngsnden
yararlanacaz.
Burada [Link] adl bir veritabannda faturalar adl bir tablo oluturduk ve bu tabloya baz
veriler girdik. Daha sonra da SELECT adl SQL komutu yardmyla bu verileri setik. imdi de
setiimiz bu verileri veritabanndan alacaz.
Yukardaki programa u satr ekliyoruz:
898
veriler = [Link]()
Burada da ilk defa grdmz bir metot var: fetchall(). Grdnz gibi, fetchall()
imlecin bir metodudur. Yukarda grdmz SELECT * FROM faturalar komutu faturalar
adl tablodaki btn verileri seiyordu. fetchall() metodu ise seilen bu verileri alma
ilevi gryor. Yukarda biz fetchall() metoduyla aldmz btn verileri veriler adl bir
deikene atadk.
Artk bu verileri rahatlkla yazdrabiliriz:
print(veriler)
Grdnz gibi, veriler bir liste iinde demet halinde yer alyor. Ama tabii siz bu
verileri istediiz gibi biimlendirecek kadar Python bilgisine sahipsiniz. Ayrca program her
altrdnzda INSERT INTO sorgusu tekrar iletilecei iin verilerin tabloya tekrar tekrar
yazlacan, bu verileri alrken de kt listesinin byyeceini unutmayn. Peki eer siz bir
veritaban dosyasna verilerin yalnzca bir kez yazlmasn istiyorsanz ne yapacaksnz? Yani
mesela yukardaki kodlarda u sorgu yalnzca tek bir kez iletilsin:
[Link]("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")
Bylece veritabann her altrdnzda ("Elektrik", 45, "23 Ocak 2010", "30 Ocak
2010") satr dosyaya tekrar tekrar yazdrlmasn.
Bunu u kodlarla halledebilirsiniz:
import sqlite3, os
dosya = '[Link]'
dosya_mevcut = [Link](dosya)
899
vt = [Link](dosya)
im = [Link]()
[Link]("""CREATE TABLE IF NOT EXISTS faturalar
(fatura, miktar, ilk_odeme_tarihi, son_odeme_tarihi)""")
if not dosya_mevcut:
[Link]("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")
[Link]()
[Link]("""SELECT * FROM faturalar""")
veriler = [Link]()
print(veriler)
Burada kodlarmzn en banda [Link] adl bir veritabannn mevcut olup olmadn kontrol
ediyoruz (zira eer ortada bir veritaban dosyas yoksa, veri de yok demektir):
dosya_mevcut = [Link](dosya)
Eer byle bir dosya mevcut deilse (dolaysyla veri mevcut deilse) INSERT INTO sorgusu
iletilerek gerekli veriler yerine yerletirilecek:
if not dosya_mevcut:
[Link]("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")
[Link]()
Eer byle bir dosya zaten mevcutsa bu sorgu iletilemeyecek, onun yerine dorudan SELECT
sorgusuna geilecek. Bylece deerler veritabanna bir kez ilendikten sonra, programmz
ayn verileri tekrar tekrar veritabanna yerletirmeye almayacak.
Bu arada, daha nce de belirttiimiz gibi, tablo olutururken stun adlarnda boluk
(ve Trke karakter) kullanmak iyi bir kir deildir. Mesela ilk deme tarihi yerine
ilk_odeme_tarihi ifadesini tercih edin. Eer kelimeler arasnda mutlaka boluk brakmak
isterseniz btn kelimeleri trnak iine aln. Mesela: "ilk odeme tarihi" veya "ilk deme
tarihi" gibi.
Yukarda grdnz gibi, fetchall() metodu, bir veritabanndan SELECT ile setiimiz btn
verileri nmze getiriyor. Eer seilen verilerden ka tanesini almak istediinizi kendiniz
belirlemek istiyorsanz fetchall() yerine fetchone() veya fetchmany() metotlarndan o anki
amacnza uygun olann kullanmay tercih edebilirsiniz. Birazdan fetchone() ve fetchmany()
metotlarndan da sz edeceiz.
Gelin isterseniz imdi fetchall() metodunu kullanarak veritabanlarndan veri ekme
konusunda biraz altrma yapalm. Bu altrmalar iin, daha nce sz ettiimiz ve
bilgisayarmza indirdiimiz [Link] adl rnek veritabann kullanacaz.
ncelikle veritabanna balanalm ve bir imle oluturalm:
>>> import sqlite3
>>> vt = [Link]('[Link]')
>>> im = [Link]()
imdi bu veritabanndaki tabloyu seeceiz. Peki ama seeceimiz tablonun adn nereden
bileceiz? Hatrlarsanz, bir tablodaki btn verileri seebilmek iin u SQL sorgusunu
900
kullanyorduk:
"SELECT * FROM tablo_ad"
import sqlite3
vt = [Link]('[Link]')
im = [Link]()
[Link]("SELECT name FROM sqlite_master")
[Link]()
Btn Sqlite veritabanlarnda, ilgili veritabannn emasn gsteren sqlite_master adl bir
tablo bulunur. te bu tabloyu sorgulayarak veritaban hakknda bilgi edinebiliriz. Yukardaki
rnekte, bu sqlite_master tablosunun name (isim) niteliini sorguladk. Bu sorgu bize u
cevab verdi:
>>> [Link]()
[('kitaplar',)]
Demek ki [Link] adl veritabannda kitaplar adl tek bir tablo varm.
Gelin imdi bu bu tablodaki btn verileri alalm:
>>> [Link]("SELECT * FROM kitaplar")
>>> [Link]()
Bu ekilde tablo iinde ne kadar veri varsa hepsini ekrana yazdrdk. Ancak tabii ki,
bir veritabannn tamamn bir anda yazdrmak her zaman iyi bir kir olmayabilir. Eer
veritabannn iinde milyonlarca girdi varsa btn verilerin seilip yazdrlmas mantkl
olmayacaktr.
Gelin o halde imdi bizim seilen verilerin ne kadarn ekeceimizi
belirleyebilmemizi salayacak metotlar inceleyelim.
901
ki tane daha...
>>> [Link]()
('WEB TASARIM REHBER', 'Mustafa Aydemir', '38,50 TL')
>>> [Link]()
('ORACLE 11g R2', 'Teoman Dinel', '34,00 TL')
902
Biraz sonra veri szmeyi rendiimizde, bir veritabanndan veri seip almann daha verimli
yollarn greceiz.
Ancak amacmz ou zaman bir tablo iindeki btn verileri semek olmayacaktr.
Programclk maceramz boyunca genellikle yalnzca belli ltlere uyan verileri semek
isteyeceiz. Zira iinde milyonlarca veri barndrabilecek olan veritabanlarndaki verilerin
tamamn semek akl kr deildir.
Verileri szme iini WHERE adl bir SQL komutu yardmyla gerekletireceiz.
komutunun szdizimi yle:
Bu SQL
nasl
Bu ekilde, btn Sqlite veritabanlarnda bulunan sqlite_master adl zel bir tablonun name
niteliini sorgulayarak, elimizdeki veritabannda bulunan tablolarn adn elde edebiliyoruz.
Adn rendiimiz tablodaki stun balklarn elde etmek iin yine buna benzer bir komuttan
yararlanacaz. Dikkatlice bakn:
>>> [Link]("SELECT sql FROM sqlite_master").fetchone()
('CREATE TABLE "kitaplar"
(\n\t`KitapAdi`\tTEXT,\n\t`Yazar`\tTEXT,\n\t`Fiyati`\tTEXT\n)',)
sqlite_master adl tablonun sql niteliini sorguladmzda, ilgili tabloyu oluturmak iin
kullanlan SQL komutunu gryoruz. Bu komuta dikkatli bakarsanz, tablonun KitapAdi,
Yazar ve Fiyati olmak zere stundan olutuunu greceksiniz. Elbette stun adlarn
renmek iin Sqlitebrowser programn da kullanabileceinizi artk biliyorsunuz.
Stun adlarn rendiimize gre gelin imdi yazar adna gre veritabannda bir sorgu
yapalm:
>>> [Link]("SELECT * FROM kitaplar WHERE Yazar = 'Frat zgl'")
Burada sorguyu nasl kurduumuza dikkat edin. Bu sorgunun ilk ksm olan SELECT * FROM
kitaplar ifadesini zaten daha nce renmitik. Yeni olan ksm WHERE Yazar = Frat
zgl. Burada da anlalmayacak bir ey yok. Bu ekilde, veritabanndaki kitaplar
tablosunun Yazar stununda Frat zgl bulunan btn kaytlar seiyoruz.
51.16. Veri Szme
903
Gayet baarl...
Bu arada, verileri almak iin fetchall() yerine for dngs
kullanabileceinizi de biliyorsunuz:
>>> for s in im:
...
print(s)
...
('HERYNYLE PYTHON', 'Frat zgl', '34,00 TL')
gre
yldzl
parametrelerden
de
>>> print(*im)
('HERYNYLE PYTHON', 'Frat zgl', '34,00 TL')
904
Bu rnekte henz bilmediimiz baz ksmlar var. Ama siz imdilik bunlar kafanza takmayn.
Nasl olsa bu kodlarda grnen her eyi biraz sonra tek tek reneceiz. Siz imdilik sadece
905
O da ne! Program sizi ieri ald... Hem de kullanc ad ve parola doru olmad halde... Hatta
u kodu sadece kullanc ad ksmna girip parola ksmn bo brakmanz da sisteme giri hakk
elde etmenize yetecektir.:
x' OR '1' = '1' --
rneklerden de grdnz gibi, and ilecinin True sonucunu verebilmesi iin her iki
nermenin de doru olmas gerekir. O yzden a == 22 and b == 13 gibi bir ifade False
deeri veriyor. Ancak or ilecinin True sonucu verebilmesi iin iki nermeden sadece birinin
doru olmas yeterlidir. Bu yzden, sadece b == 13 ksm True olduu halde a == 22 or b
== 13 ifadesi True sonucu veriyor... te biz de yukardaki SQL szdrma giriiminde orun bu
zelliinden faydalanyoruz.
906
Dilerseniz neler olup bittiini daha iyi anlayabilmek iin, szdrlan kodu dorudan ilgili satra
uygulayalm:
[Link]("""SELECT * FROM kullanicilar WHERE
kullanici_adi = 'x' OR '1' = '1' AND parola = 'x' OR '1' = '1'""")
Sanrm bu ekilde neler olup bittii daha net grlyor. Durumu biraz daha netletirmek iin
Python yardma arabiliriz:
>>> kullanici_adi = 'ahmet123'
>>> parola = '12345678'
>>> kullanici_adi == 'x'
False
>>> '1' == '1'
True
>>> kullanici_adi == 'x' or '1' == '1'
True
>>> parola == 'x'
False
>>> (kullanici_adi == 'x' or '1' == '1') and (parola == 'x' or '1' == '1')
True
1 == 1 ifadesi her zaman True deeri verecektir. Dolaysyla kullanc adnn ve parolann
doru olup olmamas hibir nem tamaz. Yani her zaman True deerini verecei kesin olan
ifadeler yardmyla yukardaki gibi bir szdrma giriiminde bulunabilirsiniz.
Yukarda yaptmz ey, %s ile gsterilen yerlere kt niyetli bir SQL komutu szdrmaktan
ibarettir. Burada zaten balang ve biti trnaklar olduu iin szdrlan kodda balang ve
biti trnaklarn yazmyoruz. O yzden szdrlan kod yle grnyor:
x' OR '1' = '1
Burada yazdmz iareti AND parola = %s ksmnn sistem tarafndan yorum olarak
alglanmasn salyor. Bu yzden kodlarn bu ksm iletilmiyor. Dolaysyla da sisteme giri
yapabilmek iin sadece kullanc adn girmemiz yeterli oluyor. Burada ayrca kodlarmzn
51.17. Veritaban Gvenlii
907
almas iin 1in sonuna bir adet trnak yerletirerek kodu kapattmza dikkat edin. nk
normal biti trna yorum tarafnda kald.
Dikkat ederseniz SQL szdrdmzda ahmet123 adl kullancnn hesabn ele geirmi olduk.
Peki neden tekiler deil de ahmet123? Bunun sebebi, ahmet123 hesabnn tablonun en
banda yer almas. Eer tablonun banda admin diye bir hesap olmu olsayd, veritabanna
azami dzeyde zarar verme imkanna kavuacaktnz.
Peki SQL szdrma giriimlerini nasl nleyeceiz? Bu giriime kar alabileceiniz balca
nlem %s iaretlerini kullanmaktan kanmak olacaktr. Bu iaret yerine ? iaretini
kullanacaksnz. Yani yukardaki program yle yazacaz:
import sqlite3
db = [Link]("[Link]")
im = [Link]()
[Link]("""CREATE TABLE IF NOT EXISTS kullanicilar
(kullanici_adi, parola)""")
veriler = [
("ahmet123", "12345678"),
("mehmet321", "87654321"),
("selin456", "123123123")
for i in veriler:
[Link]("""INSERT INTO kullanicilar VALUES (?, ?)""", i)
[Link]()
kull = input("Kullanc adnz: ")
paro = input("Parolanz: ")
[Link]("""SELECT * FROM kullanicilar WHERE
kullanici_adi = ? AND parola = ?""", (kull, paro))
data = [Link]()
if data:
print("Programa hogeldin {}!".format(data[0]))
else:
print("Parola veya kullanc ad yanl!")
Bylece kullancnn baz tehlikeli karakterleri girmesini engelleyebilir, onlar sadece harf ve
say girmeye zorlayabilirsiniz.
908
Her halkarda unutmamamz gereken ey, gvenliin ok boyutlu bir kavram olduudur.
Birka nlemle pek ok gvenlik an engelleyebilirsiniz, ancak btn gvenlik aklarn
bir rpda yamamak pek mmkn deildir. Bir programc olarak sizin greviniz, yazdnz
programlar gvenlik aklarna kar srekli taramak ve herhangi bir ak ortaya ktnda da
bunu derhal kapatmaya almaktr.
909
910
BLM 52
Daha nce de sylediimiz gibi, modller Python programlama dilinin belkemiini oluturur.
Hatta Python renmek, bir bakma modlleri renmek demektir, diyebiliriz. Biz her
ne kadar bu noktaya gelene kadar Pythondaki btn temel veri tiplerini ve fonksiyonlar
renmi olsak da modlleri renmeden ve bunlar etkili bir ekilde nasl kullanacamz
bilmeden ie yarar programlar yazamayz.
Mesela diyelim ki veritabanna kayt yapan bir program yazacaksnz. te bu i iin eitli
modllerden yararlanmanz gerekir.
Eer MS Excel veya MS Word gibi dosya biimleri zerinde almalar yapacaksanz, bu
dosyalar zerinde ilem yapabilmenizi salayan birtakm modlleri kullanmanz gerekir.
Ayn ekilde grak bir arayze sahip programlar gelitirebilmek iin de baz standart modlleri
veya nc ahs modllerini kullanmalsnz.
Bu durum oyun programlama, tanabilir cihaz programlama, a programlama, web
programlama ve baka programlama alanlar iin de geerlidir.
Geen blmde, modller konusundan sz ederken Pythondaki standart ktphane
modllerine ve nc ahs modllerine yle bir gz gezdirmitik. nmzdeki bir ka
blm boyunca ise baz nemli standart modlleri ve nc ahs modllerini ayrntl olarak
inceleyeceiz. Bu sayede programclk ufkumuz epey bir genilemi olacak.
52.1 os Modl
Bildiiniz gibi, iletim sistemlerinin alma mant birbirinden farkldr. rnein Windows
ve GNU/Linux iletim sistemleri ayn ii birbirlerinden farkl ekillerde yaparlar. Mesela
Windowsta bir dizin iinde hangi klasr ve dosyalarn olduunu renmek iin dir komutunu
kullanrz. GNU/Linuxta ise ayn ilev iin ls adl bir komut vardr.
Ayn ekilde, iki iletim sistemi arasnda dizin ayralar konusunda da farkllk bulunur.
Windowsta dizinleri birbirinden ayrmak iin ters taksim (\) iareti kullanlrken, GNU/Linuxta
ayn i iin dz taksim (/) iareti kullanlr.
Not: Dz taksim iaretini Windows da kabul eder, ancak Windowsun doal dizin ayrac ters
taksimdir.
te biz hem Windowsta, hem de GNU/Linuxta alacak bir program yazmak istediimizde
bu farkllklar gz nnde bulundurmamz ve farkl durumlarn herbiri iin ayr kodlar
911
yazmamz gerekirken, os modl bizi bu zahmetten kurtarr ve bize ortak bir arayz
zerinden farkl iletim sistemleri ile tutarl bir ekilde iletiim kurabilmemizi salayacak pek
ok fonksiyon ve nitelik sunar.
Bu nitelik ve fonksiyonlarn neler olduunu dir(os) komutuyla grebileceinizi biliyorsunuz.
Bu blmde, os modlnn sunduu bu fonksiyon ve niteliklerin en nemlilerini ve en yaygn
kullanlanlarn olabildiince ayrntl bir ekilde ele almaya alacaz.
Not: Burada os modln import os komutuyla ie aktarm olduunuz varsaylmaktadr.
52.1.1 [Link]
os modlnn, nceki derslerde yle bir deinip getiimiz name nitelii, kullanclarmzn,
yazdmz kodlar hangi iletim sisteminde altrd konusunda bize bilgi verir.
Bu nitelii yle kullanyoruz:
>>> [Link]
Eer kodlarmz Windows iletim sistemi zerinde altrlmsa buradan u kty alrz:
'nt'
Dolaysyla [Link] niteliini kullanarak farkl iletim sistemlerinde farkl alan programlar
yazabiliriz.
52.1.2 [Link]
os modlnn sep nitelii, kodlarmzn alt iletim sisteminin dizin ayracnn ne
olduunu bize gsterir.
Eer bu nitelii Windows iletim sistemi zerinde kullanrsak u kty alrz:
>>> [Link]
'\\'
912
Burada karakter dizilerinin join() metodunu [Link] ile birlikte kullandmza dikkat edin.
Bu komutu Windowsta verdiinizde u kty alrsnz:
'aylar\\mays\\test'
Yani yukardaki komutu Windowsta verdiinizde Python u komutu alm gibi davranr:
>>> liste = ['aylar', 'mays', 'test']
>>> '\\'.join(liste)
Bylece yazdnz programlarda hangi iletim sisteminin hangi dizin ayracn kullandn
dnmenize gerek kalmaz; bunu sizin yerinize Python dnr...
52.1.3 [Link]()
os modlnn getcwd() fonksiyonu bize o anda iinde bulunduumuz dizinin adn verir:
>>> [Link]()
'/home/istihza/Desktop' #GNU/Linux
veya:
>>> [Link]()
'C:\\Documents and Settings\\fozgul' #Windows
52.1.4 [Link]()
os modlnn chdir() fonksiyonu bize bir dizinden baka bir dizine geme imkan verir.
Mesela GNU/Linuxta, o anda bulunduumuz dizinden /usr/bin adl dizine gemek iin u
komutu kullanabiliriz:
>>> [Link]('/usr/bin/')
veya Windowsta C:\Documents and Settings\fozgul\Desktop adl dizine gemek iin unu:
>>> [Link]('C:\\Documents and Settings\\fozgul\\Desktop')
Grdnz gibi, gitmek istediimiz dizin adn [Link]() fonksiyonuna parametre olarak
vermemiz yeterli oluyor.
52.1. os Modl
913
52.1.5 [Link]()
os modlnn listdir() fonksiyonu, bize bir dizin iindeki dosya ve klasrleri listeleme
imkan verir. listdir(), os modlnn en kullanl fonksiyonlarndan biridir.
Mesela o anda iinde bulunduumuz dizindeki dosya ve klasrleri listelemek istersek bu
fonksiyonu yle kullanabiliriz:
>>> mevcut_dizin = [Link]()
>>> [Link](mevcut_dizin)
Eer farkl bir dizinin ieriini listelemek istersek, parametre olarak o dizinin adn yazmamz
yeterli olacaktr:
>>> [Link]('/var/www')
Grdnz gibi, [Link]() komutunun kts liste trnde bir veri tipidir. Dolaysyla
listelerle yapabildiiniz her eyi bununla da yababilirsiniz. Mesela bu liste zerinde bir dng
kurabilirsiniz:
>>> for i in [Link]([Link]()):
...
print(i)
52.1.6 [Link]
ou iletim sisteminde mevcut dizini gstermek iin . adl karakter dizisi kullanlr. rnein:
>>> [Link]([Link]())
Eer bu karakter dizisini elle yazmak istemiyorsanz os modl iindeki curdir adl nitelikten
de yararlanabilirsiniz:
>>> [Link]([Link])
914
52.1.7 [Link]
Tpk . karakter dizisi gibi, ou iletim sisteminde bir st dizini gstermek iin .. adl karakter
dizisi kullanlr. rnein:
>>> [Link]('..')
komutu, o anda iinde bulunduunuz dizindeki deil, bir st dizindeki dosya ve dizin adlarn
listeleyecektir. Yine tpk [Link] niteliinde olduu gibi, eer bu karakter dizisini kendiniz
elle yazmak istemezseniz, bu karakter dizisini iinde barndran [Link] adl bir nitelikten
yararlanabilirsiniz:
>>> [Link]([Link])
52.1.8 [Link]()
Uyar: Bu fonksiyon yalnzca Windowsta alr. GNU/Linux iletim sistemlerinde bu
fonksiyon tanml deildir.
os modl iindeki startfile() adl fonksiyonun grevi bilgisayarmzda bulunan herhangi
bir dosyay, ilikilendirilmi olduu programla amaktr.
Hemen bir rnek verelim.
O anda iinde bulunduumuz dizinde [Link] adl bir dosya olduunu varsayalm. imdi
de u komutu verelim:
>>> [Link]('[Link]')
veya:
52.1. os Modl
915
>>> [Link]([Link]())
veya:
>>> [Link]('..')
Her iki komut da Windows Explorer yardmyla bir st dizinin grntlenmesini salayacaktr.
Elbette startfile() fonksiyonuna parametre olarak belirli bir dizinin adn da verebilirsiniz:
>>> [Link](r"C:\Documents and Settings\fozgul")
Ancak bu komutun yalnzca Windowsta alacan unutmayn. O yzden bunun yerine, daha
nce rendiimiz webbrowser modln kullanmak daha doru olacaktr.
52.1.9 [Link]()
os modlnn mkdir() fonksiyonu yeni dizinler oluturabilmemizi salar.
rnein:
>>> [Link]('yenidizin')
Bu komut, o anda iinde bulunduumuz dizin iinde yenidizin adl bir dizin oluturacaktr.
Elbette eer dizini o anda iinde bulunduunuz dizin iinde deil de farkl bir konumda
oluturmak isterseniz, o konumun ak adresini belirtebilirsiniz:
>>> [Link]('/home/istihza/Desktop/yenidizin')
veya:
>>> [Link](r'C:\Documents and Settings\fozgul\yenidizin')
916
52.1.10 [Link]()
[Link]() fonksiyonu biraz nce rendiimiz [Link]() fonksiyonuna ok benzese de
aralarnda nemli farklar bulunur.
Biraz nce [Link]() fonksiyonunu anlatrken yle bir rnek vermitik:
>>> [Link](r'C:\Documents and Settings\fozgul\yenidizin')
52.1.11 [Link]()
os modlnn rename() adl fonksiyonunu kullanarak dizinlerin adlarn deitirebiliriz. Bu
fonksiyon iki parametre alr:
>>> [Link]('dizinin_imdiki_ad', 'dizinin_yeni_ad')
Mesela mevcut alma dizininde deneme adl bir dizin varsa, bu dizinin adn test olarak
deitirmek iin u komutu verebiliriz:
>>> [Link]('deneme', 'test')
Eer zaten test adl bir dizin varsa (ve ii bosa), yukardaki komut GNU/Linuxta test adl
dizinin zerine yazacak, Windowsta ise hata verecektir.
52.1.12 [Link]()
os modlnn replace() fonksiyonu biraz nce rendiimiz rename() fonksiyonu gibi
alr:
>>> [Link]('deneme', 'test')
Bu komut, tpk rename() fonksiyonunda olduu gibi, deneme adl dizinin adn test olarak
deitirecektir.
Eer test adl bir dizin zaten varsa, replace() fonksiyonu, hem Windowsta hem de
GNU/Linuxta, varolan bu test dizininin zerine yazmaya alr. GNU/Linuxta ou durumda
bunu baarr, ancak Windowsta yine de eitli izin hatalar ile karlaabilirsiniz.
52.1. os Modl
917
52.1.13 [Link]()
os modlnn remove() adl fonksiyonu, bilgisayarmzdaki dosyalar silmemizi salar:
>>> [Link]('dosya_ad')
52.1.14 [Link]()
os modlnn rmdir() fonksiyonu, ii bo bir dizini silmek iin kullanlr:
>>> [Link]('dizin_ad')
Eer silmeye altnz dizin iinde herhangi bir baka dizin veya dosya varsa bu fonksiyon
hata verecektir.
Mesela yle bir dizin yaps dnelim:
|___ anadizin
|___ dizin1
|___ dizin2
|___ dizin3
|___ dizin4
nk bu dizinlerinin hibirinin ii bo deil; her birinin iinde birer dizin var. Ama u komut
baarl olacaktr:
>>> [Link](r'anadizin/dizin1/dizin2/dizin3/dizin4')
[Link](r'anadizin/dizin1/dizin2/dizin3/')
[Link](r'anadizin/dizin1/dizin2/')
[Link](r'anadizin/dizin1')
[Link](r'anadizin/')
52.1.15 [Link]()
os modlnn removedirs() fonksiyonu, ii bo dizin yollarn silmemizi salar. Peki bu ne
demek?
Diyelim ki elimizde yle bir dizin yaps var:
918
|___ anadizin
|___ dizin1
|___ dizin2
|___ dizin3
|___ dizin4
Eer btn dizinlerin ii bosa, anadizin den dizin4 e kadar olan btn dizinler (anadizin ve
dizin4 dahil) silinecektir.
52.1.16 [Link]()
os modlnn stat() fonksiyonu dosyalar hakknda bilgi almamz salar. Bu fonksiyonu
kullanarak bir dosyann boyutunu, oluturulma tarihini, deitirilme tarihini ve eriilme
tarihini sorgulayabiliriz.
stat() fonksiyonunu yle kullanyoruz:
>>> dosya = [Link]('dosya_ad')
>>> dosya
Bu, kendi iinde birtakm nitelikler barndran zel bir veri tipidir. Bu veri tipinin barndrd
nitelikleri grmek iin, her zaman olduu gibi dir() fonksiyonundan yararlanabilirsiniz:
dir(dosya)
Bu fonksiyon bize bayt cinsinden bir kt verir. Bunu kilobayta evirmek iin, bu deeri
1024e blebilirsiniz:
>>> dosya.st_size / 1024
919
>>>
>>>
>>>
>>>
dosya = [Link]('dosya_ad')
dosya.st_ctime #oluturulma tarihi
dosya.st_atime #eriilme tarihi
dosya.st_mtime #deitirme tarihi
Uyar:
GNU/Linuxta bir dosyann ne zaman oluturulduunu renmek mmkn
deildir.
Dolaysyla dosya.st_ctime komutu yalnzca Windowsta bir dosyann
oluturulma tarihi verir. Bu komutu GNU/Linuxta verdiimizde elde edeceimiz ey
dosyann son deitirilme tarihidir.
Bu arada, yukardaki komutlarn kts size anlamsz gelmi olabilir. Birazdan, datetime
adl bir modl rendiimizde bu anlamsz grnen saylar anlaml tarih bilgilerine nasl
dntreceimizi de anlatacaz.
52.1.17 [Link]()
os modlnn system() fonksiyonu Python iinden sistem komutlarn veya baka
programlar altrabilmemizi salar. Mesela:
>>> [Link]('[Link]')
52.1.18 [Link]()
os modlnn urandom() fonksiyonu rastgele bayt dizileri elde etmek iin kullanlabilir:
>>> [Link](12)
Bu komut, 12 bayttan oluan rastgele bir dizi oluturur. Buradan elde ettiiniz rastgele deeri
kriptograk almalarda veya rastgele parola retme ilemlerinde kullanabilirsiniz.
52.1.19 [Link]()
Hatrlarsanz nceki sayfalarda os modl iindeki listdir() adl bir fonksiyondan sz
etmitik. Bu fonksiyon, bir dizinin ieriini listeleme imkan veriyordu bize. Mesela o anda
iinde bulunduumuz dizinde hangi dosya ve alt dizinlerin olduunu renmek iin yle bir
komut kullanabiliyorduk:
>>> [Link]('.')
['[Link]', 'gtk', 'kitap', '[Link]', 'Makefile',
'meta_conf.py', 'py2', 'py3', 'theme', 'tk2', '__pycache__']
Grdnz gibi bu fonksiyon yalnzca kendisine parametre olarak verilen dizinin ieriini
listeliyor.
rnein yukardaki ktda grnen gtk, kitap, py2, py3, theme, tk2 ve
__pycache__ birer dizin. Ama listdir() fonksiyonu bu dizinlerin de iine girip buradaki ierii
listelemeye almyor. Eer biz mesela theme dizininin ieriini de listelemek istersek bunu
aka belirtmemiz gerekir:
>>> [Link]('theme')
920
Veya theme dizini iindeki static adl dizine de erimek istersek bunu da u ekilde ak ak
ifade etmemiz gerekir:
>>> [Link]('theme/static')
['[Link]', '[Link]', '[Link]', '[Link]']
Peki ya biz o anda iinde bulunduumuz dizinden itibaren ie doru btn dizinleri otomatik
olarak taramak istersek ne yapacaz?
Bunun iin listdir() fonksiyonunu kullanarak zyinelemeli (recursive) bir fonksiyon
yazabilirsiniz:
import os
def tara(dizin):
balang = [Link]()
dosyalar = []
[Link](dizin)
for e in [Link]([Link]):
if not [Link](e):
[Link](e)
else:
[Link](tara(e))
[Link](balang)
return dosyalar
Bu dizinin iine girdikten sonra, mevcut dizin iindeki btn eleri listdir() fonksiyonu ile
tek tek taryoruz:
for e in [Link]([Link]):
...
52.1. os Modl
921
if not [Link](e):
...
Burada neden append() deil de extend() kullandmz anlamak iin, yukardaki kodu bir
de append() ile yazp elde ettiiniz kty deerlendirebilirsiniz.
for dngsnden ktktan sonra da tekrar en bataki konuma dnebilmek iin aadaki
komutu altryoruz:
[Link](balang)
Eer bu ekilde baa dnmezsek, dizin yaps iindeki ilk alt dizine girildikten sonra
programmz o konumda takl kalaca iin teki st dizinlerin iini tarayamaz. Bunun ne
demek olduunu anlamak iin kodlar bir de [Link](balang) kodu olmadan altrmay
deneyebilirsiniz.
Yukardaki yntem doru olsa da, Pythonda bir dizini en dibe kadar taramann en iyi yolu
deildir. Python bize bu i iin zel bir fonksiyon sunar. te, bu blmde ele alacamz bu
fonksiyonun ad walk().
Walk kelimesi ngilizcede yrmek anlamna gelir. walk() fonksiyonu da, kelimenin bu
anlamna uygun olarak, dizinler iinde yrnmesini salar. Gelin bunu biraz aklayalm.
yle bir durum dnn: Sabit diskinizde, bir dizin iinde pek ok alt dizine dalm bir sr
dosya var. Yani unun gibi:
+anadizin
|[Link]
|[Link]
|[Link]
|[Link]
+resimler
|[Link]
|[Link]
|[Link]
|[Link]
+bakadosyalar
|[Link]
|[Link]
|dosya.mp3
|[Link]
|[Link]
922
Siz bu i ie gemi dosya yn iinden, sonu .jpeg ile bitenleri tek bir yerde toplamak
istiyorsunuz. Elbette, eer isterseniz bu .jpeg dosyalarn tek tek elle bulup istediiniz yere
tayabilirsiniz. Ama bu yntem bir Python programcsna yakmaz, deil mi?
Python programclar bu tr angaryalar kendi yapmak yerine Pythona yaptrmay tercih eder.
O yzden biz de bu ii yapmak iin Pythondan yararlanacaz.
os modlnn walk() fonksiyonunu kullanarak bu grevi rahatlkla yerine getirebilirsiniz.
Peki ama nasl?
ncelikle u kodlar yardmyla, yukardaki szn ettiimiz dosya-dizin yapsn oluturalm.
Bylece daha somut bir yap zerinde alma imkan elde etmi oluruz:
import os
uzantlar = ['txt', 'doc', 'xls',
'jpeg', 'pdf', 'zip',
'mp3', 'ogg', 'jpeg']
ablon1 = ['{}.{}'.format('dosya', i) for i in uzantlar[:4]]
ablon2 = ['resim{}.{}'.format(i, uzantlar[-1]) for i in range(1, 5)]
ablon3 = ['{}.{}'.format('dosya', i) for i in uzantlar[4:]]
dosyalar = [('anadizin', ablon1),
('resimler', ablon2),
('bakadosyalar', ablon3)]
[Link]([Link]([dosya[0] for dosya in dosyalar]))
for dizin, ablon in dosyalar:
for s in ablon:
open([Link]([dizin, s]), 'w')
[Link](dizin)
52.1. os Modl
923
Grdnz gibi, burada eli bir demet var. ktnn dier ksmlarn da incelerseniz ayn
yapy greceksiniz. Dolaysyla [Link]() komutu bize u eden oluan bir demet verir:
(kkdizin, altdizinler, dosyalar)
Mesela bu eli demet iinden yalnzca dosyalar almak isterseniz yle bir komut
verebilirsiniz:
>>> for kkdizin, altdizinler, dosyalar in [Link]('anadizin'):
...
print(dosyalar)
Grdnz gibi, bu ktda anadizin ve bunun altndaki btn dizinlerde yer alan btn
dosyalar var. Bu konunun banda walk() fonksiyonunu tanmlarken dediimiz gibi, walk()
fonksiyonu gerekten de dizinler iinde yrnmesini salyor.
Bu fonksiyonu daha iyi anlamak iin birka deneme daha yapalm:
>>> for kkdizin, altdizinler, dosyalar in [Link]('anadizin'):
...
print(altdizinler)
...
924
['resimler']
['bakadosyalar']
Bildiiniz gibi, dosya deikeninin bize verdii veri tipi bir listedir. O yzden bu listenin
elerini tek tek alabilmek iin bu liste zerinde de bir for dngs kurduumuza dikkat
edin.
Eer yukardaki dizinler iinde yer alan btn .jpeg dosyalarn listelemek istersek de yle
bir kod yazabiliriz:
>>> for kkdizin, altdizinler, dosyalar in [Link]('anadizin'):
...
for dosya in dosyalar:
...
if [Link]('.jpeg'):
...
print(dosya)
...
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
925
52.1.20 [Link]
os modlnn environ adl nitelii, kullandmz iletim sistemindeki evre deikenleri
hakknda bilgi edinmemizi salar.
Bu nitelik alelade bir szlktr. Dolaysyla bu szln iinde neler olduunu u kodlarla
grebilirsiniz:
>>> for k, v in [Link]():
...
print([Link](10), v)
52.1.21 [Link]
os modl zerinde dir() fonksiyonunu uyguladnzda, orada path adl bir niteliin
olduunu greceksiniz. Bu nitelik, kendi iinde pek ok nemli fonksiyon ve baka nitelik
barndrr.
imdi bu blmde [Link] adl bu niteliin ieriini inceleyeceiz.
[Link]()
abspath() fonksiyonu, bir dosyann tam yolunun ne olduunu syler:
>>> [Link]('[Link]')
[Link]()
dirname() fonksiyonu, bir dosya yolunun dizin ksmn verir:
>>> [Link]('/home/istihza/Desktop/[Link]')
'/home/istihza/Desktop'
926
[Link]()
exists() fonksiyonu bir dosya veya dizinin varolup olmadn kontrol eder:
>>> [Link]('/home/istihza/Desktop/[Link]')
Eer byle bir dosya varsa yukardaki kod True kts, yoksa False kts verir.
[Link]()
expanduser() fonksiyonu bilgisayardaki kullancya ait dizinin adresini verir:
>>> [Link]('~')
'C:\\Documents and Settings\\fozgul'
veya:
>>> [Link]('~')
'/home/istihza'
[Link]()
isdir() fonksiyonu, kendisine parametre olarak verilen enin bir dizin olup olmadn
sorgular:
>>> [Link]('/home/istihza')
Eer parametre bir dizin ise True, eer bir dosya ise False kts alnr.
[Link]()
isfile() fonksiyonu, kendisine parametre olarak verilen enin bir dosya olup olmadn
sorgular:
>>> [Link]('/home/istihza/[Link]')
Eer parametre bir dosya ise True, eer bir dizin ise False kts alnr.
[Link]()
join() fonksiyonu, kendisine verilen parametrelerden, ilgili iletim sistemine uygun yol
adresleri oluturur:
52.1. os Modl
927
[Link]()
split() fonksiyonu, bir yol adresinin son ksmn ba ksmndan ayrr:
>>> [Link]('/home/istihza/Desktop')
('/home/istihza', 'Desktop')
[Link]()
splitext() fonksiyonu dosya ad ile uzantsn birbirinden ayrmak iin kullanlr:
>>> dosya, uzant = [Link]('[Link]')
>>> dosya
'falanca'
>>> uzant
'.txt'
Grdnz gibi, kendi iinde pek ok nitelik ve fonksiyon barndran [Link], kullandmz
iletim sistemine uygun ekilde dizin ilemleri yapabilmemizi salayan son derece faydal bir
aratr.
Gelin isterseniz imdi biraz bu [Link] niteliinin baz nemli zelliklerinden sz edelim.
Hatrlarsanz nceki derslerimizde, modllerin kaynak dosyalarn grmemizi salayan
__file__ adl bir aratan sz etmitik. Mesela bu arac os modl zerinde uyguladmzda
una benzer bir kt alyorduk:
>>> os.__file__
'C:\\Python\\lib\\[Link]'
Ama Python programlama dilinin bize [Link] adl nitelii sunmu olmas sayesinde Windows
iletim sistemi iin ntpath, GNU/Linux iletim sistemi iin ise posixpath modln ayr ayr
ie aktarmamza gerek kalmyor. Btn ii bizim yerimize Python hallediyor. Bylece farkl
iletim sistemlerine ilikin birbirinden farkl ilemleri, [Link] adl tek bir arayz zerinden
gerekletirebiliyoruz.
929
Grdnz gibi bu modl iinde de epeyce fonksiyon ve nitelik var. Biz bu blmde, sys
modlnn en yaygn kullanlan, en nemli fonksiyon ve niteliklerini ele alacaz.
lk olarak exit() fonksiyonu ile balayalm...
52.2.1 [Link]()
sys modlnn exit() fonksiyonunu kullanarak, programnzn ileyiini durdurabilir,
programnz kapanmaya zorlayabilirsiniz. Basit bir rnek verelim:
import sys
say = input('Bir say girin: ')
if int(say) < 0:
print('klyor...')
[Link]()
else:
print(say)
Eer kullanc 0dan kk bir say girerse programmz [Link]() komutunun etkisiyle
almay durdurup kapanacaktr.
52.2.2 [Link]
sys modlnn argv nitelii, yazdmz program altrlrken kullanlan parametreleri bir
liste halinde tutar.
Gelin isterseniz bunun ne demek olduunu bir rnek zerinde gsterelim.
imdi mesela masastnde [Link] adl bir dosya oluturun ve iine unlar yazn:
import sys
print([Link])
Grdnz gibi, [Link] komutu bize bir liste veriyor. Bu listenin ilk esi, yazdmz
programn ad. Yani [Link].
imdi ayn program bir de u ekilde altralm:
930
Grdnz gibi, [Link] komutu, programn ismi ile birlikte, bu programa parametre
olarak verilen deerleri de bir liste halinde saklyor. Bu olduka nemli ve kullanl bir
zelliktir. Bu zellikten pek ok farkl ekillerde yararlanabilirsiniz.
Mesela:
import sys
def k():
print('klyor...')
[Link]()
if len([Link]) < 2:
print('Gerekli parametreleri girmediniz!')
k()
elif len([Link]) > 2:
print('ok fazla parametre girdiniz!')
k()
elif [Link][1] in ['-v', '-V']:
print('Program srm: 0.8')
else:
mesaj = 'Girdiiniz parametre ({}) anlalamad!'
print([Link]([Link][1]))
k()
Eer [Link] listesinin uzunluu 2den dkse, programmz herhangi bir parametre
olmadan, yalnzca ismiyle altrlm demektir.
Bu durumda kullancya Gerekli
parametreleri girmediniz! mesajn gsterip program sonlandryoruz.
Sonraki kod bloumuz yle:
52.2. sys Modl
931
Eer [Link] listesi 2den bykse, programmz birden fazla parametre ile altrlm
demektir. Bu durumda kullancya ok fazla parametre girdiniz! mesajn gsterip yine
program sonlandryoruz.
Bir sonraki kodlarmz yle:
elif [Link][1] in ['-v', '-V']:
print('Program srm: 0.8')
Eer [Link] listesinin ikinci esi -v veya -V ise programmzn srm bilgisini veriyoruz.
Son olarak da u blou yazyoruz:
else:
mesaj = 'Girdiiniz parametre ({}) anlalamad!'
print([Link]([Link][1]))
k()
Kullancnn -v veya -V dnda bir parametre girmesi durumunda ise, girilen parametrenin
anlalamad konusunda kullancy bilgilendirip programdan kyoruz.
Aada, programmzn hangi komutlara hangi karlklar verdiini gryorsunuz:
C:\Users\fozgul\Belgelerim> python [Link]
Gerekli parametreleri girmediniz!
klyor...
C:\Users\fozgul\Belgelerim> python [Link] -a
Girdiiniz parametre (-a) anlalamad!
klyor...
C:\Users\fozgul\Belgelerim> python [Link] -a -b
ok fazla parametre girdiniz!
klyor...
C:\Users\fozgul\Belgelerim> python [Link] -v
Program srm: 0.8
C:\Users\fozgul\Belgelerim> python [Link] -V
Program srm: 0.8
52.2.3 [Link]
Eer, yazdnz bir programda, programnzn alt sistemdeki Pythonn altrlabilir
dosyasnn adn ve yolunu renmeniz gerekirse bu nitelii kullanabilirsiniz:
>>> [Link]
C:\[Link]
932
52.2.4 [Link]()
Bu fonksiyon, kullanlan Windows srmne ilikin bilgi verir:
>>> [Link]()
[Link](major=5, minor=1, build=2600,
platform=2, service_pack='Service Pack 3')
52.2.5 [Link]
Modller konusunu ilerken sys modlnn path niteliinden sz etmitik. O yzden orada
sylediklerimizi tekrarlamayacaz.
52.2.6 [Link]
os modln incelerken rendiimiz name nitelii gibi, sys modlnn platform adl
nitelii de, kodlarmzn alt iletim sistemi hakknda bize bilgi verir:
>>> [Link]
Eer bu komutu GNU/Linuxta verirsek linux kts, Windowsta verirsek win32 kts, Mac OS
Xte verirsek darvin kts alrz.
52.2.7 [Link]
sys modlnn prex nitelii Pythonn hangi dizine kurulduunu gsterir:
933
>>> [Link]
'/home/local/python'
Veya:
>>> [Link]
'C:\\Python'
52.2.8 sys.ps1
sys modlnn ps1 nitelii, etkileimli kabuktaki >>> iaretini tutar:
>>> sys.ps1
'>>> '
52.2.9 sys.ps2
Etkileimli kabukta Python bizden girdiimiz kodlarn devamn beklediini gstermek iin ...
iaretini kullanr:
>>> a = 5
>>> if a == 5:
...
sys modlnn ps2 nitelii, ite etkileimli kabuktaki devam satrlarnda grdmz bu ...
iaretini tutar:
>>> sys.ps2
'... '
52.2.10 [Link]
sys modlnn version nitelii kullandnz Python srmne ilikin ayrntl bilgi verir:
>>> [Link]
`Python 3.5.1 (default, 16.02.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
934
52.2.11 sys.version_info
sys modlnn version_info nitelii de kullandnz Python srmne ilikin bilgi verir:
>>> sys.version_info
52.2.12 [Link]
sys modlnn winver nitelii Pythonn byk srm numarasyla kk srm numarasn
verir:
>>> [Link]
3.5
Uyar: Bu nitelik yalnzca Windowsta alr; GNU/Linuxta tanml deildir.
52.2.13 [Link]
nceki derslerimizden de bildiiniz gibi stdout, standart kt konumu, yani programlarmzn
ktlarn standart olarak verdikleri konum anlamna geliyor.
Pythonda yazdmz programlar ktlarn standart olarak komut satrna verir. Yani mesela:
>>> print('merhaba zalim dnya')
935
Burada, ktnn sonundaki 19 says merhaba zalim dnya karakter dizisinin uzunluunu
gsteriyor. [Link]() fonksiyonu etkileimli kabukta kullanldnda byle bir kt
verir. Ama eer bu kodlar bir dosyaya yazp altrrsanz sonraki 19 says grnmez.
Bu arada, her ne kadar print() ve [Link]() birbirine benzese de aralarnda
nemli farklar bulunur. rnein print() fonksiyonu parametre olarak her trl veri tipini
alabilir. Ancak [Link]() fonksiyonu parametre olarak yalnzca karakter dizisi
alabilir:
>>> [Link](12)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must be str, not int
936
z
a
Grdnz gibi, print() fonksiyonu, dngye giren her eyi yeni satra basyor.
Bir de [Link]() fonksiyonunun ne yaptna bakalm:
import sys
for i in 'istihza':
[Link](i)
Grdnz gibi, [Link]() fonksiyonu elerin hepsini ayn satra bast. Eer
elerin ayr satrlara baslmasn istiyorsanz bunu aka belirtmelisiniz:
import sys
for i in 'istihza':
[Link](i+'\n')
937
f = open('[Link]', 'w')
print('merhaba zalim dnya', file=f)
Geri bu sizin bilmediiniz bir ey deil. Zira siz bunu print() Fonksiyonu konusunu ilerken
de grmtnz...
52.2.14 [Link]
nceki blmde grdmz u kodlar tekrar nmze alalm:
import sys
f = open('[Link]', 'w')
[Link] = f
[Link]('merhaba zalim dnya')
Bu kodlar, bildiiniz gibi, kt olarak verilmek istenen deerlerin [Link] adl bir dosyaya
ynlendirilmesini salyor. Ancak kodlarmz bu ekilde yazdmzda sadece normal deerler
ynlendirilecektir. Mesela alma esnasnda ortaya kan hatalar yine komut ekranna
baslmaya devam edecektir:
import sys
f = open('[Link]', 'w')
[Link] = f
[Link](1/0)
nk Pythonda hata mesajlarnn ntanml olarak basld yer komut satrdr. Nasl
ktlarn standart olarak basld yeri teknik olarak standart kt konumu (Standard Output
- stdout ) olarak adlandryorsak, hatalarn standart olarak basld yeri de teknik olarak
standart hata konumu (Standard Error - stderr ) olarak adlandryoruz.
Tpk stdout u maniple edebildiimiz gibi, stderr i de maniple edebiliriz:
import sys
f =open('[Link]', 'w')
938
[Link] = f
[Link](1/0)
Bu durumda, programmzn ileyii srasnda ortaya kan hatalar [Link] adl bir dosyaya
ynlendirilecektir.
Bu bilgiyi kullanarak yle bir kod da yazabiliriz:
import sys
ktlar = open('[Link]', 'w')
hatalar = open('[Link]', 'w')
[Link] = ktlar
[Link] = hatalar
print('normal kt')
print('hata mesaj: ', 1/0)
52.2.15 [Link]
Pythonda adet standart konum bulunur:
1. Standart kt konumu - stdout
2. Standart hata konumu - stderr
3. Standart girdi konumu - stdin
lk ikisini zaten grmtk. ncsn de imdi ele alacaz.
Bildiiniz gibi Pythonda kullancdan veri almak iin input() fonksiyonunu kullanyoruz:
say = input('Ltfen bir say girin: ')
Bu komutlar verdiinizde, komut satr sizden veri almaya hazr hale gelir. Bu ekilde
istediiniz kadar veriyi komut satrna girebilirsiniz. Veri giriini durdurmak istediinizde
ise Windowsta CTRL+C, GNU/Linuxta ise CTRL+D tularna basmanz gerekir. Bu ekilde
komut satrn terkettiinizde, girmi olduunuz deerler bir karakter dizisi olarak ekrana
baslacaktr.
[Link] nitelii, bize veri okumak iin farkl fonksiyon sunar:
1. [Link]()
939
2. [Link]()
3. [Link]()
read() fonksiyonu birden fazla satr ieren verilerin girilmesine msaade eder ve kt olarak
bir karakter dizisi verir:
>>> [Link]()
(Girdi)
Frat
zgl
Adana
(kt)
'Frat\nzgl\nAdana\n'
readline() fonksiyonu tek bir satr ieren verilerin girilmesine msaade eder ve kt olarak
bir karakter dizisi verir:
>>> [Link]()
(Girdi)
Frat
(kt)
'Frat\n'
readlines() fonksiyonu birden fazla satr ieren verilerin girilmesine msaade eder ve kt
olarak bir liste verir:
>>> [Link]()
(Girdi)
Frat
zgl
Adana
(kt)
['Frat\n', 'zgl\n', 'Adana\n']
Gelin isterseniz [Link] niteliinin nasl kullanlabileceine ilikin birka rnek verelim:
import sys
with open('[Link]', 'w') as kaytlar:
while True:
satrlar = [Link]()
if [Link]() == ':q':
break
else:
[Link](satrlar)
Burada [Link] adl bir dosya oluturduk ncelikle. Daha sonra da readline() fonksiyonu
araclyla kullancdan aldmz btn verileri bu dosyaya yazdk. Kullancnn programdan
kabilmesini salamak iin de :q tu kombinasyonunu ayarladk. Bylece komut satrndan
alan basit bir metin dzenleyici yazm olduk!
Tpk [Link] ve [Link] konumlarn deitirdiimiz gibi, [Link] konumunu da
deitirebiliriz. Bylece verileri komut satr araclyla deil, mesela bir dosya araclyla
alabiliriz.
Aadaki rnei dikkatlice inceleyin:
940
import sys
f = open('[Link]')
[Link] = f
while True:
satrlar = [Link]()
if [Link]() == ':q':
break
else:
[Link](satrlar)
Bu kodlar yazdktan sonra, bu kodlarn bulunduu dizinde [Link] adl bir dosya oluturun.
Ardndan programnz altrn. Programnz u anda sizden veri girmenizi bekliyor. Verileri
[Link] adl dosyaya gireceksiniz.
[Link] adl dosyay ap bir eyler yazn. Veri girerken dosyay her kaydediinizde dosya
iindeki verilerin komut satrna dtn greceksiniz. Veri giriini tamamladktan sonra
dosyann en son satrna :q yazp dosyay kaydettiiniz anda da programnz kapanacaktr.
52.3.1 random()
random modlnn random() adl fonksiyonunu kullanarak, 0.0 ile 1.0 arasnda rastgele bir
kayan noktal say retebilirsiniz:
>>> [Link]()
0.8064301704207291
random() fonksiyonu, kendisini her altrnzda farkl bir kayan noktal say retecektir:
>>> [Link]()
0.6825988062501599
941
Mesela bu fonksiyonu kullanarak, 0 ile 1 aras 10 tane say retelim. Bu saylar gsterirken
de noktadan sonra yalnzca drt basamak grntlenmesine izin verelim:
>>> for i in range(10):
...
print("{:.4f}".format([Link]()))
...
0.3094
0.5277
0.1588
0.2832
0.8742
0.9989
0.6847
0.5672
0.5529
0.9717
52.3.2 uniform()
Biraz nce grdmz random() fonksiyonu, dikkat ederseniz herhangi bir parametre
almyordu. nk bu fonksiyonun tek grevi 0 ile 1 aras saylar retmektir. Peki ya biz
reteceimiz saylarn farkl bir aralkta olmasn istersek ne yapacaz?
te, belirli bir aralkta kayan noktal saylar retmek istediimizde, random() yerine uniform()
adl bir fonksiyon kullanacaz. Dikkatlice inceleyim:
>>> [Link](0.5, 1.5)
Bu kod, her altrlnda 0.5 ile 1.5 aras rastgele bir kayan noktal say retecektir:
>>> [Link](0.5, 1.5)
0.9624863371746406
>>> [Link](0.5, 1.5)
0.900446344810926
52.3.3 randint()
imdiye kadar rendiimiz random() ve uniform() fonksiyonlar bize yalnzca kayan noktal
saylar retme imkan veriyordu. Ancak elbette biz kimi durumlarda kayan noktal saylar
yerine tam saylar retmek de isteyebiliriz. te byle bir durumda, random modlnn
randint() adl baka bir fonksiyonunu kullanabiliriz.
Mesela 45 ile 500 arasnda rastgele bir say retmek isterseniz, randint() fonksiyonunu u
ekilde kullanabilirsiniz:
>>> [Link](45, 500)
Bu fonksiyon, her altrlnda 45 ile 500 arasnda rastgele bir tam say retecektir.
942
52.3.4 choice()
random modlnn choice() adl fonksiyonunu kullanarak, dizi nitelii tayan veri
tiplerinden rastgele eler seebiliriz. Bu tanm biraz anlalmaz gelmi olabilir. O yzden
bunu bir rnekle aklayalm.
Diyelim ki elimizde yle bir liste var:
>>> liste = ['ali', 'veli', 'ahmet',
... 'mehmet', 'celal', 'selin', 'nihat']
Bildiiniz gibi, listeler, dizi nitelii tayan veri tipleridir. Dolaysyla choice() fonksiyonunu
kullanarak bu diziden rastgele bir e seebiliriz:
>>> liste = ['ali', 'veli', 'ahmet', 'mehmet', 'celal', 'selin', 'nihat']
>>> [Link](liste)
'ali'
>>> [Link](liste)
'mehmet'
>>> [Link](liste)
'selin'
Tpk bu rnekte olduu gibi, karakter dizileri de dizi nitelii tayan bir veri tipi olduu iin,
choice() fonksiyonuna cevap verir:
>>> kardiz = 'istihza'
>>> [Link](kardiz)
'i'
Peki acaba bu i har karakter dizisinin bandaki i har mi, yoksa ortasndaki i har mi?
Sizce bunu nasl anlayabiliriz?
52.3.5 shue()
shuffle() fonksiyonunu kullanarak, dizi nitelii tayan veri tiplerindeki eleri
kartrabilirsiniz (yani elerin srasn kark bir hale getirebilirsiniz). Mesela:
>>> l = list(range(10))
10 eli bir listemiz var. Bu listedeki eler 0 dan 10 a kadar dzgn bir ekilde sralanm:
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
943
[8, 0, 7, 9, 1, 4, 6, 5, 3, 2]
Burada dikkat etmemiz gereken nemli nokta, shuffle() fonksiyonunun, zgn listenin
kendisi zerinde deiiklik yapyor oluudur. Yani liste zerinde shuffle() metodunu
uyguladktan sonra artk zgn listeyi kaybediyoruz. Dolaysyla elimizde artk eleri 0dan
10a kadar dzgn bir ekilde sralanm liste yok. Onun yerine, eleri kartrlm bir liste
var elimizde.
Liste zerine shuffle() fonksiyonunu her uygulaynzda zgn listenin eleri bir daha
kartrlacaktr.
Peki size bir soru...
Elinizde yle bir liste var:
arkadalar = [ali, veli, mehmet, ahmet, serkan, selin]
Grevimiz bu listenin elerini kartrmak. Ama biz ayn zamanda zgn arkadalar
listesindeki e sralamasn da kaybetmek istemiyoruz. Bunu nasl baarabiliriz?
52.3.6 randrange()
randrange() fonksiyonu, yukarda rendiimiz randint() fonksiyonu ile ayn ii yapar. Yani
her iki fonksiyon da, belli bir aralkta rastgele tamsaylar retir. Ancak aralarnda iki ufak fark
bulunur.
lk nce birincisine bakalm...
Dikkatlice inceleyin:
>>> [Link](10)
5
Grdnz gibi, randrange() fonksiyonunu tek parametre ile kullanabiliyoruz. Yukardaki
komutu eer randint() ile yazmak istersek unu yapmamz gerekir:
>>> [Link](0, 10)
Elbette, eer istersek randrange() fonksiyonunu da ift parametre ile kullanarak, farkl bir
say aral belirtme imkanna sahibiz:
>>> [Link](10, 500)
Bu komut, 10 ile 500 aras rastgele tam saylar retecektir. Ayrca bu komut ununla da
edeerdir:
944
Bu iki fonksiyon arasndaki ikinci fark ise, rastgele say retilecek araln son deeridir. Bu
mulak ifadeyi bir rnekle anlalr hale getirmeye alalm:
>>> [Link](10, 20)
Bu komut, 10 ile 20 arasnda rastgele bir say retir. retilecek en dk say 10 iken, en
byk say ise 19 olacaktr. 20 says asla retilmez.
Bir de una bakalm:
>>> [Link](10, 20)
Burada da yime 10 ile 20 arasnda rastgele bir say retilir. Tpk randrange() metodunda
olduu gibi, retilecek en dk say 10 dur. Ancak en byk say 20 olacaktr.
Bu iki fonksiyonu kullanrken bu farklla dikkat etmemiz gerekir. Aksi halde yazdmz
programlar hatal alabilir.
Peki size bir soru: Acaba randint() ile randrange() arasndaki bu fark nasl kantlarsnz?
52.3.7 sample()
Sample kelimesi numune anlamna gelir. te kelimenin bu anlamna paralel olarak
sample() fonksiyonu da, dizi nitelii tayan veri tiplerinden belli sayda numune
alnabilmesini salar. Baknz:
>>> liste = range(100)
100 eli bir liste oluturduk. imdi bu listeden 5 tane rastgele numune alalm:
>>> [Link](liste, 5)
[56, 74, 2, 3, 80]
Grdnz gibi, sample() fonksiyonunun ilk parametresi numune alnacak diziyi, ikinci
parametresi ise bu diziden ka tane numune alnacan gsteriyor.
945
Komutunu vererek datetime modl iindeki datetime adl snf ie aktarmay tercih
edebilirsiniz.
Bakalm datetime modlnn datetime snf iinde neler varm:
>>> dir(datetime)
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__',
'__forma t__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__le__', '__lt__', '__ne__', '__new__', '__radd__',
'__reduce__', '__reduce_ex__', '__rep r__', '__rsub__', '__setattr__',
'__sizeof__', '__str__', '__sub__', '__subclass hook__', 'astimezone',
'combine', 'ctime', 'date', 'day', 'dst', 'fromordinal', 'fromtimestamp',
'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond',
'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second',
'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today',
'toord inal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset',
'utctimetuple', 'weekday', 'year']
Bu durumda, datetime modl iindeki datetime snfna erimek iin modl adn da
kullanmanz gerekir:
>>> dir([Link])
52.4.1 now()
datetime modlnn iindeki datetime snfnn now() adl fonksiyonu, bize iindeki
bulunduumuz andaki tarih, saat ve zaman bilgilerini verir. datetime modln import
datetime eklinde ie aktardmz varsayarsak bunu u ekilde kullanyoruz:
>>> an = [Link]()
946
>>> an
[Link](2014, 12, 5, 9, 54, 53, 867108)
Ayn ekilde aadaki nitelikler de, iinde bulunduumuz ana ilikin eitli bilgiler verir:
>>> [Link] #ay
12
>>> [Link] #gn
5
>>> [Link] #saat
10
>>> [Link] #dakika
20
>>> [Link] #saniye
33
>>> [Link] #mikrosaniye
337309
52.4.2 today()
Bu fonksiyon now() ile ayn ierie ve ileve sahiptir. today() fonksiyonunu now fonksiyonunu
kullandnz gibi kullanabilirsiniz:
>>> bugn = [Link]()
>>> [Link]
2014
>>> [Link]
12
>>> [Link]
35
947
>>> [Link]
24
>>> [Link]
669774
52.4.3 ctime()
ctime() fonksiyonu, iinde bulunduumuz ana ilikin tarih ve zaman bilgilerini ieren
okunakl bir karakter dizisi verir.
Bu fonksiyona, parametre olarak biraz nce
oluturduumuza benzer bir [Link] snf vermemiz gerekir. Yani:
>>> an = [Link]()
>>> tarih = [Link](an)
>>> tarih
'Fri Dec
5 10:30:35 2014'
Bu fonksiyon tarihleri ngilizce olarak gsterir. Yukardaki ktya gre tarih 5 Aralk Cuma
2014 saat 10:30:35.
52.4.4 strftime()
strftime() fonksiyonu, size tarih ve zaman bilgilerini ihtiyalarnz dorultusunda
biimlendirme imkan sunar.
Bu fonksiyon toplam iki parametre alr. lk parametre, tpk ctime() fonksiyonunda olduu
gibi, bir [Link] snfdr. kinci parametre ise, tarih/zaman bilgisini ieren karakter
dizisini nasl biimlendirmek istediimizi gsteren bir biimlendiricidir. Yani:
>>> an = [Link]()
>>> tarih = [Link](an, '%c')
>>> tarih
'Fri 05 Dec 2014 12:53:21 PM '
%U belli bir tarihin yln kanc haftasna geldiini gsteren 0-53 aras bir say
%y yln son iki rakam
%Y yln drt haneli tam hali
%x tam tarih bilgisi
%X tam saat bilgisi
Yukardaki biimlendiricilerle ilgili birka rnek verelim:
>>> [Link](an, '%Y') # Yl
'2014'
>>> [Link](an, %'X') # Saat
'12:26:32'
>>> [Link](an, '%d') # Gn
'05'
Eer isterseniz, locale adl baka bir modl kullanarak, strftime() modlnn,
sisteminizdeki tanml dili kullanmasn salayabilirsiniz.
Bunun iin ncelikle locale modln ie aktaralm:
>>> import locale
949
Ayrca bkz.:
Yerel dil adlar iin Windowsta [Link]
adresine bakabilirsiniz. GNU/Linuxta ise, desteklenen yerel/dil adlarn grmek iin sistem
komut satrnda locale - a komutunu verebilirsiniz.
Yukarda grdnz tarih biimlendiricileri kullanarak istediiniz karmaklktaki tarihleri
oluturabilirsiniz. Mesela:
>>> [Link](an, '%d %B %Y')
'05 Aralk 2014'
Veya:
>>> [Link](an, '%d.%m.%Y tarihinde bulualm.')
52.4.5 strptime()
Diyelim ki elimizde, herhangi bir kaynaktan gelmi yle bir karakter dizisi var:
>>> t = '27 Mays 2014'
Amacmz, tarih bilgisi ieren bu karakter dizisini gn, ay ve yl elerine ayrmak. Bunun iin
basite yle bir kod yazabiliriz:
>>> gn, ay, yl = [Link]()
>>> gn
'27'
>>> ay
'Mays'
>>> yl
'2014'
950
Bunun iin de t deikeni zerine split() metodunu uyguladktan sonra saat kelimesini
listeden atmay tercih edebiliriz:
>>> gn, ay, yl, saat = [i for i in [Link]() if 'saat' not in i]
>>> gn
'27'
>>> ay
'Mays'
>>> yl
'2014'
>>> saat
'12:34:44'
Yukardaki yntemler, tarih bilgisi ieren karakter dizilerini ayklamak iin geerli ve uygun
olsa da epey meakkatlidir. stelik bu ekilde aykladmz verilerin kullanm alan da olduka
kstl olacaktr. Mesela bu verileri [Link] trnde verileri bekleyen uygulamalar
iinde kullanamayz.
te byle bir durumda strptime() adl fonksiyon devreye girerek, tarih/zaman bilgisi ieren
herhangi bir karakter dizisini [Link] trnde bir nesneye dntrebilmemiz iin
bize bir yol sunar.
imdi dikkatlice bakn:
Elimizdeki karakter dizisi u:
>>> t = '27 Mays 2014 saat 12:34:44'
==>
==>
==>
==>
==>
==>
%d
%B
%Y
%H
%M
%S
951
52.4.6 fromtimestamp()
Hatrlarsanz os modln anlatrken stat() adl bir fonksiyondan sz etmitik.
fonksiyonun, dosyalar hakknda bilgi almamz saladn biliyorsunuz:
Bu
>>> [Link]('dosya_ad')
Mesela bir dosyann son deitirilme tarihi renmek iin yle bir kod kullanyorduk:
>>> [Link]('dosya_ad').st_mtime
Bu, iinde ayrntl tarih bilgisi barndran bir zaman damgasdr (timestamp). te bu zaman
damgasn anlaml bir tarih bilgisine dntrebilmek iin datetime modlnn datetime
snf iindeki fromtimestamp() adl fonksiyondan yararlanacaz:
>>> zaman_damgas = [Link]('dosya_ad').st_mtime
>>> tarih = [Link](zaman_damgas)
>>> tarih
[Link](2014, 12, 5, 15, 0, 45, 888196)
Bu ekilde bir [Link] nesnesi elde ettikten sonra artk bu nesneyi istediimiz
ekilde maniple edebiliriz. Mesela:
>>> [Link](tarih, '%c')
'12/05/14 15:00:45'
952
52.4.7 timestamp()
Eer [Link] nesnelerinden bir zaman damgas retmek isterseniz timestamp()
fonksiyonunu kullanabilirsiniz:
>>> tarih = [Link]()
>>> zaman_damgas = [Link](tarih)
>>> zaman_damgas
1417790594.558625
Eer daha sonra bu zaman damgasn anlaml bir tarihe dntrmeniz gerekirse
fromtimestamp() fonksiyonunu kullanabileceinizi biliyorsunuz:
>>> tarih = [Link](zaman_damgas)
veya:
>>> [Link]()
Peki biz mesela bugnn deil de, gemiteki veya gelecekteki belirli bir tarihi almak istersek
ne yapacaz?
Bu i iinde yine datetime modlnn datetime adl snfndan yararlanacaz.
Diyelim ki 16 ubat 2016, saat 13:45:32yi bir datetime snf olarak kaydetmek istiyoruz.
Bunun iin yle bir kod kullanacaz:
>>> tarih = [Link](2016, 2, 16, 13, 45, 32)
Grdnz gibi, belirli bir tarihi bir [Link] nesnesi olarak kaydetmek
istediimizde datetime snfna parametre olarak srasyla ilgili tarihin yl, ay, gn, saat, dakika
ve saniye ksmlarn giriyoruz.
Bu arada, eer isterseniz bu tarih iin bir mikrosaniye de belirtebilirsiniz:
>>> tarih = [Link](2016, 2, 16, 13, 45, 32, 5)
953
Bylece belirli bir tarihi bir datetime snf olarak kaydetmi olduk.
[Link] nesnelerinin btn zelliklerine sahiptir:
Bu snf,
Buradan elde ettiimiz ey bir timedelta nesnesi. Bu nesne, tarihler arasndaki fark gn,
saniye ve mikrosaniye olarak tutan zel bir veri tipidir. Yukardaki ktdan anladmza
gre, 27 Mays 2015 tarihi ile 9 Aralk 2014 tarihi arasnda 168 gn, 34694 saniye ve 719236
mikrosaniye varm...
Yukardaki timedelta nesnesinin niteliklerine u ekilde ulaabilirsiniz:
>>> [Link] #gn
168
>>> [Link] #saniye
34694
>>> [Link] #mikrosaniye
719236
954
Demek ki bugnden 200 gn, 40 saniye ve 30 mikrosaniye sonras 27 Haziran 2015, saat
14:47:32ye denk geliyormu...
Gemi Bir Tarihi Bulmak
Gemi bir tarihi bulmak da, tahmin edebileceiniz gibi, ileri bir tarihi bulmaya ok benzer.
Basit bir rnek verelim:
>>> bugn = [Link]()
955
52.5.1 gmtime()
Pythonda (ve baka programlama dillerinde), zaman-tarih hesaplamalarnda zamann
balangc (EPOCH) diye bir kavram bulunur. Zamann balangc, bir iletim sisteminin, tarih
hesaplamalarnda sfr noktas olarak ald tarihtir. Kullandnz iletim sisteminin hangi
tarihi zamann balangc olarak kabul ettiini bulmak iin u komutu verebilirsiniz:
>>> [Link](0)
tm_hour=12,
Ancak bu kt, zellikle saat ksm konusunda her zaman doru olmayabilir. ktnn birka
saat saptn grebilirsiniz.
956
52.5.2 time()
time() fonksiyonu, zamann balangcndan, o anda iinde bulunduumuz ana kadar geen
toplam saniye miktarn verir:
>>> [Link]()
1418213083.726988
Elde ettiiniz bu deeri, gmtime() fonksiyonunu kullanarak anlaml bir tarih deerine
dntrebilirsiniz:
>>> [Link]([Link]())
time.struct_time(tm_year=2014, tm_mon=12, tm_mday=10,
tm_hour=12, tm_min=9, tm_sec=19, tm_wday=2, tm_yday=344,
tm_isdst=0)
52.5.3 localtime()
Tpk gmtime() fonksiyonundan olduu gibi, anlk tarih ve zaman bilgisini bir struct_time
nesnesi olarak almak iin localtime() fonksiyonunu da kullanabiliriz. Bu fonksiyon bize yerel
saati doru bir ekilde verecektir:
>>> [Link]()
time.struct_time(tm_year=2014, tm_mon=12, tm_mday=10,
tm_hour=14, tm_min=24, tm_sec=21, tm_wday=2, tm_yday=344, tm_isdst=0)
Bu nesnenin iindeki yl, ay ve gn gibi bilgilere tek tek nasl eriebileceinizi biliyorsunuz.
52.5.4 asctime()
Bata da sylediimiz gibi, time modl, datetime modlne benzer. Bunlarn ayn ii gren
eitli fonksiyonlar vardr. Bir rnek verelim.
Hatrlarsanz, bugnn tarihini bir karakter dizisi olarak almak iin datetime modln u
ekilde kullanabiliyorduk:
>>> import datetime
>>> an = [Link]()
>>> [Link](an)
'Wed Dec 10 13:56:22 2014'
asctime() fonksiyonu tercihe bal bir parametre de alabilir. sterseniz bu fonksiyona 9 eli
bir demet veya bir struct_time nesnesi verebilirsiniz.
52.5. time Modl
957
1 00:00:00 1970'
Ayn ekilde localtime() fonksiyonunun da bize bir struct_time() nesnesi verdiini biliyoruz.
Dolaysyla bu fonksiyon da asctime() fonksiyonuna parametre olarak verilebilir:
>>> [Link]([Link]())
'Wed Dec 10 14:28:05 2014'
Veya, srasyla yl, ay, gn, saat, dakika, saniye, haftann gn, yln gn, gn ndan
yararlanma durumu deerini ieren bir demet de oluturabilir, daha sonra bunu asctime()
fonksiyonuna parametre olarak verebilirsiniz:
>>> demet = (2014, 5, 27, 13, 45, 23, 0, 0, 0)
>>> [Link](demet)
52.5.5 strftime()
Hatrlarsanz datetime modln anlatrken, datetime snf iindeki strftime() adl bir
fonksiyondan sz etmitik. Bu fonksiyonun, tarih-saat bilgisi ieren karakter dizilerini
maniple edebilmemizi saladn biliyorsunuz.
Bu fonksiyonu yle kullanyorduk:
>>> import datetime
>>> an = [Link]()
>>> [Link](an, '%c')
'10.12.2014 14:57:48'
%B ayn tam ad
%c tam tarih, saat ve zaman bilgisi
%d say deerli bir karakter dizisi olarak gn
%j belli bir tarihin, yln kanc gnne denk geldiini gsteren 1-366 aras bir say
%m say deerli bir karakter dizisi olarak ay
%U belli bir tarihin yln kanc haftasna geldiini gsteren 0-53 aras bir say
%y yln son iki rakam
%Y yln drt haneli tam hali
%x tam tarih bilgisi
%X tam saat bilgisi
Uyar: Sistem yerelinin locale modl araclyla Trkeye ayarlanm olmas gerektiini
unutmuyoruz:
import locale
[Link](locale.LC_ALL, 'turkish')
52.5.6 strptime()
time modlnn strptime() fonksiyonunun yapt i, datetime modlnn datetime
snfnn strptime() fonksiyonunun yapt ie ok benzer:
>>>
>>>
>>>
>>>
import datetime
t = '27 Mays 1980'
tarih = [Link](t, '%d %B %Y')
tarih
[Link](1980, 5, 27, 0, 0)
Burada 27 Mays 1980 tarihini, strptime() fonksiyonu yardmyla bir datetime nesnesine
dntrdk. Ayn eyi u ekilde de yapabiliriz:
>>>
>>>
>>>
>>>
import time
t = '27 Mays 1980'
tarih = [Link](t, '%d %B %Y')
tarih
52.5.7 sleep()
sleep() fonksiyonu, time modlnn en sk kullanlan aralarndan bir tanesidir.
fonksiyonu kullanarak kodlarmzn ileyiini belli srelerle kesintiye uratabiliriz.
52.5. time Modl
Bu
959
Bu kodlar altrdnzda, 0dan 10a kadar olan saylar ekrana baslrken her bir say
arasna 1er saniyelik duraklamalar eklendiini greceksiniz. Eer arzu ederseniz bu sreyi
1 saniyenin de altna ekebilirsiniz:
>>> for i in range(10):
...
[Link](0.5)
...
print(i)
Grdnz gibi, sleep() fonksiyonuna 0.5 parametresini vererek, duraklama sresinin 500
milisaniye olmasn saladk.
time modlnn sleep() fonksiyonunu, kodlarnz arasna duraklama eklemek istediiniz her
durumda kullanabilirsiniz.
960
BLM 53
Katkda Bulunanlar
eklinde
gsterilen
kts
961
962
963
53.12 mer Gk
Dngler (Loops)
Dosya karlatrma kodlarndaki deiken hatalar giderildi.
Ka Dizileri
C:\\aylar\\nisan\\toplam
masraf
eklinde
gsterilen
C:\aylar\nisan\toplam masraf eklinde dzeltildi.
dizin
yolu
965
966
yazlan
kod
szlk[i] =
evre
deikeni
967
969
970