Sayılar¶
Geçen bölümde sayma sistemlerini ayrıntılı bir şekilde inceledik. Bu bölümde ise yine bununla bağlantılı bir konu olan sayılar konusunu ele alacağız. Esasında biz sayıların ne olduğuna ve Python’da bunların nasıl kullanılacağına dair tamamen bilgisiz değiliz. Buraya gelene kadar, sayılar konusunda epey şey söyledik aslında. Mesela biz Python’da üç tür sayı olduğunu biliyoruz:
Tam Sayılar (integers)
Kayan Noktalı Sayılar (floating point numbers veya kısaca floats)
Karmaşık Sayılar (complex numbers)
Eğer bir veri type(veri)
sorgulamasına int cevabı veriyorsa o veri bir
tam sayıdır. Eğer bir veri type(veri)
sorgulamasına float cevabı veriyorsa
o veri bir kayan noktalı sayıdır. Eğer bir veri type(veri)
sorgulamasına
complex cevabını veriyorsa o veri bir karmaşık sayıdır.
Mesela şunlar birer tam sayıdır:
15, 4, 33
Şunlar birer kayan noktalı sayıdır:
3.5, 6.6, 2.3
Şunlarsa birer karmaşık sayıdır:
3+3j, 5+2j, 19+10j
Ayrıca şimdiye kadar öğrendiklerimiz sayesinde bu sayıların çeşitli fonksiyonlar yardımıyla birbirlerine dönüştürülebileceğini de biliyoruz:
Fonksiyon
Görevi
Örnek
int()
Bir veriyi tam sayıya dönüştürür
int('2')
float()
Bir veriyi kayan noktalı sayıya dönüştürür
float(2)
complex()
Bir veriyi karmaşık sayıya dönüştürür
complex(2)
Dediğimiz gibi, bunlar bizim zaten sayılara dair bildiğimiz şeyler. Elbette bir de henüz öğrenmediklerimiz var.
Gelin şimdi bunların neler olduğunu inceleyelim.
Sayıların Metotları¶
Tıpkı öteki veri tiplerinde olduğu gibi, sayıların da bazı metotları bulunur. Bu metotları kullanarak sayılar üzerinde çeşitli işlemler gerçekleştirebiliriz.
Tam Sayıların Metotları¶
Dediğimiz gibi, Python’da birkaç farklı sayı tipi bulunur. Biz ilk olarak tam sayı (integer) denen sayı tipinin metot ve niteliklerini inceleyeceğiz.
Öncelikle hangi metotlar ve niteliklerle karşı karşıya olduğumuza bakalım:
>>> [i for i in dir(int) if not i.startswith("_")]
['bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator',
'real', 'to_bytes']
Bu listede şimdilik bizi ilgilendiren tek bir metot var. Bu metodun adı
bit_length()
.
bit_length()¶
Bilgisayarlar hakkında bilmemiz gereken en önemli bilgilerden biri şudur: Bilgisayarlar ancak ve ancak sayılarla işlem yapabilir. Bilgisayarların işlem yapabildiği sayılar da onlu sistemdeki sayılar değil, ikili sistemdeki sayılardır. Yani 0’lar ve 1’ler.
Bilgisayar terminolojisinde bu 0’lar ve 1’lerden oluşan herbir basamağa ‘bit’ adı verilir. Yani ikili sayma sisteminde ‘0’ ve ‘1’ sayılarından herbiri 1 bit’tir. Mesela onlu sistemde 2 sayısının ikili sistemdeki karşılığı olan 10 sayısı iki bit’lik bir sayıdır. Onlu sistemdeki 100 sayısının ikili sistemdeki karşılığı olan 1100100 sayısı ise yedi bitlik bir sayıdır.
Bu durumu daha net bir şekilde görebilmek için şu kodları yazalım:
>>> 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 sütundaki sayılar ilk sütundaki sayıların ikili sistemdeki karşılıklarıdır. Üçüncü sütundaki sayılar ise her bir sayının kaç bit olduğunu, yani bir bakıma ikili sayma sisteminde kaç basamağa sahip olduğunu gösteriyor.
İşte herhangi bir tam sayının kaç bit’lik bir yer kapladığını öğrenmek için, tam
sayıların metotlarından biri olan bit_length()
metodundan yararlanacağız:
>>> sayı = 10
>>> sayı.bit_length()
4
Demek ki 10 sayısı bellekte dört bitlik bir yer kaplıyormuş. Yani bu sayının ikili sistemdeki karşılığı olan 1010 sayısı dört basamaktan oluşuyormuş.
Yukarıdaki örneklerden de rahatlıkla çıkarabileceğiniz gibi, bit_length()
metodu, ikili sayma sistemindeki bir sayı üzerine len()
fonksiyonunun
uygulanması ile eşdeğerdir. Yani:
>>> len(bin(10)[2:]) == (10).bit_length()
True
Bu arada şu son örnekte bir şey dikkatinizi çekmiş olmalı: bit_length()
metodunu doğrudan sayılar üzerine uygulayamıyoruz. Yani:
>>> 10.bit_length()
File "<stdin>", line 1
10.bit_length()
^
SyntaxError: invalid syntax
Bu metodu sayılarla birlikte kullanabilmek için iki seçeneğimiz var:
bit_length()
metodunu uygulamak istediğimiz sayıyı önce bir değişkene
atayabiliriz:
>>> a = 10
>>> a.bit_length()
4
…veya ilgili sayıyı parantez içine alabiliriz:
>>> (10).bit_length()
4
Bu durum, yani sayıyı parantez içinde gösterme zorunluluğu, 10 sayısının
sağına bir nokta işareti koyduğumuzda, Python’ın bu sayıyı bir kayan noktalı
sayı olarak değerlendirmesinden kaynaklanıyor. Yani biz ‘10’ yazıp,
bit_length()
metodunu bu sayıya bağlama amacıyla sayının sağına bir nokta
koyduğumuz anda, Python bu sayının bir kayan noktalı sayı olduğunu zannediyor.
Çünkü Python açısından, 10. sayısı bir kayan noktalı sayıdır. Bunu teyit
edelim:
>>> type(10.)
<class 'float'>
Kayan noktalı sayıların bit_length()
adlı bir metodu olmadığı için de
Python’ın bize bir hata mesajı göstermekten başka yapabileceği bir şey kalmıyor.
Kayan Noktalı Sayıların Metotları¶
Python’da tam sayılar dışında kayan noktalı sayıların da olduğunu biliyoruz. Bu sayı tipinin şu metotları vardır:
>>> [i for i in dir(float) if not i.startswith("_")]
['as_integer_ratio', 'conjugate', 'fromhex', 'hex', 'imag', 'is_integer', 'real']
Biz bu metotlar arasından, as_integer_ratio()
ve is_integer()
adlı
metotlarla ilgileneceğiz.
as_integer_ratio()¶
Bu metot, birbirine bölündüğünde ilgili kayan noktalı sayıyı veren iki adet tam sayı verir bize. Örnek üzerinden açıklayalım:
>>> sayı = 4.5
>>> sayı.as_integer_ratio()
(9, 2)
9 sayısını 2 sayısına böldüğümüzde 4.5 sayısını elde ederiz. İşte
as_integer_ratio()
metodu, bu 9 ve 2 sayılarını bize ayrı ayrı verir.
is_integer()¶
Bir kayan noktalı sayının ondalık kısmında 0 harici bir sayının olup olmadığını kontrol etmek için bu metodu kullanıyoruz. Örneğin:
>>> (12.0).is_integer()
True
>>> (12.5).is_integer()
False
Karmaşık Sayıların Metotları¶
Gelelim karmaşık sayıların metot ve niteliklerine…
>>> [i for i in dir(complex) if not i.startswith("_")]
['conjugate', 'imag', 'real']
Gördüğünüz gibi, karmaşık sayıların da birkaç tane metot ve niteliği var. Biz
bunlar arasından imag
ve real
adlı nitelikleri inceleyeceğiz.
imag¶
Bir gerçek bir de sanal kısımdan oluşan sayılara karmaşık sayılar (complex) adı verildiğini biliyorsunuz. Örneğin şu bir karmaşık sayıdır:
12+4j
İşte imag
adlı nitelik, bize bir karmaşık sayının sanal kısmını verir:
>>> c = 12+4j
>>> c.imag
4.0
real¶
real
adlı nitelik bize bir karmaşık sayının gerçek kısmını verir:
>>> c = 12+4j
>>> c.real
12.0
Aritmetik Fonksiyonlar¶
Python programlama dili, bize sayılarla rahat çalışabilmemiz için bazı fonksiyonlar sunar. Bu fonksiyonları kullanarak, karmaşık aritmetik işlemleri kolayca yapabiliriz.
Biz bu bölümde Python’ın bize sunduğu bu gömülü fonksiyonları tek tek inceleyeceğiz.
Gömülü fonksiyonlar, Python programlama dilinde, herhangi bir özel işlem
yapmamıza gerek olmadan, kodlarımız içinde doğrudan kullanabileceğimiz
fonksiyonlardır. Biz şimdiye kadar pek çok gömülü fonksiyonla zaten tanışmıştık.
O yüzden gömülü fonksiyonlar bizim yabancısı olduğumuz bir konu değil. Mesela
buraya gelene kadar gördüğümüz, len()
, range()
, type()
, open()
,
print()
ve id()
gibi fonksiyonların tamamı birer gömülü fonksiyondur.
Biz bu fonksiyonları ilerleyen derslerde çok daha ayrıntılı bir şekilde
inceleyeceğiz. Ama şu anda bile fonksiyonlar konusunda epey bilgiye
sahibiz.
Şimdiye kadar öğrendiğimiz gömülü fonksiyonlardan şu listede yer alanlar, matematik işlemlerinde kullanılmaya uygun olanlardır:
complex()
float()
int()
pow()
round()
hex()
oct()
bin()
Biz bu fonksiyonların ne işe yaradığını önceki derslerimizde zaten ayrıntılı olarak incelemiştik. O yüzden burada bunlardan söz etmeyeceğiz. Onun yerine, henüz öğrenmediğimiz, ama mutlaka bilmemiz gereken gömülü fonksiyonları ele alacağız.
O halde hiç vakit kaybetmeden yola koyulalım…
abs()¶
Bu fonksiyon bize bir sayının mutlak değerini verir:
>>> abs(-2)
2
>>> abs(2)
2
divmod()¶
Bu fonksiyon, bir sayının bir sayıya bölünmesi işleminde bölümü ve kalanı verir:
>>> divmod(10, 2)
(5, 0)
10 sayısı 2 sayısına bölündüğünde ‘bölüm’ 5, ‘kalan’ ise 0’dır.
Bir örnek daha verelim:
>>> divmod(14, 3)
(4, 2)
Bu sonuçtan gördüğünüz gibi, aslında divmod()
fonksiyonu şu kodlarla aynı
işi yapıyor:
>>> 14 // 3, 14 % 3
Bu fonksiyonun gerçekleştirdiği bölme işleminin bir ‘taban bölme’ işlemi olduğuna özellikle dikkatinizi çekmek istiyorum.
max()¶
Size şöyle bir soru sorduğumu düşünün: Acaba aşağıdaki listede yer alan sayıların en büyüğü kaçtır?
[882388, 260409, 72923, 692476, 131925, 259114, 47630, 84513, 25413, 614654,
239479, 299159, 175488, 345972, 458112, 791030, 243610, 413702, 565285,
773607, 131583, 979177, 247202, 615485, 647512, 556823, 242460, 852928,
893126, 792435, 273904, 544434, 627222, 601984, 966446, 384143, 308858,
915106, 914423, 826315, 258342, 188056, 934954, 253918, 468223, 262875,
462902, 370061, 336521, 367829, 147846, 838385, 605377, 175140, 957437,
105779, 153499, 435097, 9934, 435761, 989066, 357279, 341319, 420455,
220075, 28839, 910043, 891209, 975758, 140968, 837021, 526798, 235190,
634295, 521918, 400634, 385922, 842289, 106889, 742531, 359913, 842431,
666182, 516933, 22222, 445705, 589281, 709098, 48521, 513501, 277645,
860937, 655966, 923944, 7895, 77482, 929007, 562981, 904166, 619260,
616293, 203512, 67534, 615578, 74381, 484273, 941872, 110617, 53517,
402324, 156156, 839504 , 625325, 694080, 904277, 163914, 756250, 809689,
354050, 523654, 26723, 167882, 103404, 689579, 121439, 158946, 485258,
850804, 650603, 717388, 981770, 573882, 358726, 957285, 418479, 851590,
960182, 11955, 894146, 856069, 369866, 740623, 867622, 616830, 894801,
827179, 580024, 987174, 638930, 129200, 214789, 45268, 455924, 655940,
335481, 845907, 942437, 759380, 790660, 432715, 858959, 289617, 757317,
982063, 237940, 141714, 939369, 198282, 975017, 785968, 49954, 854914,
996780, 121633, 436419, 471, 776271, 91626, 209175, 894281, 417963, 624464,
736535, 418888, 506194, 591087, 64075, 50252, 952943, 25878, 217085,
223996, 416042, 484123, 810460, 423284, 956886, 237772, 960241, 601551,
830147, 449088, 364567, 337281, 524358, 980387, 393760, 619710, 100181,
96738, 275199, 553783, 975654, 662536, 979103, 869504, 702350, 174361,
970250, 267625, 661580, 444662, 871532, 881977, 981660, 446047, 508758,
530694, 608789, 339540, 242774, 637473, 874011, 732999, 511638, 744144,
710805, 641326, 88085, 128487, 59732, 739340, 443638, 830333, 832136,
882277, 403538, 441349, 721048, 32859]
İşte böyle bir soruyu çözmek için max()
fonksiyonundan yararlanabilirsiniz.
Yukarıdaki listeyi sayılar adlı bir değişkene atadığımızı varsayarsak,
aşağıdaki kod bize listedeki en büyük sayıyı verecektir:
>>> max(sayılar)
Yukarıdaki örneklerde max()
fonksiyonunu kullanarak bir dizi içindeki en
büyük sayıyı bulduk. Peki bu fonksiyonu kullanarak bir dizi içindeki en
uzun karakter dizisini bulabilir miyiz? Evet, bulabiliriz.
Diyelim ki elimizde şöyle bir liste var:
isimler = ["ahmet", "mehmet", "necla", "sedat", "abdullah",
"gıyaseddin", "sibel", "can", "necmettin", "savaş", "özgür"]
Amacımız bu liste içindeki en uzun kelimeyi bulmak. İşte bunu max()
fonksiyonu ile yapabiliriz. Dikkatlice bakın:
print(max(isimler, key=len))
Bu kodları çalıştırdığımızda, listedeki en uzun isim olan ‘gıyaseddin’i elde edeceğiz.
Gördüğünüz gibi, max()
fonksiyonu key adlı özel bir parametre daha alıyor.
Bu parametreye biz ‘len’ değerini verdik. Böylece max()
fonksiyonu liste
içindeki öğeleri uzunluklarına göre sıralayıp en uzun öğeyi bize sundu.
Hatırlarsanız geçen bölümde şöyle bir kod yazmıştık:
sayı_sistemleri = ["onlu", "sekizli", "on altılı", "ikili"]
print(("{:^9} "*len(sayı_sistemleri)).format(*sayı_sistemleri))
for i in range(17):
print("{0:^9} {0:^9o} {0:^9x} {0:^9b}".format(i))
Bu kodlar, farklı sayma sistemleri arasındaki farkları daha net görmemizi
sağlamıştı. Yalnız burada dikkat ettiyseniz, sayı_sistemleri adlı listeye her
öğe ekleyişimizde, listedeki en uzun değeri dikkate alarak karakter dizisi
biçimlendiricileri içindeki, öğeler arasında ne kadar boşluk bırakılacağını
belirleyen sayıları güncelliyorduk. Mesela yukarıdaki örnekte, öğeler arasında
yeterince boşluk bırakabilmek için bu sayıyı 9 olarak belirlemiştik. İşte
şimdi öğrendiğimiz max()
fonksiyonunu kullanarak bu sayının otomatik olarak
belirlenmesini sağlayabiliriz. Dikkatlice inceleyin:
sayı_sistemleri = ["onlu", "sekizli", "on altılı", "ikili"]
en_uzun = len(max(sayı_sistemleri, key=len))
print(("{:^{aralık}} "*len(sayı_sistemleri)).format(*sayı_sistemleri, aralık=en_uzun))
for i in range(17):
print("{0:^{1}} {0:^{1}o} {0:^{1}x} {0:^{1}b}".format(i, en_uzun))
Gördüğünüz gibi, max()
fonksiyonunu ve bu fonksiyonun key parametresini
kullanarak, oluşturduğumuz tablodaki öğelerin arasına uygun boşluğu otomatik
olarak eklemiş olduk. Bunun için, sayı_sistemleri adlı listedeki en uzun
öğenin uzunluk miktarını temel aldık.
min()¶
Bu fonksiyon, max()
fonksiyonun yaptığı işin tam tersini yapar. Yani bu
fonksiyonu kullanarak bir dizi içindeki en küçük sayıyı bulabilirsiniz:
>>> min(sayılar)
Tıpkı max()
fonksiyonunda olduğu gibi, min()
fonksiyonunda da key
parametresini kullanabilirsiniz. Mesela max()
fonksiyonunu anlatırken
verdiğimiz isim listesindeki en kısa ismi bulabilmek için şu kodu
yazabilirsiniz:
print(min(isimler, key=len))
sum()¶
Bu fonksiyon bir dizi içinde yer alan bütün sayıları birbiriyle toplar. Örneğin:
>>> a = [10, 20, 43, 45 , 77, 2, 0, 1]
>>> sum(a)
198
Eğer bu fonksiyonun, toplama işlemini belli bir sayının üzerine gerçekleştirmesini istiyorsanız şu kodu yazabilirsiniz:
>>> sum(a, 10)
208
sum()
fonksiyonuna bu şekilde ikinci bir parametre verdiğinizde, bu ikinci
parametre toplam değere eklenecektir.
Önemli Not
Sorularınızı yorumlarda dile getirmek yerine Yazbel Forumunda sorarsanız çok daha hızlı cevap alabilirsiniz.Belgelerdeki bir hata veya eksiği dile getirecekseniz lütfen yorumları kullanmak yerine Github'da bir konu (issue) açın.
Eğer yazdığınız yorum içinde kod kullanacaksanız kodlarınızı <pre><code> etiketleri içine alın. Örneğin:
<pre><code class="python"> print("Merhaba Dünya!") </code></pre>