istihza.com¶
Bu Kitap Hakkında¶
Elinizdeki kitap, Python programlama dili için kapsamlı bir Türkçe kaynak oluşturma projesi olan yazbel.com’un bir ürünüdür. Bu kitabın amacı, herhangi bir sebeple Python programlama diline ilgi duyan, bu programlama dilini öğrenmek isteyen kişilere bu dili olabildiğince hızlı, ayrıntılı ve kolay bir şekilde öğretmektir.
Bu kitabın hedef kitlesi, programlamayı hiç bilmeyen kişilerdir. Bu sebeple, bu kitapta ders konularını olabildiğince ayrıntılı ve basitleştirilmiş bir şekilde ele almaya çalıştık.
Bu Kitaptan Nasıl Yararlanabilirim?¶
Elinizdeki kitap, epey uzun ve ayrıntılı makalelerden oluşuyor. Dolayısıyla bu kitabı elinize alıp bir roman gibi okumaya çalışırsanız, sıkılıp öğrenme azminizi kaybedebilirsiniz. Bu kitabı sıkılmadan ve bıkkınlığa düşmeden takip edebilmeniz için size birkaç öneride bulunalım.
Programlama dillerini, sanki tarih, coğrafya veya felsefe çalışıyormuşsunuz gibi, kitaba gömülüp harıl harıl okuyarak öğrenemezsiniz. Programlama dillerini öğrenebilmek için sizin de etkin bir şekilde öğrenme sürecine katılmanız gerekir. Yani bu kitaptaki makalelere kafanızı gömmek yerine, bol bol örnek kod yazmaya çalışırsanız, öğrendiğiniz şeyler zihninizde daha kolay yer edecektir. Birincisi bu.
İkincisi, kimse sizden bu kitaptaki her ayrıntıyı ezberlemenizi beklemiyor. Maharet, bir konuya ilişkin bütün ayrıntıları akılda tutabilmekte değildir. İyi bir programcı, bir konuya dair nasıl araştırma yapacağını ve kaynaklardan nasıl faydalanacağını bilir. Bir yazılım geliştirici adayı olarak sizin de öğrenmeniz gereken şey, gördüğünüz bütün konuları en ince ayrıntısına kadar ezberlemeye kalkışmaktan ziyade, o konuya ilişkin ilk aşamada fikir sahibi olmaya çalışmaktır. Python’da ilerledikçe, zaten belli alanlara ilgi duyacak, kendinizi o alanlarda geliştirmeye çalışacaksınız. Elbette çok uğraştığınız konulara ilişkin ayrıntılar da daha kolay aklınızda kalacaktır. Üstelik bir projeye ilişkin gerekliliklerin sizi yönlendirmesiyle, belli konularda daha ayrıntılı araştırma yapma fırsatı da bulacaksınız.
Üçüncüsü, bir konuyu çalışırken yeterince anlayamadığınızı hissederseniz, lütfen dudağınızı büzüp bir duvar köşesine kıvrılarak kendi kendinizi yılgınlığa düşürmeyin. Eğer bir konuyu anlamadıysanız, okuyup geçin. Okuyup geçmek içinize sinmiyorsa, aşağıda belirttiğimiz şekilde yardım isteyin.
Son olarak, bu kitaptan çevrimdışı olarak faydalanmak istiyorsanız buradaki seçenekleri takip edebilirsiniz.
Nereden Yardım Alabilirim?¶
Bu kitapta Python programlama diline ilişkin konuları olabildiğince temiz ve anlaşılır bir dille anlatmaya çalıştık. Ancak yine de bazı konular zihninizde tam olarak yer etmeyebilir. Üstelik kimi zaman, bir konuyu daha iyi anlayabilmek ya da bir sorunun üstesinden gelebilmek için bilen birilerinin yardımına da ihtiyaç duyabilirsiniz. İşte böyle durumlarda yazbel.com’un forum alanına uğrayarak başka Python programcılarından yardım isteyebilirsiniz.
Forum alanı hem bilgi edinmek, hem de bildiklerinizi paylaşmak için oldukça elverişli bir ortamdır. Foruma ilk girişiniz muhtemelen yardım istemek için olacaktır. Ama ilerleyen zamanlarda Python bilginiz arttıkça bir de bakacaksınız ki yardım ararken yardım eder duruma gelmişsiniz. İşte forum; kendinizdeki değişimi görmek, bilgi düzeyinizdeki artışı takip etmek ve hatta yeni şeyler öğrenmek için bulunmaz bir fırsattır.
Projeye Nasıl Yardımcı Olabilirim?¶
Bu kitabın amacı, kitabı okuyanlara Python programlama dilini doğru ve ayrıntılı bir şekilde öğretmek olduğu kadar, bu programlama dilini öğretirken düzgün ve anlaşılır bir Türkçe de kullanmaktır. Bu bakımdan, kitapta bulabileceğiniz kod hatalarıyla birlikte, kitaptaki anlatım, yazım ve noktalama hatalarını da GitHub’daki veri havuzunda düzelterek ya da GitHub’da bir konu açarak bu projeye önemli bir katkıda bulunmuş olursunuz.
Ayrıca bakınız
Projeye bu şekilde katkıda bulunanların listesini Katkıda Bulunanlar başlıklı sayfada görebilirsiniz.
Bunun dışında, projeye destek olmanın bir başka yolu, forum alanında sorulan soruları cevaplamaya çalışmaktır. Bu şekilde hem projeye destek olmuş, hem başkalarına yardım etmiş, hem de kendi bilginizi artırmış olursunuz.
Python’da kendinizi belli bir seviyeye getirdikten sonra, eğer kaleminize de güveniyorsanız eksik konular hakkında yazıp kitaba katkıda bile bulunabilirsiniz.
Kullanım Koşulları¶
Bu kitaptaki bilgiler Creative Commons lisansı altındadır. Bu lisansa göre, bu kitaptaki bütün bilgilerden herkes ücretsiz olarak yararlanabilir. Eğer isterseniz burada gördüğünüz belgelerin çıktısını alabilir, tanıdığınız veya tanımadığınız herkesle gönül rahatlığıyla paylaşabilirsiniz. Ancak bu belgeleri başka bir yerde kullanacaksanız, yine bu lisans altında kullanmalı ve bu belgeleri kesinlikle satmamalısınız. Arzu ederseniz belgeleri çoğaltıp ücretsiz olarak dağıtabilirsiniz.
Python Hakkında¶
Eğer yaşamınızın bir döneminde herhangi bir programlama dili ile az veya çok ilgilendiyseniz, Python adını duymuş olabilirsiniz. Önceden bir programlama dili deneyiminiz hiç olmamışsa dahi, Python adının bir yerlerden kulağınıza çalınmış olma ihtimali bir hayli yüksek. Bu satırları okuyor olduğunuza göre, Python adını en az bir kez duymuş olduğunuzu ve bu şeye karşı içinizde hiç değilse bir merak uyandığını varsayabiliriz.
Peki, en kötü ihtimalle kulak dolgunluğunuz olduğunu varsaydığımız bu şey hakkında acaba neler biliyorsunuz?
İşte biz bu ilk bölümde, fazla teknik ayrıntıya kaçmadan, Python hakkında kısa kısa bilgiler vererek Python’ın ne olduğunu ve bununla neler yapabileceğinizi anlatmaya çalışacağız.
Python Nedir?¶
Tahmin edebileceğiniz gibi Python (C, C++, Perl, Ruby ve benzerleri gibi) bir programlama dilidir ve tıpkı öteki programlama dilleri gibi, önünüzde duran kara kutuya, yani bilgisayara hükmetmenizi sağlar.
Bu programlama dili Guido Van Rossum adlı Hollandalı bir programcı tarafından 90’lı yılların başında geliştirilmeye başlanmıştır. Çoğu insan, isminin Python olmasına aldanarak, bu programlama dilinin, adını piton yılanından aldığını düşünür. Ancak zannedildiğinin aksine bu programlama dilinin adı piton yılanından gelmez. Guido Van Rossum bu programlama dilini, The Monty Python adlı bir İngiliz komedi grubunun, Monty Python’s Flying Circus adlı gösterisinden esinlenerek adlandırmıştır. Ancak her ne kadar gerçek böyle olsa da, Python programlama dilinin pek çok yerde bir yılan figürü ile temsil edilmesi neredeyse bir gelenek halini almıştır.
Dediğimiz gibi, Python bir programlama dilidir. Üstelik pek çok dile kıyasla öğrenmesi kolay bir programlama dilidir. Bu yüzden, eğer daha önce hiç programlama deneyiminiz olmamışsa, programlama maceranıza Python’la başlamayı tercih edebilirsiniz.
Neden Programlama Öğrenmek İsteyeyim?¶
Günlük yaşamınıza şöyle bir bakın. Gerek iş yerinizde olsun, gerek evde bilgisayar başında olsun, belli işleri tekdüze bir şekilde tekrar ettiğinizi göreceksiniz. Mesela sürekli olarak yazılı belgelerle uğraşmanızı gerektiren bir işte çalışıyor olabilirsiniz. Belki de her gün onlarca belgeyi açıp bu belgelerde birtakım bilgiler arıyor, bu bilgileri düzeltiyor, yeniliyor veya siliyorsunuzdur. Bu işlemlerin ne kadar vakit alıcı ve sıkıcı olduğunu düşünün. Eğer bir programlama dili biliyor olsaydınız, bütün bu işlemleri sizin yerinize bu programlama dili hallediyor olabilirdi.
İşte Python programlama dili böyle bir durumda devreye girer. Her gün saatler boyunca uğraştığınız işlerinizi, yalnızca birkaç satır Python kodu yardımıyla birkaç saniye içinde tamamlayabilirsiniz.
Ya da şöyle bir durum düşünün: Çalıştığınız iş yerinde PDF belgeleriyle bolca haşır neşir oluyor olabilirsiniz. Belki de yüzlerce sayfalık kaşeli ve imzalı belgeyi PDF haline getirmeniz gerekiyordur. Üstelik sizden bu belgeleri mümkün olduğunca tek parça halinde PDF’lemeniz isteniyor olabilir. Ama o yüzlerce sayfayı tarayıcıdan geçirirken işin tam ortasında bir aksilik oluyor, makine arızalanıyor ve belki de ister istemez belgeniz bölünüyordur.
İşte Python programlama dili böyle bir durumda da devreye girer. Eğer Python programlama dilini öğrenirseniz, İnternet’te saatlerce ücretsiz PDF birleştirme programı aramak veya profesyonel yazılımlara onlarca dolar para vermek yerine, belgelerinizi birleştirip işinizi görecek programı kendiniz yazabilirsiniz.
Elbette Python’la yapabilecekleriniz yukarıda verdiğimiz basit örneklerle sınırlı değildir. Python’ı kullanarak masaüstü programlama, oyun programlama, taşınabilir cihaz programlama, web programlama ve ağ programlama gibi pek çok alanda çalışmalar yürütebilirsiniz.
Neden Python?¶
Python programlarının en büyük özelliklerinden birisi, C ve C++ gibi dillerin aksine, derlenmeye gerek olmadan çalıştırılabilmeleridir. Python’da derleme işlemi ortadan kaldırıldığı için, bu dille oldukça hızlı bir şekilde program geliştirilebilir.
Ayrıca Python programlama dilinin basit ve temiz söz dizimi, onu pek çok programcı tarafından tercih edilen bir dil haline getirmiştir. Python’ın söz diziminin temiz ve basit olması sayesinde hem program yazmak, hem de başkası tarafından yazılmış bir programı okumak, başka dillere kıyasla çok kolaydır.
Python’ın yukarıda sayılan özellikleri sayesinde dünya çapında ün sahibi büyük kuruluşlar (Google, YouTube ve Yahoo! gibi) bünyelerinde her zaman Python programcılarına ihtiyaç duyuyor. Mesela pek çok büyük şirketin Python bilen programcılara iş imkanı sağladığını, Python’ın baş geliştiricisi Guido Van Rossum’un 2005 ile 2012 yılları arasında Google’da çalıştığını, 2012 yılının sonlarına doğru ise Dropbox şirketine geçtiğini söylersek, bu programlama dilinin önemi ve geçerliliği herhalde daha belirgin bir şekilde ortaya çıkacaktır.
Python programlama dili ve bu dili hakkıyla bilenler sadece uluslararası şirketlerin ilgisini çekmekle kalmıyor. Python son zamanlarda Türkiye’deki kurum ve kuruluşların da dikkatini çekmeye başladı. Bu dil artık yavaş yavaş Türkiye’deki üniversitelerin müfredatında da kendine yer buluyor.
Sözün özü, pek çok farklı sebepten, başka bir programlama dilini değil de, Python programlama dilini öğrenmek istiyor olabilirsiniz.
Python Nasıl Telaffuz Edilir?¶
Python programlama dili üzerine bu kadar söz söyledik. Peki yabancı bir kelime olan python’ı nasıl telaffuz edeceğimizi biliyor muyuz?
Geliştiricisi Hollandalı olsa da python İngilizce bir kelimedir. Dolayısıyla bu kelimenin telaffuzunda İngilizcenin kuralları geçerli. Ancak bu kelimeyi hakkıyla telaffuz etmek, ana dili Türkçe olanlar için pek kolay değil. Çünkü bu kelime içinde, Türkçede yer almayan ve telaffuzu peltek s’yi andıran [th] sesi var. İngilizce bilenler bu sesi think (düşünmek) kelimesinden hatırlayacaklardır. Ana dili Türkçe olanlar think kelimesini genellikle [tink] şeklinde telaffuz eder. Dolayısıyla python kelimesini de [paytın] şeklinde telaffuz edebilirsiniz.
Python kelimesini tamamen Türkçeleştirerek [piton] şeklinde telaffuz etmeyi yeğleyenler de var. Elbette siz de dilinizin döndüğü bir telaffuzu tercih etmekte özgürsünüz.
Bu arada, eğer python kelimesinin İngilizce telaffuzunu dinlemek istiyorsanız howjsay.com adresini ziyaret edebilir, Guido Van Rossum’un bu kelimeyi nasıl telaffuz ettiğini merak ediyorsanız da https://www.youtube.com/watch?v=UIDdgeISLUI adresindeki tanıtım videosunu izleyebilirsiniz.
Platform Desteği¶
Python programlama dili pek çok farklı işletim sistemi ve platform üzerinde çalışabilir. GNU/Linux, Windows, Mac OS X, AS/400, BeOS, MorphOS, MS-DOS, OS/2, OS/390, z/OS, RiscOS, S60, Solaris, VMS, Windows CE, HP-UX, iOS ve Android gibi, belki adını dahi duymadığınız pek çok ortamda Python uygulamaları geliştirebilirsiniz. Ayrıca herhangi bir ortamda yazdığınız bir Python programı, üzerinde hiçbir değişiklik yapılmadan veya ufak değişikliklerle başka ortamlarda da çalıştırılabilir.
Biz bu belgelerde Python programlama dilini GNU/Linux ve Microsoft Windows işletim sistemi üzerinden anlatacağız. Ancak sıkı sıkıya bel bağlayacağımız özel bir GNU/Linux dağıtımı veya Windows sürümü yok. Bu yüzden, hangi GNU/Linux dağıtımını veya hangi Windows sürümünü kullanıyor olursanız olun, buradaki bilgiler yardımıyla Python programlama dilini öğrenebilir, öğrendiklerinizi kendi işletim sisteminize uyarlayabilirsiniz.
Not
Bu satırların yazarının, Ubuntu, CentOS, Windows 7 ve Windows 10 kurulu bilgisayarlara erişimi olduğu için, bu kitaptaki ekran görüntüleri genellikle bu işletim sistemlerinden alınmış olacaktır.
Farklı Python Sürümleri¶
Eğer daha önce Python programlama dili ile ilgili araştırma yaptıysanız, şu anda piyasada iki farklı Python serisinin olduğu dikkatinizi çekmiş olmalı. 19.08.2024 tarihi itibariyle piyasada olan en yeni Python sürümleri Python 2.7.18 ve Python 3.12.1’dir.
Eğer bir Python sürümü 2 sayısı ile başlıyorsa (mesela 2.7.15), o sürüm Python 2.x serisine aittir. Yok eğer bir Python sürümü 3 sayısı ile başlıyorsa (mesela 3.7.0), o sürüm Python 3.x serisine aittir.
Peki neden piyasada iki farklı Python sürümü var ve bu bizim için ne anlama geliyor?
Python programlama dili 1990 yılından bu yana geliştirilen bir dil. Bu süre içinde pek çok Python programı yazıldı ve insanların kullanımına sunuldu. Şu anda piyasada Python’ın 2.x serisinden bir sürümle yazılmış pek çok program bulunuyor. 3.x serisi ise ancak son yıllarda yaygınlık kazanmaya başladı.
Not
Biz bu kitapta kolaylık olsun diye Python’ın 3.x serisini Python3; 2.x serisini ise Python2 olarak adlandıracağız.
Python3, Python2’ye göre hem çok daha güçlüdür, hem de Python2’nin hatalarından arındırılmıştır. Python3’teki büyük değişikliklerden ötürü, Python2 ile yazılmış bir program Python3 altında çalışmayacaktır. Aynı durum bunun tersi için de geçerlidir. Yani Python3 kullanarak yazdığınız bir program Python2 altında çalışmaz.
Dediğimiz gibi, piyasada Python2 ile yazılmış çok sayıda program var. İşte bu sebeple Python geliştiricileri uzun bir süre daha Python2’yi geliştirmeye devam edecek. Elbette geliştiriciler bir yandan da Python3 üzerinde çalışmayı ve bu yeni seriyi geliştirmeyi sürdürecek.
Farklı Python serilerinin var olmasından ötürü, Python ile program yazarken hangi seriye ait sürümlerden birini kullandığınızı bilmeniz, yazacağınız programın kaderi açısından büyük önem taşır.
Not
Biz bu kitapta Python 3.7 kullanacağız. Aksi belirtilmediği sürece bütün kodların bu sürüm ile çalıştırıldığını varsayabilirsiniz. Ayrıca Python3.7 için yazacağımız kodlar daha yüksek versiyonlarda da çalışacaktır.
Hangi Seriyi Öğrenmeliyim?¶
Dediğimiz gibi, şu anda piyasada iki farklı Python serisi var: Python3 ve Python2. Peki acaba hangi seriye ait bir sürümü öğrenmelisiniz?
[Kısa cevap]
Python3’ü öğrenmelisiniz.
[Uzun cevap]
Eğer Python programlama diline yeni başlıyorsanız Python3’ü öğrenmeniz daha doğru olacaktır. Ama eğer Python programlama dilini belirli bir proje üzerinde çalışmak üzere öğreniyorsanız, hangi sürümü öğrenmeniz gerektiği, projede kullanacağınız yardımcı modüllerin durumuna bağlıdır. Zira şu anda piyasada bulunan bütün Python modülleri/programları henüz Python3’e aktarılmış değil.
Eğer projenizde kullanmayı planladığınız yardımcı modüller halihazırda Python3’e aktarılmışsa Python3’ü öğrenebilirsiniz. Ancak eğer bu modüllerin henüz Python3 sürümü çıkmamışsa sizin de Python2 ile devam etmeniz daha uygun olabilir. Ama her halükarda Python3’ün bu dilin geleceği olduğunu ve günün birinde Python2’nin tamamen tedavülden kalkacağını da aklınızın bir köşesinde bulundurun.
Uyarı
1 Ocak 2020 itibarıyla Python2’ye verilen destek bitmiştir. Python Yazılım Vakfı artık Python2.x sürümlerini geliştirmemektedir. Yukarıda yazarın yazdığı satırların günümüzde bir geçerliliği kalmamış, önemli Python kütüphanelerinin neredeyse hepsi Python3’e geçmiş ve Python2 desteklerini 2021’de bırakacaklarını duyurmuştur. Python’u yeni öğrenen biri olarak Python2 yerine Python3’ü seçmeniz çok daha doğru olur. Ayrıntılı bilgi için bu linklere bakabilirsiniz:
Python Nasıl Kurulur?¶
Python ile program yazabilmemiz için bu programlama dilinin bilgisayarımızda kurulu olması gerekiyor. Bu programlama dilini kurmanızın gerekip gerekmediği, kullandığınız işletim sistemine bağlıdır. Biz burada hem GNU/Linux hem de Windows kullanıcılarının durumunu sırasıyla ve ayrı ayrı inceleyeceğiz. Dilerseniz öncelikle GNU/Linux kullanıcılarının durumuna bakalım:
Not
Bu kitap boyunca bazı konuların GNU/Linux ve Windows kullanıcıları için ayrı ayrı anlatıldığını göreceksiniz. Ancak konular bu şekilde ayrılmış da olsa, ben size her ikisini de okumanızı tavsiye ederim. Çünkü bu bölümlerde her iki kullanıcı grubunun da ilgisini çekebilecek bilgilere rastlayacaksınız. Ayrıca bu bölümler farklı kullanıcı gruplarına hitap ediyor olsa da, aslında bu bölümlerin birbirini tamamlayıcı nitelikte olduğunu göreceksiniz.
GNU/Linux Kullanıcıları¶
GNU/Linux dağıtımlarına Python programlama dilini kurarken bazı noktaları göz önünde bulundurmamız gerekiyor. İşte bu bölümde bu önemli noktaların neler olduğunu inceleyeceğiz.
Kurulu Python Sürümü¶
Hemen hemen bütün GNU/Linux dağıtımlarında Python programlama dili kurulu olarak gelir. Örneğin Ubuntu’da Python zaten kuruludur.
Ancak burada şöyle bir durum var:
Daha önce de belirttiğimiz gibi, şu anda piyasada iki farklı Python serisi bulunuyor. Bunlardan birinin Python’ın 2.x serisi, ötekinin ise 3.x serisi olduğunu biliyorsunuz.
Sisteminizde kurulu olan Python sürümünü denetlemek için komut satırında öncelikle şu komutu vermeyi deneyin (büyük ‘V’ ile):
python -V
Eğer bu komuttan Python 2.x.y şeklinde bir çıktı alıyorsanız, yani x ve y’den önceki kısım 2 ile başlıyorsa sisteminizde Python2 kuruludur.
Ancak python -V
komutundan Python 2.x.y şeklinde bir çıktı almanız sisteminizde sadece Python2’nin kurulu olduğunu göstermez.
Sisteminizde Python2 ile birlikte Python3 de halihazırda kurulu olabilir.
Örneğin Ubuntu GNU/Linux’un 12.10 sürümünden itibaren hem Python2, hem de Python3 sistemde kurulu vaziyettedir.
Kullandığınız GNU/Linux dağıtımında durumun ne olduğunu denetlemek için yukarıdaki komutu bir de python3 -V
şeklinde çalıştırmayı deneyebilirsiniz.
Eğer bu komut size bir hata mesajı yerine bir sürüm numarası veriyorsa sisteminizde Python3 de kuruludur.
Sisteminizdeki Python sürümlerine ilişkin daha kesin bir rapor içinse şu komutu kullanabilirsiniz:
ls -g {,/usr{,/local}}/bin | grep python
Buradan aldığınız çıktıyı inceleyerek de sisteminizde birden fazla Python sürümünün kurulu olup olmadığını görebilirsiniz.
Ayrıca kullandığınız GNU/Linux dağıtımında whereis python
gibi bir komut vererek de sistemde kurulu Python sürümleri hakkında bilgi edinebilirsiniz.
Eğer sisteminizde Python3 kuruluysa ve siz de kurulu olan Python3 sürümünden memnunsanız herhangi bir şey yapmanıza gerek yok. Farklı bir Python sürümü kurmaya çalışmadan yolunuza devam edebilirsiniz.
Paket Deposundan Kurulum¶
Sistemlerinde öntanımlı olarak herhangi bir Python3 sürümü kurulu olmayan veya sistemlerinde kurulu öntanımlı Python3 sürümünden memnun olmayan GNU/Linux kullanıcılarının, Python3’ü elde etmek için tercih edebileceği iki yol var: Birincisi ve benim size önereceğim yol, öncelikle kullandığınız dağıtımın paket yöneticisini kontrol etmenizdir. Python3 sisteminizde kurulu olmasa bile, dağıtımınızın depolarında bu sürüm paketlenmiş halde duruyor olabilir. O yüzden sisteminize uygun bir şekilde paket yöneticinizi açıp orada ‘python’ kelimesini kullanarak bir arama yapmanızı öneririm. Örneğin Ubuntu GNU/Linux dağıtımının paket depolarında Python3 var. Dolayısıyla Ubuntu kullanıcıları, eğer sistemlerinde zaten kurulu değilse (ki muhtemelen kuruludur), bu paketi Ubuntu Yazılım Merkezi aracılığıyla veya doğrudan şu komutla kurabilir:
sudo apt-get install python3
RHEL/CentOS kullanıcıları ise şu komutu kullanabilir:
sudo yum install python3
Bu komutlar, Python3’ü bütün bağımlılıkları ile beraber bilgisayarınıza kuracaktır.
Kaynaktan Kurulum¶
Peki ya kullandığınız dağıtımın depolarında Python3 yoksa veya depodaki Python3 sürümü eskiyse ve siz daha yeni bir Python3 sürümü kullanmak istiyorsanız ne yapacaksınız?
Eğer dağıtımınızın depolarında Python3 paketini bulamazsanız veya depodaki sürüm sizi tatmin etmiyorsa, Python3’ü kaynaktan derlemeniz gerekecektir. Python3’ü kaynaktan derlerken iki seçeneğiniz var: Python3’ü root hakları ile kurmak veya Python3’ü yetkisiz kullanıcı olarak kurmak. Normal şartlar altında eğer kullandığınız sistemde root haklarına sahipseniz Python3’ü yetkili kullanıcı olarak kurmanızı tavsiye ederim.
root Hakları İle Kurulum¶
Python’ı kurmadan önce sistemimizde bulunması gereken bazı programlar var. Aslında bu programlar olmadan da Python kurulabilir, ancak eğer bu programları kurmazsanız Python’ın bazı özelliklerinden yararlanamazsınız. Bu programlar şunlardır:
tcl-dev
tk-dev
zlib1g-dev
ncurses-dev
libreadline-dev
libdb-dev
libgdbm-dev
libzip-dev
libssl-dev
libsqlite3-dev
libbz2-dev
liblzma-dev
Bu programları, kullandığınız GNU/Linux dağıtımının paket yöneticisi aracılığıyla kurabilirsiniz. Yalnız paket adlarının ve gerekli paket sayısının dağıtımlar arasında farklılık gösterebileceğini unutmayın. Yukarıdaki liste Ubuntu için geçerlidir. Mesela yukarıda tcl-dev olarak verdiğimiz paket adı başka bir dağıtımda sadece tcl olarak geçiyor ya da yukarıdaki paketlerin bazıları kullandığınız dağıtımda halihazırda kurulu olduğu için sizin daha az bağımlılık kurmanız gerekiyor olabilir.
Ubuntu’da yukarıdaki paketlerin hepsini şu komutla kurabilirsiniz:
sudo apt-get install tcl-dev tk-dev zlib1g-dev ncurses-dev libreadline-dev libdb-dev libgdbm-dev libzip-dev libssl-dev libsqlite3-dev libbz2-dev liblzma-dev
Yukarıdaki programları kurduktan sonra https://www.python.org/ftp/python/3.7.0 adresine gidiyoruz. Bu adreste, üzerinde ‘Python-3.7.0.tar.xz’ yazan bağlantıya tıklayarak sıkıştırılmış kurulum dosyasını bilgisayarımıza indiriyoruz.
Daha sonra bu sıkıştırılmış dosyayı açıyoruz. Açılan klasörün içine girip, orada ilk olarak şu komutu veriyoruz:
./configure
Bu komut, Python programlama dilinin sisteminize kurulabilmesi için gereken hazırlık aşamalarını gerçekleştirir. Bu betiğin temel olarak yaptığı iş, sisteminizin Python programlama dilinin kurulmasına uygun olup olmadığını, derleme işlemi için gereken yazılımların sisteminizde kurulu olup olmadığını denetlemektir. Bu betik ayrıca, bir sonraki adımda gerçekleştireceğimiz inşa işleminin nasıl yürüyeceğini tarif eden Makefile adlı bir dosya da oluşturur.
Bu arada bu komutun başındaki ./ işareti, o anda içinde bulunduğunuz dizinde yer alan configure adlı bir betiği çalıştırmanızı sağlıyor.
Eğer yalnızca configure
komutu verirseniz, işletim sistemi bu betiği PATH dizinleri içinde arayacak ve bulamayacağı için de hata verecektir.
./configure
komutu hatasız olarak tamamlandıktan sonra ikinci olarak şu komutu veriyoruz:
make
Burada aslında ./configure
komutu ile oluşan Makefile adlı dosyayı make adlı bir program aracılığıyla çalıştırmış oluyoruz.
make
bir sistem komutudur.
Bu komutu yukarıdaki gibi parametresiz olarak çalıştırdığımızda make
komutu, o anda içinde bulunduğumuz dizinde bir Makefile dosyası arar ve eğer böyle bir dosya varsa onu çalıştırır.
Eğer bir önceki adımda çalıştırdığımız ./configure
komutu başarısız olduysa, dizinde bir Makefile dosyası oluşmayacağı için yukarıdaki make
komutu da çalışmayacaktır.
O yüzden derleme işlemi sırasında verdiğimiz komutların çıktılarını takip edip, bir sonraki aşamaya geçmeden önce komutun düzgün sonlanıp sonlanmadığından emin olmamız gerekiyor.
make
komutunun yaptığı iş, Python programlama dilinin sisteminize kurulması esnasında sistemin çeşitli yerlerine kopyalanacak olan dosyaları inşa edip oluşturmaktır.
Bu komutun tamamlanması, kullandığınız bilgisayarın kapasitesine bağlı olarak biraz uzun sürebilir.
make
komutu tamamlandıktan sonra, komut çıktısının son satırlarına doğru şöyle bir uyarı mesajı görebilirsiniz:
Python build finished, but the necessary bits to build these modules were not found:
[burada eksik olan modül veya modüllerin adları sıralanır]
Burada Python, sistemimizde bazı paketlerin eksik olduğu konusunda bizi uyarıyor. Uyarı mesajında bir veya daha fazla paketin eksik olduğunu görebilirsiniz. Eğer öyleyse, eksik olduğu bildirilen bütün paketleri kurmamız gerekiyor.
Gerekli paketi ya da paketleri kurduktan sonra make
komutunu tekrar çalıştırıyoruz.
Endişe etmeyin, make
komutunu ikinci kez verdiğimizde komutun tamamlanması birincisi kadar uzun sürmez.
Eğer bu komutu ikinci kez çalıştırdığınızda yukarıdaki uyarı mesajı kaybolduysa şu komutla yolunuza devam edebilirsiniz:
sudo make altinstall
Daha önce kaynaktan program derlemiş olan GNU/Linux kullanıcılarının eli, make
komutundan sonra make install
komutunu vermeye gitmiş olabilir.
Ama burada bizim make install
yerine make altinstall
komutunu kullandığımıza dikkat edin.
make altinstall
komutu, Python kurulurken klasör ve dosyalara sürüm numarasının da eklenmesini sağlar.
Böylece yeni kurduğunuz Python, sistemdeki eski Python3 sürümünü silip üzerine yazmamış olur ve iki farklı sürüm yan yana varolabilir.
Eğer make altinstall
yerine make install
komutunu verirseniz sisteminizde zaten varolan eski bir Python3 sürümüne ait dosya ve dizinlerin üzerine yazıp silerek o sürümü kullanılamaz hale getirebilirsiniz.
Bu da sistemde beklenmedik problemlerin ortaya çıkmasına yol açabilir.
Bu önemli ayrıntıyı kesinlikle gözden kaçırmamalısınız.
Derleme aşamalarının hiçbirinde herhangi bir hata mesajı almadıysanız kurulum başarıyla gerçekleşmiş ve sisteminize Python programlama dilinin 3.x sürümü kurulmuş demektir.
Yetkisiz Kullanıcı Olarak Kurulum¶
Elbette sudo make altinstall
komutunu verip Python’ı kurabilmek için root haklarına sahip olmanız gerekiyor.
Ama eğer kullandığınız sistemde bu haklara sahip değilseniz Python’ı bu şekilde kuramazsınız.
Kısıtlı haklara sahip olduğunuz bir sistemde Python’ı ancak kendi ev dizininize ($HOME
) kurabilirsiniz.
Eğer Python’ı yetkisiz kullanıcı olarak kuracaksanız, öncelikle yukarıda bahsettiğimiz Python bağımlılıklarının sisteminizde kurulu olup olmadığını kontrol etmeniz lazım. Kullandığınız sistemde herhangi bir Python sürümü halihazırda kuruluysa, bu bağımlılıklar da muhtemelen zaten kuruludur. Ama değilse, bunları kurması için ya sistem yöneticisine ricada bulunacaksınız, ya da bu bağımlılıkları da tek tek kendi ev dizininize kuracaksınız. Eğer sistem yöneticisini bu bağımlılıkları kurmaya ikna edemezseniz, internet üzerinden bulabileceğiniz bilgiler yardımıyla bu bağımlılıkları tek tek elle kendiniz kurabilirsiniz. Ancak bu işlemin epey zaman alacağını ve süreç sırasında pek çok başka bağımlılıkla da karşılacağınızı söyleyebilirim. O yüzden ne yapıp edip sistem yöneticisini bağımlılıkları kurmaya ikna etmenizi tavsiye ederim… Tabii sistem yöneticisini bu bağımlılıkları kurmaya ikna edebilirseniz, istediğiniz Python sürümünü de kurmaya ikna edebileceğinizi düşünebiliriz! Ama biz burada sizin Python’ı kendinizin kuracağını varsayarak yolumuza devam edelim.
Python’ı yetkisiz olarak kurmak, root haklarıyla kurmaya çok benzer.
Aralarında yalnızca bir-iki ufak fark vardır.
Mesela Python’ı yetkisiz kullanıcı olarak kurarken, ./configure
komutunu şu şekilde vermeniz gerekiyor:
./configure --prefix=$HOME/python
Python’ı root haklarıyla kurduğunuzda Python /usr dizini altına kurulacaktır. Ancak siz yetkisiz kullanıcı olduğunuz için /usr dizinine herhangi bir şey kuramazsınız. İşte bu yüzden, configure betiğine verdiğimiz –prefix parametresi yardımıyla Python’ı, yazma yetkimiz olan bir dizine kuruyoruz. Mesela yukarıdaki komut Python’ın /usr dizinine değil, ev dizininiz içinde python adlı bir klasöre kurulmasını sağlayacaktır. Elbette siz python yerine farklı bir dizin adı da belirleyebilirsiniz. Burada önemli olan nokta, –prefix parametresine vereceğiniz dizin adının, sizin yazmaya yetkili olduğunuz bir dizin olmasıdır.
Bu komutu çalıştırdıktan sonra make
komutunu normal bir şekilde veriyoruz.
Bunun ardından da make install
(veya duruma göre make altinstall
) komutuyla Python’ı ev dizinimize kuruyoruz.
Burada make install
komutunu sudo
’suz kullandığımıza dikkat edin.
Çünkü, dediğimiz gibi, siz yetkili kullanıcı olmadığınız için sudo
komutunu kullanamazsınız.
Python’ı bu şekilde ev dizininiz altında bir klasöre kurduğunuzda Python ile ilgili bütün dosyaların bu klasör içinde yer aldığını göreceksiniz. Bu klasörü dikkatlice inceleyip neyin nerede olduğuna aşinalık kazanmaya çalışın. Eğer mümkünse root hakları ile kurulmuş bir Python sürümünü inceleyerek, dosyaların iki farklı kurulum türünde nerelere kopyalandığını karşılaştırın.
Böylece Python programlama dilini bilgisayarımıza nasıl kuracağımızı öğrenmiş olduk. Ama bu noktada bir uyarı yapmadan geçmeyelim: Python özellikle bazı GNU/Linux dağıtımlarında pek çok sistem aracıyla sıkı sıkıya bağlantılıdır. Yani Python, kullandığınız dağıtımın belkemiği durumunda olabilir. Bu yüzden Python’ı kaynaktan derlemek bazı riskler taşıyabilir. Eğer yukarıda anlatıldığı şekilde, kaynaktan Python derleyecekseniz, karşı karşıya olduğunuz risklerin farkında olmalısınız. Ayrıca GNU/Linux üzerinde kaynaktan program derlemek konusunda tecrübeli değilseniz ve eğer yukarıdaki açıklamalar size kafa karıştırıcı geliyorsa, mesela ‘Ben bu komutları nereye yazacağım?’ diye bir soru geçiyorsa aklınızdan, kesinlikle dağıtımınızla birlikte gelen Python sürümünü kullanmalısınız. Python sürümlerini başa baş takip ettiği için, ben size Ubuntu GNU/Linux’u denemenizi önerebilirim. Ubuntu’nun depolarında Python’ın en yeni sürümlerini rahatlıkla bulabilirsiniz. Ubuntu’nun resmi sitesine ubuntu.com adresinden, yerel Türkiye sitesine ise forum.ubuntu-tr.net adresinden ulaşabilirsiniz. Eğer şu anda kullandığınız GNU/Linux dağıtımından vazgeçmek istemiyorsanız, sabit diskinizden küçük bir bölüm ayırıp bu bölüme sadece Python çalışmalarınız için Ubuntu dağıtımını da kurmayı tercih edebilirsiniz.
Yalnız küçük bir uyarı daha yapalım. Kaynaktan kurulum ile ilgili bu söylediklerimizden, Python’ın GNU/Linux’a kesinlikle kaynaktan derlenerek kurulmaması gerektiği anlamı çıkmamalı. Yukarıdaki uyarıların amacı, kullanıcının Python’ı kaynaktan derlerken sadece biraz daha dikkatli olması gerektiğini hatırlatmaktır. Örneğin bu satırların yazarı, kullandığı Ubuntu sisteminde Python3’ü kaynaktan derleyerek kullanmayı tercih ediyor ve herhangi bir problem yaşamıyor.
Bu önemli uyarıları da yaptığımıza göre gönül rahatlığıyla yolumuza devam edebiliriz.
Kurduğumuz yeni Python’ı nasıl çalıştıracağımızı biraz sonra göreceğiz. Ama önce Windows kullanıcılarının Python3’ü nasıl kuracaklarına bakalım.
Sürüm Yöneticisi ile Kurulum (pyenv)¶
Sisteminize bir veya birden fazla Python sürümü kurmak istiyorsunuz fakat root hakları, kaynaktan sürüm derlemeleri vb. işlemler gözünüzü mü korkutuyor? Bütün bu işlemleri çok daha hızlı, pratik ve güvenli bir şekilde pyenv ile gerçekleştirebilirsiniz. pyenv sisteminizde birden fazla Python sürümünü kullanabilmenizi sağlayan ve birçok kolaylığı da beraberinde getiren bir araçtır. Bunun için öncelikle pyenv-installer ile sistemimize pyenv kurmamız gerekmektedir. Kurulum için aşağıdaki komutu çalıştırmanız yeterlidir:
curl https://pyenv.run | bash
Kurulum tamamlandıktan sonra aşağıdaki şekilde bir mesaj çıkacaktır:
# Load pyenv automatically by adding
# the following to ~/.bashrc:
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
Buradaki son 3 satırı ana dizininizdeki .bashrc
dosyanızın (veya farklı bir shell kullanıyorsanız ilgili dosyanın) sonuna eklemeniz gerekmektedir. Eklemeyi yapıp kaydettikten sonra pyenv’i kullanmaya başlamak için terminali yeniden başlatmanız veya terminale source ~/.bashrc
yazmanız yeterlidir.
pyenv ile yükleyebileceğiniz Python sürümlerini listeleyebilmek için tek yapmanız gereken şu komutu çalıştırmaktır:
pyenv install --list
Yalnızca 3.8.x sürümlerini listelemek içinse:
pyenv install --list |grep " 3.8.*"
Komutunu çalıştırabilirsiniz. Eğer bütün sürümleri listelediyseniz görebileceğiniz üzere, pyenv ile kurabileceğiniz Python sürümü sayısı oldukça fazladır. Bu sürümlerden herhangi bir tanesini kurmadan önce pyenv’in kurulumları tamamlayabilmesi için ihtiyaç duyduğu bağımlılıkları kurmanızı tavsiye ederim. Aksi takdirde kurulumu bekleyip hata alma olasılığınız yüksektir. O hata mesajı da sizi şu linke yönlendirecektir: (pyenv | Sık Karşılaşılan Hatalar)
pyenv Bağımlılıkların Kurulumu¶
Ubuntu/Debian:
sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \ libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
Fedora:
sudo dnf install zlib-devel bzip2 bzip2-devel readline-devel sqlite \ sqlite-devel openssl-devel xz xz-devel libffi-devel findutils
RHEL/CentOS:
sudo yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite \ sqlite-devel openssl-devel xz xz-devel libffi-devel findutils
Arch ve türevleri:
pacman -S --needed base-devel openssl zlib bzip2 readline sqlite curl \ llvm ncurses xz tk libffi python-pyopenssl git
Yeni Sürümlerin Kurulumu¶
pyenv için gerekli ayarları yaptıktan sonra yeni bir Python sürümü kurabilmek için tek yapmanız gereken pyenv install <python-sürümü>
şeklinde bir komut çalıştırmaktır. <python-sürümü>
kısmına yazacağımız sürüm bilgisi pyenv install --list
sonuçları ile aynı isimde olmalıdır. Python 3.8.5 sürümünü kurmak için yapmanız gereken aşağıdaki komutu çalıştırmaktır:
pyenv install 3.8.5
Bu komut ile 3.8.5
sürümü sisteminize yüklenecektir.
Yüklenen Sürümün Kullanımı¶
Yüklediğiniz sürümün doğrulamasını yapmak için pyenv versions
komutunu çalıştırabilirsiniz. Eğer yükleme uygun bir şekilde tamamlandı ise komutu çalıştırdığınızda görmeniz gereken çıktı şu şekildedir:
* system
3.8.5
* işareti hali hazırda aktif olan sürümü temsil etmektedir. Kurduğunuz sürümü aktif olarak kullanabilmek için çalıştırmanız gereken komut şudur:
pyenv global 3.8.5
pyenv ile temel seviyede Python yükleme ve etkinleştirme kısmı bu şekilde özetlenebilir. pyenv
kullanımıyla ilgili detaylara GNU/Linux’ta Farklı Sürümleri Birlikte Kullanmak :ref:`gnu-linux-ta-farkli-surumleri-birlikte-kullanmak kısmında değineceğiz.
Windows Kullanıcıları¶
Windows sürümlerinin hiçbirinde Python kurulu olarak gelmez. O yüzden Windows kullanıcıları, Python’ı sitesinden indirip kuracak.
Bunun için öncelikle https://www.python.org/downloads/ adresine gidiyoruz.
Bu adrese gittiğinizde, üzerinde ‘Download Python 3.7.0’ yazan bir düğme göreceksiniz. Daha önce de söylediğimiz gibi, eğer bir Python sürüm numarası ‘2’ ile başlıyorsa o sürüm 2.x serisine, yok eğer ‘3’ ile başlıyorsa 3.x serisine aittir. Dolayısıyla bu düğme Python3 sürümünü içerir.
Bu düğmeye tıklıyoruz. Bu düğmeye tıkladığınızda bilgisayarınıza .exe uzantılı kurulum dosyası inecek. Bu dosyaya çift tıklayarak kurulum programını başlatabilirsiniz.
Not
Eğer indireceğiniz Python sürümünün mimarisini ve sürümünü kendiniz seçmek isterseniz https://www.python.org/ftp/python/3.7.0 adresinden kendinize uygun olan sürümü bulup indirebilirsiniz.
Kurulum dosyasına çift tıkladığınızda karşınıza ilk gelen ekranda, pencerenin alt tarafında şu kutucukları göreceksiniz:
Install launcher for all users (recommended)
Add Python 3.7 to PATH
Burada ilk kutucuk zaten seçilidir.
Bunu bu şekilde bırakabilirsiniz.
İkinci kutucuk ise Python’ı yola eklememizi, böylece yalnızca python
komutu vererek Python’ı başlatabilmemizi sağlayacak.
O yüzden oradaki ikinci kutucuğu da işaretliyoruz.
Aynı pencerenin üst tarafında ise şu seçenekleri göreceksiniz:
-> Install Now
-> Customize Installation
Burada ‘Install Now’ yazan kısma tıklayarak kurulumu başlatıyoruz.
Eğer Python’ın bilgisayarda nereye kurulacağını ve başka birtakım kurulum özelliklerini değiştirmek istiyorsanız ‘Customize Installation’ yazılı kısma tıklayabilirsiniz. Ben bu kitapta sizin ‘Install Now’ yazan kısma tıklayarak kurulum yaptığınızı varsayacağım.
Not
Python’ın resmi sitesinde dolaşırken kurulum dosyaları arasında, ‘web-based installer’ (web tabanlı kurulum betiği) adlı bir kurulum dosyası görebilirsiniz. Bu kurulum dosyası, Python’ın çalışması için gereken dosyaları kurulum esnasında internetten indirip kuran, 1MB’dan küçük bir kurulum programı içerir. Dolayısıyla eğer kurulumu bu dosyadan yapacaksanız, kesintisiz bir internet bağlantısına ihtiyacınız olacak.
Uyarı
Eğer Windows’ta Python’ı kurmaya çalışırken hata alıyorsanız, muhtemelen işletim sisteminiz güncel değildir. Örneğin Windows 7’de Python kurabilmeniz için, SP1 (Service Pack 1) kurulu olmalıdır. Windows güncellemelerini kurduktan sonra Python’ı kurmayı tekrar deneyin. Ancak Windows XP kullanıyorsanız kurabileceğiniz en yüksek sürüm, Python 3.4’tür. Ne yazık ki Windows XP artık desteklenmiyor.
Python Kurulum ve Çalışma Dizini¶
Python programlama dilini, kullandığımız işletim sistemine nasıl kurabileceğimizi bilmek kadar önemli bir konu da Python’ı hangi dizine kurduğumuzu bilmektir. Zira programcılık maceramız boyunca karşılaşacağımız bazı sorunlar, Python’ın kurulu olduğu dizine gitmemizi gerektirecek, üstelik kendi yazdığımız bazı programlarda da Python’ın kurulu olduğu dizinde çeşitli işlemler yapmak ihtiyacı duyacağız. Ayrıca bazı durumlarda, o anda çalışan Python sürümünün hangi konumdan çalıştığını tespit etmemiz de gerekebilir.
İşte bu sebeplerden, Python’ın hangi dizine kurulduğunu mutlaka biliyor olmamız lazım.
Python’ın, işletim sisteminizde hangi dizine kurulduğu, Python’ı nasıl kurduğunuza bağlı olarak farklılık gösterir.
GNU/Linux dağıtımlarında Python genellikle /usr/lib/python3.7 dizininde kurulur. Ama elbette, eğer siz Python’ı kaynaktan derlediyseniz, derleme sırasında configure betiğine verdiğiniz –prefix parametresi yardımıyla Python’ın kurulum dizinini kendiniz de belirlemiş olabilirsiniz.
Windows’ta Python programlama dilini aynen bu kitapta gösterdiğimiz şekilde kurduysanız, Python %LOCALAPPDATA%\Programs\Python
dizini içine kurulacaktır.
Ancak eğer kurulum penceresinde ‘Customize Installation’ düğmesine basarak kurulumu özelleştirdiyseniz ve ‘Install for all users’ seçeneğini işaretlediyseniz Python %PROGRAMFILES% veya %PROGRAMFILES(x86) adlı çevre değişkenlerinin işaret ettiği dizin içine kurulacaktır.
Python Nasıl Çalıştırılır?¶
Bir önceki bölümde, Python’ı farklı platformlara nasıl kuracağımızı bütün ayrıntılarıyla anlattık. Bu bölümde ise kurduğumuz bu Python programını hem GNU/Linux’ta hem de Windows’ta nasıl çalıştıracağımızı göreceğiz. Öncelikle GNU/Linux kullanıcılarının Python’ı nasıl çalıştıracağına bakalım.
GNU/Linux Kullanıcıları¶
Geçen bölümlerde gördüğünüz gibi, Python3’ü GNU/Linux sistemleri üzerine farklı şekillerde kurabiliyoruz. Bu bölümde, her bir kurulum türü için Python3’ün nasıl çalıştırılacağını ayrı ayrı inceleyeceğiz.
Kurulu Python3’ü Kullananlar¶
Eğer sisteminizde zaten Python3 kurulu ise komut satırında yalnızca şu komutu vererek Python3’ü başlatabilirsiniz:
python
Ancak daha önce de dediğimiz gibi, 19.08.2024 tarihi itibariyle pek çok GNU/Linux dağıtımında öntanımlı olarak Python2 kuruludur.
Dolayısıyla python
komutunu verdiğinizde çalışan sürüm muhtemelen Python2 olacaktır.
Bu yüzden sistemimizde öntanımlı olarak hangi sürümün kurulu olduğuna ve python
komutunun hangi sürümü başlattığına çok dikkat etmelisiniz.
Yine daha önce de söylediğimiz gibi, sisteminizde hem Python2 hem de Python3 zaten kurulu durumda olabilir.
O yüzden yukarıdaki komutu bir de python3
şeklinde vermeyi deneyebilirsiniz.
Örneğin Ubuntu GNU/Linux dağıtımının 12.10 sürümünden itibaren python
komutu Python2’yi; python3
komutu ise Python3’ü çalıştırıyor.
Python3’ü Depodan Kuranlar¶
Dediğimiz gibi, 19.08.2024 tarihi itibariyle GNU/Linux dağıtımlarında öntanımlı Python sürümü ağırlıklı olarak Python2’dir.
Dolayısıyla python
komutu Python’ın 2.x sürümlerini çalıştırır.
Bu durumdan ötürü, herhangi bir çakışmayı önlemek için GNU/Linux dağıtımları Python3 paketini farklı bir şekilde adlandırma yoluna gider.
Şu anda piyasada bulunan dağıtımların ezici çoğunluğu Python3 paketini ‘python3’ şeklinde adlandırıyor.
O yüzden GNU/Linux kullanıcıları, eğer paket yöneticilerini kullanarak Python kurulumu gerçekleştirmiş iseler, komut satırında şu komutu vererek Python3’ü başlatabilirler:
python3
Bu komutun ardından şuna benzer bir ekranla karşılaşmış olmalısınız:
yazbel@ubuntu:~$ # python3 Python 3.7.0 (default, 19.08.2024, 12:24:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux Type “help”, “copyright”, “credits” or “license” for more information. >>>
Eğer yukarıdaki ekranı gördüyseniz Python’la programlama yapmaya hazırsınız demektir. Değilse, geriye dönüp işlerin nerede ters gittiğini bulmaya çalışabilirsiniz.
Bu aşamada işlerin nerede ters gitmiş olabileceğine dair birkaç ipucu verelim:
Python3 kurulurken paket yöneticinizin herhangi bir hata vermediğinden, programın sisteminize başarıyla kurulduğundan emin olun. Bunun için Python3’ün kurulu paketler listesinde görünüp görünmediğini denetleyebilirsiniz.
python3
komutunu doğru verdiğinize emin olun. Python programlama diline özellikle yeni başlayanların en sık yaptığı hatalardan biri python kelimesini yanlış yazmaktır. Python yerine yanlışlıkla pyhton, pyton veya phyton yazmış olabilirsiniz. Ayrıcapython3
komutunun tamamen küçük harflerden oluştuğuna dikkat edin. Python ve python bilgisayar açısından aynı şeyler değildir.Kullandığınız dağıtımın Python3 paketini adlandırma politikası yukarıda anlattığımızdan farklı olabilir. Yani sizin kullandığınız dağıtım, belki de Python3 paketini farklı bir şekilde adlandırmıştır. Eğer durum böyleyse, dağıtımınızın yardım kaynaklarını (wiki, forum, irc, yardım belgeleri, kullanıcı listeleri, vb.) kullanarak ya da forum.yazbel.com adresinde sorarak Python3’ün nasıl çalıştırılacağını öğrenmeyi deneyebilirsiniz.
Gelelim Python3’ü kaynaktan derlemiş olanların durumuna…
Python3’ü root Olarak Derleyenler¶
Eğer Python3’ü önceki bölümlerde anlattığımız şekilde kaynaktan root hakları ile derlediyseniz python3
komutu çalışmayacaktır.
Bunun yerine şu komutu kullanmanız gerekecek:
python3.7
Not
Kurduğunuz Python3 sürümünün 3.7 olduğunu varsayıyorum.
Eğer farklı bir Python3 sürümü kurduysanız, elbette başlatıcı komut olarak o sürümün adını kullanmanız gerekecektir.
Mesela: python3.0
veya python3.1
.
Bu arada python3.7
komutunda 37 sayısının rakamları arasında bir adet nokta işareti olduğunu gözden kaçırmıyoruz…
Tıpkı paket deposundan kurulumda olduğu gibi, eğer yukarıdaki komut Python’ı çalıştırmanızı sağlamıyorsa, kurulum esnasında bazı şeyler ters gitmiş olabilir. Örneğin kaynaktan kurulumun herhangi bir aşamasında bir hata almış olabilirsiniz ve bu da Python’ın kurulumunu engellemiş olabilir.
Gördüğünüz gibi, Python’ı kaynaktan derleyenler Python programlama dilini çalıştırabilmek için Python’ın tam sürüm adını belirtiyor.
Dilerseniz bu şekilde çalışmaya devam edebilirsiniz.
Bunun hiçbir sakıncası yok.
Ancak ben size kolaylık açısından, /usr/bin/ dizini altına py3 adında bir sembolik bağ yerleştirmenizi tavsiye ederim.
Böylece sadece py3
komutunu vererek Python3’ü başlatabilirsiniz.
Peki bunu nasıl yapacağız?
Python kaynaktan derlendiğinde çalıştırılabilir dosya /usr/local/bin/ dizini içine Python3.7 (veya kurduğunuz Python3 sürümüne bağlı olarak Python3.0 ya da Python3.1) adıyla kopyalanır.
Bu nedenle Python3’ü çalıştırabilmek için python3.7
komutunu kullanmamız gerekir.
Python3’ü çalıştırabilmek için mesela sadece py3
gibi bir komut kullanmak istiyorsak yapacağımız tek şey /usr/local/bin/ dizini içindeki python3.7 adlı dosyaya /usr/bin dizini altından, py3 adlı bir sembolik bağ oluşturmak olacaktır.
Bunun için ln
komutunu kullanacağız:
ln -s /usr/local/bin/python3.7 /usr/bin/py3
Tabii bu komutu yetkili kullanıcı olarak vermeniz gerektiğini söylememe herhalde gerek yoktur.
Bu komutu verdikten sonra artık sadece py3
komutu ile Python programlama dilini başlatabilirsiniz.
Çok Önemli Bir Uyarı¶
Bir önceki adımda anlattığımız gibi Python3’ü resmi sitesinden indirip kendiniz derlediniz. Gayet güzel. Ancak bu noktada çok önemli bir konuya dikkatinizi çekmek isterim. En baştan beri söylediğimiz gibi, Python programlama dili GNU/Linux işletim sistemlerinde çok önemli bir yere sahiptir. Öyle ki bu programlama dili, kullandığınız dağıtımın belkemiği durumunda olabilir.
Örneğin Ubuntu GNU/Linux dağıtımında pek çok sistem aracı Python ile yazılmıştır.
Bu yüzden, sistemdeki öntanımlı Python sürümünün ne olduğu ve dolayısıyla python
komutunun hangi Python sürümünü çalıştırdığı çok önemlidir.
Çünkü sisteminizdeki hayati bazı araçlar, python
komutunun çalıştırdığı Python sürümüne bel bağlamış durumdadır.
Dolayısıyla sizin bu python
komutunun çalıştırdığı Python sürümüne dokunmamanız gerekir.
Mesela eğer kullandığınız işletim sisteminde python
komutu Python’ın 2.x sürümlerinden birini çalıştırıyorsa sembolik bağlar veya başka araçlar vasıtasıyla python
komutunu Python’ın başka bir sürümüne bağlamayın.
Bu şekilde bütün sistemi kullanılmaz hale getirirsiniz.
Elbette eğer kurulum aşamasında tarif ettiğimiz gibi, Python3’ü make install
yerine make altinstall
komutu ile kurmaya özen gösterdiyseniz, sonradan oluşturduğunuz bağ dosyasını silip python
komutunu yine sistemdeki öntanımlı sürüme bağlayabilirsiniz.
Bu şekilde her şey yine eski haline döner.
Ama eğer Python’ı make install
komutuyla kurmanızdan ötürü sistemdeki öntanımlı Python sürümüne ait dosyaları kaybettiyseniz sizin için yapılacak fazla bir şey yok…
Sistemi tekrar eski kararlı haline getirmek için kan, ter ve gözyaşı dökeceksiniz…
Aynı şekilde, kullandığınız dağıtımda python3
komutunun öntanımlı olarak belirli bir Python sürümünü başlatıp başlatmadığı da önemlidir.
Yukarıda python
komutu ile ilgili söylediklerimiz python3
ve buna benzer başka komutlar için de aynen geçerli.
Örneğin, Ubuntu GNU/Linux dağıtımında python
komutu sistemde kurulu olan Python 2.x sürümünü; python3
komutu ise sistemde kurulu olan Python 3.x sürümünü çalıştırdığından, biz kendi kurduğumuz Python sürümleri için, sistemdeki sürümlerle çakışmayacak isimler seçtik.
Mesela kendi kurduğumuz Python3 sürümünü çalıştırmak için py3
gibi bir komut tercih ettik.
İyi bir test olarak, Python programlama dilini kendiniz kaynaktan derlemeden önce şu komutun çıktısını iyice inceleyebilirsiniz:
ls -g {,/usr{,/local}}/bin | grep python
Bu komut iki farklı Python sürümünün kurulu olduğu sistemlerde şuna benzer bir çıktı verir (çıktı kırpılmıştır):
dh_python2 dh_python3 pdb2.7 -> ../lib/python2.7/pdb.py pdb3.7 -> ../lib/python3.7/pdb.py py3versions -> ../share/python3/py3versions.py python -> python2.7 python2 -> python2.7 python2.7 python3 -> python3.7 python3.7 -> python3.7mu python3.7mu python3mu -> python3.7mu pyversions -> ../share/python/pyversions.py
Yatık harflerle gösterdiğimiz kısımlara dikkat edin.
Gördüğünüz gibi python
ve python2
komutları bu sistemde Python’ın 2.7 sürümünü çalıştırıyor.
python3
komutu ise Python’ın 3.7 sürümünü…
Dolayısıyla yukarıdaki çıktıyı aldığımız bir sistemde kendi kurduğumuz Python sürümlerine ‘python’, ‘python2’ veya ‘python3’ gibi isimler vermekten kaçınmalıyız.
Sözün özü, bir GNU/Linux kullanıcısı olarak sistemdeki öntanımlı hiçbir Python sürümünü silmemeli, öntanımlı sürüme ulaşan komutları değiştirmemelisiniz.
Eğer mesela sisteminizde python3
komutu halihazırda bir Python sürümünü çalıştırıyorsa, siz yeni kurduğunuz Python sürümüne ulaşmak için öntanımlı adla çakışmayacak başka bir komut adı kullanın.
Yani örneğin sisteminizde python3
komutu Python’ın 3.7 sürümünü çalıştırıyorsa, siz yeni kurduğunuz sürümü çalıştırmak için py3
gibi bir sembolik bağ oluşturun.
Bırakın öntanımlı komut (python
, python3
vb.) öntanımlı Python sürümünü çalıştırmaya devam etsin.
Asla unutmayın. Siz bir programcı adayı olarak, program yazacağınız işletim sistemini enine boyuna tanımakla yükümlüsünüz. Dolayısıyla işletim sisteminizi kararsız hale getirecek davranışları bilmeli, bu davranışlardan kaçınmalı, yanlış bir işlem yaptığınızda da nasıl geri döneceğinizi bilmelisiniz. Hele ki bir programı kaynaktan derlemeye karar vermişseniz…
Bu ciddi uyarıyı da yaptığımıza göre gönül rahatlığıyla yolumuza devam edebiliriz.
Python3’ü Ev Dizinine Kuranlar¶
Eğer Python3’ü kısıtlı kullanıcı hakları ile derleyip ev dizininize kurduysanız yukarıdaki komutlar Python’ı çalıştırmanızı sağlamayacaktır. Python3’ü ev dizinine kurmuş olan kullanıcılar Python3’ü çalıştırabilmek için, öncelikle komut satırı aracılığıyla Python3’ü kurdukları dizine, oradan da o dizin altındaki bin/ klasörüne ulaşacak ve orada şu komutu verecek:
./python3.7
Diyelim ki Python3’ü $HOME/python adlı dizine kurdunuz. Önce şu komutla $HOME/python/bin adlı dizine ulaşıyoruz:
cd $HOME/python/bin
Ardından da şu komutu veriyoruz:
./python3.7
Not
Komutun başındaki ./ işaretinin ne işe yaradığını artık adınız gibi biliyorsunuz…
Not
Elbette ben burada kurduğunuz Python sürümünün 3.7 olduğunu varsaydım. Eğer farklı bir sürüm kurduysanız yukarıdaki komutu ona göre yazmanız gerekiyor.
Eğer isterseniz bu şekilde çalışmaya devam edebilirsiniz. Ancak her defasında Python’ın kurulu olduğu dizin altına gelip orada ./python3.7 komutunu çalıştırmak bir süre sonra eziyete dönüşecektir. İşlerinizi kolaylaştırmak için şu işlemleri takip etmelisiniz:
1. ev dizininizin altında bulunan .profile (veya kullandığınız dağıtıma göre .bash_profile ya da .bashrc) adlı dosyayı açın.
2. Bu dosyanın en sonuna şuna benzer bir satır yerleştirerek Python’ı çalıştırmamızı sağlayan dosyanın bulunduğu dizini yola ekleyin:
export PATH=$PATH:$HOME/python/bin/
3. $HOME/python/bin/ satırı Python3’ün çalıştırılabilir dosyasının hangi dizin altında olduğunu gösteriyor. Ben burada Python3’ün çalıştırılabilir dosyasının $HOME/python/bin dizini içinde olduğunu varsaydım. O yüzden de $HOME/python/bin/ gibi bir satır yazdım. Ama eğer Python3’ün çalıştırılabilir dosyası sizde farklı bir dizindeyse bu satırı ona göre yazmalısınız.
4. Kendi sisteminize uygun satırı dosyaya ekledikten sonra dosyayı kaydedip çıkın. Dosyada yaptığımız değişikliğin etkin hale gelebilmesi için şu komutu verin:
source .profile
Elbette eğer sizin sisteminizdeki dosyanın adı .bash_profile veya .bashrc ise yukarıdaki komutu ona göre değiştirmelisiniz.
5. Daha sonra $HOME/python/bin/python3.7 adlı dosyaya $HOME/python/bin/ dizini altından mesela py3 gibi bir sembolik bağ verin:
ln -s $HOME/python/bin/python3.7 $HOME/python/bin/py3
6. Bilgisayarınızı yeniden başlatın.
7. Artık hangi konumda bulunursanız bulunun, şu komutu vererek Python3’ü başlatabilirsiniz:
py3
Burada da eğer yukarıdaki komut Python3’ü çalıştırmanızı sağlamıyorsa, bazı şeyleri eksik veya yanlış yapmış olabilirsiniz. Yardım almak için forum.yazbel.com adresine uğrayabilirsiniz.
Python3’ü başarıyla kurup çalıştırabildiğinizi varsayarak yolumuza devam edelim.
GNU/Linux’ta Farklı Sürümleri Birlikte Kullanmak¶
Daha önce de dediğimiz gibi, şu anda piyasada iki farklı Python serisi bulunuyor: Python2 ve Python3. 2020 yılı itibariyle Python2 desteği bitmiştir fakat hem Python2 ile yazılmış programları çalıştırmak, hem de Python3 ile geliştirme yapmak istiyorsanız, sisteminizde hem Python2’yi hem de Python3’ü aynı anda bulundurmayı tercih edebilir veya yazdığınız kodu farklı sürümlerde test etmek isteyebilirsiniz. Peki bunu nasıl yapacaksınız?
En başta da söylediğimiz gibi, hemen hemen bütün GNU/Linux dağıtımlarında Python2 kurulu olarak gelir.
Dolayısıyla eğer sisteminize ek olarak Python3’ü de kurduysanız (kaynaktan veya paket deposundan), başka herhangi bir şey yapmanıza gerek yok.
Yukarıda anlattığımız yönergeleri takip ettiyseniz, konsolda python
komutu verdiğinizde Python2, python3
(veya py3
) komutunu verdiğinizde ise Python3 çalışacaktır.
Ama eğer sisteminizde Python2 bile kurulu değilse, ki bu çok çok düşük bir ihtimaldir, Python2’yi paket yöneticiniz yardımıyla sisteminize kurabilirsiniz. Şu anda piyasada olup da paket deposunda Python bulundurmayan GNU/Linux dağıtımı pek azdır.
pyenv ile Sürümleri Yönetmek¶
Sürüm Yöneticisi ile Kurulum (pyenv) kısmında anlatıldığı şekilde pyenv kurulumu yaptıktan sonra pyenv install <python-sürümü>
ile istediğiniz python sürümünü kolayca kurabilir ve sürümler arasında geçiş yapabilirsiniz. Sürüm geçişlerini şu şekilde örneklendirebiliriz. Sisteminizde 3.8.5 sürümünün aktif olduğunu varsayarak sisteme 2 yeni Python sürümü daha kuralım:
pyenv install 2.7.18
pyenv install 3.6.9
Bu durumda pyenv versions
komutunun çıktısı şu şekilde olacaktır:
system
2.7.18
3.6.9
* 3.8.5 (set by /home/{kullanıcı-adınız}/.pyenv/version)
pyenv ile kurulan sürümlerin kullanılabilmesi için 3 farklı komut bulunmaktadır.
pyenv local
:pyenv local <python-sürümü>
local
komutu ile sürüm seçtiğinizde, bulunduğunuz dizinde .python-version isimli bir dosya oluşur. Bu dosya içerisinde yalnızca seçtiğiniz Python sürümü numarası bulunur ve bu sürüm yalnızca mevcut dizin içerisinde aktif olur. Aşağıdaki şekilde bir klasör yapısında proje1 dizininde pyenv local 3.6.9
komutunu çalıştırdığımızı düşünelim:
projeler
├── proje1
│ └── .python-version # 3.6.9
└── proje2
Bu durumda proje1 dizininde python
komutu 3.6.9 sürümü, bunun dışındaki bütün dizinlerde 3.8.5 sürümü çalışacaktır.
pyenv global
:pyenv global <python-sürümü>
Kurulum kısmında da bahsettiğimiz gibi aktif kullandığınız Python sürümünü global
komutu ile etkinleştirerek sürekli olarak kullanabilirsiniz. Python2 yüklü sistemlerde python
komutu Python2 sürümünü çalıştırırken, global
komutu ile aktifleştirme sonrasında python
yazdığınızda seçtiğiniz Python sürümü çalışacaktır.
pyenv global 3.8.5
pyenv shell
:pyenv shell <python-sürümü>
shell
komutu ile aktifleştirdiğiniz Python sürümü mevcut terminal oturumunuz süresince aktif olacaktır. shell
komutu local
ve global
sürümleri geçersiz kılar. Yani local olarak ayarladığınız bir dizine girdiğinizde bile hala shell ile aktifleştirdiğiniz sürüm çalışır. Normal şekilde kullanmaya devam edebilmek için pyenv shell --unset
komutunu çalıştırmalı veya terminali yeniden başlatmalısınız.
Yeni Python sürümleri çıktıkça pyenv
’e eklenmektedir. Yeni sürümleri indirebilmek için pyenv update
komutu ile pyenv
aracını güncellemelisiniz.
GNU/Linux’ta Python’ı nasıl çalıştıracağımızı ve farklı Python sürümlerini bir arada nasıl kullanacağımızı öğrendiğimize göre, Windows kullanıcılarının durumuna bakabiliriz.
Windows Kullanıcıları¶
Windows kullanıcıları Python3’ü iki şekilde başlatabilir:
Başlat > Tüm Programlar > Python3.7 > Python 3.7 yolunu takip ederek.
Komut satırında
python
komutunu vererek.
Eğer birinci yolu tercih ederseniz, Python’ın size sunduğu komut satırına doğrudan ulaşmış olursunuz. Ancak Python komut satırına bu şekilde ulaştığınızda bazı kısıtlamalarla karşı karşıya kalırsınız. Doğrudan Python’ın komut satırına ulaşmak yerine önce MS-DOS komut satırına ulaşıp, oradan Python komut satırına ulaşmak özellikle ileride yapacağınız çalışmalar açısından çok daha mantıklı olacaktır. O yüzden komut satırına bu şekilde ulaşmak yerine ikinci seçeneği tercih etmenizi tavsiye ederim. Bunun için komut satırına ulaşın ve orada şu komutu çalıştırın:
python
Bu komutu verdiğinizde şuna benzer bir ekranla karşılaşacaksınız:
C:\Users\yazbel> python3 Python 3.7.0 (v3.7.0:c0e311e010fc, 19.08.2024, 12:24:55) [MSC v.1600 32 bit (Intel)] on win32 Type “help”, “copyright”, “credits” or “license” for more information. >>>
Eğer bu komut yukarıdakine benzer bir ekran yerine bir hata mesajı verdiyse kurulum sırasında bazı adımları eksik veya yanlış yapmış olabilirsiniz. Yukarıdaki komut çalışmıyorsa, muhtemelen kurulum sırasında Add Python 3.7 to PATH kutucuğunu işaretlemeyi unutmuşsunuzdur. Eğer öyleyse, kurulum dosyasını tekrar çalıştırıp, ilgili adımı gerçekleştirmeniz veya Python’ı kendiniz YOL’a eklemeniz gerekiyor.
python
komutunu başarıyla çalıştırabildiğinizi varsayarak yolumuza devam edelim.
Windows’ta Farklı Sürümleri Birlikte Kullanmak¶
Daha önce de dediğimiz gibi, şu anda piyasada iki farklı Python serisi bulunuyor: Python2 ve Python3. Çok uzun zamandan beri kullanımda olduğu için, Python2 Python3’e kıyasla daha yaygın. Eğer hem Python2 ile yazılmış programları çalıştırmak, hem de Python3 ile geliştirme yapmak istiyorsanız, sisteminizde hem Python2’yi hem de Python3’ü aynı anda bulundurmayı tercih edebilirsiniz. Peki bunu nasıl yapacaksınız?
Windows’ta bu işlemi yapmak çok kolaydır. python.org/download adresine giderek farklı Python sürümlerini bilgisayarınıza indirebilir ve bunları bilgisayarınıza normal bir şekilde kurabilirsiniz. Bu şekilde sisteminize istediğiniz sayıda farklı Python sürümü kurabilirsiniz. Peki bu farklı sürümlere nasıl ulaşacaksınız?
Python, bilgisayarımızdaki farklı Python sürümlerini çalıştırabilmemiz için bize ‘py’ adlı özel bir program sunar.
Not
Py programı yalnızca Windows’a özgüdür. GNU/Linux’ta böyle bir program bulunmaz.
Py programını çalıştırmak için, sistem komut satırına ulaşıyoruz ve orada şu komutu veriyoruz:
py
Bu komutu verdiğinizde (teorik olarak) sisteminize en son kurduğunuz Python sürümü çalışmaya başlayacaktır. Ancak bu her zaman böyle olmayabilir. Ya da aldığınız çıktı beklediğiniz gibi olmayabilir. O yüzden bu komutu verdiğinizde hangi sürümün başladığına dikkat edin.
Eğer sisteminizde birden fazla Python sürümü kurulu ise, bu betik yardımıyla istediğiniz sürümü başlatabilirsiniz. Mesela sisteminizde hem Python’ın 2.x sürümlerinden biri, hem de Python’ın 3.x sürümlerinden biri kurulu ise, şu komut yardımıyla Python 2.x’i başlatabilirsiniz:
py -2
Python 3.x’i başlatmak için ise şu komutu veriyoruz:
py -3
Eğer sisteminizde birden fazla Python2 veya birden fazla Python3 sürümü kurulu ise, ana ve alt sürüm numaralarını belirterek istediğiniz sürüme ulaşabilirsiniz:
py -2.6
py -2.7
py -3.4
py -3.5
Bu arada dikkat ettiyseniz, Python programlarını başlatabilmek için hem python
hem de py
komutunu kullanma imkanına sahibiz.
Eğer sisteminizde tek bir Python sürümü kurulu ise, Python’ı başlatmak için python
komutunu kullanmak isteyebilir, farklı sürümlerin bir arada bulunduğu durumlarda ise py
ile bu farklı sürümlere tek tek erişmek isteyebilirsiniz.
Böylece Python’la ilgili en temel bilgileri edinmiş olduk. Bu bölümde öğrendiklerimiz sayesinde Python programlama dilini bilgisayarımıza kurabiliyor ve bu programlama dilini başarıyla çalıştırabiliyoruz.
Hangi Komut Hangi Sürümü Çalıştırıyor?¶
Artık Python programlama dilinin bilgisayarımıza nasıl kurulacağını ve bu programlama dilinin nasıl çalıştırılacağını biliyoruz. Ancak konunun öneminden ötürü, tekrar vurgulayıp, cevabını bilip bilmediğinizden emin olmak istediğimiz bir soru var: Kullandığınız işletim sisteminde acaba hangi komut, hangi Python sürümünü çalıştırıyor?
Bu kitapta anlattığımız farklı yöntemleri takip ederek, Python programlama dilini bilgisayarınıza farklı şekillerde kurmuş olabilirsiniz.
Örneğin Python programlama dilini, kullandığınız GNU/Linux dağıtımının paket yöneticisi aracılığıyla kurduysanız, Python’ı başlatmak için python3
komutunu kullanmanız gerekebilir.
Aynı şekilde, eğer Python’ı Windows’a kurduysanız, bu programlama dilini çalıştırmak için python
komutunu kullanıyor olabilirsiniz.
Bütün bunlardan farklı olarak, eğer Python’ın kaynak kodlarını sitesinden indirip derlediyseniz, Python’ı çalıştırmak için kendi belirlediğiniz bambaşka bir adı da kullanıyor olabilirsiniz.
Örneğin belki de Python’ı çalıştırmak için py3
gibi bir komut kullanıyorsunuzdur…
Python programlama dilini çalıştırmak için hangi komutu kullanıyor olursanız olun, lütfen bir sonraki konuya geçmeden önce kendi kendinize şu soruları sorun:
Kullandığım işletim sisteminde Python programı halihazırda kurulu mu?
Kullandığım işletim sisteminde toplam kaç farklı Python sürümü var?
python
komutu bu Python sürümlerinden hangisini çalıştırıyor?python3
komutu çalışıyor mu?Eğer çalışıyorsa, bu komut Python sürümlerinden hangisini çalıştırıyor?
Kaynaktan derlediğim Python sürümünü çalıştırmak için hangi komutu kullanıyorum?
Biz bu kitapta şunları varsayacağız:
Kullandığınız işletim sisteminde Python’ın 2.x sürümlerini
python
komutuyla çalıştırıyorsunuz.Kullandığınız işletim sisteminde Python’ın 3.x sürümlerini
python3
komutuyla çalıştırıyorsunuz.
Bu kitaptan yararlanırken, bu varsayımları göz önünde bulundurmalı, eğer bunlardan farklı komutlar kullanıyorsanız, kodlarınızı ona göre ayarlamalısınız.
Sistem Komut Satırı ve Python Komut Satırı¶
Buraya kadar Python programlama dilini nasıl çalıştıracağımız konusundaki bütün bilgileri edindik. Ancak programlamaya yeni başlayanların çok sık yaptığı bir hata var: Sistem komut satırı ile Python komut satırını birbirine karıştırmak.
Asla unutmayın, kullandığınız işletim sisteminin komut satırı ile Python’ın komut satırı birbirinden farklı iki ortamdır.
Yani Windows’ta cmd
, Ubuntu’da ise Ctrl+Alt+T ile ulaştığınız ortam, sistem komut satırı iken, bu ortamı açıp python3
(veya python
ya da py3
) komutu vererek ulaştığınız ortam Python’ın komut satırıdır.
Sistem komut satırında sistem komutları (mesela cd
, ls
, dir
, pwd
) verilirken, Python komut satırında, biraz sonra öğrenmeye başlayacağımız Python komutları verilir.
Dolayısıyla python3
(veya python
ya da py3
) komutunu verdikten sonra ulaştığınız ortamda cd Desktop
ve ls
gibi sistem komutlarını kullanmaya çalışmanız sizi hüsrana uğratacaktır.
Etkileşimli Python¶
Şu ana kadar öğrendiklerimiz sayesinde Python programlama dilinin farklı sistemlere nasıl kurulacağını ve nasıl çalıştırılacağını biliyoruz. Dolayısıyla Python’ı bir önceki bölümde anlattığımız şekilde çalıştırdığımız zaman şuna benzer bir ekranla karşılaşacağımızın farkındayız:
yazbel@ubuntu:~$ # python3 Python 3.7.0 (default, 19.08.2024, 12:24:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux Type “help”, “copyright”, “credits” or “license” for more information. >>>
Biz şimdiye kadar bu ekrana Python komut satırı demeyi tercih ettik. Dilerseniz bundan sonra da bu adı kullanmaya devam edebilirsiniz. Ancak teknik olarak bu ekrana etkileşimli kabuk (interactive shell) adı verildiğini bilmemizde fayda var. Etkileşimli kabuk, bizim Python programlama dili ile ilişki kurabileceğimiz, yani onunla etkileşebileceğimiz bir üst katmandır. Etkileşimli kabuk, asıl programımız içinde kullanacağımız kodları deneme imkanı sunar bize. Burası bir nevi test alanı gibidir. Örneğin bir Python kodunun çalışıp çalışmadığını denemek veya nasıl çalıştığını, ne sonuç verdiğini görmek istediğimizde bu ekran son derece faydalı bir araç olarak karşımıza çıkar. Bu ortam, özellikle Python’a yeni başlayanların bu programlama diline aşinalık kazanmasını sağlaması açısından da bulunmaz bir araçtır. Biz de bu bölümde etkileşimli kabuk üzerinde bazı çalışmalar yaparak, Python’a alışma turları atacağız.
Bu arada, geçen bölümde söylediğimiz gibi, bu ortamın sistem komut satırı adını verdiğimiz ortamdan farklı olduğunu aklımızdan çıkarmıyoruz.
O zaman da dediğimiz gibi, sistem komut satırında sistem komutları, Python komut satırında (yani etkileşimli kabukta) ise Python komutları verilir.
Mesela echo %PATH%
, cd Desktop
, dir
ve ls
birer sistem komutudur.
Eğer bu komutları etkileşimli kabukta vermeye kalkışırsanız, bunlar birer Python komutu olmadığı için, Python size bir hata mesajı gösterecektir.
Mesela Python’ın etkileşimli kabuğunda cd Desktop
komutunu verirseniz şöyle bir hata alırsınız:
>>> cd Desktop
File "<stdin>", line 1
cd Desktop
^
SyntaxError: invalid syntax
Çünkü cd Desktop
bir Python komutu değildir.
O yüzden bu komutu Python’ın etkileşimli kabuğunda veremeyiz.
Bu komutu ancak ve ancak kullandığımız işletim sisteminin komut satırında verebiliriz.
Ne diyorduk? Etkileşimli kabuk bir veya birkaç satırlık kodları denemek/test etmek için gayet uygun bir araçtır. İsterseniz konuyu daha fazla lafa boğmayalım. Zira etkileşimli kabuğu kullandıkça bunun ne büyük bir nimet olduğunu siz de anlayacaksınız. Özellikle derlenerek çalıştırılan programlama dilleri ile uğraşmış olan arkadaşlarım, etkileşimli kabuğun gücünü gördüklerinde göz yaşlarına hakim olamayacaklar.
Farklı işletim sistemlerinde py3
, py -3
, python3
veya python
komutunu vererek Python’ın komut satırına nasıl erişebileceğimizi önceki derslerde ayrıntılı olarak anlatmıştık.
Etkileşimli kabuğa ulaşmakta sıkıntı yaşıyorsanız eski konuları tekrar gözden geçirmenizi tavsiye ederim.
Etkileşimli kabuk üzerinde çalışmaya başlamadan önce dilerseniz önemli bir konuyu açıklığa kavuşturalım: Etkileşimli kabuğu başarıyla çalıştırdık. Peki bu kabuktan çıkmak istersek ne yapacağız? Elbette doğrudan pencere üzerindeki çarpı tuşuna basarak bu ortamı terk edebilirsiniz. Ancak bu işlemi kaba kuvvete başvurmadan yapmanın bir yolu olmalı, değil mi?
Etkileşimli kabuktan çıkmanın birkaç farklı yolu vardır:
Pencere üzerindeki çarpı düğmesine basmak (kaba kuvvet)
Önce Ctrl+Z tuşlarına, ardından da Enter tuşuna basmak (Windows)
Ctrl+Z tuşlarına basmak (GNU/Linux)
Önce F6 tuşuna, ardından da Enter tuşuna basmak (Windows)
quit()
yazıp Enter tuşuna basmak (Bütün işletim sistemleri)import sys; sys.exit()
komutunu vermek (Bütün işletim sistemleri)
Siz bu farklı yöntemler arasından, kolayınıza hangisi geliyorsa onu seçebilirsiniz. Bu satırların yazarı, Windows’ta 2 numaralı; GNU/Linux’ta ise 3 numaralı seçeneği tercih ediyor.
Etkileşimli Kabukta İlk Adımlar¶
Python’da etkileşimli kabuğu nasıl çalıştıracağımızı ve bu ortamı nasıl terk edeceğimizi öğrendiğimize göre artık etkileşimli kabuk aracılığıyla Python programlama dilinde ilk adımlarımızı atmaya başlayabiliriz.
Şimdi kendi sistemimize uygun bir şekilde etkileşimli kabuğu tekrar çalıştıralım. Etkileşimli kabuğu çalıştırdığımızda ekranda görünen >>> işareti Python’ın bizden komut almaya hazır olduğunu gösteriyor. Python kodlarımızı bu >>> işaretinden hemen sonra, hiç boşluk bırakmadan yazacağız.
Buradaki ‘hiç boşluk bırakmadan’ kısmı önemli. Python’a yeni başlayanların en sık yaptığı hatalardan biri >>> işareti ile komut arasında boşluk bırakmalarıdır. Eğer bu şekilde boşluk bırakırsanız yazdığınız kod hata verecektir.
İsterseniz basit bir deneme yapalım. >>> işaretinden hemen sonra, hiç boşluk bırakmadan şu komutu yazalım:
>>> "Merhaba Zalim Dünya!"
Bu arada yukarıdaki kodlar içinde görünen >>> işaretini siz yazmayacaksınız. Bu işareti etkileşimli kabuğun görünümünü temsil etmek için yerleştirdik oraya. Siz “Merhaba Zalim Dünya!” satırını yazdıktan sonra doğruca Enter düğmesine basacaksınız.
Bu komutu yazıp Enter tuşuna bastığımızda şöyle bir çıktı almış olmalıyız:
'Merhaba Zalim Dünya!'
Böylece yarım yamalak da olsa ilk Python programımızı yazmış olduk…
Muhtemelen bu kod, içinizde en ufak bir heyecan dahi uyandırmamıştır. Hatta böyle bir kod yazmak size anlamsız bile gelmiş olabilir. Ama aslında şu küçücük kod parçası bile bize Python programlama dili hakkında çok önemli ipuçları veriyor. Gelin isterseniz bu tek satırlık kodu biraz inceleyelim…
Karakter Dizilerine Giriş¶
Dediğimiz gibi, yukarıda yazdığımız küçücük kod parçası sizi heyecanlandırmamış olabilir, ama aslında bu kod Python programlama dili ve bu dilin yapısı hakkında çok önemli bilgileri içinde barındırıyor.
Teknik olarak söylemek gerekirse, yukarıda yazdığımız “Merhaba Zalim Dünya!” ifadesi bir karakter dizisidir. İngilizcede buna string adı verilir ve programlama açısından son derece önemli bir kavramdır bu. Kavramın adından da rahatlıkla anlayabileceğiniz gibi, bir veya daha fazla karakterden oluşan öğelere karakter dizisi (string) diyoruz.
Karakter dizileri bütün programcılık maceramız boyunca karşımıza çıkacak. O yüzden bu kavramı ne kadar erken öğrenirsek o kadar iyi.
Peki bir verinin karakter dizisi olup olmamasının bize ne faydası var? Yani yukarıdaki cümle karakter dizisi olmuş olmamış bize ne?
Python’da, o anda elinizde bulunan bir verinin hangi tipte olduğunu bilmek son derece önemlidir. Çünkü bir verinin ait olduğu tip, o veriyle neler yapıp neler yapamayacağınızı belirler. Python’da her veri tipinin belli başlı özellikleri vardır. Dolayısıyla, elimizdeki bir verinin tipini bilmezsek o veriyi programlarımızda etkin bir şekilde kullanamayız. İşte yukarıda örneğini verdiğimiz “Merhaba Zalim Dünya!” adlı karakter dizisi de bir veri tipidir. Python’da karakter dizileri dışında başka veri tipleri de bulunur. Biraz sonra başka veri tiplerini de inceleyeceğiz.
Dikkat ederseniz “Merhaba Zalim Dünya!” adlı karakter dizisini tırnak içinde gösterdik. Bu da çok önemli bir bilgidir. Eğer bu cümleyi tırnak içine almazsak programımız hata verecektir:
>>> Merhaba Zalim Dünya!
File "<stdin>", line 1
Merhaba Zalim Dünya!
^
SyntaxError: invalid syntax
Zaten tırnak işaretleri, karakter dizilerinin ayırt edici özelliğidir. Öyle ki, Python’da tırnak içinde gösterdiğiniz her şey bir karakter dizisidir. Örneğin şu bir karakter dizisidir:
>>> "a"
Gördüğünüz gibi, tırnak içinde gösterilen tek karakterlik bir öğe de Python’da karakter dizisi sınıfına giriyor.
Mesela şu, içi boş bir karakter dizisidir:
>>> ""
Şu da içinde bir adet boşluk karakteri barındıran bir karakter dizisi…
>>> " "
Bu ikisi arasındaki farka dikkat ediyoruz: Python’da ‘boş karakter dizisi’ ve ‘bir adet boşluktan oluşan karakter dizisi’ birbirlerinden farklı iki kavramdır. Adından da anlaşılacağı gibi, boş karakter dizileri içlerinde hiçbir karakter (başka bir deyişle ‘öğe’) barındırmayan karakter dizileridir. Bir (veya daha fazla) boşluktan oluşan karakter dizileri ise içlerinde boşluk karakteri barındıran karakter dizileridir. Yani bu karakter dizilerinden biri boş, öteki ise doludur. Ama neticede her ikisi de karakter dizisidir. Şu anda oldukça anlamsız bir konu üzerinde vakit kaybediyormuşuz hissine kapılmış olabilirsiniz, ama emin olun, Python programlama diline yeni başlayanların önemli tökezleme noktalarından biridir bu söylediğimiz şey…
Dilerseniz biz karakter dizilerine elimizin alışması için birkaç örnek verelim:
>>> "Elma"
'Elma'
>>> "Guido Van Rossum"
'Guido Van Rossum'
>>> "Python programlama dili"
'Python programlama dili'
>>> "ömnhbgfgh"
'ömnhbgfgh'
>>> "$5&"
'$5&'
>>> ""
''
>>> " "
' '
Yukarıdaki örneklerin hepsi birer karakter dizisidir. Dikkat ettiyseniz yukarıdaki karakter dizilerinin hepsinin ortak özelliği tırnak içinde gösteriliyor olmasıdır. Dediğimiz gibi, tırnak işaretleri karakter dizilerinin ayırt edici özelliğidir.
Peki bir verinin karakter dizisi olup olmadığından nasıl emin olabilirsiniz?
Eğer herhangi bir verinin karakter dizisi olup olmadığı konusunda tereddütünüz varsa, type()
adlı bir fonksiyondan yararlanarak o verinin tipini sorgulayabilirsiniz.
Bu fonksiyonu şöyle kullanıyoruz:
>>> type("Elma")
<class 'str'>
Not
Bu ‘fonksiyon’ kelimesinin kafanızı karıştırmasına izin vermeyin.
İleride fonksiyonları oldukça ayrıntılı bir şekilde inceleyeceğimiz için, type()
ifadesinin bir fonksiyon olduğunu bilmeniz şimdilik yeterli olacaktır.
Üstelik fonksiyon konusunu ayrıntılı bir şekilde anlatma vakti geldiğinde siz fonksiyonlara dair pek çok şeyi zaten öğrenmiş olacaksınız.
Burada amacımız “Elma” adlı öğenin tipini denetlemek.
Denetlenecek öğeyi type()
fonksiyonunun parantezleri arasında belirttiğimize dikkat edin.
(Fonksiyonların parantezleri içinde belirtilen değerlere teknik dilde parametre adı verilir.)
Yukarıdaki çıktıda bizi ilgilendiren kısım, sondaki ‘str’ ifadesi. Tahmin edebileceğiniz gibi, bu ifade string kelimesinin kısaltmasıdır. Bu kelimenin Türkçede karakter dizisi anlamına geldiğini söylemiştik. O halde yukarıdaki çıktıya bakarak, “Elma” öğesinin bir karakter dizisi olduğunu söyleyebiliyoruz.
type()
fonksiyonu yardımıyla kendi kendinize bazı denemeler yaparak konuyu iyice sindirmenizi tavsiye ederim.
Mesela “½{656$#gfd” ifadesinin hangi sınıfa girdiğini kontrol etmekle başlayabilirsiniz.
Peki karakter dizileri ile neler yapabiliriz? Şu anda Python bilgimiz kısıtlı olduğu için karakter dizileri ile çok fazla şey yapamayız, ama ileride bilgimiz arttıkça, karakter dizileriyle sıkı fıkı olacağız.
Esasında, henüz bilgimiz kısıtlı da olsa karakter dizileriyle yine de ufak tefek bazı şeyler yapamayacak durumda değiliz. Mesela şu anki bilgilerimizi ve görür görmez size tanıdık gelecek bazı basit parçaları kullanarak, karakter dizilerini birbirleriyle birleştirebiliriz:
>>> "yazbel" + ".com"
'yazbel.com'
Burada + işaretini kullanarak karakter dizilerini nasıl birleştirebildiğimize dikkat edin. İki karakter dizisini + işareti ile birleştirdiğimizde karakter dizilerinin arasında boşluk olmadığına özellikle dikkatinizi çekmek isterim. Bu durumu şu örnekte daha net görebiliriz:
>>> "Fırat" + "Özgül"
'FıratÖzgül'
Gördüğünüz gibi, bu iki karakter dizisi, arada boşluk olmadan birbiriyle bitiştirildi. Araya boşluk eklemek için birkaç farklı yöntemden yararlanabilirsiniz:
>>> "Fırat" + " " + "Özgül"
'Fırat Özgül'
Burada iki karakter dizisi arasına bir adet boşluk karakteri yerleştirdik. Aynı etkiyi şu şekilde de elde edebilirsiniz:
>>> "Fırat" + " Özgül"
Burada da Özgül karakter dizisinin başına bir adet boşluk yerleştirerek istediğimiz çıktıyı elde ettik.
Bu arada, karakter dizilerini birleştirmek için mutlaka + işareti kullanmak zorunda değilsiniz. Siz + işaretini kullanmasanız da Python sizin karakter dizilerini birleştirmek istediğinizi anlayacak kadar zekidir:
>>> "www" "." "google" "." "com"
'www.google.com'
Ancak gördüğünüz gibi, + işaretini kullandığınızda kodlarınız daha okunaklı oluyor.
+ işareti dışında karakter dizileri ile birlikte * (çarpı) işaretini de kullanabiliriz. O zaman şöyle bir etki elde ederiz:
>>> "w" * 3
'www'
>>> "yavaş " * 2
'yavaş yavaş '
>>> "-" * 10
'----------'
>>> "uzak" + " " * 5 + "çok uzak..."
'uzak çok uzak...'
Gördüğünüz gibi, çok basit parçaları bir araya getirerek karmaşık çıktılar elde edebiliyoruz.
Mesela son örnekte “uzak” adlı karakter dizisine önce 5 adet boşluk karakteri (" " * 5
), ardından da “çok uzak…” adlı karakter dizisini ekleyerek istediğimiz çıktıyı aldık.
Burada + ve * adlı iki yeni araç görüyoruz. Bunlar aslında sayılarla birlikte kullanılan birer aritmetik işleçtir. Normalde + işleci toplama işlemleri için, * işleci ise çarpma işlemleri için kullanılır. Ama yukarıdaki örneklerde, + işaretinin ‘birleştirme’; * işaretinin ise ‘tekrarlama’ anlamından ötürü bu iki işleci bazı durumlarda karakter dizileri ile birlikte de kullanabiliyoruz. Bunların dışında bir de - (eksi) ve / (bölü) işleçleri bulunur. Ancak bu işaretleri karakter dizileri ile birlikte kullanamıyoruz.
Karakter dizilerini sonraki bir bölümde bütün ayrıntılarıyla inceleyeceğiz. O yüzden şimdilik bu konuya bir ara verelim.
Sayılara Giriş¶
Dedik ki, Python’da birtakım veri tipleri bulunur ve karakter dizileri de bu veri tiplerinden yalnızca biridir. Veri tipi olarak karakter dizilerinin dışında, biraz önce aritmetik işleçler vesilesiyle sözünü ettiğimiz, bir de ‘sayı’ (number) adlı bir veri tipi vardır.
Herhalde sayıların ne anlama geldiğini tarif etmeye gerek yok. Bunlar bildiğimiz sayılardır. Mesela:
>>> 23
23
>>> 4567
4567
>>> 2.3
2.3
>>> (10+2j)
(10+2j)
Python’da sayıların farklı alt türleri bulunur. Mesela tamsayılar, kayan noktalı sayılar, karmaşık sayılar…
Yukarıdaki örnekler arasında geçen 23 ve 4567 birer tamsayıdır. İngilizcede bu tür sayılara integer adı verilir.
2.3 ise bir kayan noktalı sayıdır (floating point number veya kısaca float). Bu arada kayan noktalı sayılarda basamak ayracı olarak virgül değil, nokta işareti kullandığımıza dikkat edin.
En sonda gördüğümüz 10+2j sayısı ise bir karmaşık sayıdır (complex). Ancak eğer matematikle yoğun bir şekilde uğraşmıyorsanız karmaşık sayılar pek karşınıza çıkmaz.
Sayıları temel olarak öğrendiğimize göre etkileşimli kabuğu basit bir hesap makinesi niyetine kullanabiliriz:
>>> 5 + 2
7
>>> 25 * 25
625
>>> 5 / 2
2.5
>>> 10 - 3
7
Yukarıdaki örneklerde kullandığımız aritmetik işleçlerden biraz önce bahsetmiştik. O yüzden bunlara yabancılık çektiğinizi zannetmiyorum. Ama biz yine de bu işleçleri ve görevlerini şöylece sıralayalım:
İşleç
Görevi
+
toplama
-
çıkarma
*
çarpma
/
bölme
Yukarıdaki örneklerde bir şey dikkatinizi çekmiş olmalı: Karakter dizilerini tanımlarken tırnak işaretlerini kullandık. Ancak sayılarda tırnak işareti yok. Daha önce de dediğimiz gibi, tırnak işaretleri karakter dizilerinin ayırt edici özelliğidir. Python’da tırnak içinde gösterdiğiniz her şey bir karakter dizisidir. Mesela şu örneklere bakalım:
>>> 34657
34657
Bu bir sayıdır. Peki ya şu?
>>> "34657"
'34657'
Bu ise bir karakter dizisidir.
Dilerseniz biraz önce öğrendiğimiz type()
fonksiyonu yardımıyla bu verilerin tipini sorgulayalım:
>>> type(34657)
<class 'int'>
Buradaki ‘int’ ifadesi İngilizce “integer”, yani tamsayı kelimesinin kısaltmasıdır. Demek ki 34657 sayısı bir tamsayı imiş. Bir de şuna bakalım:
>>> type("34657")
<class 'str'>
Gördüğünüz gibi, 34657 sayısını tırnak içine aldığımızda bu sayı artık sayı olma özelliğini yitiriyor ve bir karakter dizisi oluyor. Şu anda bu çok önemsiz bir ayrıntıymış gibi gelebilir size, ama aslında son derece önemli bir konudur bu. Bu durumun etkilerini şu örneklerde görebilirsiniz:
>>> 23 + 65
88
Burada normal bir şekilde iki sayıyı birbiriyle topladık.
Bir de şuna bakın:
>>> "23" + "65"
'2365'
Burada ise Python iki karakter dizisini yan yana yazmakla yetindi; yani bunları birleştirdi. Python açısından “23” ve 23 birbirinden farklıdır. “23” bir karakter dizisi iken, 23 bir sayıdır. Aynı şey “65” ve 65 için de geçerlidir. Yani Python açısından “65” ile “Merhaba Zalim Dünya!” arasında hiç bir fark yoktur. Bunların ikisi de karakter dizisi sınıfına girer. Ancak 65 ile “65” birbirinden farklıdır. 65 bir sayı iken, “65” bir karakter dizisidir.
Bu bilgi, özellikle aritmetik işlemlerde büyük önem taşır. Bunu dilerseniz şu örnekler üzerinde gösterelim:
>>> 45 + "45"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Gördüğünüz gibi, yukarıdaki kodlar hata veriyor. Bunun sebebi bir sayı (45) ile bir karakter dizisini (“45”) birbiriyle toplamaya çalışmamızdır. Asla unutmayın, aritmetik işlemler ancak sayılar arasında yapılır. Karakter dizileri ile herhangi bir aritmetik işlem yapılamaz.
Bir de şuna bakalım:
>>> 45 + 45
90
Bu kodlar ise düzgün çalışır. Çünkü burada iki sayıyı aritmetik işleme soktuk ve başarılı olduk.
Son olarak şu örneği verelim:
>>> "45" + "45"
'4545'
Burada + işlecinin toplama anlamına gelmediğine dikkat edin. Bu işleç burada iki karakter dizisini birleştirme görevi üstleniyor. Yani yukarıdaki örneğin şu örnekten hiçbir farkı yoktur:
>>> "yazbel." + "com"
'yazbel.com'
Bu iki örnekte de yaptığımız şey karakter dizilerini birbiriyle birleştirmektir.
Gördüğünüz gibi, + işlecinin sağındaki ve solundaki değerler birer karakter dizisi ise bu işleç bu iki değeri birbiriyle birleştiriyor. Ama eğer bu değerler birer sayı ise + işleci bu değerleri birbiriyle aritmetik olarak topluyor.
* işleci de + işlecine benzer bir iş yapar. Yani eğer * işleci bir sayı ve bir karakter dizisi ile karşılaşırsa, o karakter dizisini, verilen sayı kadar tekrarlar. Örneğin:
>>> "w" * 3
'www'
Burada * işleci bir karakter dizisi (“w”) ve bir sayı (3) arasında işlem yaptığı için, karakter dizisini, ilgili sayı kadar tekrarlıyor. Yani “w” karakter dizisini 3 kez tekrarlıyor.
Bir de şuna bakalım:
>>> 25 * 3
75
Burada ise * işleci iki adet sayı arasında işlem yaptığı için bu değerleri birbiriyle aritmetik olarak çarpıyor ve 75 değerini elde etmemizi sağlıyor.
Gördüğünüz gibi, o anda elimizde bulunan verilerin tipini bilmek gerçekten de büyük önem taşıyor. Çünkü eğer elimizdeki verilerin tipini bilmezsek nasıl sonuçlar elde edeceğimizi de kestiremeyiz.
Böylece karakter dizileri ile sayılar arasındaki farkı öğrenmiş olduk. Bu bilgiler size önemsizmiş gibi gelebilir, ama aslında karakter dizileri ile sayılar arasındaki farkı anlamak, Python programlama dilinin önemli bir bölümünü öğrenmiş olmak demektir. İleride yazacağınız en karmaşık programlarda bile, bazen programınızın çalışmamasının (veya daha kötüsü yanlış çalışmasının) nedeninin karakter dizileri ile sayıları birbirine karıştırmanız olduğunu göreceksiniz. O yüzden burada öğrendiğiniz hiçbir bilgi kırıntısını baştan savmamanızı (ve sabırsızlık ya da acelecilik etmemenizi) tavsiye ederim.
Değişkenler¶
Şimdi şöyle bir durum düşünün: Diyelim ki sisteme kayıt için kullanıcı adı ve parola belirlenmesini isteyen bir program yazıyorsunuz. Yazacağınız bu programda, belirlenebilecek kullanıcı adı ve parolanın toplam uzunluğu 40 karakteri geçmeyecek.
Bu programı yazarken ilk aşamada yapmanız gereken şey, kullanıcının belirlediği kullanıcı adı ve parolanın uzunluğunu tek tek denetlemek olmalı.
Mesela kullanıcı şöyle bir kullanıcı adı belirlemiş olsun:
firat_ozgul_1980
Kullanıcının belirlediği parola ise şu olsun:
rT%65#$hGfUY56123
İşte bizim öncelikle kullanıcıdan gelen bu verilerin teker teker uzunluğunu biliyor olmamız lazım, ki bu verilerin toplam 40 karakter sınırını aşıp aşmadığını denetleyebilelim.
Peki bu verilerin uzunluğunu nasıl ölçeceğiz? Elbette bunun için verilerdeki harfleri elle tek tek saymayacağız. Bunun yerine, Python programlama dilinin bize sunduğu bir aracı kullanacağız. Peki nedir bu araç?
Hatırlarsanız birkaç sayfa önce type()
adlı bir fonksiyondan söz etmiştik.
Bu fonksiyonun görevi bir verinin hangi tipte olduğunu bize bildirmekti.
İşte tıpkı type()
gibi, Python’da len()
adlı başka bir fonksiyon daha bulunur.
Bu fonksiyonun görevi ise karakter dizilerinin (ve ileride göreceğimiz gibi, başka veri tiplerinin) uzunluğunu ölçmektir.
Yani bu fonksiyonu kullanarak bir karakter dizisinin toplam kaç karakterden oluştuğunu öğrenebiliriz.
Biz henüz kullanıcıdan nasıl veri alacağımızı bilmiyoruz. Ama şimdilik şunu söyleyebiliriz: Python’da kullanıcıdan herhangi bir veri aldığımızda, bu veri bize bir karakter dizisi olarak gelecektir. Yani kullanıcıdan yukarıdaki kullanıcı adı ve parolayı aldığımızı varsayarsak, bu veriler bize şu şekilde gelir:
"firat_ozgul_1980"
ve:
"rT%65#$hGfUY56123"
Gördüğünüz gibi, elde ettiğimiz veriler tırnak içinde yer alıyor.
Yani bunlar birer karakter dizisi.
Şimdi gelin yukarıda bahsettiğimiz len()
fonksiyonunu kullanarak bu karakter dizilerinin uzunluğunu ölçelim.
Dediğimiz gibi, len()
de tıpkı type()
gibi bir fonksiyondur.
Dolayısıyla len()
fonksiyonunun kullanımı type()
fonksiyonunun kullanımına çok benzer.
Nasıl type()
fonksiyonu bize, kendisine verdiğimiz parametrelerin tipini söylüyorsa, len()
fonksiyonu da kendisine verdiğimiz parametrelerin uzunluğunu söyler.
Dikkatlice bakın:
>>> len("firat_ozgul_1980")
16
>>> len("rT%65#$hGfUY56123")
17
Demek ki “firat_ozgul_1980” adlı karakter dizisinde 16; “rT%65#$hGfUY56123” adlı karakter dizisinde ise 17 karakter varmış. Bizim istediğimiz şey bu iki değerin toplam uzunluğunun 40 karakteri aşmaması. Bunu denetlemek için yapmamız gereken şey bu iki değerin uzunluğunu birbiriyle toplamak olmalı. Yani:
>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")
Buradan alacağımız sonuç 33 olacaktır. Demek ki kullanıcı 40 karakter limitini aşmamış. O halde programımız bu kullanıcı adı ve parolayı kabul edebilir…
Bu arada, belki farkettiniz, belki de farketmediniz, ama burada da çok önemli bir durumla karşı karşıyayız.
Gördüğünüz gibi len()
fonksiyonu bize sayı değerli bir veri gönderiyor.
Gelin isterseniz bunu teyit edelim:
>>> type(len("firat_ozgul_1980"))
<class 'int'>
len()
fonksiyonunun bize sayı değerli bir veri göndermesi sayesinde bu fonksiyondan elde ettiğimiz değerleri birbiriyle toplayabiliyoruz:
>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")
33
Eğer len()
fonksiyonu bize sayı değil de mesela karakter dizisi verseydi, bu fonksiyondan elde ettiğimiz değerleri yukarıdaki gibi doğrudan birbiriyle aritmetik olarak toplayamazdık.
Öyle bir durumda, bu iki veriyi birbiriyle toplamaya çalıştığımızda, + işleci 16 ve 17 değerlerini birbiriyle toplamak yerine bu değerleri birbiriyle birleştirerek bize ‘1617’ gibi bir sonuç verecekti.
Her zaman söylediğimiz gibi, Python’da veri tipi kavramını çok iyi anlamak ve o anda elimizde bulunan bir verinin hangi tipte olduğunu bilmek çok önemlidir. Aksi halde programlarımızda hata yapmamız kaçınılmazdır.
Eğer yukarıda anlattığımız şeyleri kafa karıştırıcı bulduysanız hiç endişe etmeyin.
Birkaç bölüm sonra input()
adlı bir fonksiyondan bahsettiğimizde şimdi söylediğimiz şeyleri çok daha net anlayacaksınız.
Biraz sonra len()
fonksiyonundan bahsetmeye devam edeceğiz, ama isterseniz ondan önce çok önemli bir konuya değinelim.
Biraz önce şöyle bir örnek vermiştik:
>>> len("firat_ozgul_1980")
16
>>> len("rT%65#$hGfUY56123")
17
>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")
Bu kodlar, istediğimiz şeyi gayet güzel yerine getiriyor. Ama sizce de yukarıdaki kodlarda çok rahatsız edici bir durum yok mu?
Dikkat ederseniz, yukarıdaki örneklerde kullandığımız verileri, program içinde her ihtiyaç duyduğumuzda tekrar tekrar yazdık. Böylece aynı program içinde iki kez “firat_ozgul_1980”; iki kez de “rT%65#$hGfUY56123” yazmak zorunda kaldık. Halbuki bu verileri programlarımızın içinde her ihtiyaç duyduğumuzda tekrar tekrar yazmak yerine bir değişkene atasak ve gerektiğinde o değişkeni kullansak çok daha iyi olmaz mı? Herhalde olur…
Peki nedir bu değişken dediğimiz şey?
Python’da bir program içinde değerlere verilen isimlere değişken denir. Hemen bir örnek verelim:
>>> n = 5
Burada 5 sayısını bir değişkene atadık. Değişkenimiz ise n. Ayrıca 5 sayısını bir değişkene atamak için = işaretinden yararlandığımıza da çok dikkat edin. Buradan, = işaretinin Python programlama dilinde değer atama işlemleri için kullanıldığı sonucunu çıkarıyoruz.
n = 5
gibi bir komut yardımıyla 5 değerini n adlı değişkene atamamız sayesinde artık ne zaman 5 sayısına ihtiyaç duysak bu n değişkenini çağırmamız yeterli olacaktır:
>>> n
5
>>> n * 10
50
>>> n / 2
2.5
Gördüğünüz gibi, 5 değerini bir değişkene atadıktan sonra, bu 5 değerini kullanmamız gereken yerlerde sadece değişkenin adını kullandığımızda değişkenin değerini Python otomatik olarak yerine koyabiliyor.
Yani n = 5
komutuyla n adlı bir değişken tanımladıktan sonra, artık ne zaman 5 sayısına ihtiyaç duysak n değişkenini çağırmamız yeterli olacaktır.
Python o 5 değerini otomatik olarak yerine koyar.
Şimdi de pi adlı başka bir değişken tanımlayalım:
>>> pi = 3.14
Bu pi değişkeninin değeri ile n değişkeninin değerini toplayalım:
>>> pi + n
8.14
Gördüğünüz gibi, değerleri her defasında tekrar yazmak yerine bunları bir değişkene atayıp, gereken yerde bu değişkeni kullanmak çok daha pratik bir yöntem.
Aynı şeyi programımız için de yapabiliriz:
>>> kullanıcı_adı = "firat_ozgul_1980"
>>> parola = "rT%65#$hGfUY56123"
= işaretini kullanarak ilgili değerlere artık birer ad verdiğimiz, yani bu değerleri birer değişkene atadığımız için, bu değerleri kullanmamız gereken yerlerde değerlerin kendisini uzun uzun yazmak yerine, belirlediğimiz değişken adlarını kullanabiliriz. Mesela:
>>> len(kullanıcı_adı)
16
>>> len(parola)
17
>>> len(kullanıcı_adı) + len(parola)
33
>>> k_adı_uzunluğu = len(kullanıcı_adı)
>>> type(k_adı_uzunluğu)
<class 'int'>
Gördüğünüz gibi, değişken kullanımı işlerimizi bir hayli kolaylaştırıyor.
Değişken Adı Belirleme Kuralları¶
Python programlama dilinde, değişken adı olarak belirleyebileceğimiz kelime sayısı neredeyse sınırsızdır. Yani hemen hemen her kelimeyi değişken adı olarak kullanabiliriz. Ama yine de değişken adı belirlerken dikkat etmemiz gereken bazı kurallar var. Bu kuralların bazıları zorunluluk, bazıları ise yalnızca tavsiye niteliğindedir.
Şimdi bu kuralları tek tek inceleyelim:
1. Değişken adları bir sayı ile başlayamaz. Yani şu kullanım yanlıştır:
>>> 3_kilo_elma = "5 TL"
2. Değişken adları aritmetik işleçlerle başlayamaz. Yani şu kullanım yanlıştır:
>>> +değer = 4568
3. Değişken adları ya bir alfabe harfiyle ya da _ işaretiyle başlamalıdır:
>>> _değer = 4568
>>> değer = 4568
4. Değişken adları içinde Türkçe karakterler kullanabilirsiniz. Ancak ileride beklenmedik uyum sorunları çıkması ihtimaline karşı değişken adlarında Türkçe karakter kullanmaktan kaçınmak isteyebilirsiniz.
5. Aşağıdaki kelimeleri değişken adı olarak kullanamazsınız:
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', '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 Python’da özel anlam ifade eden kelimelerdir. Etkileşimli kabuk zaten bu kelimeleri değişken adı olarak kullanmanıza izin vermez. Örneğin:
>>> elif = "hoş kız"
File "<stdin>", line 1
elif = "hoş kız"
^
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 ileride göreceğimiz gibi, programlarınızı bir dosyaya yazarken bu kelimeleri değişken adı olarak kullanmaya çalışırsanız programınız tespit etmesi çok güç hatalar üretecektir.
Bu arada elbette yukarıdaki listeyi bir çırpıda ezberlemeniz beklenmiyor sizden. Python programlama dilini öğrendikçe özel kelimeleri bir bakışta tanıyabilecek duruma geleceksiniz. Ayrıca eğer isterseniz şu komutları vererek, istediğiniz her an yukarıdaki listeye ulaşabilirsiniz:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', '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']
Size bir soru: Acaba bu listede kaç tane kelime var?
Bu soru karşısında listedeki kelimeleri tek tek elle saymaya kalkışan arkadaşlarıma teessüflerimi iletiyorum… Bu tür işler için hangi aracı kullanabileceğimizi artık çok iyi biliyor olmalısınız:
>>> len(keyword.kwlist)
35
Bu kodları şöyle yazabileceğimizi de biliyorsunuz:
>>> yasaklı_kelimeler = keyword.kwlist
>>> len(yasaklı_kelimeler)
35
Bu arada, yukarıdaki kodların bir kısmını henüz anlayamamış olabilirsiniz. Hiç endişe etmeyin. Yukarıdaki kodları vermemizin sebebi değişken adı olarak kullanılamayacak kelimelere kısa yoldan nasıl ulaşabileceğinizi gösterebilmek içindir. Bir-iki bölüm sonra burada yazdığımız kodları rahatlıkla anlayabilecek düzeye geleceksiniz.
Yukarıda verdiğimiz kodların çıktısından anladığımıza göre, toplam 35 tane kelime varmış değişken adı belirlerken kullanmaktan kaçınmamız gereken…
6. Yukarıdaki kelimeler dışında, Python programlama diline ait fonksiyon ve benzeri araçların adlarını da değişken adı olarak kullanmamalısınız.
Örneğin yazdığınız programlarda değişkenlerinize type veya len adı vermeyin.
Çünkü ‘type’ ve ‘len’ Python’a ait iki önemli fonksiyonun adıdır.
Eğer mesela bir değişkene type adını verirseniz, o programda artık type()
fonksiyonunu kullanamazsınız:
>>> type = 3456
Bu örnekte type adında bir değişken tanımladık.
Şimdi mesela “elma” kelimesinin tipini denetlemek için type()
fonksiyonunu kullanmaya çalışalım:
>>> type("elma")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Gördüğünüz gibi, artık type()
fonksiyonu çalışmıyor.
Çünkü siz ‘type’ kelimesini bir değişken adı olarak kullanarak, type()
fonksiyonunu kullanılamaz hale getirdiniz.
Bu durumdan kurtulmak için etkileşimli kabuğu kapatıp tekrar açabilirsiniz. Ya da eğer etkileşimli kabuğu kapatmak istemiyorsanız şu komut yardımıyla type değişkenini ortadan kaldırmayı da tercih edebilirsiniz:
>>> del type
Böylece, (tahmin edebileceğiniz gibi delete (silmek) kelimesinin kısaltması olan) del
komutuyla type değişkenini silmiş oldunuz.
Artık ‘type’ kelimesi yine type()
fonksiyonunu çağıracak:
>>> type("elma")
<class 'str'>
7. Değişken adlarını belirlerken, değişkeni oluşturan kelimeler arasında boşluk bırakılamaz. Yani şu kullanım yanlıştır:
>>> kullanıcı adı = "yazbel"
Yukarıdaki değişkeni şu şekilde tanımlayabiliriz:
>>> kullanıcı_adı = "yazbel"
Ya da şöyle:
>>> kullanıcıAdı = "yazbel"
8. Değişken adları belirlerken, değişken adının, değişkenin değerini olabildiğince betimlemesine dikkat etmemiz kodlarımızın okunaklılığını artıracaktır. Örneğin:
>>> personel_sayısı = 45
Yukarıdaki, tanımladığı değere uygun bir değişken adıdır. Şu ise kurallara uygun bir değişken adı olsa da yeterince betimleyici değildir:
>>> sayı = 45
9. Değişken adları ne çok kısa, ne de çok uzun olmalıdır. Mesela şu değişken adı, kodları okuyan kişiye, değişken değerinin anlamı konusunda pek fikir vermez:
>>> a = 345542353
Şu değişken adı ise gereksiz yere uzundur:
>>> türkiye_büyük_millet_meclisi_milletvekili_sayısı = 600
Değişken adlarının uzunluğunu makul seviyede tutmak esastır:
>>> tbmm_mv_sayısı = 600
Yukarıda verdiğimiz bütün bu örnekler bize, Python’da değişkenlerin, değerlere atanmış adlardan ibaret olduğunu gösteriyor. Değişkenler, yazdığımız programlarda bize çok büyük kolaylık sağlar. Mesela 123432456322 gibi bir sayıyı ya da “Türkiye Cumhuriyeti Çalışma ve Sosyal Güvenlik Bakanlığı” gibi bir karakter dizisini gerektiği her yerde tek tek elle yazmak yerine, bunları birer değişkene atayarak, gerektiğinde sadece bu değişken adını kullanmak çok daha mantıklı bir iştir.
Ayrıca zaten ileride kullanıcıdan veri almaya başladığınızda, aldığınız bu verileri, yazdığınız programda kullanabilmek için mutlaka bir değişkene atamanız gerekecek. O yüzden Python’daki değişken kavramını şimdiden iyi tanıyıp anlamakta büyük fayda var.
Uygulama Örnekleri¶
Gelin isterseniz yukarıda verdiğimiz bilgileri pekiştirmek için birkaç ufak alıştırma yapalım, alıştırma yaparken de sizi yine Python programlama diline ilişkin çok önemli bazı yeni bilgilerle tanıştıralım.
Diyelim ki aylık yol masrafımızı hesaplayan bir program yazmak istiyoruz. Elimizdeki verilerin şunlar olduğunu varsayalım:
Cumartesi-Pazar günleri çalışmıyoruz.
Dolayısıyla ayda 22 gün çalışıyoruz.
Evden işe gitmek için kullandığımız vasıtanın ücreti 1.5 TL
İşten eve dönmek için kullandığımız vasıtanın ücreti 1.4 TL
Aylık yol masrafımızı hesaplayabilmek için gidiş ve dönüş ücretlerini toplayıp, bunları çalıştığımız gün sayısıyla çarpmamız yeterli olacaktır. Elimizdeki bu bilgilere göre aylık yol masrafımızı hesaplamak için şöyle bir formül üretebiliriz:
masraf = gün sayısı x (gidiş ücreti + dönüş ücreti)
Dilerseniz hemen bunu bir Python programı haline getirelim:
>>> 22 * (1.5 + 1.4)
63.8
Demek ki bir ayda 63.8 TL’lik bir yol masrafımız varmış.
Bu arada, yukarıdaki örnekte bir şey dikkatinizi çekmiş olmalı. Aritmetik işlemi yaparken bazı sayıları parantez içine aldık. Python’da aritmetik işlemler yapılırken alıştığımız matematik kuralları geçerlidir. Yani mesela aynı anda bölme, çıkarma, toplama ve çarpma işlemleri yapılacaksa işlem öncelik sırası önce bölme ve çarpma, sonra toplama ve çıkarma şeklinde olacaktır. Elbette siz parantezler yardımıyla bu işlem sırasını değiştirebilirsiniz.
Bu anlattıklarımıza göre, eğer yukarıda yol masrafını hesaplayan programda parantezleri kullanmazsak, işlem öncelik kuralları gereğince Python önce 22 ile 1.5’i çarpıp, çıkan sonucu 1.4 ile toplayacağı için elde ettiğimiz sonuç yanlış çıkacaktır. Bizim burada doğru sonuç alabilmemiz için önce 1.5 ile 1.4’ü toplamamız, çıkan sonucu da 22 ile çarpmamız gerekiyor. Bu sıralamayı da parantezler yardımıyla elde ediyoruz.
Yine dikkat ederseniz, yukarıdaki örnek programda aslında çok verimsiz bir yol izledik. Gördüğünüz gibi, bu programda bütün değerleri tek tek elle kendimiz giriyoruz. Örneğin çalışılan gün sayısına karşılık gelen 22 değerini başka bir yerde daha kullanmak istesek aynı sayıyı tekrar elle doğrudan kendimiz girmek zorundayız. Mesela yılda kaç gün çalıştığımızı hesaplayalım:
>>> 22 * 12
264
Gördüğünüz gibi, burada da 22 sayısına ihtiyaç duyduk. Aslında değerleri bu şekilde her defasında tekrar tekrar elle girmek hem hata yapma riskini artırdığı, hem de bize fazladan iş çıkardığı için tercih edilmeyen bir yöntemdir. Bunun yerine, 22 sayısına bir isim verip, gereken yerlerde bu ismi kullanmak daha mantıklı olacaktır. Yani tıpkı kullanıcı ve parola örneğinde olduğu gibi, burada da verileri öncelikle bir değişkene atamak çok daha akıllıca bir iştir:
>>> gün = 22
>>> gidiş_ücreti = 1.5
>>> dönüş_ücreti = 1.4
>>> gün * (gidiş_ücreti + dönüş_ücreti)
63.8
Bütün değerleri birer değişkene atadığımız için, artık bu değişkenleri istediğimiz yerde kullanabiliriz. Mesela yılda toplam kaç gün çalıştığımızı bulmak istersek, ilgili değeri elle yazmak yerine, yukarıda tanımladığımız gün değişkenini kullanabiliriz:
>>> gün * 12
264
İlerleyen zamanda aylık çalışılan gün sayısı değişirse sadece gün değişkeninin değerini değiştirmemiz yeterli olacaktır:
>>> gün = 23
>>> gün * (gidiş_ücreti + dönüş_ücreti)
66.7
>>> gün * 12
276
Eğer bu şekilde değişken atamak yerine, değerleri gerektiği her yerde elle yazsaydık, bu değerlerde herhangi bir değişiklik yapmamız gerektiğinde program içinde geçen ilgili bütün değerleri bulup tek tek değiştirmemiz gerekecekti:
>>> 23 * (1.6 + 1.5)
71.3
>>> 23 * 12
276
Değişken kavramı şu anda gözünüze pek anlamlı görünmemiş olabilir. Ama programlarımızı ileride dosyaya kaydettiğimiz zaman bu değişkenler çok daha kullanışlı araçlar olarak karşımıza çıkacaktır.
Dilerseniz bir örnek daha yaparak yukarıdaki bilgilerin kafamıza iyice yerleşmesini sağlayalım. Mesela bir dairenin alanını (yaklaşık olarak) hesaplayan bir program yazalım.
Öncelikle çap adlı bir değişken tanımlayarak dairenin çapını belirleyelim:
>>> çap = 16
Bu değeri kullanarak dairemizin yarıçapını hesaplayabiliriz. Bunun için çap değişkeninin değerinin yarısını almamız yeterli olacaktır:
>>> yarıçap = çap / 2
pi sayısını 3.14159 olarak alalım.
>>> pi = 3.14159
Bir dairenin alan formülü (pi)r2’dir:
>>> alan = pi * (yarıçap * yarıçap)
Son olarak alan değişkeninin değerini ekrana yazdırabiliriz:
>>> alan
201.06176
Böylece bir dairenin alanını yaklaşık olarak hesaplamış olduk. Dilerseniz programımızı bir de derli toplu olarak görelim:
>>> çap = 16
>>> yarıçap = çap / 2
>>> pi = 3.14159
>>> alan = pi * (yarıçap * yarıçap)
>>> alan
201.06176
Görüyorsunuz ya, değişkenler işimizi nasıl da kolaylaştırıyor. Eğer yukarıdaki programda değişken kullanmasaydık kodlarımız şöyle görünecekti:
>>> 3.14159 * ((16/2) * (16/2))
201.06176
Bu kodlar tek kullanımlıktır. Eğer yukarıdaki örnekte mesela dairenin çapını değiştirmeniz gerekirse, iki yerde elle değişiklik yapmanız gerekir. Ama değişkenleri kullandığımızda sadece çap değişkeninin değerini değiştirmeniz yeterli olacaktır. Ayrıca değişken kullanmadığınızda, ilgili değeri program boyunca aklınızda tutmanız gerekir. Örneğin çap değişkenini kullanmak yerine, gereken her yerde 16 değerini kullanacaksanız, bu 16 değerini sürekli aklınızda tutmanız lazım. Ama bu değeri en başta bir değişkene atarsanız, 16 değerini kullanmanız gereken yerlerde, akılda tutması daha kolay bir ifade olan çap ismini kullanabilirsiniz.
Bu arada yeri gelmişken sizi yeni bir işleçle daha tanıştıralım. Şimdiye kadar Python’da toplama (+), çıkarma (-), çarpma (*), bölme (/) ve değer atama (=) işleçlerini gördük. Ama yukarıda verdiğimiz son örnek, başka bir işleç daha öğrenmemizi gerektiriyor…
Yukarıdaki şu örneğe tekrar bakalım:
alan = pi * (yarıçap * yarıçap)
Burada yarıçap değişkeninin karesini alabilmek için bu değeri kendisiyle çarptık. Aslında gayet mantıklı ve makul bir yöntem. Kare bulmak için değeri kendisiyle çarpıyoruz. Eğer bir sayının küpünü bulmak isteseydik o sayıyı üç kez kendisiyle çarpacaktık:
>>> 3 * 3 * 3
27
Peki ya bir sayının mesela beşinci kuvvetini hesaplamak istersek ne yapacağız? O sayıyı beş kez kendisiyle mi çarpacağız? Bu ne kadar vasat bir yöntem, değil mi?
Elbette bir sayının herhangi bir kuvvetini hesaplamak için o sayıyı kendisiyle kuvvetince çarpmayacağız. Python’da bu tür ‘kuvvet hesaplamaları’ için ayrı bir işleç (ve fonksiyon) bulunur.
Öncelikle kuvvet hesaplarını yapmamızı sağlayan işleçten söz edelim.
Python’da ** adlı bir işleç bulunur. Bu işlecin görevi bir sayının kuvvetini hesaplamamızı sağlamaktır. Örneğin bir sayının 2. kuvvetini, ya da başka bir deyişle karesini hesaplamak istersek şöyle bir kod yazabiliriz:
>>> 12 ** 2
144
Burada 12 sayısının 2. kuvvetini, yani karesini hesapladık. Bu bilgiyi yukarıdaki formüle uygulayalım:
>>> alan = pi * (yarıçap ** 2)
Bu işleci herhangi bir sayının herhangi bir kuvvetini hesaplamak için kullanabiliriz elbette. Mesela 23 sayısının küpünü (yani 3. kuvvetini) hesaplayalım:
>>> 23 ** 3
12167
Aynı işleçten, bir sayının karekökünü hesaplamak için de yararlanabilirsiniz. Neticede bir sayının 0.5’inci kuvveti, o sayının kareköküdür:
>>> 144 ** 0.5
12.0
Gördüğünüz gibi, kuvvet hesaplama işlemleri için bu işleç son derece kullanışlı bir araç vazifesi görüyor.
Ama eğer istersek aynı iş için özel bir fonksiyondan da yararlanabiliriz.
Bu fonksiyonun adı pow()
.
Peki bu fonksiyonu nasıl kullanacağız?
Daha önce öğrendiğimiz type()
ve len()
fonksiyonlarını nasıl kullanıyorsak pow()
fonksiyonu da aynı şekilde kullanacağız.
type()
ve len()
fonksiyonlarını birtakım parametreler ile birlikte kullanıyorduk hatırlarsanız.
Aynı şekilde pow()
fonksiyonu da birtakım parametreler alır.
Daha önce öğrendiğimiz fonksiyonları tek bir parametre ile birlikte kullanmıştık.
pow()
fonksiyonu ise toplam üç farklı parametre alır.
Ama genellikle bu fonksiyon yalnızca iki parametre ile kullanılır.
Bu fonksiyonu şöyle kullanıyoruz:
>>> pow(12, 2)
144
>>> pow(23, 3)
12167
>>> pow(144, 0.5)
12.0
Gördüğünüz gibi, pow()
fonksiyonunun ilk parametresi asıl sayıyı, ikinci parametresi ise bu sayının hangi kuvvetini hesaplamak istediğimizi gösteriyor.
Bu arada, fonksiyonun parantezleri içinde belirttiğimiz parametreleri birbirinden virgül ile ayırdığımızı gözden kaçırmayın.
Dediğimiz gibi, pow()
fonksiyonu, pek kullanılmayan üçüncü bir parametre daha alır.
Bu fonksiyonun üçüncü parametresi şöyle kullanılır.
Dikkatlice bakın:
>>> pow(16, 2, 2)
0
Bu komut şu anlama gelir:
16 sayısının 2’nci kuvvetini hesapla ve çıkan sayıyı 2’ye bölüp, bölme işleminden kalan sayıyı göster!
16 sayısının 2. kuvveti 256 sayısıdır. 256 sayısını 2’ye böldüğümüzde, bölme işleminin kalanı 0’dır. Yani 256 sayısı 2’ye tam bölünür…
Bir örnek daha verelim:
>>> pow(11, 3, 4)
3
Demek ki, 11 sayısının 3. kuvveti olan 1331 sayısı 4’e bölündüğünde, bölme işleminden kalan sayı 3 imiş…
Dediğimiz gibi, pow()
fonksiyonu genellikle sadece iki parametre ile kullanılır.
Üçüncü parametrenin kullanım alanı oldukça dardır.
Değişkenlere Dair Bazı İpuçları¶
Değişkenin ne demek olduğunu öğrendiğimize göre, değişkenlere dair bazı ufak ipuçları verebiliriz.
Aynı Değere Sahip Değişkenler Tanımlama¶
Şimdi size şöyle bir soru sormama izin verin: Acaba aynı değere sahip iki değişkeni nasıl tanımlayabiliriz? Yani mesela değeri 4 sayısı olan iki farklı değişkeni nasıl belirleyeceğiz?
Aklınıza şöyle bir çözüm gelmiş olabilir:
>>> a = 4
>>> b = 4
Böylece ikisi de 4 değerine sahip a ve b adlı iki farklı değişken tanımlamış olduk. Bu tamamen geçerli bir yöntemdir. Ancak Python’da bu işlemi yapmanın daha kolay bir yolu var. Bakalım:
>>> a = b = 4
Bu kodlar bir öncekiyle tamamen aynı işlevi görür. Yani her iki kod da 4 değerine sahip a ve b değişkenleri tanımlamamızı sağlar:
>>> a
4
>>> b
4
Bu bilgiyi kullanarak mesela bir yıl içindeki her bir ayın çektiği gün sayısını ay adlarına atayabilirsiniz:
>>> ocak = mart = mayıs = temmuz = ağustos = ekim = aralık = 31
>>> nisan = haziran = eylül = kasım = 30
>>> şubat = 28
Böylece bir çırpıda değeri 31 olan yedi adet değişken, değeri 30 olan dört adet değişken, değeri 28 olan bir adet değişken tanımlamış olduk. Bu değişkenlerin değerine nasıl ulaşacağınızı biliyorsunuz:
>>> ocak
31
>>> haziran
30
>>> şubat
28
>>> mayıs
31
>>> ekim
31
>>> eylül
30
Eğer Python’ın aynı anda birden fazla değişkene tek bir değer atama özelliği olmasaydı yukarıdaki kodları şöyle yazmamız gerekirdi:
>>> ocak = 31
>>> şubat = 28
>>> mart = 31
>>> nisan = 30
>>> mayıs = 31
>>> haziran = 30
>>> temmuz = 31
>>> ağustos = 31
>>> eylül = 30
>>> ekim = 31
>>> kasım = 30
>>> aralık = 31
Bu değişkenleri nasıl bir program içinde kullanacağınız tamamen sizin hayal gücünüze kalmış. Mesela bu değişkenleri kullanarak aylara göre doğalgaz faturasını hesaplayan bir program yazabiliriz.
Hemen son gelen doğalgaz faturasını (örn. Mart ayı) elimize alıp inceliyoruz ve bu faturadan şu verileri elde ediyoruz:
Mart ayı doğalgaz faturasına göre sayaçtan ölçülen hacim 346 m3. Demek ki bir ayda toplam 346 m3 doğalgaz harcamışız.
Fatura tutarı 273.87 TL imiş. Yani 346 m3 doğalgaz tüketmenin bedeli 273.87 TL. Buna göre değişkenlerimizi tanımlayalım:
>>> aylık_sarfiyat = 346
>>> fatura_tutarı = 273.87
Bu bilgiyi kullanarak doğalgazın birim fiyatını hesaplayabiliriz. Formülümüz şöyle olmalı:
>>> birim_fiyat = fatura_tutarı / aylık_sarfiyat
>>> birim_fiyat
0.7915317919075144
Demek ki doğalgazın m3 fiyatı (vergilerle birlikte yaklaşık) 0.79 TL’ye karşılık geliyormuş.
Bu noktada günlük ortalama doğalgaz sarfiyatımızı da hesaplamamız gerekiyor:
>>> günlük_sarfiyat = aylık_sarfiyat / mart
>>> günlük_sarfiyat
11.161290322580646
Demek ki Mart ayında günlük ortalama 11 m3 doğalgaz tüketmişiz.
Bütün bu bilgileri kullanarak Nisan ayında gelecek faturayı tahmin edebiliriz:
>>> nisan_faturası = birim_fiyat * günlük_sarfiyat * nisan
>>> nisan_faturası
265.03548387096777
Şubat ayı faturası ise şöyle olabilir:
>>> şubat_faturası = birim_fiyat * günlük_sarfiyat * şubat
>>> şubat_faturası
247.36645161290326
Burada farklı değişkenlerin değerini değiştirerek daha başka işlemler de yapabilirsiniz. Örneğin pratik olması açısından günlük_sarfiyat değişkeninin değerini 15 yaparak hesaplamalarınızı buna göre güncelleyebilirsiniz.
Gördüğünüz gibi, aynı anda birden fazla değişken tanımlayabilmek işlerimizi epey kolaylaştırıyor.
Değişkenlerle ilgili bir ipucu daha verelim…
Değişkenlerin Değerini Takas Etme¶
Diyelim ki, işyerinizdeki personelin unvanlarını tuttuğunuz bir veritabanı var elinizde. Bu veritabanında şuna benzer ilişkiler tanımlı:
>>> osman = "Araştırma Geliştirme Müdürü"
>>> mehmet = "Proje Sorumlusu"
İlerleyen zamanda işvereniniz sizden Osman ve Mehmet’in unvanlarını değiştirmenizi talep edebilir. Yani Osman’ı Proje Sorumlusu, Mehmet’i de Araştırma Geliştirme Müdürü yapmanızı isteyebilir sizden.
Patronunuzun bu isteğini Python’da çok rahat bir biçimde yerine getirebilirsiniz. Dikkatlice bakın:
>>> osman, mehmet = mehmet, osman
Böylece tek hamlede bu iki kişinin unvanlarını takas etmiş oldunuz. Gelin isterseniz değişkenlerin son durumuna bakalım:
>>> osman
'Proje Sorumlusu
>>> mehmet
'Araştırma Geliştirme Müdürü'
Gördüğünüz gibi, osman değişkeninin değerini mehmet’e; mehmet değişkeninin değerini ise osman’a başarıyla verebilmişiz.
Yukarıdaki yöntem Python’ın öteki diller üzerinde önemli bir üstünlüğüdür. Başka programlama dillerinde bu işlemi yapmak için geçici bir değişken tanımlamanız gerekir. Yani mesela:
>>> osman = "Araştırma Geliştirme Müdürü"
>>> mehmet = "Proje Sorumlusu"
Elimizdeki değerler bunlar. Biz şimdi Osman’ın değerini Mehmet’e; Mehmet’in değerini ise Osman’a aktaracağız. Bunun için öncelikle bir geçici değişken tanımlamalıyız:
>>> geçici = "Proje Sorumlusu"
Bu sayede “Proje Sorumlusu” değerini yedeklemiş olduk. Bu işlem sayesinde, takas sırasında bu değeri kaybetmeyeceğiz.
Şimdi Osman’ın değerini Mehmet’e aktaralım:
>>> mehmet = osman
Şimdi elimizde iki tane Araştırma Geliştirme Müdürü olmuş oldu:
>>> mehmet
'Araştırma Geliştirme Müdürü'
>>> osman
'Araştırma Geliştirme Müdürü'
Gördüğünüz gibi, mehmet = osman
kodunu kullanarak mehmet değişkeninin değerini osman değişkeninin değeriyle değiştirdiğimiz için “Proje Sorumlusu” değeri ortadan kayboldu.
Ama biz önceden bu değeri geçici adlı değişkene atadığımız için bu değeri kaybetmemiş olduk.
Şimdi Osman’a geçici değişkeni içinde tuttuğumuz “Proje Sorumlusu” değerini verebiliriz:
>>> osman = geçici
Böylece istediğimiz takas işlemini gerçekleştirmiş olduk. Son durumu kontrol edelim:
>>> osman
'Proje Sorumlusu
>>> mehmet
'Araştırma Geliştirme Müdürü'
Basit bir işlem için ne kadar büyük bir zaman kaybı, değil mi? Ama dediğimiz gibi, Python’da bu şekilde geçici bir değişken atamakla uğraşmamıza hiç gerek yok. Sadece şu formülü kullanarak değişkenlerin değerini takas edebiliriz:
a, b = b, a
Bu şekilde a değişkeninin değerini b değişkenine; b değişkeninin değerini ise a değişkenine vermiş oluyoruz. Eğer bu işlemi geri alıp her şeyi eski haline döndürmek istersek, tahmin edebileceğiniz gibi yine aynı yöntemden yararlanabiliriz:
b, a = a, b
Böylece değişkenler konusunu da oldukça ayrıntılı bir şekilde incelemiş olduk.
Ayrıca bu esnada len()
ve pow()
adlı iki yeni fonksiyon ile ** adlı bir işleç de öğrendik.
Hazır lafı geçmişken, len()
fonksiyonunun bazı kısıtlamalarından söz edelim.
Dediğimiz gibi, bu fonksiyonu kullanarak karakter dizileri içinde toplam kaç adet karakter bulunduğunu hesaplayabiliyoruz.
Örneğin:
>>> kelime = "muvaffakiyet"
>>> len(kelime)
12
Yalnız bu len()
fonksiyonunu sayıların uzunluğunu ölçmek için kullanamıyoruz:
>>> len(123456)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
Gördüğünüz gibi, len()
fonksiyonu, şu ana kadar öğrendiğimiz veri tipleri arasında yalnızca karakter dizileri ile birlikte kullanılabiliyor.
Bu fonksiyonu sayılarla birlikte kullanamıyoruz.
Bu bölümün başında, o anda elimizde bulunan bir verinin tipini bilmemizin çok önemli olduğunu ve Python’da bir verinin tipinin, o veri ile neler yapıp neler yapamayacağınızı belirlediğini söylediğimizi hatırlıyorsunuz, değil mi?
İşte len()
fonksiyonu bu duruma çok güzel bir örnektir.
len()
fonksiyonu sayılarla birlikte kullanılamaz.
Dolayısıyla eğer elinizdeki verinin bir sayı olduğunu bilmezseniz, bu sayıyı len()
fonksiyonu ile birlikte kullanmaya çalışabilir ve bu şekilde programınızın hata vererek çökmesine yol açabilirsiniz.
Ayrıca daha önce de söylediğimiz gibi, len()
fonksiyonunu doğru kullanabilmek için, bu fonksiyonun bize sayı değerli bir çıktı verdiğini de bilmemiz gerekir.
len()
fonksiyonu ile ilgili bu durumu da bir kenara not ettikten sonra yolumuza kaldığımız yerden devam edelim.
Etkileşimli Kabuğun Hafızası¶
Bir önceki bölümde Python’ın etkileşimli kabuğunun nasıl kullanılacağına dair epey örnek verdik ve etkileşimli kabuk üzerinden Python’ın bazı temel araçlarına kısa bir giriş yaptık. Şimdi isterseniz yeri gelmişken Python’ın etkileşimli kabuğunun bir başka yeteneğinden daha söz edelim.
Etkileşimli kabukta _ adlı işaret (alt çizgi işareti), yapılan son işlemin veya girilen son öğenin değerini tutma işlevi görür. Yani:
>>> 2345 + 54355
56700
Eğer bu işlemin ardından _
komutunu verirsek şöyle bir çıktı alırız:
>>> _
56700
Gördüğünüz gibi, _
komutu son girilen öğeyi hafızasında tutuyor.
Bu özellikten çeşitli şekillerde yararlanabilirsiniz:
>>> _ + 15
56715
Burada _
komutunun değeri bir önceki işlemin sonucu olan 56700 değeri olduğu için, _
komutuna 15 eklediğimizde 56715 değerini elde ediyoruz.
_
komutunun değerini tekrar kontrol edelim:
>>> _
56715
Gördüğünüz gibi, _
komutunun değeri artık 56715 sayısıdır…
_
komutu yalnızca sayıları değil, karakter dizilerini de hafızasında tutabilir:
>>> "www"
'www'
>>> _
'www'
>>> _ + ".yazbel.com"
'www.yazbel.com'
Bu işaret öyle çok sık kullanılan bir araç değildir, ama zaman zaman işinizi epey kolaylaştırır.
Yalnız, unutmamamız gereken şey, bu özelliğin sadece etkileşimli kabuk ortamında geçerli olmasıdır.
_
komutunun etkileşimli kabuk ortamı dışında herhangi bir geçerliliği yoktur.
Aslında burada söylenecek daha çok şey var. Ama biz şimdilik bunları sonraki konulara bırakacağız. Zira bu bölümdeki amacımız size konuların her ayrıntısını vermekten ziyade, Python’a ısınmanızı sağlamaktır.
print() Fonksiyonu¶
Geçen bölümde bir yandan Python’ın etkileşimli kabuğunu yakından tanıyıp bu
vesileyle bazı önemli fonksiyon ve araçları öğrenirken, öbür yandan bu
öğrendiklerimizi kullanarak örnek programlar yazdık. Gördüğünüz gibi, azıcık bir
bilgiyle dahi az çok işe yarar programlar yazmak mümkün olabiliyor. Daha yararlı
programlar yazabilmek için henüz öğrenmemiz gereken pek çok şey var. İşte bu
bölümde, ‘daha yararlı programlar yazmamızı’ sağlayacak çok önemli bir araçtan
söz edeceğiz. Öneminden dolayı ayrıntılı bir şekilde anlatacağımız bu aracın adı
print()
fonksiyonu.
Elbette bu bölümde sadece print()
fonksiyonundan bahsetmeyeceğiz. Bu bölümde
print()
fonksiyonunun yanısıra Python’daki bazı önemli temel konuları da ele
alacağız. Mesela bu bölümde Python’daki karakter dizilerine ve sayılara ilişkin
çok önemli bilgiler vereceğiz. Ayrıca print()
fonksiyonu vesilesiyle
Python’daki ‘fonksiyon’ konusuna da sağlam bir giriş yapmış, bu kavram ile
ilgili ilk bilgilerimizi almış olacağız. Sözün özü, bu bölüm bizim için, deyim
yerindeyse, tam anlamıyla bir dönüm noktası olacak.
O halde isterseniz lafı daha fazla uzatmadan işe print()
fonksiyonunun ne
olduğu ve ne işe yaradığını anlatarak başlayalım.
Nedir, Ne İşe Yarar?¶
Şimdiye kadar etkileşimli kabukta gerek karakter dizilerini gerekse sayıları doğrudan ekrana yazdık. Yani şöyle bir şey yaptık:
>>> "Python programlama dili"
'Python programlama dili'
>>> 6567
6567
Etkileşimli kabuk da, ekrana yazdığımız bu karakter dizisi ve sayıyı doğrudan
bize çıktı olarak verdi. Ancak ilerde Python kodlarımızı bir dosyaya kaydedip
çalıştırdığımızda da göreceğiniz gibi, Python’ın ekrana çıktı verebilmesi için
yukarıdaki kullanım yeterli değildir. Yani yukarıdaki kullanım yalnızca
etkileşimli kabukta çalışır. Bu kodları bir dosyaya kaydedip çalıştırmak
istediğimizde hiçbir çıktı alamayız. Python’da yazdığımız şeylerin ekrana çıktı
olarak verilebilmesi için print()
adlı özel bir fonksiyondan yararlanmamız
gerekir.
O halde gelin bu print()
fonksiyonunun ne işe yaradığını ve nasıl
kullanıldığını anlamaya çalışalım:
print()
de tıpkı daha önce gördüğümüz type()
, len()
ve pow()
gibi bir fonksiyondur. Fonksiyonları ilerde daha ayrıntılı bir şekilde
inceleyeceğimizi söylemiştik hatırlarsanız. O yüzden fonksiyon kelimesine
takılarak, burada anlattığımız şeylerin kafanızı karıştırmasına, moralinizi
bozmasına izin vermeyin.
print()
fonksiyonunun görevi ekrana çıktı vermemizi sağlamaktır. Hemen
bununla ilgili bir örnek verelim:
>>> print("Python programlama dili")
Python programlama dili
Bildiğiniz gibi burada gördüğümüz “Python programlama dili” bir karakter
dizisidir. İşte print()
fonksiyonunun görevi bu karakter dizisini ekrana
çıktı olarak vermektir. Peki bu karakter dizisini print()
fonksiyonu olmadan
yazdığımızda da ekrana çıktı vermiş olmuyor muyuz? Aslında olmuyoruz. Dediğimiz
gibi, ilerde programlarımızı dosyalara kaydedip çalıştırdığımızda, başında
print()
olmayan ifadelerin çıktıda görünmediğine şahit olacaksınız.
Daha önce de dediğimiz gibi, etkileşimli kabuk bir test ortamı olması açısından
rahat bir ortamdır. Bu sebeple bu ortamda ekrana çıktı verebilmek için
print()
fonksiyonunu kullanmak zorunda değilsiniz. Yani başında print()
olsa da olmasa da etkileşimli kabuk ekrana yazdırmak istediğiniz şeyi yazdırır.
Ama iyi bir alışkanlık olması açısından, ekrana herhangi bir şey
yazdıracağınızda ben size print()
fonksiyonunu kullanmanızı tavsiye ederim.
print()
son derece güçlü bir fonksiyondur. Gelin isterseniz bu güçlü ve
faydalı fonksiyonu derin derin incelemeye koyulalım.
Nasıl Kullanılır?¶
Yukarıda verdiğimiz örnekte ilk gözümüze çarpan şey, karakter dizisini
print()
fonksiyonunun parantezleri içine yazmış olmamızdır. Biz bir
fonksiyonun parantezleri içinde belirtilen öğelere ‘parametre’ dendiğini geçen
bölümde öğrenmiştik. Tıpkı öğrendiğimiz öteki fonksiyonlar gibi, print()
fonksiyonu da birtakım parametreler alır.
Bu arada print()
fonksiyonunun parantezini açıp parametreyi yazdıktan sonra,
parantezi kapatmayı unutmuyoruz. Python programlama diline yeni başlayanların,
hatta bazen deneyimli programcıların bile en sık yaptığı hatalardan biri
açtıkları parantezi kapatmayı unutmalarıdır.
Elbette, eğer istersek burada doğrudan “Python programlama dili” adlı karakter
dizisini kullanmak yerine, önce bu karakter dizisini bir değişkene atayıp, sonra
da print()
fonksiyonunun parantezleri içinde bu değişkeni kullanabiliriz.
Yani:
>>> dil = "Python programlama dili"
>>> print(dil)
Python programlama dili
Bu arada, hem şimdi verdiğimiz, hem de daha önce yazdığımız örneklerde bir şey dikkatinizi çekmiş olmalı. Şimdiye kadar verdiğimiz örneklerde karakter dizilerini hep çift tırnakla gösterdik. Ama aslında tek seçeneğimiz çift tırnak değildir. Python bize üç farklı tırnak seçeneği sunar:
Tek tırnak (’ ‘)
Çift tırnak (” “)
Üç tırnak (“”” “””)
Dolayısıyla yukarıdaki örneği üç farklı şekilde yazabiliriz:
>>> print('Python programlama dili')
Python programlama dili
>>> print("Python programlama dili")
Python programlama dili
>>> print("""Python programlama dili""")
Python programlama dili
Gördüğünüz gibi çıktılar arasında hiçbir fark yok.
Peki çıktılarda hiçbir fark yoksa neden üç farklı tırnak çeşidi var?
İsterseniz bu soruyu bir örnek üzerinden açıklamaya çalışalım. Diyelim ki ekrana şöyle bir çıktı vermek istiyoruz:
Python programlama dilinin adı "piton" yılanından gelmez
Eğer bu cümleyi çift tırnaklar içinde gösterirsek programımız hata verecektir:
>>> print("Python programlama dilinin adı "piton" yılanından gelmez")
File "<stdin>", line 1
print("Python programlama dilinin adı "piton" yılanından gelmez")
^
SyntaxError: invalid syntax
Bunun sebebi, cümle içinde geçen ‘piton’ kelimesinin de çift tırnaklar içinde gösterilmiş olmasıdır. Cümlenin, yani karakter dizisinin kendisi de çift tırnak içinde gösterildiği için Python, karakter dizisini başlatan ve bitiren tırnakların hangisi olduğunu ayırt edemiyor. Yukarıdaki cümleyi en kolay şu şekilde ekrana yazdırabiliriz:
>>> print('Python programlama dilinin adı "piton" yılanından gelmez')
Python programlama dilinin adı "piton" yılanından gelmez
Burada karakter dizisini tek tırnak içine aldık. Karakter dizisi içinde geçen ‘piton’ kelimesi çift tırnak içinde olduğu için, karakter dizisini başlatıp bitiren tırnaklarla ‘piton’ kelimesindeki tırnakların birbirine karışması gibi bir durum söz konusu değildir.
Bir de şöyle bir örnek verelim: Diyelim ki aşağıdaki gibi bir çıktı elde etmek istiyoruz:
İstanbul'un 5 günlük hava durumu tahmini
Eğer bu karakter dizisini tek tırnak işaretleri içinde belirtirseniz Python size bir hata mesajı gösterecektir:
>>> print('İstanbul'un 5 günlük hava durumu tahmini')
File "<stdin>", line 1
print('İstanbul'un 5 günlük hava durumu tahmini')
^
SyntaxError: invalid syntax
Bu hatanın sebebi ‘İstanbul’un’ kelimesi içinde geçen kesme işaretidir. Tıpkı bir önceki örnekte olduğu gibi, Python karakter dizisini başlatan ve bitiren tırnakların hangisi olduğunu kestiremiyor. Python, karakter dizisinin en başındaki tek tırnak işaretinin ardından ‘İstanbul’un’ kelimesi içindeki kesme işaretini görünce karakter dizisinin burada sona erdiğini zannediyor. Ancak karakter dizisini soldan sağa doğru okumaya devam edince bir yerlerde bir terslik olduğunu düşünüyor ve bize bir hata mesajı göstermekten başka çaresi kalmıyor. Yukarıdaki karakter dizisini en kolay şöyle tanımlayabiliriz:
>>> print("İstanbul'un 5 günlük hava durumu tahmini")
İstanbul'un 5 günlük hava durumu tahmini
Burada da, karakter dizisi içinde geçen kesme işaretine takılmamak için karakter dizimizi çift tırnak işaretleri içine alıyoruz.
Yukarıdaki karakter dizilerini düzgün bir şekilde çıktı verebilmek için üç tırnak işaretlerinden de yararlanabiliriz:
>>> print("""Python programlama dilinin adı "piton" yılanından gelmez""")
Python programlama dilinin adı "piton" yılanından gelmez
>>> print("""İstanbul'un 5 günlük hava durumu tahmini""")
İstanbul'un 5 günlük hava durumu tahmini
Bütün bu örneklerden sonra kafanızda şöyle bir düşünce uyanmış olabilir:
Görünüşe göre üç tırnak işaretiyle her türlü karakter dizisini hatasız bir şekilde ekrana çıktı olarak verebiliyoruz. O zaman ben en iyisi bütün karakter dizileri için üç tırnak işaretini kullanayım!
Elbette, eğer isterseniz pek çok karakter dizisi için üç tırnak işaretini kullanabilirsiniz. Ancak Python’da karakter dizileri tanımlanırken genellikle tek tırnak veya çift tırnak işaretleri kullanılır. Üç tırnak işaretlerinin asıl kullanım yeri ise farklıdır. Peki nedir bu üç tırnak işaretlerinin asıl kullanım yeri?
Üç tırnak işaretlerini her türlü karakter dizisiyle birlikte kullanabiliyor olsak da, bu tırnak tipi çoğunlukla sadece birden fazla satıra yayılmış karakter dizilerini tanımlamada kullanılır. Örneğin şöyle bir ekran çıktısı vermek istediğinizi düşünün:
[H]=========HARMAN========[-][o][x]
| |
| Programa Hoşgeldiniz! |
| Sürüm 0.8 |
| Devam etmek için herhangi |
| bir düğmeye basın. |
| |
|=================================|
Böyle bir çıktı verebilmek için eğer tek veya çift tırnak kullanmaya kalkışırsanız epey eziyet çekersiniz. Bu tür bir çıktı vermenin en kolay yolu üç tırnakları kullanmaktır:
>>> print("""
... [H]=========HARMAN========[-][o][x]
... | |
... | Programa Hoşgeldiniz! |
... | Sürüm 0.8 |
... | Devam etmek için herhangi |
... | bir düğmeye basın. |
... | |
... |=================================|
... """)
Burada bazı şeyler dikkatinizi çekmiş olmalı. Gördüğünüz gibi, üç tırnaklı yapı öteki tırnak tiplerine göre biraz farklı davranıyor. Şimdi şu örneğe bakın:
>>> print("""Game Over!
...
Buraya çok dikkatli bakın. Karakter dizisine üç tırnakla başladıktan sonra, kapanış tırnağını koymadan Enter tuşuna bastığımızda >>> işareti … işaretine dönüştü. 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ış tırnağı koyulmadan Enter tuşuna basıldığında >>> işaretinin … işaretine dönüşmesi üç tırnağa özgü bir durumdur. Eğer aynı şeyi tek veya çift tırnaklarla yapmaya çalışırsanız programınız 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
Üç tırnak işaretlerinin tırnak kapanmadan Enter tuşuna basıldığında hata vermeme özelliği sayesinde, bu tırnak tipi özellikle birden fazla satıra yayılmış karakter dizilerinin gösterilmesi için birebirdir.
Gelin isterseniz üç tırnak kullanımına ilişkin bir örnek daha verelim:
>>> print("""Python programlama dili Guido Van Rossum
... adlı Hollandalı bir programcı tarafından 90’lı
... yılların başında geliştirilmeye başlanmıştır. Çoğu
... insan, isminin "Python" olmasına bakarak, bu programlama
... dilinin, adını piton yılanından aldığını düşünür.
... Ancak zannedildiğinin aksine bu programlama dilinin
... adı piton yılanından gelmez.""")
Python programlama dili Guido Van Rossum
adlı Hollandalı bir programcı tarafından 90'lı
yılların başında geliştirilmeye başlanmıştır. Çoğu
insan, isminin "Python" olmasına bakarak, bu programlama
dilinin, adını piton yılanından aldığını düşünür.
Ancak zannedildiğinin aksine bu programlama dilinin
dı piton yılanından gelmez.
Elbette eğer istersek bu metni önce bir değişkene atamayı da tercih edebiliriz:
>>> python_hakkinda = """Python programlama dili Guido Van Rossum
... adlı Hollandalı bir programcı tarafından 90’lı
... yılların başında geliştirilmeye başlanmıştır. Çoğu
... insan, isminin "Python" olmasına bakarak, bu programlama
... dilinin, adını piton yılanından aldığını düşünür.
... Ancak zannedildiğinin aksine bu programlama dilinin
... adı piton yılanından gelmez."""
>>> print(python_hakkinda)
Python programlama dili Guido Van Rossum
adlı Hollandalı bir programcı tarafından 90'lı
yılların başında geliştirilmeye başlanmıştır. Çoğu
insan, isminin "Python" olmasına bakarak, bu programlama
dilinin, adını piton yılanından aldığını düşünür.
Ancak zannedildiğinin aksine bu programlama dilinin
adı piton yılanından gelmez.
Siz yukarıdaki çıktıyı tek veya çift tırnak kullanarak nasıl ekrana yazdırabileceğinizi düşünedurun, biz önemli bir konuya geçiş yapalım!
Bir Fonksiyon Olarak print()¶
print()
ifadesinin bir fonksiyon olduğunu söylemiştik hatırlarsanız.
Dediğimiz gibi, fonksiyonlarla ilgili ayrıntılı açıklamaları ilerleyen derslerde
vereceğiz. Ancak şimdi dilerseniz bundan sonra anlatacaklarımızı daha iyi
kavrayabilmemiz için, fonksiyonlar hakkında bilmemiz gereken bazı temel şeyleri
öğrenmeye çalışalım.
Gördüğünüz gibi, print()
fonksiyonunu şöyle kullanıyoruz:
>>> print("Aramak istediğiniz kelimeyi yazın: ")
Burada print()
bir fonksiyon, “Aramak istediğiniz kelimeyi yazın:” adlı
karakter dizisi ise bu fonksiyonun parametresidir. Daha önce len()
adlı
başka bir fonksiyon daha öğrenmiştik hatırlarsanız. Onu da şöyle kullanıyorduk:
>>> len("elma")
Burada da len()
bir fonksiyon, “elma” adlı karakter dizisi ise bu
fonksiyonun parametresidir. Aslında biçim olarak print()
ve len()
fonksiyonlarının birbirinden hiçbir farkı olmadığını görüyorsunuz.
Daha önce söylediğimiz ve bu örneklerden de anladığımız gibi, bir fonksiyonun
parantezleri içinde belirtilen öğelere parametre adı veriliyor. Mesela aşağıdaki
örnekte print()
fonksiyonunu tek bir parametre ile kullanıyoruz:
>>> print('En az 8 haneli bir parola belirleyin.')
print()
fonksiyonu, tıpkı pow()
fonksiyonu gibi, birden fazla parametre alabilir:
>>> print('Fırat', 'Özgül')
Fırat Özgül
Bu örnekte bizim için çıkarılacak çok dersler var. Bir defa burada print()
fonksiyonunu iki farklı parametre ile birlikte kullandık. Bunlardan ilki Fırat
adlı bir karakter dizisi, ikincisi ise Özgül adlı başka bir karakter dizisi.
Python’ın bu iki karakter dizisini nasıl birleştirdiğine dikkat edin.
print()
fonksiyonu bu iki karakter dizisini çıktı olarak verirken aralarına
da birer boşluk yerleştirdi. Ayrıca, geçen derste de vurguladığımız gibi,
parametrelerin birbirinden virgül ile ayrıldığını da gözden kaçırmıyoruz.
Gelin bununla ilgili bir iki örnek daha verelim elimizin alışması için:
>>> print("Python", "Programlama", "Dili")
Python Programlama Dili
>>> print('Fırat', 'Özgül', 'Adana', 1980)
Fırat Özgül Adana 1980
Bu arada dikkatinizi önemli bir noktaya çekmek istiyorum. Yukarıdaki örneklerde bazen tek tırnak, bazen de çift tırnak kullandık. Daha önce de söylediğimiz gibi, hangi tırnak tipini kullandığımız önemli değildir. Python hangi tırnak tipini kullandığımızdan ziyade, tırnak kullanımında tutarlı olup olmadığımızla ilgilenir. Yani Python için önemli olan, karakter dizisini hangi tırnakla başlatmışsak, o tırnakla bitirmemizdir. Yani şu tip kullanımlar geçerli değildir:
>>> print("karakter dizisi')
>>> print('karakter dizisi")
Karakter dizisini tanımlamaya başlarken kullandığımız tırnak tipi ile karakter dizisini tanımlamayı bitirirken kullandığımız tırnak tipi birbirinden farklı olduğu için bu iki kullanım da hata verecektir.
print() Fonksiyonunun Parametreleri¶
Şimdiye kadar verdiğimiz örneklerde belki çok da belli olmuyordur, ama aslında
print()
fonksiyonu son derece güçlü bir araçtır. İşte şimdi biz bu
fonksiyonun gücünü gözler önüne seren özelliklerini incelemeye başlayacağız. Bu
bölümü dikkatle takip etmeniz, ilerde yapacağımız çalışmaları daha rahat
anlayabilmeniz açısından büyük önem taşır.
sep¶
print()
fonksiyonu ile ilgili olarak yukarıda verdiğimiz örnekleri
incelediğimizde, bu fonksiyonun kendine özgü bir davranış şekli olduğunu
görüyoruz. Mesela bir önceki bölümde verdiğimiz şu örneğe bakalım:
>>> print('Fırat', 'Özgül')
Fırat Özgül
Burada print()
fonksiyonunu iki farklı parametre ile birlikte kullandık. Bu
fonksiyon, kendisine verdiğimiz bu parametreleri belli bir düzene göre
birbiriyle birleştirdi. Bu düzen gereğince print()
, kendisine verilen
parametreleri birleştirirken, parametreler arasına bir boşluk yerleştiriyor.
Bunu daha net görmek için şöyle bir örnek daha verelim:
>>> print("Python", "PHP", "C++", "C", "Erlang")
Python PHP C++ C Erlang
Gördüğünüz gibi, print()
fonksiyonu gerçekten de, kendisine verilen
parametreleri birleştirirken, parametrelerin her biri arasına bir boşluk
yerleştiriyor. Halbuki bu boşluğu biz talep etmedik! Python bize bu boşluğu
eşantiyon olarak verdi. Çoğu durumda istediğimiz şey bu olacaktır, ama bazı
durumlarda bu boşluğu istemeyebiliriz. Örneğin:
>>> print("http://", "www.", "istihza.", "com")
http:// www. istihza. com
Ya da boşluk karakteri yerine daha farklı bir karakter kullanmak istiyor da olabiliriz. Peki böyle bir durumda ne yapmamız gerekir?
İşte bu noktada bazı özel araçlardan yararlanarak print()
fonksiyonunun
öntanımlı davranış kalıpları üzerinde değişiklikler yapabiliriz.
Peki nedir print()
fonksiyonunu özelleştirmemizi sağlayacak bu araçlar?
Hatırlarsanız, Python’da fonksiyonların parantezleri içindeki değerlere
parametre adı verildiğini söylemiştik. Mesela print()
fonksiyonunu bir ya da
daha fazla parametre ile birlikte kullanabileceğimizi biliyoruz:
>>> print("Mehmet", "Öz", "İstanbul", "Çamlıca", 156, "/", 45)
Mehmet Öz İstanbul Çamlıca 156 / 45
print()
fonksiyonu içinde istediğimiz sayıda karakter dizisi ve/veya sayı
değerli parametre kullanabiliriz.
Fonksiyonların bir de daha özel görünümlü parametreleri vardır. Mesela
print()
fonksiyonunun sep adlı özel bir parametresi bulunur. Bu parametre
print()
fonksiyonunda görünmese bile her zaman oradadır. Yani diyelim ki
şöyle bir kod yazdık:
>>> print("http://", "www.", "google.", "com")
Burada herhangi bir sep parametresi görmüyoruz. Ancak Python yukarıdaki kodu aslında şöyle algılar:
>>> print("http://", "www.", "google.", "com", sep=" ")
sep ifadesi, İngilizcede separator (ayırıcı, ayraç) kelimesinin
kısaltmasıdır. Dolayısıyla print()
fonksiyonundaki bu sep parametresi,
ekrana basılacak öğeler arasına hangi karakterin yerleştirileceğini gösterir. Bu
parametrenin öntanımlı değeri bir adet boşluk karakteridir (” “). Yani siz bu
özel parametrenin değerini başka bir şeyle değiştirmezseniz, Python bu
parametrenin değerini bir adet boşluk karakteri olarak alacak ve ekrana
basılacak öğeleri birbirinden birer boşlukla ayıracaktır. Ancak eğer biz
istersek bu sep parametresinin değerini değiştirebiliriz. Böylece Python,
karakter dizilerini birleştirirken araya boşluk değil, bizim istediğimiz başka
bir karakteri yerleştirebilir. Gelin şimdi bu parametrenin değerini nasıl
değiştireceğimizi görelim:
>>> print("http://", "www.", "istihza.", "com", sep="")
http://www.istihza.com
Gördüğünüz gibi, karakter dizilerini başarıyla birleştirip, geçerli bir internet adresi elde ettik.
Burada yaptığımız şey aslında çok basit. Sadece sep parametresinin ‘bir adet boşluk karakteri’ olan öntanımlı değerini silip, yerine ‘boş bir karakter dizisi’ değerini yazdık. Bu iki kavramın birbirinden farklı olduğunu söylediğimizi hatırlıyorsunuz, değil mi?
Gelin bir örnek daha yapalım:
>>> print("T", "C", sep=".")
T.C
Burada Python’a şöyle bir emir vermiş olduk:
“T” ve “C” karakter dizilerini birbiriyle birleştir! Bunu yaparken de bu karakter dizilerinin arasına nokta işareti yerleştir!
sep parametresinin öteki parametrelerden farkı her zaman ismiyle birlikte kullanılmasıdır. Zaten teknik olarak da bu tür parametrelere ‘isimli parametreler’ adı verilir. Örneğin:
>>> print("Adana", "Mersin", sep="-")
Adana-Mersin
Eğer burada sep parametresinin ismini belirtmeden, doğrudan parametrenin değerini yazarsak, bu değerin öteki parametrelerden hiçbir farkı kalmayacaktır:
>>> print("Adana", "Mersin", "-")
Adana Mersin -
Gelin isterseniz bu parametreyle ilgili bir örnek daha yapalım:
‘Bir mumdur iki mumdur…’ diye başlayan türküyü biliyorsunuzdur. Şimdi bu türküyü Python’la nasıl yazabileceğimizi görelim!
>>> print("bir", "iki", "üç", "dört", "on dört", sep="mumdur")
birmumdurikimumdurüçmumdurdörtmumduron dört
Burada bir terslik olduğu açık! Karakter dizileri birbirlerine sıkışık düzende birleştirildi. Bunların arasında birer boşluk olsa tabii daha iyi olurdu. Ancak biliyorsunuz sep parametresinin öntanımlı değerini silip, yerine “mumdur” değerini yerleştirdiğimiz için, Python’ın otomatik olarak yerleştirdiği boşluk karakteri kayboldu. Ama eğer istersek o boşluk karakterlerini kendimiz de ayarlayabiliriz:
>>> print("bir", "iki", "üç", "dört", "on dört", sep=" mumdur ")
bir mumdur iki mumdur üç mumdur dört mumdur on dört
Gördüğünüz gibi, sep parametresine verdiğimiz “mumdur” değerinin sağında ve solunda birer boşluk bırakarak sorunumuzu çözebildik. Bu sorunu çözmenin başka bir yolu daha var. Hatırlarsanız etkileşimli kabukta ilk örneklerimizi verirken karakter dizilerini birleştirmek için + işaretinden de yararlanabileceğimizi söylemiştik. Dolayısıyla sep parametresini şöyle de yazabiliriz:
>>> print("bir", "iki", "üç", "dört", "on dört", sep=" " + "mumdur" + " ")
Burada da, “mumdur” adlı karakter dizisinin başında ve sonunda birer boşluk bırakmak yerine, gerekli boşlukları + işareti yardımıyla bu karakter dizisine birleştirdik. Hatta istersek + işlecini kullanmak zorunda olmadığımızı dahi biliyorsunuz:
>>> print("bir", "iki", "üç", "dört", "on dört", sep=" " "mumdur" " ")
Ama gördüğünüz gibi bir problemimiz daha var. Türkünün sözleri şu şekilde olmalıydı:
bir mumdur iki mumdur üç mumdur dört mumdur on dört mumdur
Ama sondaki ‘mumdur’ kelimesi yukarıdaki çıktıda yok. Normal olan da bu aslında.
sep parametresi, karakter dizilerinin arasına bir değer yerleştirir.
Karakter dizilerinin son tarafıyla ilgilenmez. Bu iş için print()
fonksiyonu
başka bir parametreye sahiptir.
Bu arada, yukarıdaki örneklerde hep karakter dizilerini kullanmış olmamız sizi yanıltmasın. sep parametresi yalnızca karakter dizilerinin değil sayıların arasına da istediğiniz bir değerin yerleştirilmesini sağlayabilir. Mesela:
>>> print(1, 2, 3, 4, 5, sep="-")
1-2-3-4-5
Ancak sep parametresine değer olarak yalnızca karakter dizilerini ve None adlı özel bir sözcüğü verebiliriz. (None sözcüğünden ileride söz edeceğiz):
>>> 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
Gördüğünüz gibi, sep parametresine bir sayı olan 0 değerini veremiyoruz.
Peki bu parametreye None değeri verirsek ne olur? Bu parametreye None değeri
verildiğinde, print()
fonksiyonu bu parametre için öntanımlı değeri (yani
bir adet boşluk) kullanır:
>>> print('a', 'b', sep=None)
a b
Eğer amacınız parametreleri birbirine bitiştirmekse, yani sep parametresinin öntanımlı değeri olan boşluk karakterini ortadan kaldırmaksa, sep parametresine boş bir karakter dizisi vermeniz gerektiğini biliyorsunuz:
>>> print('a', 'b', sep='')
ab
print()
fonksiyonunun sep parametresini bütün ayrıntılarıyla
incelediğimize göre, bu fonksiyonun bir başka özel parametresinden söz
edebiliriz.
end¶
Bir önceki bölümde şöyle bir laf etmiştik:
print()
fonksiyonun sep adlı özel bir parametresi bulunur. Bu parametreprint()
fonksiyonunda görünmese bile her zaman oradadır.
Aynı bu şekilde, print()
fonksiyonunun end adlı özel bir parametresi daha
bulunur. Tıpkı sep parametresi gibi, end parametresi de print()
fonksiyonunda görünmese bile her zaman oradadır.
Bildiğiniz gibi, sep parametresi print()
fonksiyonuna verilen parametreler
birleştirilirken araya hangi karakterin gireceğini belirliyordu. end
parametresi ise bu parametrelerin sonuna neyin geleceğini belirler.
print()
fonksiyonu öntanımlı olarak, parametrelerin sonuna ‘satır başı
karakteri’ ekler. Peki bu satır başı karakteri (veya ‘yeni satır karakteri’)
denen şey de ne oluyor?
Dilerseniz bunu bir örnek üzerinde görelim.
Şöyle bir kodumuz olsun:
>>> print("Pardus ve Ubuntu birer GNU/Linux dağıtımıdır.")
Bu kodu yazıp Enter tuşuna bastığımız anda print()
fonksiyonu iki farklı
işlem gerçekleştirir:
Öncelikle karakter dizisini ekrana yazdırır.
Ardından bir alt satıra geçip bize >>> işaretini gösterir.
İşte bu ikinci işlem, karakter dizisinin sonunda bir adet satır başı karakteri
olmasından, daha doğrusu print()
fonksiyonunun, satır başı karakterini
karakter dizisinin sonuna eklemesinden kaynaklanır. Bu açıklama biraz kafa
karıştırıcı gelmiş olabilir. O halde biraz daha açıklayalım. Şu örneğe bakın:
>>> print("Pardus\nUbuntu")
Pardus
Ubuntu
Burada “Pardus” ve “Ubuntu” karakter dizilerinin tam ortasında çok özel bir karakter dizisi daha görüyorsunuz. Bu karakter dizisi şudur: \n. İşte bu özel karakter dizisine satır başı karakteri (newline) adı verilir. Bu karakterin görevi, karakter dizisini, bulunduğu noktadan bölüp, karakter dizisinin geri kalanını bir alt satıra geçirmektir. Zaten çıktıda da bu işlevi yerine getirdiğini görüyorsunuz. Karakter dizisi “Pardus” kısmından sonra ikiye bölünüyor ve bu karakter dizisinin geri kalan kısmı olan “Ubuntu” karakter dizisi bir alt satıra yazdırılıyor. Bunu daha iyi anlamak için bir örnek daha verelim:
>>> print("birinci satır\nikinci satır\nüçüncü satır")
birinci satır
ikinci satır
üçüncü satır
Peki size bir soru sorayım: Acaba yukarıdaki kodları daha verimli bir şekilde nasıl yazabiliriz?
Evet, doğru tahmin ettiniz… Tabii ki sep parametresini kullanarak:
>>> print("birinci satır", "ikinci satır", "üçüncü satır", sep="\n")
birinci satır
ikinci satır
üçüncü satır
Burada yaptığımız şey çok basit. sep parametresinin değerini \n, yani yeni satır karakteri (veya satır başı karakteri) olarak değiştirdik. Böylece karakter dizileri arasına birer \n karakteri yerleştirerek her bir karakter dizisinin farklı satıra yazdırılmasını sağladık.
İşte end parametresinin öntanımlı değeri de bu \n karakteridir ve bu
parametre print()
fonksiyonunda görünmese bile her zaman oradadır.
Yani diyelim ki şöyle bir kod yazdık:
>>> print("Bugün günlerden Salı")
Burada herhangi bir end parametresi görmüyoruz. Ancak Python yukarıdaki kodu aslında şöyle algılar:
>>> print("Bugün günlerden Salı", end="\n")
Biraz önce de dediğimiz gibi, bu kodu yazıp Enter tuşuna bastığımız anda
print()
fonksiyonu iki farklı işlem gerçekleştirir:
Öncelikle karakter dizisini ekrana yazdırır.
Ardından bir alt satıra geçip bize >>> işaretini gösterir.
Bunun ne demek olduğunu anlamak için end parametresinin değerini değiştirmemiz yeterli olacaktır:
>>> print("Bugün günlerden Salı", end=".")
Bugün günlerden Salı.>>>
Gördüğünüz gibi, end parametresinin öntanımlı değeri olan \n karakterini
silip yerine . (nokta) işareti koyduğumuz için, komutu yazıp Enter tuşuna
bastığımızda print()
fonksiyonu satır başına geçmedi. Yeni satıra geçebilmek
için Enter tuşuna kendimiz basmalıyız. Elbette, eğer yukarıdaki kodları şöyle
yazarsanız, print()
fonksiyonu hem karakter dizisinin sonuna nokta
ekleyecek, hem de satır başına geçecektir:
>>> print("Bugün günlerden Salı", end=".\n")
Bugün günlerden Salı.
Şimdi bu öğrendiklerimizi türkümüze uygulayalım:
>>> print("bir", "iki", "üç", "dört", "on dört",
... sep=" mumdur ", end=" mumdur\n")
Not
Burada kodlarımızın sağa doğru çirkin bir şekilde uzamasını engellemek için “on dört” karakter dizisini yazıp virgülü koyduktan sonra Enter tuşuna basarak bir alt satıra geçtik. Bir alt satıra geçtiğimizde >>> işaretinin … işaretine dönüştüğüne dikkat edin. Python’da doğru kod yazmak kadar, yazdığımız kodların düzgün görünmesi de önemlidir. O yüzden yazdığımız her bir kod satırının mümkün olduğunca 79 karakteri geçmemesini sağlamalıyız. Eğer yazdığınız bir satır 79 karakteri aşıyorsa, aşan kısmı yukarıda gösterdiğimiz şekilde alt satıra alabilirsiniz.
end parametresi de, tıpkı sep parametresi gibi, her zaman ismiyle birlikte kullanılması gereken bir parametredir. Yani eğer end parametresinin ismini belirtmeden sadece değerini kullanmaya çalışırsak Python ne yapmaya çalıştığımızı anlayamaz.
Yine tıpkı sep parametresi gibi, end parametresinin değeri 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
Gördüğünüz gibi, end parametresine bir sayı olan 0 değerini veremiyoruz.
Eğer bu parametreye None değeri verirsek, tıpkı sep parametresinde olduğu
gibi, print()
fonksiyonu bu parametre için öntanımlı değeri (yani satır başı
karakteri) kullanır:
>>> print('a', 'b', end=None)
a b
Eğer amacınız yeni satıra geçilmesini engellemekse, yani end parametresinin öntanımlı değeri olan \n kaçış dizisini ortadan kaldırmaksa, end parametresine boş bir karakter dizisi vermelisiniz:
>>> print('a', 'b', end='')
a b>>>
file¶
Not
Burada henüz öğrenmediğimiz bazı şeyler göreceksiniz. Hiç endişe etmeyin. Bunları ilerde bütün ayrıntılarıyla öğreneceğiz. Şimdilik konu hakkında biraz olsun fikir sahibi olmanızı sağlayabilirsek kendimizi başarılı sayacağız.
print()
fonksiyonunun sep ve end dışında üçüncü bir özel parametresi
daha bulunur. Bu parametrenin adı file’dır. Görevi ise, print()
fonksiyonuna verilen karakter dizisi ve/veya sayıların, yani parametrelerin
nereye yazılacağını belirtmektir.
Bu parametrenin öntanımlı değeri sys.stdout’tur. Peki bu ne anlama geliyor? sys.stdout, ‘standart çıktı konumu’ anlamına gelir. Peki ‘standart çıktı konumu’ ne demek?
Standart çıktı konumu; bir programın, ürettiği çıktıları verdiği yerdir. Aslında bu kavramın ne demek olduğu adından da anlaşılıyor:
standart çıktı konumu = çıktıların standart olarak verildiği konum.
Mesela Python öntanımlı olarak, ürettiği çıktıları ekrana verir. Eğer o anda
etkileşimli kabukta çalışıyorsanız, Python ürettiği çıktıları etkileşimli kabuk
üzerinde gösterir. Eğer yazdığınız bir programı komut satırında
çalıştırıyorsanız, üretilen çıktılar komut satırında görünür. Dolayısıyla
Python’ın standart çıktı konumu etkileşimli kabuk veya komut satırıdır. Yani
print()
fonksiyonu yardımıyla bastığınız çıktılar etkileşimli kabukta ya da
komut satırında görünecektir.
Şimdi bu konuyu daha iyi anlayabilmek için birkaç örnek yapalım.
Normal şartlar altında print()
fonksiyonunun çıktısını etkileşimli kabukta
görürüz:
>>> print("Ben Python, Monty Python!")
Ben Python, Monty Python!
Ama eğer istersek print()
fonksiyonunun, çıktılarını ekrana değil, bir
dosyaya yazdırmasını da sağlayabiliriz. Mesela biz şimdi print()
fonksiyonunun deneme.txt adlı bir dosyaya çıktı vermesini sağlayalım.
Bunun için sırasıyla şu kodları yazalım:
>>> dosya = open("deneme.txt", "w")
>>> print("Ben Python, Monty Python!", file=dosya)
>>> dosya.close()
Herhangi bir çıktı almadınız, değil mi? Evet. Çünkü yazdığımız bu kodlar
sayesinde print()
fonksiyonu, çıktılarını deneme.txt adlı bir dosyaya
yazdırdı.
Gelin isterseniz yukarıdaki kodları satır satır inceleyelim:
1. Öncelikle deneme.txt adlı bir dosya oluşturduk ve bu dosyayı dosya adlı
bir değişkene atadık. Burada kullandığımız open()
fonksiyonuna çok
takılmayın. Bunu birkaç bölüm sonra inceleyeceğiz. Biz şimdilik bu şekilde dosya
oluşturulduğunu bilelim yeter. Bu arada open
fonksiyonunun da biçim olarak
type()
, len()
, pow()
ve print()
fonksiyonlarına ne kadar
benzediğine dikkat edin. Gördüğünüz gibi open()
fonksiyonu da tıpkı
type()
, len()
, pow()
ve print()
fonksiyonları gibi birtakım
parametreler alıyor. Bu fonksiyonun ilk parametresi “deneme.txt” adlı bir
karakter dizisi. İşte bu karakter dizisi bizim oluşturmak istediğimiz dosyanın
adını gösteriyor. İkinci parametre ise “w” adlı başka bir karakter dizisi. Bu
da deneme.txt dosyasının yazma kipinde (modunda) açılacağını gösteriyor. Ama
dediğim gibi, siz şimdilik bu ayrıntılara fazla takılmayın. İlerleyen derslerde,
bu konuları adınızı bilir gibi bileceğinizden emin olabilirsiniz.
2. Oluşturduğumuz bu deneme.txt adlı dosya, o anda bulunduğunuz dizin içinde oluşacaktır. Bu dizinin hangisi olduğunu öğrenmek için şu komutları verebilirsiniz:
>>> import os
>>> os.getcwd()
Bu komutun çıktısında hangi dizinin adı görünüyorsa, deneme.txt dosyası da o dizinin içindedir. Mesela bendeki çıktı /home/yazbel/Desktop. Demek ki oluşturduğum deneme.txt adlı dosya masaüstündeymiş. Ben bu komutları Ubuntu üzerinde verdim. Eğer Windows üzerinde verseydim şuna benzer bir çıktı alacaktım: C:\Users\yazbel\Desktop
3. Ardından da normal bir şekilde print()
fonksiyonumuzu çalıştırdık. Ama
gördüğünüz gibi print()
fonksiyonu bize herhangi bir çıktı vermedi. Çünkü,
daha önce de söylediğimiz gibi, print()
fonksiyonunu biz ekrana değil,
dosyaya çıktı verecek şekilde ayarladık. Bu işlemi, file adlı bir parametreye,
biraz önce tanımladığımız dosya değişkenini yazarak yaptık.
4. Son komut yardımıyla da, yaptığımız değişikliklerin dosyada görünebilmesi için ilk başta açtığımız dosyayı kapatıyoruz.
Şimdi deneme.txt adlı dosyayı açın. Biraz önce print()
fonksiyonuyla
yazdırdığımız “Ben Python, Monty Python!” karakter dizisinin dosyaya işlenmiş
olduğunu göreceksiniz.
Böylece print()
fonksiyonunun standart çıktı konumunu değiştirmiş olduk.
Yani print()
fonksiyonunun file adlı parametresine farklı bir değer
vererek, print()
fonksiyonunun etkileşimli kabuğa değil dosyaya yazmasını
sağladık.
Tıpkı sep ve end parametreleri gibi, file parametresi de, siz görmeseniz
bile her zaman print()
fonksiyonunun içinde vardır. Yani diyelim ki şöyle
bir komut verdik:
>>> print("Tahir olmak da ayıp değil", "Zühre olmak da")
Python bu komutu şöyle algılar:
>>> print("Tahir olmak da ayıp değil", "Zühre olmak da",
... sep=" ", end="\n", file=sys.stdout)
Yani kendisine parametre olarak verilen değerleri ekrana yazdırırken sırasıyla şu işlemleri gerçekleştirir:
Parametrelerin arasına birer boşluk koyar (
sep=" "
),Ekrana yazdırma işlemi bittikten sonra parametrelerin sonuna satır başı karakteri ekler (
end="\n"
)Bu çıktıyı standart çıktı konumuna gönderir (
file=sys.stdout
).
İşte biz burada file parametresinin değeri olan standart çıktı konumuna başka bir değer vererek bu konumu değiştiriyoruz.
Gelin isterseniz bununla ilgili bir örnek daha yapalım. Mesela kişisel bilgilerimizi bir dosyaya kaydedelim. Öncelikle bilgileri kaydedeceğimiz dosyayı oluşturalım:
>>> f = open("kişisel_bilgiler.txt", "w")
Bu kodlarla, kişisel_bilgiler.txt adını taşıyan bir dosyayı yazma kipinde (w) açmış ve bu dosyayı f adlı bir değişkene atamış olduk. Şimdi bilgileri yazmaya başlayabiliriz:
>>> print("Fırat Özgül", file=f)
>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)
İşimiz bittiğinde dosyayı kapatmayı unutmuyoruz. Böylece bütün bilgiler dosyaya yazılmış oluyor:
>>> f.close()
Oluşturduğumuz kişisel_bilgiler.txt adlı dosyayı açtığımızda, print()
fonksiyonuna verdiğimiz parametrelerin dosyaya yazdırıldığını görüyoruz.
En başta da söylediğim gibi, bu bölümde henüz öğrenmediğimiz bazı şeylerle karşılaştık. Eğer yukarıda verilen örnekleri anlamakta zorlandıysanız hiç endişe etmenize gerek yok. Birkaç bölüm sonra burada anlattığımız şeyler size çocuk oyuncağı gibi gelecek…
flush¶
Şimdiye kadar print()
fonksiyonunun sep, end ve file adlı özel
birtakım parametreleri olduğunu öğrendik. print()
fonksiyonunun bunların
dışında başka bir özel parametresi daha bulunur. Bu parametrenin adı flush.
İşte şimdi biz print()
fonksiyonunun bu flush adlı parametresinden söz
edeceğiz.
Bildiğiniz gibi, print()
gibi bir komut verdiğimizde Python, yazdırmak
istediğimiz bilgiyi standart çıktı konumuna gönderir. Ancak Python’da bazı
işlemler standart çıktı konumuna gönderilmeden önce bir süre tamponda bekletilir
ve daha sonra bekleyen bu işlemler topluca standart çıktı konumuna gönderilir.
Peki ilk başta çok karmaşıkmış gibi görünen bu ifade ne anlama geliyor?
Aslında siz bu olguya hiç yabancı değilsiniz. file parametresini anlatırken verdiğimiz şu örneği tekrar ele alalım:
>>> f = open("kişisel_bilgiler.txt", "w")
Bu komutla kişisel_bilgiler.txt adlı bir dosyayı yazma kipinde açtık. Şimdi bu dosyaya bazı bilgiler ekleyelim:
>>> print("Fırat Özgül", file=f)
Bu komutla kişisel_bilgiler.txt adlı dosyaya ‘Fırat Özgül’ diye bir satır eklemiş olduk.
Şimdi bilgisayarınızda oluşan bu kişisel_bilgiler.txt dosyasını açın. Gördüğünüz gibi dosyada hiçbir bilgi yok. Dosya şu anda boş görünüyor. Halbuki biz biraz önce bu dosyaya ‘Fırat Özgül’ diye bir satır eklemiştik, değil mi?
Python bizim bu dosyaya eklemek istediğimiz satırı tampona kaydetti. Dosyaya yazma işlemleri sona erdiğinde ise Python, tamponda bekleyen bütün bilgileri standart çıktı konumuna (yani bizim durumumuzda f adlı değişkenin tuttuğu kişisel_bilgiler.txt adlı dosyaya) boşaltacak.
Dosyaya başka bilgiler de yazalım:
>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)
Dosyaya yazacağımız şeyler bu kadar. Artık yazma işleminin sona erdiğini Python’a bildirmek için şu komutu veriyoruz:
>>> f.close()
Böylece dosyamızı kapatmış olduk. Şimdi kişisel_bilgiler.txt adlı dosyaya çift tıklayarak dosyayı tekrar açın. Orada ‘Fırat Özgül’, ‘Adana’ ve ‘Ubuntu’ satırlarını göreceksiniz.
Gördüğünüz gibi, gerçekten de Python dosyaya yazdırmak istediğimiz bütün verileri önce tamponda bekletti, daha sonra dosya kapatılınca tamponda bekleyen bütün verileri dosyaya boşalttı. İşte flush parametresi ile, bahsettiğimiz bu boşaltma işlemini kontrol edebilirsiniz. Şimdi dikkatlice inceleyin:
>>> f = open("kişisel_bilgiler.txt", "w")
Dosyamızı oluşturduk. Şimdi bu dosyaya bazı bilgiler ekleyelim:
>>> print("Merhaba Dünya!", file=f, flush=True)
Gördüğünüz gibi, burada flush adlı yeni bir parametre kullandık. Bu parametreye verdiğimiz değer True. Şimdi dosyaya çift tıklayarak dosyayı açın. Gördüğünüz gibi, henüz dosyayı kapatmadığımız halde bilgiler dosyaya yazıldı. Bu durum, tahmin edebileceğiniz gibi, flush parametresine True değeri vermemiz sayesindedir. Bu parametre iki değer alabilir: True ve False. Bu parametrenin öntanımlı değeri False’tur. Yani eğer biz bu parametreye herhangi bir değer belirtmezsek Python bu parametrenin değerini False olarak kabul edecek ve bilgilerin dosyaya yazılması için dosyanın kapatılmasını bekleyecektir. Ancak bu parametreye True değerini verdiğimizde ise veriler tamponda bekletilmeksizin standart çıktı konumuna gönderilecektir.
Yazdığınız bir programda, yapmak istediğiniz işin niteliğine göre, bir dosyaya yazmak istediğiniz bilgilerin bir süre tamponda bekletilmesini veya hiç bekletilmeden doğrudan dosyaya yazılmasını isteyebilirsiniz. İhtiyacınıza bağlı olarak da flush parametresinin değerini True veya False olarak belirleyebilirsiniz.
Birkaç Pratik Bilgi¶
Buraya gelene kadar print()
fonksiyonu ve bu fonksiyonun parametreleri
hakkında epey söz söyledik. Dilerseniz şimdi de, programcılık maceranızda
işinize yarayacak, işlerinizi kolaylaştıracak bazı ipuçları verelim.
Yıldızlı Parametreler¶
Şimdi size şöyle bir soru sormama izin verin: Acaba aşağıdaki gibi bir çıktıyı nasıl elde ederiz?
L.i.n.u.x
Aklınıza hemen şöyle bir cevap gelmiş olabilir:
>>> print("L", "i", "n", "u", "x", sep=".")
L.i.n.u.x
Yukarıdaki, gerçekten de doğru bir çözümdür. Ancak bu soruyu çözmenin çok daha basit bir yolu var. Şimdi dikkatle bakın:
>>> print(*"Linux", sep=".")
L.i.n.u.x
Konuyu açıklamaya geçmeden önce bir örnek daha verelim:
>>> print(*"Galatasaray")
G a l a t a s a r a y
Burada neler döndüğünü az çok tahmin ettiğinizi zannediyorum. Son örnekte de
gördüğünüz gibi, “Galatasaray” karakter dizisinin başına eklediğimiz yıldız
işareti; “Galatasaray” karakter dizisinin her bir öğesini parçalarına
ayırarak, bunları tek tek print()
fonksiyonuna yolluyor. Yani sanki
print()
fonksiyonunu şöyle yazmışız 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
Dediğimiz gibi, bir fonksiyona parametre olarak verdiğimiz bir karakter dizisinin başına eklediğimiz yıldız işareti, bu karakter dizisini tek tek öğelerine ayırıp, bu öğeleri yine tek tek ve sanki her bir öğe ayrı bir parametreymiş gibi o fonksiyona gönderdiği için doğal olarak yıldız işaretini ancak, birden fazla parametre alabilen fonksiyonlara uygulayabiliriz.
Örneğin len()
fonksiyonu sadece tek bir parametre alabilir:
>>> len("Galatasaray")
11
Bu fonksiyonu birden fazla parametre ile kullanamayız:
>>> len("Galatasaray", "Fenerbahçe", "Beşiktaş")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: len() takes exactly one argument (3 given)
Hata mesajında da söylendiği gibi, len()
fonksiyonu yalnızca tek bir
parametre alabilirken, biz 3 parametre vermeye çalışmışız…
Dolayısıyla yıldızlı parametreleri len()
fonksiyonuna uygulayamayız:
>>> len(*"Galatasaray")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: len() takes exactly one argument (11 given)
Bir parametrenin başına yıldız eklediğimizde, o parametreyi oluşturan bütün
öğeler tek tek fonksiyona gönderildiği için, sanki len()
fonksiyonuna 1
değil de, 11 ayrı parametre vermişiz gibi bir sonuç ortaya çıkıyor.
Yıldızlı parametreleri bir fonksiyona uygulayabilmemiz için o fonksiyonun birden
fazla parametre alabilmesinin yanısıra, yapısının da yıldızlı parametre almaya
uygun olması gerekir. Mesela open()
, type()
ve biraz önce bahsettiğimiz
len()
fonksiyonlarının yapısı yıldızlı parametre almaya uygun değildir.
Dolayısıyla yıldızlı parametreleri her fonksiyonla birlikte kullanamayız, ama
print()
fonksiyonu yıldızlı parametreler için 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(*"abcçdefgğh", sep="/")
a/b/c/ç/d/e/f/g/ğ/h
Bu örneklerden de gördüğünüz gibi, print()
fonksiyonuna verdiğimiz bir
parametrenin başına yıldız eklediğimizde, o parametre tek tek parçalarına
ayrılıp print()
fonksiyonuna gönderildiği için, sonuç olarak sep
parametresinin karakter dizisi öğelerine tek tek uygulanmasını sağlamış
oluyoruz.
Hatırlarsanız sep parametresinin öntanımlı değerinin bir adet boşluk karakteri olduğunu söylemiştik. Yani aslında Python yukarıdaki ilk komutu şöyle görüyor:
>>> print(*"Galatasaray", sep=" ")
Dolayısıyla, yıldız işareti sayesinde “Galatasaray” adlı karakter dizisinin
her bir öğesinin arasına bir adet boşluk karakteri yerleştiriliyor. Bir sonraki
“TBMM” karakter dizisinde ise, sep parametresinin değerini nokta işareti
olarak değiştirdiğimiz için “TBMM” karakter dizisinin her bir öğesinin arasına
bir adet nokta işareti yerleştiriliyor. Aynı şekilde “abcçdefgğh” karakter
dizisinin her bir öğesini tek tek print()
fonksiyonuna yollayarak, sep
parametresine verdiğimiz / işareti yardımıyla her öğenin arasına bu /
işaretini yerleştirebiliyoruz.
Yıldızlı parametrelerle ilgili tek kısıtlama, bunların sayılarla birlikte kullanılamayacak olmasıdır:
>>> print(*2345)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print() argument after * must be a sequence, not int
Çünkü yıldızlı parametreler ancak ve ancak dizi özelliği taşıyan veri tipleriyle birlikte kullanılabilir. Mesela karakter dizileri bu türden bir veri tipidir. İlerde dizi özelliği taşıyan ve bu sayede yıldızlı parametrelerle birlikte kullanılabilecek başka veri tiplerini de öğreneceğiz.
Yukarıda verdiğimiz örnekler bize yıldızlı parametrelerin son derece kullanışlı araçlar olduğunu gösteriyor. İleride de bu parametrelerden bol bol yararlanacağız. Biz şimdi bu konuyu burada kapatıp başka bir şeyden söz edelim.
sys.stdout’u Kalıcı Olarak Değiştirmek¶
Önceki başlıklar altında verdiğimiz örneklerden de gördüğünüz gibi, print()
fonksiyonunun file parametresi yardımıyla Python’ın standart çıktı konumunu
geçici olarak değiştirebiliyoruz. Ama bazı durumlarda, yazdığınız programlarda,
o programın işleyişi boyunca standart dışı bir çıktı konumu belirlemek
isteyebilirsiniz. Yani standart çıktı konumunu geçici olarak değil, kalıcı
olarak değiştirmeniz gerekebilir. Mesela yazdığınız programda bütün çıktıları
bir dosyaya yazdırmayı tercih edebilirsiniz. Elbette bu işlemi her defasında
file parametresini, çıktıları yazdırmak istediğiniz dosyanın adı olarak
belirleyerek yapabilirsiniz. Tıpkı şu örnekte olduğu gibi:
>>> f = open("dosya.txt", "w")
>>> print("Fırat Özgül", file=f)
>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)
>>> f.close()
Gördüğünüz gibi, her defasında file parametresine f değerini vererek işimizi hallettik. Ama bunu yapmanın daha pratik bir yöntemi var. Dilerseniz yazdığınız programın tüm işleyişi boyunca çıktıları başka bir konuma yönlendirebilirsiniz. Bunun için hem şimdiye kadar öğrendiğimiz, hem de henüz öğrenmediğimiz bazı bilgileri kullanacağız.
İlk önce şöyle bir kod yazalım:
>>> import sys
Bu kod yardımıyla sys adlı özel bir ‘modülü’ programımıza dahil etmiş, yani içe aktarmış olduk. Peki ‘modül’ nedir, ‘içe aktarmak’ ne demek?
Aslında biz bu ‘modül’ ve ‘içe aktarma’ kavramlarına hiç de yabancı değiliz.
Önceki derslerde, pek üzerinde durmamış da olsak, biz Python’daki birkaç modülle
zaten tanışmıştık. Mesela os adlı bir modül içindeki getcwd()
adlı bir
fonksiyonu kullanarak, o anda hangi dizinde bulunduğumuzu öğrenebilmiştik:
>>> import os
>>> os.getcwd()
Aynı şekilde keyword adlı başka bir modül içindeki kwlist adlı değişkeni kullanarak, hangi kelimelerin Python’da değişken adı olarak kullanılamayacağını da listeleyebilmiştik:
>>> import keyword
>>> keyword.kwlist
İşte şimdi de, os ve keyword modüllerine ek olarak sys adlı bir modülden söz ediyoruz. Gelin isterseniz öteki modülleri şimdilik bir kenara bırakıp, bu sys denen modüle dikkatimizi verelim.
Dediğimiz gibi, sys modülü içinde pek çok önemli değişken ve fonksiyon
bulunur. Ancak bir modül içindeki değişken ve fonksiyonları kullanabilmek için o
modülü öncelikle programımıza dahil etmemiz, yani içe aktarmamız gerekiyor. Bunu
import
komutuyla yapıyoruz:
>>> import sys
Artık sys modülü içindeki bütün fonksiyon ve değişkenlere ulaşabileceğiz.
sys modülü içinde bulunan pek çok değişken ve fonksiyondan biri de stdout adlı değişkendir. Bu değişkenin değerine şöyle ulaşabilirsiniz:
>>> sys.stdout
Bu komut şuna benzer bir çıktı verir:
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1254'>
Bu çıktıdaki name=’<stdout>’ kısmına dikkat edin. Bu ifadeye birazdan geri döneceğiz. Biz şimdi başka bir şeyden söz edelim.
Hatırlarsanız etkileşimli kabuğu nasıl kapatabileceğimizi anlatırken, etkileşimli kabuktan çıkmanın bir yolunun da şu komutları vermek olduğunu söylemiştik:
>>> import sys; sys.exit()
Bu komutu tek satırda yazmıştık, ama istersek şöyle de yazabiliriz elbette:
>>> import sys
>>> sys.exit()
Dedik ya, sys modülü içinde pek çok değişken ve fonksiyon bulunur. Nasıl
stdout sys modülü içindeki değişkenlerden biri ise, exit()
de sys
modülü içinde bulunan fonksiyonlardan biridir.
Biz ‘modüller’ konusunu ilerleyen derslerde ayrıntılı bir şekilde inceleyeceğiz. Şimdilik modüllere ilişkin olarak yalnızca şunları bilelim yeter:
1. Python’da modüller import
komutu ile içe aktarılır. Örneğin sys
adlı modülü içe aktarmak için import sys
komutunu veriyoruz.
2. Modüller içinde pek çok faydalı değişken ve fonksiyon bulunur. İşte bir modülü içe aktardığımızda, o modül içindeki bu değişken ve fonksiyonları kullanma imkanı elde ederiz.
3. sys modülü içindeki değişkenlere bir örnek stdout; fonksiyonlara
örnek ise exit()
fonksiyonudur. Bir modül içindeki bu değişken ve
fonksiyonlara ‘modül_adı.değişken_ya_da_fonksiyon’ formülünü kullanarak
erişebiliriz. Örneğin:
>>> sys.stdout >>> sys.exit()
4. Hatırlarsanız bundan önce de, open()
fonksiyonu ile dosya oluşturmayı
anlatırken, oluşturulan dosyanın hangi dizinde olduğunu bulabilmek amacıyla, o
anda içinde bulunduğumuz dizini tespit edebilmek için şu kodları kullanmıştık:
>>> import os >>> os.getcwd()
Burada da os adlı başka bir modül görüyoruz. İşte os da tıpkı sys gibi
bir modüldür ve tıpkı sys modülünde olduğu gibi, os modülünün de içinde
pek çok yararlı değişken ve fonksiyon bulunur. getcwd()
adlı fonksiyon
da os modülü içinde yer alan ve o anda hangi dizin altında bulunduğumuzu
gösteren bir fonksiyondur. Elbette, yine tıpkı sys modülünde olduğu gibi,
os modülü içindeki bu yararlı değişken ve fonksiyonları kullanabilmek için
de öncelikle bu os modülünü içe aktarmamız, yani programımıza dahil
etmemiz gerekiyor. os modülünü import
komutu aracılığıyla uygun bir
şekilde içe aktardıktan sonra, modül içinde yer alan getcwd()
adlı
fonksiyona yine ‘modül_adı.fonksiyon’ formülünü kullanarak erişebiliyoruz.
Modüllere ilişkin şimdilik bu kadar bilgi yeter. Modülleri bir kenara bırakıp yolumuza devam edelim…
Eğer sys.exit()
komutunu verip etkileşimli kabuktan çıktıysanız, etkileşimli
kabuğa tekrar girin ve sys modülünü yeniden içe aktarın:
>>> import sys
Not
Bir modülü aynı etkileşimli kabuk oturumu içinde bir kez içe aktarmak yeterlidir. Bir modülü bir kez içe aktardıktan sonra, o oturum süresince bu modül içindeki değişken ve fonksiyonları kullanmaya devam edebilirsiniz. Ama tabii ki etkileşimli kabuğu kapatıp tekrar açtıktan sonra, bir modülü kullanabilmek için o modülü tekrar içe aktarmanız gerekir.
Şimdi şu kodu yazın:
>>> f = open("dosya.txt", "w")
Bu kodun anlamını biliyorsunuz. Burada dosya.txt adlı bir dosyayı yazma kipinde açmış olduk. Tahmin edebileceğiniz gibi, çıktılarımızı ekran yerine bu dosyaya yönlendireceğiz.
Şimdi de şöyle bir kod yazalım:
>>> sys.stdout = f
Bildiğiniz gibi, sys.stdout değeri Python’ın çıktıları hangi konuma vereceğini belirliyor. İşte biz burada sys.stdout’un değerini biraz önce oluşturduğumuz f adlı dosya ile değiştiriyoruz. Böylece Python bütün çıktıları f değişkeni içinde belirttiğimiz dosya.txt adlı dosyaya gönderiyor.
Bu andan sonra yazacağınız her şey dosya.txt adlı dosyaya gidecektir:
>>> print("deneme metni", flush=True)
Gördüğünüz gibi, burada file parametresini kullanmadığımız halde çıktılarımız
ekrana değil, dosya.txt adlı bir dosyaya yazdırıldı. Peki ama bu nasıl oldu?
Aslında bunun cevabı çok basit: Biraz önce sys.stdout = f
komutuyla
sys.stdout’un değerini f değişkeninin tuttuğu dosya ile değiştirdik. Bu
işlemi yapmadan önce sys.stdout
’un değeri şuydu hatırlarsanız:
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1254'>
Ama sys.stdout = f
komutundan sonra her şey değişti. Kontrol edelim:
>>> print(sys.stdout, flush=True)
Elbette bu komuttan herhangi bir çıktı almadınız. Çıktının ne olduğunu görmek için dosya.txt adlı dosyayı açın. Orada şu satırı göreceksiniz:
<_io.TextIOWrapper name='dosya.txt' mode='w' encoding='cp1254'>
Gördüğünüz gibi, özgün stdout çıktısındaki name=’<stdout>’ değeri name=’dosya.txt’ olmuş. Dolayısıyla artık bütün çıktılar dosya.txt adlı dosyaya gidiyor…
Bu arada, yukarıdaki çıktıda görünen name, mode ve encoding değerlerine şu şekilde ulaşabilirsiniz:
>>> sys.stdout.name
>>> sys.stdout.mode
>>> sys.stdout.encoding
Burada sys.stdout.name
komutu standart çıktı konumunun o anki adını
verecektir. sys.stdout.mode
komutu ise standart çıktı konumunun hangi kipe
sahip olduğunu gösterir. Standart çıktı konumu genellikle yazma kipinde (w)
bulunur. sys.stdout.encoding
kodu ise standart çıktı konumunun sahip olduğu
kodlama biçimini gösterir. Kodlama biçimi, standart çıktı konumuna
yazdıracağınız karakterlerin hangi kodlama biçimi ile kodlanacağını belirler.
Kodlama biçimi Windows’ta genellikle ‘cp1254’, GNU/Linux’ta ise ‘utf-8’dir. Eğer
bu kodlama biçimi yanlış olursa, mesela dosyaya yazdıracağınız karakterler
içindeki Türkçe harfler düzgün görüntülenemez. Eğer burada söylediklerimiz size
şu anda anlaşılmaz geliyorsa, söylediklerimizi dikkate almadan yolunuza devam
edebilirsiniz. Birkaç bölüm sonra bu söylediklerimiz size daha fazla şey ifade
etmeye başlayacak nasıl olsa.
Peki standart çıktı konumunu eski haline döndürmek isterseniz ne yapacaksınız? Bunun için etkileşimli kabuktan çıkıp tekrar girebilirsiniz. Etkileşimli kabuğu tekrar açtığınızda her şeyin eski haline döndüğünü göreceksiniz. Aynı şekilde, eğer bu kodları bir program dosyasına yazmış olsaydınız, programınız kapandığında her şey eski haline dönecekti.
Peki standart çıktı konumunu, etkileşimli kabuktan çıkmadan veya programı kapatmadan eski haline döndürmenin bir yolu var mı? Elbette var. Dikkatlice bakın:
>>> import sys
>>> f = open("dosya.txt", "w")
>>> sys.stdout, f = f, sys.stdout
>>> print("deneme", flush=True)
>>> f, sys.stdout = sys.stdout, f
>>> print("deneme")
deneme
Uyarı
Eğer yukarıdaki kodları çalıştıramıyorsanız, aynı etkileşimli kabuk oturumunda önceden verdiğiniz kodlar bu kodların doğru çıktı vermesini engelliyor olabilir. Bu sorunu aşmak için, etkileşimli kabuğu kapatıp tekrar açın ve yukarıdaki komutları tekrar verin.
Aslında burada anlayamayacağınız hiçbir şey yok. Burada yaptığımız şeyi geçen bölümlerde değişkenlerin değerini nasıl takas edeceğimizi anlatırken de yapmıştık. Hatırlayalım:
>>> osman = "Araştırma Geliştirme Müdürü"
>>> mehmet = "Proje Sorumlusu"
>>> osman, mehmet = mehmet, osman
Bu kodlarla Osman ve Mehmet’in unvanlarını birbiriyle takas etmiştik. İşte
yukarıda yaptığımız şey de bununla aynıdır. sys.stdout, f = f, sys.stdout
dediğimizde f değerini sys.stdout’a, sys.stdout’un değerini ise f’ye
vermiş oluyoruz. f, sys.stdout = sys.stdout, f
dediğimizde ise, bu işlemin
tam tersini yaparak her şeyi eski haline getirmiş oluyoruz.
Python’ın bize sunduğu bu kolaylıktan faydalanarak değişkenlerin değerini birbiriyle kolayca takas edebiliyoruz. Eğer böyle bir kolaylık olmasaydı yukarıdaki kodları şöyle yazabilirdik:
>>> import sys
>>> f = open("dosya.txt", "w")
>>> özgün_stdout = sys.stdout
>>> sys.stdout = f
>>> print("deneme", flush=True)
>>> sys.stdout = özgün_stdout
>>> print("deneme")
deneme
Gördüğünüz gibi, sys.stdout’un değerini kaybetmemek için, sys.stdout değerini f adlı dosyaya göndermeden önce şu kod yardımıyla yedekliyoruz:
>>> özgün_stdout = sys.stdout
sys.stdout’un özgün değerini özgün_stdout değişkenine atadığımız için, bu değere sonradan tekrar ulaşabileceğiz. Zaten yukarıdaki kodlardan da gördüğünüz gibi, sys.stdout’un özgün değerine dönmek istediğimizde şu kodu yazarak isteğimizi gerçekleştirebiliyoruz:
>>> sys.stdout = özgün_stdout
Böylece stdout değeri eski haline dönmüş oluyor ve bundan sonra yazdırdığımız her şey yeniden ekrana basılmaya başlıyor.
…ve böylece uzun bir bölümü daha geride bıraktık. Bu bölümde hem print()
fonksiyonunu bütün ayrıntılarıyla incelemiş olduk, hem de Python programlama
diline dair başka çok önemli kavramlardan söz ettik. Bu bakımdan bu bölüm bize
epey şey öğretti. Artık öğrendiğimiz bu bilgileri de küfemize koyarak başımız
dik bir şekilde yola devam edebiliriz.
Kaçış Dizileri¶
Python’da karakter dizilerini tanımlayabilmek için tek, çift veya üç tırnak işaretlerinden faydalandığımızı geçen bölümde öğrenmiştik. Python bir verinin karakter dizisi olup olmadığına bu tırnak işaretlerine bakarak karar verdiği için, tek, çift ve üç tırnak işaretleri Python açısından özel bir önem taşıyor. Zira Python’ın gözünde bir başlangıç tırnağı ile bitiş tırnağı arasında yer alan her şey bir karakter dizisidir.
Örneğin ilk olarak bir “ işareti koyup ardından “elma şeklinde devam ettiğinizde, Python ilk tırnağı gördükten sonra karakter dizisini tanımlayabilmek için ikinci bir tırnak işareti aramaya başlar. Siz “elma” şeklinde kodunuzu tamamladığınızda ise Python bellekte “elma” adlı bir karakter dizisi oluşturur.
Bu noktada size şöyle bir soru sormama izin verin: Acaba tırnak işaretleri herhangi bir metin içinde kaç farklı amaçla kullanılabilir?
İsterseniz bu sorunun cevabını örnekler üzerinde vermeye çalışalım:
Ahmet, “Bugün sinemaya gidiyorum,” dedi.
Burada tırnak işaretlerini, bir başkasının sözlerini aktarmak için kullandık.
‘book’ kelimesi Türkçede ‘kitap’ anlamına gelir.
Burada ise tırnak işaretlerini bazı kelimeleri vurgulamak için kullandık.
Bir de şuna bakalım:
Yarın Adana’ya gidiyorum.
Burada da tırnak işaretini, çekim eki olan ‘-(y)a’ ile özel isim olan ‘Adana’ kelimesini birbirinden ayırmak için kesme işareti görevinde kullandık.
Şimdi yukarıda verdiğimiz ilk cümleyi bir karakter dizisi olarak tanımlamaya çalışalım:
>>> 'Ahmet, "Bugün sinemaya gidiyorum," dedi.'
Burada karakter dizisini tanımlamaya tek tırnak işareti ile başladık. Böylece Python bu karakter dizisini tanımlama işlemini bitirebilmek için ikinci bir tek tırnak işareti daha aramaya koyuldu ve aradığı tek tırnak işaretini cümlenin sonunda bularak, karakter dizisini düzgün bir şekilde oluşturabildi.
Dediğimiz gibi, Python’ın gözünde tırnak işaretleri bir karakter dizisini başka veri tiplerinden ayırt etmeye yarayan bir ölçüttür. Ama biz insanlar, yukarıda verdiğimiz örnek cümlelerden de göreceğiniz gibi, programlama dillerinden farklı olarak, tırnak işaretlerini bir metin içinde daha farklı amaçlar için de kullanabiliyoruz.
Şimdi yukarıdaki karakter dizisini şöyle tanımlamaya çalıştığımızı düşünün:
>>> "Ahmet, "Bugün sinemaya gidiyorum," dedi."
İşte burada Python’ın çıkarları ile bizim çıkarlarımız birbiriyle çatıştı. Python karakter dizisini başlatan ilk çift tırnak işaretini gördükten sonra, karakter dizisini tanımlama işlemini bitirebilmek için ikinci bir tırnak işareti daha aramaya koyuldu. Bu arayış sırasında da ‘Bugün’ kelimesinin başındaki çift tırnak işaretini gördü ve karakter dizisinin şu olduğunu zannetti:
>>> "Ahmet, "
Buraya kadar bir sorun yok. Bu karakter dizisi Python’ın sözdizimi kurallarına uygun.
Karakter dizisi bu şekilde tanımlandıktan sonra Python cümlenin geri kalanını okumaya devam ediyor ve herhangi bir tırnak işareti ile başlamayan ve kendisinden önce gelen öğeden herhangi bir virgül işareti ile ayrılmamış ‘Bugün’ kelimesini görüyor. Eğer bir kelime tırnak işareti ile başlamıyorsa bu kelime ya bir değişkendir ya da sayıdır. Ama ‘Bugün’ kelimesi ne bir değişken, ne de bir sayı olduğu, üstelik önceki öğeden de virgülle ayrılmadığı için Python’ın hata vermekten başka çaresi kalmıyor. Çünkü biz burada ‘Bugün’ kelimesinin baş tarafındaki çift tırnak işaretini karakter dizisi tanımlamak için değil, başkasının sözlerini aktarmak amacıyla kullandık. Ancak elbette bir programlama dili bizim amacımızın ne olduğunu kestiremez ve hata mesajını suratımıza yapıştırır:
File "<stdin>", line 1
"Ahmet, "Bugün sinemaya gidiyorum," dedi."
^
SyntaxError: invalid syntax
Peki biz böyle bir durumda ne yapmalıyız?
Bu hatayı engellemek için karakter dizisini tanımlamaya çift tırnak yerine tek tırnakla ya da üç tırnakla başlayabiliriz:
>>> 'Ahmet, "Bugün sinemaya gidiyorum," dedi.'
… veya:
>>> """Ahmet, "Bugün sinemaya gidiyorum," dedi."""
Böylece karakter dizisini başlatan işaret ‘Bugün sinemaya gidiyorum,’ cümlesinin başındaki ve sonundaki işaretlerden farklı olduğu için, Python okuma esnasında bu cümleye takılmaz ve doğru bir şekilde, karakter dizisini kapatan tırnak işaretini bulabilir.
Bu yöntem tamamen geçerli ve mantıklıdır. Ama eğer istersek, aynı karakter dizisini çift tırnakla tanımlayıp, yine de hata almayı engelleyebiliriz. Peki ama nasıl?
İşte burada ‘kaçış dizileri’ adı verilen birtakım araçlardan faydalanacağız.
Peki nedir bu ‘kaçış dizisi’ denen şey?
Kaçış dizileri, Python’da özel anlam taşıyan işaret veya karakterleri, sahip oldukları bu özel anlam dışında bir amaçla kullanmamızı sağlayan birtakım araçlardır. Mesela yukarıda da örneklerini verdiğimiz gibi, tırnak işaretleri Python açısından özel anlam taşıyan işaretlerdir. Normalde Python bu işaretleri karakter dizilerini tanımlamak için kullanır. Ama eğer siz mesela bir metin içinde bu tırnak işaretlerini farklı bir amaçla kullanacaksanız Python’ı bu durumdan haberdar etmeniz gerekiyor. İşte kaçış dizileri, Python’ı böyle bir durumdan haberdar etmemize yarayan araçlardır.
Python’da pek çok kaçış dizisi bulunur. Biz burada bu kaçış dizilerini tek tek inceleyeceğiz. O halde hemen işe koyulalım.
Ters Taksim (\)¶
Yukarıda verdiğimiz örneklerde, çift tırnakla gösterdiğimiz karakter dizilerinin içinde de çift tırnak işareti kullanabilmek için birkaç farklı yöntemden yararlanabildiğimizi öğrenmiştik. Buna göre, eğer bir karakter dizisi içinde çift tırnak işareti geçiyorsa, o karakter dizisini tek tırnakla; eğer tek tırnak geçiyorsa da o karakter dizisini çift tırnakla tanımlayarak bu sorunun üstesinden gelebiliyorduk. Ama daha önce de söylediğimiz gibi, ‘kaçış dizileri’ adı verilen birtakım araçları kullanarak, mesela içinde çift tırnak geçen karakter dizilerini yine çift tırnakla tanımlayabiliriz.
Dilerseniz, kaçış dizisi kavramını açıklamaya geçmeden önce bununla ilgili birkaç örnek verelim. Bu sayede ne ile karşı karşıya olduğumuz, zihnimizde biraz daha belirginleşebilir:
>>> print('Yarın Adana\'ya gidiyorum.')
Yarın Adana'ya gidiyorum.
Bir örnek daha verelim:
>>> print("\"book\" kelimesi Türkçede \"kitap\" anlamına gelir.")
"book" kelimesi Türkçede "kitap" anlamına gelir.
Burada da cümle içinde çift tırnak işaretlerini kullandığımız halde, \ işaretleri sayesinde karakter dizilerini yine çift tırnakla tanımlayabildik.
Bir de şu örneğe bakalım:
>>> print("Python programlama dilinin adı \"piton\" yılanından gelmez")
Bütün bu örneklerde, karakter dizisini hem çift tırnakla tanımlayıp hem de karakter dizisi içinde çift tırnak işaretlerini kullandığımız halde, herhangi bir hata almadığımızı görüyorsunuz. Yukarıdaki kodlarda hata almamızı önleyen şeyin \ işareti olduğu belli. Ama dilerseniz bu işaretin, hata almamızı nasıl önlediğini anlatmadan önce son bir örnek daha verelim.
Hatırlarsanız önceki sayfalarda şöyle bir karakter dizisi ile karşılaşmıştık:
>>> print('İstanbul'un 5 günlük hava durumu tahmini')
File "<stdin>", line 1
print('İstanbul'un 5 günlük hava durumu tahmini')
^
SyntaxError: invalid syntax
Burada da ‘İstanbul’un’ kelimesi içinde geçen tırnak işareti nedeniyle karakter dizisini tek tırnak kullanarak tanımlayamıyorduk. Bu karakter dizisini hatasız bir şekilde tanımlayabilmek için ya çift tırnak ya da üç tırnak kullanmamız gerekiyordu:
>>> print("İstanbul'un 5 günlük hava durumu tahmini")
İstanbul'un 5 günlük hava durumu tahmini
… veya:
>>> print("""İstanbul'un 5 günlük hava durumu tahmini""")
İstanbul'un 5 günlük hava durumu tahmini
Tıpkı önceki örneklerde olduğu gibi, yukarıdaki karakter dizisini de aslında tek tırnakla tanımlayıp hata oluşmasını önleyebiliriz. Hemen görelim:
>>> print('İstanbul\'un 5 günlük hava durumu tahmini')
İstanbul'un 5 günlük hava durumu tahmini
Bütün örneklerde \ işaretini kullandığımızı görüyorsunuz. İşte bu tür işaretlere Python’da kaçış dizisi (escape sequence) adı verilir. Bu işaretler karakter dizilerini tanımlarken oluşabilecek hatalardan kaçmamızı sağlar. Peki bu \ işareti nasıl oluyor da karakter dizisini tanımlarken hata almamızı önlüyor? Gelin bu süreci adım adım tarif edelim:
Python bir karakter dizisi tanımladığımızda, karakter dizisini soldan sağa doğru okumaya başlar. Mesela yukarıdaki örnekte ilk olarak karakter dizisini tanımlamaya tek tırnakla başladığımızı görür.
Python karakter dizisini başlatan bu tek tırnak işaretini gördüğü zaman, soldan sağa doğru ilerleyerek karakter dizisini bitirecek olan tek tırnak işaretini aramaya başlar.
Soldan sağa doğru ilerlerken ‘İstanbul’un’ kelimesi içinde geçen kesme işaretini görür ve karakter dizisinin burada sona erdiğini düşünür. Ancak karakter dizisini sona erdiren işaret bu olmadığı için Python’ın hata vermekten başka çaresi kalmaz.
İşte biz ‘İstanbul’un’ kelimesi içinde geçen bu kesme işaretinin sol tarafına bir adet \ işareti yerleştirerek Python’a, ‘Aradığın işaret bu değil. Sen karakter dizisini okumaya devam et. Biraz sonra aradığın tırnağı bulacaksın!’ mesajı vermiş, yani orada tırnak işaretini farklı bir amaçla kullandığımız konusunda Python’ı bilgilendirmiş oluruz.
Şurada da aynı durum sözkonusu:
>>> print("Python programlama dilinin adı \"piton\" yılanından gelmez")
Tıpkı bir önceki örnekte olduğu gibi, burada da Python karakter dizisini soldan sağa doğru okumaya başlıyor, karakter dizisini başlatan çift tırnak işaretini görüyor ve bunun üzerine Python karakter dizisini bitirecek olan çift tırnak işaretini aramaya koyuluyor.
Karakter dizisini soldan sağa doğru okuduğu sırada, karakter dizisi içinde geçen ‘piton’ kelimesini görüyor. Eğer burada bir önlem almazsak Python bu kelimenin başındaki çift tırnak işaretini, karakter dizisini sona erdiren tırnak olarak algılar ve durum aslında böyle olmadığı için de hata verir.
Bu hatayı önlemek için ‘piton’ kelimesinin başındaki çift tırnağın soluna bir adet \ işareti yerleştirerek Python’a, ‘Aradığın tırnak bu değil!’ mesajı veriyoruz. Yani bir bakıma, \ adlı kaçış dizisi kendisini tırnak işaretine siper edip Python’ın bu tırnağı görmesine mani oluyor…
Bunun üzerine Python bu çift tırnak işaretini görmezden gelerek, soldan sağa doğru okumaya devam eder ve yol üzerinde ‘piton’ kelimesinin sonundaki çift tırnak işaretini görür. Eğer burada da bir önlem almazsak Python yine bir hata verecektir.
Tıpkı biraz önce yaptığımız gibi, bu tırnak işaretinin de soluna bir adet \ işareti yerleştirerek Python’a, ‘Aradığın tırnak bu da değil. Sen yine okumaya devam et!’ mesajı veriyoruz.
Bu mesajı alan Python karakter dizisini soldan sağa doğru okumaya devam ediyor ve sonunda karakter dizisini bitiren çift tırnak işaretini bularak bize hatasız bir çıktı veriyor.
Böylece \ işareti üzerinden hem kaçış dizilerinin ne olduğunu öğrenmiş, hem de bu kaçış dizisinin nasıl kullanılacağına dair örnekler vermiş olduk. Ancak \ kaçış dizisinin yetenekleri yukarıdakilerle sınırlı değildir. Bu kaçış dizisini, uzun karakter dizilerini bölmek için de kullanabiliriz. Şimdi şu örneği dikkatlice inceleyin:
>>> print("Python 1990 yılında Guido Van Rossum \
... tarafından geliştirilmeye başlanmış, oldukça \
... güçlü ve yetenekli bir programlama dilidir.")
Python 1990 yılında Guido Van Rossum tarafından geliştirilmeye
başlanmış, oldukça güçlü ve yetenekli bir programlama dilidir.
Normal şartlar altında, bir karakter dizisini tanımlamaya tek veya çift tırnakla başlamışsak, karakter dizisinin kapanış tırnağını koymadan Enter tuşuna bastığımızda Python bize bir hata mesajı gösterir:
>>> print("Python 1990 yılında Guido Van Rossum
File "<stdin>", line 1
print("Python 1990 yılında Guido Van Rossum
^
SyntaxError: EOL while scanning string literal
İşte \ kaçış dizisi bizim burada olası bir hatadan kaçmamızı sağlar. Eğer Enter tuşuna basmadan önce bu işareti kullanırsak Python tıpkı üç tırnak işaretlerinde şahit olduğumuz gibi, hata vermeden bir alt satıra geçecektir. Bu sırada, yani \ kaçış dizisini koyup Enter tuşuna bastığımızda >>> işaretinin … işaretine dönüştüğünü görüyorsunuz. Bu işaretin, Python’ın bize verdiği bir ‘Yazmaya devam et!’ mesajı olduğunu biliyorsunuz.
Satır Başı (\n)¶
Python’daki en temel kaçış dizisi biraz önce örneklerini verdiğimiz \
işaretidir. Bu kaçış dizisi başka karakterlerle birleşerek, farklı işlevlere
sahip yeni kaçış dizileri de oluşturabilir. Aslında bu olguya yabancı değiliz.
Önceki sayfalarda bu duruma bir örnek vermiştik. Hatırlarsanız print()
fonksiyonunu anlatırken end parametresinin ön tanımlı değerinin \n, yani
satır başı karakteri olduğunu söylemiştik.
Not
Satır başı karakterine ‘yeni satır karakteri’ dendiği de olur.
Satır başı karakterini ilk öğrendiğimizde bu karakteri anlatırken bazı örnekler de vermiştik:
>>> print("birinci satır\nikinci satır\nüçüncü satır")
birinci satır
ikinci satır
üçüncü satır
Gördüğünüz gibi, \n adlı kaçış dizisi, bir alt satıra geçilmesini sağlıyor. İşte aslında \n kaçış dizisi de, \ ile ‘n’ harfinin birleşmesinden oluşmuş bir kaçış dizisidir. Burada \ işaretinin görevi, ‘n’ harfinin özel bir anlam kazanmasını sağlamaktır. \ işareti ile ‘n’ harfi birleştiğinde ‘satır başı karakteri’ denen özel bir karakter dizisi ortaya çıkarıyor.
Gelin bu kaçış dizisi ile ilgili bir örnek verelim. Şimdi şu kodları dikkatlice inceleyin:
>>> başlık = "Türkiye'de Özgür Yazılımın Geçmişi"
>>> print(başlık, "\n", "-"*len(başlık), sep="")
Türkiye'de Özgür Yazılımın Geçmişi
----------------------------------
Burada, başlık adlı değişkenin tuttuğu “Türkiye’de Özgür Yazılımın Geçmişi” adlı karakter dizisinin altını çizdik. Dikkat ederseniz, başlığın altına koyduğumuz çizgiler başlığın uzunluğunu aşmıyor. Yazdığımız program, başlığın uzunluğu kadar çizgiyi başlığın altına ekliyor. Bu programda başlık ne olursa olsun, programımız çizgi uzunluğunu kendisi ayarlayacaktır. Örneğin:
>>> başlık = "Python Programlama Dili"
>>> print(başlık, "\n", "-"*len(başlık), sep="")
Python Programlama Dili
-----------------------
>>> başlık = "Alışveriş Listesi"
>>> print(başlık, "\n", "-"*len(başlık), sep="")
Alışveriş Listesi
-----------------
Gelin isterseniz bu kodlardaki print()
satırını şöyle bir inceleyelim.
Kodumuz şu:
>>> print(başlık, "\n", "-"*len(başlık), sep="")
Burada öncelikle başlık adlı değişkeni print()
fonksiyonunun parantezleri
içine yazdık. Böylece başlık değişkeninin değeri ekrana yazdırılacak.
print()
fonksiyonunun ikinci parametresinin \n adlı kaçış dizisi olduğunu
görüyoruz. Bu kaçış dizisini eklememiz sayesinde Python ilk parametreyi çıktı
olarak verdikten sonra bir alt satıra geçiyor. Bu parametrenin tam olarak ne işe
yaradığını anlamak için, yukarıdaki satırı bir de o parametre olmadan
çalıştırmayı deneyebilirsiniz:
>>> print(başlık, "-"*len(başlık), sep="")
Alışveriş Listesi-----------------
print()
fonksiyonunun üçüncü parametresinin ise şu olduğunu görüyoruz:
"-"*len(başlık)
.
İşte başlık değişkeninin altına gerekli sayıda çizgiyi çizen kodlar bunlardır.
Burada len()
fonksiyonunu nasıl kullandığımıza çok dikkat edin. Bu kod
sayesinde başlık değişkeninin uzunluğu (len(başlık)
) sayısınca -
işaretini ekrana çıktı olarak verebiliyoruz.
Yukarıdaki kodlarda print()
fonksiyonunun son parametresi ise sep=''
. Peki
bu ne işe yarıyor? Her zaman olduğu gibi, bu kod parçasının ne işe yaradığını
anlamak için programı bir de o kodlar olmadan çalıştırmayı deneyebilirsiniz:
>>> print(başlık, "\n", "-"*len(başlık))
Alışveriş Listesi
-----------------
Gördüğünüz gibi, başlık değişkeninin tam altına gelmesi gereken çizgi işaretleri sağa kaymış. Bunun nedeni sep parametresinin öntanımlı değerinin bir adet boşluk karakteri olmasıdır. sep parametresinin öntanımlı değeri nedeniyle çizgilerin baş tarafına bir adet boşluk karakteri ekleniyor çıktıda. O yüzden bu çizgiler sağa kaymış görünüyor. İşte biz yukarıdaki kodlarda sep parametresinin öntanımlı değerini değiştirip, boşluk karakteri yerine boş bir karakter dizisi yerleştiriyoruz. Böylece çizgiler çıktıda sağa kaymıyor.
Satır başı karakteri, programlama maceramız sırasında en çok kullanacağımız kaçış dizilerinden biri ve hatta belki de birincisidir. O yüzden bu kaçış dizisini çok iyi öğrenmenizi tavsiye ederim.
Ayrıca bu kaçış dizisini (ve tabii öteki kaçış dizilerini) tanıyıp öğrenmeniz, yazacağınız programların selameti açısından da büyük önem taşır. Eğer bir karakter dizisi içinde geçen kaçış dizilerini ayırt edemezseniz Python size hiç beklemediğiniz çıktılar verebilir. Hatta yazdığınız programlar kaçış dizilerini tanımıyor olmanızdan ötürü bir anda hata verip çökebilir. Peki ama nasıl?
Şimdi şu örneğe dikkatlice bakın:
Diyelim ki bilgisayarınızın ‘C:\’ dizinindeki ‘nisan’ adlı bir klasörün içinde yer alan masraflar.txt adlı bir dosyayı yazdığınız bir program içinde kullanmanız gerekiyor. Mesela bu dosyayı, tam adresiyle birlikte kullanıcılarınıza göstermek istiyorsunuz.
İlk denememizi yapalım:
>>> print("C:\nisan\masraflar.txt")
Buradan şöyle bir çıktı aldık:
C:
isan\masraflar.txt
Gördüğünüz gibi, bu çıktıyı normal yollardan vermeye çalıştığımızda Python bize hiç de beklemediğimiz bir çıktı veriyor. Peki ama neden?
Python’da karakter dizileri ile çalışırken asla aklımızdan çıkarmamamız gereken bir şey var: Eğer yazdığımız herhangi bir karakter dizisinin herhangi bir yerinde \ işaretini kullanmışsak, bu işaretten hemen sonra gelen karakterin ne olduğuna çok dikkat etmemiz gerekir. Çünkü eğer dikkat etmezsek, farkında olmadan Python için özel anlam taşıyan bir karakter dizisi oluşturmuş olabiliriz. Bu da kodlarımızın beklediğimiz gibi çalışmasını engeller.
Yukarıdaki sorunun kaynağını anlamak için "C:\nisan\masraflar.txt"
adlı
karakter dizisine çok dikkatlice bakın. Python bu karakter dizisinde bizim
‘\nisan’ olarak belirttiğimiz kısmın başındaki \n karakterlerini bir kaçış
dizisi olarak algıladı. Çünkü \n adlı karakter dizisi, ‘satır başı kaçış
dizisi’ adını verdiğimiz, Python açısından özel anlam taşıyan bir karakter
dizisine işaret ediyor. Zaten yukarıdaki tuhaf görünen çıktıya baktığınızda da,
bu kaçış dizisinin olduğu noktadan itibaren karakter dizisinin bölünüp yeni bir
satıra geçildiğini göreceksiniz. İşte biz yukarıdaki örnekte alelade bir dizin
adı belirttiğimizi zannederken aslında hiç farkında olmadan bir kaçış dizisi
üretmiş oluyoruz. Bu nedenle, daha önce de söylediğimiz gibi, karakter dizileri
içinde farkında olarak veya olmayarak kullandığımız kaçış dizilerine karşı her
zaman uyanık olmalıyız. Aksi takdirde, yukarıda olduğu gibi hiç beklemediğimiz
çıktılarla karşılaşabiliriz.
Esasen yukarıdaki problem bir dereceye kadar (ve yerine göre) ‘masum bir kusur’
olarak görülebilir. Çünkü bu hata programımızın çökmesine yol açmıyor. Ama bir
karakter dizisi içindeki gizli kaçış dizilerini gözden kaçırmak, bazı durumlarda
çok daha yıkıcı sonuçlara yol açabilir. Mesela yukarıdaki sorunlu dizin adını
ekrana yazdırmak yerine open()
fonksiyonunu kullanarak, bu karakter dizisi
içinde belirttiğimiz masraflar.txt adlı dosyayı açmaya çalıştığımızı düşünün:
>>> open("C:\nisan\masraflar.txt")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'C:\nisan\\masraflar.txt'
Eğer sorunun gözden kaçan bir kaçış dizisinden kaynaklandığını farkedemezseniz, bu sorunu çözebilmek için saatlerinizi ve hatta günlerinizi harcamak zorunda kalabilirsiniz. Çünkü yukarıdaki hata mesajı sorunun nedenine dair hiçbir şey söylemiyor. Ancak ve ancak yukarıdaki karakter dizisi içinde sinsice gizlenen bir \n kaçış dizisi olduğu gözünüze çarparsa bu sorunu çözme yolunda bir adım atabilirsiniz.
Diyelim ki sorunun ‘\nisan’ ifadesinin başındaki \n karakterlerinin Python tarafından bir kaçış dizisi olarak algılanmasından kaynaklandığını farkettiniz. Peki bu sorunu nasıl çözeceksiniz?
Bu sorunun birkaç farklı çözüm yolu var. Biz şimdilik sadece ikisini göreceğiz. Bu bölümün sonuna vardığınızda öteki çözüm yolunu da öğrenmiş olacaksınız.
Yukarıdaki problemi, ilgili kaçış dizisi içindeki ters taksim işaretini çiftleyerek çözebilirsiniz:
>>> open("C:\\nisan\masraflar")
Tabii tutarlılık açısından karakter dizisi içindeki bütün ters taksim işaretlerini çiftlemek mantıklı olacaktır:
>>> open("C:\\nisan\\masraflar")
Bunun dışında, bu örnek için, dizin adlarını ters taksim yerine düz taksim işaretiyle ayırmayı tercih edebilirsiniz:
>>> open("C:/nisan/masraflar")
Dediğimiz gibi, üçüncü (ve aslında daha kullanışlı olan) yöntemi biraz sonra inceleyeceğiz. Biz şimdilik kaçış dizilerini anlatmaya devam edelim.
Sekme (\t)¶
Python’da \ işareti sadece ‘n’ harfiyle değil, başka harflerle de birleşebilir. Örneğin \ işaretini ‘t’ harfiyle birleştirerek yine özel bir anlam ifade eden bir kaçış dizisi elde edebiliriz:
>>> print("abc\tdef")
abc def
Burada \t adlı kaçış dizisi, “abc” ifadesinden sonra sanki Tab (sekme) tuşuna basılmış gibi bir etki oluşturarak “def” ifadesini sağa doğru itiyor. Bir de şu örneğe bakalım:
>>> print("bir", "iki", "üç", sep="\t")
bir iki üç
Bir örnek daha:
>>> print(*"123456789", sep="\t")
1 2 3 4 5 6 7 8 9
Gördüğünüz gibi, parametreler arasında belli aralıkta bir boşluk bırakmak istediğimizde \t adlı kaçış dizisinden yararlanabiliyoruz.
Tıpkı \n kaçış dizisinde olduğu gibi, karakter dizilerinde \t kaçış dizisinin varlığına karşı da uyanık olmalıyız:
>>> 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 yaşadığımız soruna benzer bir durum var. Biz toplam_masraf.txt adlı bir dosyaya atıfta bulunmaya çalışıyoruz, ama Python bu ifadenin başındaki ‘t’ harfinin, kendisinden önce gelen \ işareti ile birleşmesinden ötürü, bunu \t kaçış dizisi olarak algılıyor ve ona göre davranıyor.
Belki yukarıdaki kodları şöyle yazarsak durumu anlamak daha kolay olabilir:
>>> print("C:\nisan\masraflar\toplam_masraf.txt")
C:
isan\masraflar oplam_masraf.txt
Gördüğünüz gibi, Python \n kaçış dizisini gördüğü noktada alt satırın başına geçiyor ve \t kaçış dizisini gördüğü noktada da önceki ve sonraki öğeler arasında bir sekme boşluğu bırakıyor. Bu durumu engellemek için ne yapmanız gerektiğini biliyorsunuz: Ya ters taksim işaretlerini çiftleyeceksiniz:
>>> print("C:\\nisan\\masraflar\\toplam_masraf.txt")
Ya da dizin adı ayracı olarak düz taksim işaretini kullanacaksınız:
>>> print("C:/nisan/masraflar/toplam_masraf.txt")
Daha önce de söylediğimiz gibi, üçüncü ve daha pratik olan yolu biraz sonra göreceğiz. Şimdilik sadece biraz sabır…
Zil Sesi (\a)¶
\ işaretinin birleştiğinde farklı bir anlam türettiği bir başka harf de ‘a’ harfidir. \ işareti ‘a’ harfiyle birleşerek !bip! benzeri bir zil sesi üretilmesini sağlayabilir:
>>> print("\a")
!bip!
İsterseniz yukarıdaki komutu şu şekilde yazarak, kafa şişirme katsayısını artırabilirsiniz:
>>> print("\a" * 10)
Bu şekilde !bip! sesi 10 kez tekrar edilecektir. Ancak bu kaçış dizisi çoğunlukla sadece Windows üzerinde çalışacaktır. Bu kaçış dizisinin GNU/Linux üzerinde çalışma garantisi yoktur. Hatta bu kaçış dizisi bütün Windows sistemlerinde dahi çalışmayabilir. Dolayısıyla bu kaçış dizisinin işlevine bel bağlamak pek mantıklı bir iş değildir.
Tıpkı \n ve \t kaçış dizilerinde olduğu gibi bu kaçış dizisinin varlığına karşı da uyanık olmalıyız. Burada da mesela ‘C:\aylar’ gibi bir dizin adı tanımlamaya çalışırken aslında \a kaçış dizisini oluşturuyor olabilirsiniz farkında olmadan.
Aynı Satır Başı (\r)¶
Bu kaçış dizisi, bir karakter dizisinde aynı satırın en başına dönülmesini sağlar. Bu kaçış dizisinin işlevini tanımına bakarak anlamak biraz zor olabilir. O yüzden dilerseniz bu kaçış dizisinin ne işe yaradığını bir örnek üzerinde göstermeye çalışalım:
>>> print("Merhaba\rZalim Dünya!")
Zalim Dünya!
Burada olan şey şu: Normal şartlar altında, print()
fonksiyonu içine
yazdığımız bir karakter dizisindeki bütün karakterler soldan sağa doğru tek tek
ekrana yazdırılır:
>>> print("Merhaba Zalim Dünya!")
Merhaba Zalim Dünya!
Ancak eğer karakter dizisinin herhangi bir yerine \r adlı kaçış dizisini yerleştirirsek, bu kaçış dizisinin bulunduğu konumdan itibaren aynı satırın başına dönülecek ve \r kaçış dizisinden sonra gelen bütün karakterler satır başındaki karakterlerin üzerine yazacaktır. Şu örnek daha açıklayıcı olabilir:
>>> print("Merhaba\rDünya")
Dünyaba
Burada, “Merhaba” karakter dizisi ekrana yazdırıldıktan sonra \r kaçış dizisinin etkisiyle satır başına dönülüyor ve bu kaçış dizisinden sonra gelen “Dünya” karakter dizisi “Merhaba” karakter dizisinin üzerine yazıyor. Tabii “Dünya” karakter dizisi içinde 5 karakter, “Merhaba” karakter dizisi içinde ise 7 karakter olduğu için, “Merhaba” karakter dizisinin son iki karakteri (“ba”) dışarda kalıyor. Böylece ortaya “Dünyaba” gibi bir şey çıkıyor.
Önceki kaçış dizilerinde olduğu gibi, bu kaçış dizisini de farkında olmadan karakter dizisi içinde kullanırsanız beklemediğiniz çıktılar alırsınız:
>>> print("C:\ülke\türkiye\iller\rize\nüfus.txt")
izeülke ürkiye\iller
üfus.txt
Burada farkında olmadan sadece bir değil, üç kaçış dizisi birden oluşturduk!
Düşey Sekme (\v)¶
Eğer \ işaretini ‘v’ harfiyle birlikte kullanırsak düşey sekme denen şeyi elde ederiz. Hemen bir örnek verelim:
>>> print("düşey\vsekme")
düşey
sekme
Yalnız bu \v adlı kaçış dizisi her işletim sisteminde çalışmayabilir. Dolayısıyla, birden fazla platform üzerinde çalışmak üzere tasarladığınız programlarınızda bu kaçış dizisini kullanmanızı önermem.
İmleç Kaydırma (\b)¶
\ kaçış dizisinin, biraraya geldiğinde özel bir anlam kazandığı bir başka harf de b’dir. \b kaçış dizisinin görevi, imleci o anki konumundan sola kaydırmaktır. Bu tanım pek anlaşılır değil. O yüzden bir örnek verelim:
>>> print("yahoo.com\b")
Bu kodu çalıştırdığınızda herhangi bir değişiklik görmeyeceksiniz. Ama aslında en sonda gördüğümüz \b kaçış dizisi, imleci bir karakter sola kaydırdı. Dikkatlice bakın:
>>> print("yahoo.com\b.uk")
Gördüğünüz gibi, \b kaçış dizisinin etkisiyle imleç bir karakter sola kaydığı için, ‘com’ kelimesinin son harfi silindi ve bunun yerine \b kaçış dizisinden sonra gelen .uk karakterleri yerleştirildi. Dolayısıyla biz de şu çıktıyı aldık:
yahoo.co.uk
Bir örnek daha verelim…
Bildiğiniz gibi, print()
fonksiyonu, kendisine verilen parametreler arasına
birer boşluk yerleştirir:
>>> print('istihza', '.', 'com')
istihza . com
Biz bu öğeleri birbirine bitiştirmek için şöyle bir yol izleyebileceğimizi biliyoruz:
>>> print('istihza', '.', 'com', sep='')
istihza.com
İşte aynı etkiyi \b kaçış dizisini kullanarak da elde edebiliriz:
>>> print('istihza', '\b.', '\bcom')
istihza.com
Gördüğünüz gibi, \b kaçış dizisi, ‘.’ ve ‘com’ parametrelerinden önce imleci birer karakter sola kaydırdığı için, parametreler arasındaki boşluk karakterleri ortadan kalktı.
Bu kaçış dizisini kullanarak şöyle gereksiz işler peşinde de koşabilirsiniz:
>>> print('istihza\b\b\bsn')
istisna
Burada \b kaçış dizisini üst üste birkaç kez kullanarak imleci birkaç karakter sola kaydırdık ve ‘sn’ harflerini ‘hz’ harflerinin üzerine bindirdik. Böylece ‘istihza’ kelimesi ‘istisna’ kelimesine dönüşmüş oldu…
Daha fazla uzatmadan, bu kaçış dizisinin Python’da çok nadir kullanıldığı bilgisini vererek yolumuza devam edelim…
Küçük Unicode (\u)¶
Tıpkı bundan önceki kaçış dizileri gibi, karakter dizileri içindeki varlığı konusunda dikkatli olmamız gereken bir başka kaçış dizisi de \u adlı kaçış dizisidir. Eğer bu kaçış dizisini tanımaz ve dikkatli kullanmazsak, yazdığımız programlar tespit etmesi çok güç hatalar üretebilir.
Örneğin şöyle bir çıktı vermek istediğinizi düşünün:
Dosya konumu: C:\users\zeynep\gizli\dosya.txt
Bu çıktıyı normal yollardan vermeye çalışırsak Python bize bir hata mesajı gösterecektir:
>>> print("Dosya konumu: C:\users\zeynep\gizli\dosya.txt")
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 16-18: truncated \uXXXX escape
Belki sağda solda ‘UNICODE’ diye bir şey duymuşsunuzdur. Eğer şimdiye kadar böyle bir şey duymadıysanız veya duyduysanız bile ne olduğunu bilmiyorsanız hiç ziyanı yok. Birkaç bölüm sonra bunun ne anlama geldiğini bütün ayrıntılarıyla anlatacağız. Biz şimdilik sadece şunu bilelim: UNICODE, karakterlerin, harflerin, sayıların ve bilgisayar ekranında gördüğümüz öteki bütün işaretlerin her biri için tek ve benzersiz bir numaranın tanımlandığı bir sistemdir. Bu sistemde, ‘kod konumu’ (code point) adı verilen bu numaralar özel bir şekilde gösterilir. Örneğin ‘ı’ harfi UNICODE sisteminde şu şekilde temsil edilir:
u+0131
Aynı şekilde ‘a’ harfi bu sistemde şu kod konumu ile gösterilir:
u+0061
Python programlama dilinde ise, yukarıdaki kod konumu düzeni şöyle gösterilir:
\\u0131
Gördüğünüz gibi, Python UNICODE sistemindeki her bir kod konumunu gösterebilmek için, önce \u şeklinde bir kaçış dizisi tanımlıyor, ardından UNICODE sisteminde + işaretinden sonra gelen sayıyı bu kaçış dizisinin hemen sağına ekliyor. Gelin kendi kendimize birkaç deneme çalışması yapalım:
>>> '\u0130'
'İ'
>>> '\u0070'
'p'
>>> "\ufdsf"
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 0-4: truncated \uXXXX escape
Gördüğünüz gibi, eğer \u kaçış dizisinden sonra doğru bir kod konumu belirtmezsek Python bize bir hata mesajı gösteriyor…
Bu hata mesajının, biraz önce print("Dosya konumu:
C:\users\zeynep\gizli\dosya.txt")
kodunu yazdıktan sonra aldığımız hata ile
aynı olduğuna dikkat edin. Tıpkı \ufdsf örneğinde olduğu gibi, \users
ifadesi de varolan bir UNICODE kod konumuna karşılık gelmediği için, Python’ın
hata vermekten başka çaresi kalmıyor.
Biz bu örnekte ‘users’ kelimesini kullanmaya çalışıyoruz, ama ‘u’ harfinden hemen önce gelen \ kaçış dizisi nedeniyle, hiç farkında olmadan Python açısından önemli bir karakter dizisi (\u) meydana getirmiş oluyoruz. O yüzden, böyle can sıkıcı hatalarla karşılaşmamak için olası kaçış dizilerine karşı her zaman uyanık olmamız gerekiyor.
Peki biz bu kaçış dizisi yüzünden, yazdığımız programlarda Dosya konumu: C:\users\zeynep\gizli\dosya.txt”) gibi bir çıktı veremeyecek miyiz?
Verebileceğimizi ve bunun bir yolu yordamı olduğunu biliyorsunuz:
>>> print("Dosya konumu: C:\\users\\zeynep\\gizli\\dosya.txt")
Dosya konumu: C:\users\zeynep\gizli\dosya.txt
Gördüğünüz gibi, karakter dizisi içinde geçen bütün \ işaretlerini çiftleyerek sorunumuzu çözdük. Buradaki gibi bir sorunla karşılaşmamak için, dizin adlarını ayırırken ters taksim işareti yerine düz taksim işaretini kullanmayı da tercih edebilirsiniz:
>>> print("Dosya konumu: C:/users/zeynep/gizli/dosya.txt")
Biraz sonra bu sorunu halletmenin üçüncü ve daha kolay bir yönteminden daha söz edeceğiz. Ama biz şimdilik bu kaçış dizisini bir kenara bırakıp başka bir kaçış dizisini incelemeye geçelim.
Büyük Unicode (\U)¶
Bu kaçış dizisi biraz önce gördüğümüz \u adlı kaçış dizisiyle hemen hemen aynı anlama gelir. Bu kaçış dizisi de, tıpkı \u gibi, UNICODE kod konumlarını temsil etmek için kullanılır. Ancak U ile gösterilen kod konumları u ile gösterilenlere göre biraz daha uzundur. Örneğin, hatırlarsanız u kaçış dizisini kullanarak ‘ı’ harfinin UNICODE kod konumunu şöyle temsil ediyorduk:
>>> '\u0131'
'ı'
Eğer aynı kod konumunu U adlı kaçış dizisi ile göstermek istersek şöyle bir şey yazmamız gerekir:
>>> '\U00000131'
Gördüğünüz gibi, burada \U kaçış dizisinden sonra gelen kısım toplam 8 haneli bir sayıdan oluşuyor. u kaçış dizisinde ise bu kısmı toplam 4 haneli bir sayı olarak yazıyorduk. İşte \u kaçış dizisi ile U kaçış dizisi arasındaki fark budur. u kaçış dizisi hakkında söylediğimiz öteki her şey U kaçış dizisi için de geçerlidir.
Uzun Ad (\N)¶
UNICODE sistemi ile ilgili bir başka kaçış dizisi de \N adlı kaçış dizisidir.
Dediğimiz gibi, UNICODE sistemine ilişkin ayrıntılardan ilerleyen derslerde söz edeceğiz, ama bu sistemle ilgili ufak bir bilgi daha verelim.
UNICODE sisteminde her karakterin tek ve benzersiz bir kod konumu olduğu gibi, tek ve benzersiz bir de uzun adı vardır. Örneğin ‘a’ harfinin UNICODE sistemindeki uzun adı şudur:
LATIN SMALL LETTER A
Bir karakterin UNICODE sistemindeki uzun adını öğrenmek için unicodedata adlı bir modülden yararlanabilirsiniz:
>>> import unicodedata
>>> unicodedata.name('a')
LATIN SMALL LETTER A
>>> unicodedata.name('Ş')
LATIN CAPITAL LETTER S WITH CEDILLA
Bu arada, daha önce de söylediğimiz gibi, bu ‘modül’ kavramına şimdilik takılmayın. İlerde modülleri ayrıntılı olarak inceleyeceğiz. Şimdilik unicodedata denen şeyin, (tıpkı daha önce örneklerini gördüğümüz os, sys ve keyword gibi) bir modül olduğunu ve bu modül içindeki name adlı bir fonksiyonu kullanarak, parantez içinde belirttiğimiz herhangi bir karakterin UNICODE sistemindeki uzun adını elde edebileceğimizi bilelim yeter.
İşte \N kaçış dizisi bu uzun isimleri, Python programlarımızda kullanma imkanı verir bize. Bu kaçış dizisini, karakterlerin UNICODE sistemindeki uzun adları ile birlikte kullanarak asıl karakterleri elde edebiliriz. Dikkatlice bakın:
>>> print("\N{LATIN SMALL LETTER A}")
a
>>> print("\N{LATIN CAPITAL LETTER S WITH CEDILLA}")
Ş
>>> print("\Nisan")
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 0-1: malformed \N character escape
Gördüğünüz gibi, herhangi bir karşılığı olmayan bir uzun ad belirttiğimizde Python bize bir hata mesajı gösteriyor. Çünkü Python \N kaçış dizisinin hemen ardından { işaretinin getirilmesini ve sonra da UNICODE sistemi dahilinde geçerli bir uzun ad belirtilmesini bekliyor. Yukarıdaki örnekte \N kaçış dizisinden sonra { işareti yok. Zaten \N kaçış dizisinin hemen ardından gelen ‘isan’ ifadesi de doğru bir uzun ada işaret etmiyor. Dolayısıyla da Python’ın bize hata mesajı göstermekten başka çaresi kalmıyor…
\u, \U ve \N kaçış dizileri, UNICODE sistemi ile ilgili çalışmalar yapmak isteyen programcılar için Python programlama dilinin sunduğu faydalı araçlardan yalnızca birkaçıdır. Ancak bu araçların sizin işinize yaramayacağını asla düşünmeyin. Zira \u, \U ve \N kaçış dizileri ile ilgili yukarıdaki durum hiç beklemediğiniz bir anda sizi de vurabilir. Çünkü bu kaçış dizilerinin oluşturduğu risk hiç de öyle nadir karşılaşılacak bir sorun değildir.
Bildiğiniz gibi Windows 7’de kullanıcının dosyalarını içeren dizin adı C:\Users\kullanıcı_adı şeklinde gösteriliyor. Dolayısıyla Windows kullananlar UNICODE kaçış dizilerinden kaynaklanan bu tuzağa her an düşebilir. Ya da eğer adınız ‘u’ veya ‘n’ harfi ile başlıyorsa yine bu tuzağa düşme ihtimaliniz epey yüksek olacak, C:\Users\umut veya C:\Users\Nihat gibi bir dizin adı belirtirken çok dikkatli olmanız gerekecektir. Zira özellikle dosyalar üzerinde işlem yaparken, bu tür dizin adlarını sık sık kullanmak durumunda kalacaksınız. Bu yüzden, alelade bir kelime yazdığınızı zannederken hiç farkında olmadan bir kaçış dizisi tanımlıyor olma ihtimalini her zaman göz önünde bulundurmalı ve buna uygun önlemleri almış olmalısınız.
Onaltılı Karakter (\x)¶
‘x’ harfi de \ işareti ile birleştiğinde özel anlam kazanarak bir kaçış dizisi meydana getirir.
\x kaçış dizisini kullanarak, onaltılı (hexadecimal) sayma sistemindeki bir sayının karakter karşılığını gösterebilirsiniz. Dikkatlice bakın:
>>> "\x41"
'A'
Onaltılı sayma sistemindeki 41 sayısı ‘A’ harfine karşılık gelir. Eğer hangi karakterlerin hangi sayılara karşılık geldiğini merak ediyorsanız https://ascii.cl/ adresindeki tabloyu inceleyebilirsiniz. Bu tabloda ‘hex’ sütunu altında gösterilen sayılar onaltılı sayılar olup, ‘symbol’ sütununda gösterilen karakterlere karşılık gelirler. Örneğin ‘hex’ sütunundaki 4E sayısı ‘symbol’ sütunundaki ‘N’ harfine karşılık gelir. Bu durumu Python’la da teyit edebilirsiniz:
>>>"\x4E"
N
Eğer sayılarla karakterler arasındaki bağlantının tam olarak ne olduğunu bilmiyorsanız hiç endişe etmeyin. Birkaç bölüm sonra sayılarla karakterler arasında nasıl bir bağ olduğunu gayet ayrıntılı bir şekilde anlatacağız. Biz şimdilik yalnızca \x karakter dizisinin özel bir kaçış dizisine karşılık geldiğini ve bu kaçış dizisini karakter dizileri içinde kullanırken dikkatli olmamız gerektiğini bilelim yeter:
>>> print("C:\Users\Ayşe\xp_dosyaları")
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 2-4: truncated \UXXXXXXXX escape
Gördüğünüz gibi, Python \x ifadesinden sonra onaltılı bir sayı belirtmenizi bekliyor. Halbuki biz burada \x ifadesini ‘xp_dosyaları’ adlı dizini gösterebilmek için kullanmıştık. Ama görünüşe göre yanlışlıkla Python için özel bir anlam ifade eden bir karakter dizisi oluşturmuşuz…
Etkisizleştirme (r)¶
Dediğimiz gibi, Python’daki en temel kaçış dizisi \ işaretidir. Bu işaret bazı başka harflerle birleşerek yeni kaçış dizileri de oluşturabilir.
Python’da \ işaretinin dışında temel bir kaçış dizisi daha bulunur. Bu kaçış dizisi ‘r’ harfidir. Şimdi bu kaçış dizisinin nasıl kullanılacağını ve ne işe yaradığını inceleyelim:
Şöyle bir çıktı vermek istediğimizi düşünün:
Kurulum dizini: C:\aylar\nisan\toplam masraf
Bildiğimiz yoldan bu çıktıyı vermeye çalışırsak neler olacağını adınız gibi biliyorsunuz:
>>> print("Kurulum dizini: C:\aylar\nisan\toplam masraf")
Kurulum dizini: C:ylar
isan oplam masraf
Not
Eğer Windows üzerinde çalışıyorsanız bu komutu verdikten sonra bir !bip! sesi de duymuş olabilirsiniz…
Python tabii ki, karakter dizisi içinde geçen ‘\aylar’, ‘\nisan’, ve ‘\toplam masraf’ ifadelerinin ilk karakterlerini yanlış anladı! \a, \n ve \t gibi ifadeler Python’ın gözünde birer kaçış dizisi. Dolayısıyla Python \a karakterlerini görünce bir !bip! sesi çıkarıyor, \n karakterlerini görünce satır başına geçiyor ve \t karakterlerini görünce de Tab tuşuna basılmış gibi bir tepki veriyor. Sonuç olarak da yukarıdaki gibi bir çıktı üretiyor.
Daha önce bu durumu şöyle bir kod yazarak engellemiştik:
>>> print("Kurulum dizini: C:\\aylar\\nisan\\toplam masraf")
Kurulum dizini: C:\aylar\nisan\toplam masraf
Burada, \ işaretlerinin her birini çiftleyerek sorunun üstesinden geldik. Yukarıdaki yöntem doğru ve kabul görmüş bir çözümdür. Ama bu sorunun üstesinden gelmenin çok daha basit ve pratik bir yolu var. Bakalım:
>>> print(r"Kurulum dizini: C:\aylar\nisan\toplam masraf")
Kurulum dizini: C:\aylar\nisan\toplam masraf
Gördüğünüz gibi, karakter dizisinin baş kısmının dış tarafına bir adet r harfi yerleştirerek sorunun üstesinden geliyoruz. Bu kaçış dizisinin, kullanım açısından öteki kaçış dizilerinden farklı olduğuna dikkat edin. Öteki kaçış dizileri karakter dizisinin içinde yer alırken, bu kaçış dizisi karakter dizisinin dışına yerleştiriliyor.
Bu kaçış dizisinin tam olarak nasıl işlediğini görmek için dilerseniz bir örnek daha verelim:
>>> print("Kaçış dizileri: \, \n, \t, \a, \\, r")
Kaçış dizileri: \,
, , , \, r
Burada da Python bizim yapmak istediğimiz şeyi anlayamadı ve karakter dizisi içinde geçen kaçış dizilerini doğrudan ekrana yazdırmak yerine bu kaçış dizilerinin işlevlerini yerine getirmesine izin verdi. Tıpkı biraz önceki örnekte olduğu gibi, istersek kaçış dizilerini çiftleyerek bu sorunu aşabiliriz:
>>> print("Kaçış dizileri: \\, \\n, \\t, \\a, \\\, r")
Kaçış dizileri: \, \n, \t, \a, \\, r
Ama tabii ki bunun çok daha kolay bir yöntemi olduğunu biliyorsunuz:
>>> print(r"Kaçış dizileri: \, \n, \t, \a, \\, r")
Kaçış dizileri: \, \n, \t, \a, \\, r
Gördüğünüz gibi, karakter dizisinin başına getirdiğimiz r kaçış dizisi, karakter dizisi içinde geçen kaçış dizilerinin işlevlerini yerine getirmesine engel olarak, istediğimiz çıktıyı elde etmemizi sağlıyor.
Bu arada bu kaçış dizisini, daha önce öğrendiğimiz \r adlı kaçış dizisi ile karıştırmamaya dikkat ediyoruz.
Python’daki bütün kaçış dizilerinden söz ettiğimize göre, konuyu kapatmadan önce önemli bir ayrıntıdan söz edelim.
Python’da karakter dizilerinin sonunda sadece çift sayıda \ işareti bulunabilir. Tek sayıda \ işareti kullanıldığında karakter dizisini bitiren tırnak işareti etkisizleşeceği için çakışma sorunu ortaya çıkar. Bu etkisizleşmeyi, karakter dizisinin başına koyduğunuz ‘r’ kaçış dizisi de engelleyemez. Yani:
>>> print("Kaçış dizisi: \")
Bu şekilde bir tanımlama yaptığımızda Python bize bir hata mesajı gösterir. Çünkü kapanış tırnağının hemen öncesine yerleştirdiğimiz \ kaçış dizisi, Python’ın karakter dizisini kapatan tırnak işaretini görmezden gelmesine yol açarak bu tırnağı etkisizleştiriyor. Böylece sanki karakter dizisini tanımlarken kapanış tırnağını hiç yazmamışız gibi bir sonuç ortaya çıkıyor:
>>> print("Kaçış dizisi: \")
File "<stdin>", line 1
print("Kaçış dizisi: \")
^
SyntaxError: EOL while scanning string literal
Üstelik bu durumu, r adlı kaçış dizisi de engelleyemiyor:
>>> print(r"Kaçış dizisi: \")
File "<stdin>", line 1
print(r"Kaçış dizisi: \")
^
SyntaxError: EOL while scanning string literal
Çözüm olarak birkaç farklı yöntemden yararlanabilirsiniz. Mesela karakter dizisini kapatmadan önce karakter dizisinin sonundaki \ işaretinin sağına bir adet boşluk karakteri yerleştirmeyi deneyebilirsiniz:
>>> print("Kaçış dizisi: \ ")
Veya kaçış dizisini çiftleyebilirsiniz:
>>> print("Kaçış dizisi: \\")
Ya da karakter dizisi birleştirme yöntemlerinden herhangi birini kullanabilirsiniz:
>>> print("Kaçış dizisi: " + "\\")
>>> print("Kaçış dizisi:", "\\")
>>> print("Kaçış dizisi: " "\\")
Böyle bir durumla ilk kez karşılaştığınızda bunun Python programlama dilinden kaynaklanan bir hata olduğunu düşünebilirsiniz, ancak bu durum Python’ın resmi internet sitesinde ‘Sıkça Sorulan Sorular’ bölümüne alınacak kadar önemli bir tasarım tercihidir: https://docs.python.org/2/faq/design.html#why-can-t-raw-strings-r-strings-end-with-a-backslash
Sayfa Başı (\f)¶
\f artık günümüzde pek kullanılmayan bir kaçış dizisidir. Bu kaçış dizisinin görevi, özellikle eski yazıcılarda, bir sayfanın sona erip yeni bir sayfanın başladığını göstermektir. Dolayısıyla eski model yazıcılar, bu karakteri gördükleri noktada mevcut sayfayı sona erdirip yeni bir sayfaya geçer.
Bu kaçış dizisinin tam olarak ne işe yaradığını test etmek için şu kodları çalıştırın:
>>> f = open("deneme.txt", "w")
>>> print("deneme\fdeneme", file=f)
>>> f.close()
Şimdi bu kodlarla oluşturduğunuz deneme.txt adlı dosyayı LibreOffice veya Microsoft Word gibi bir programla açın. ‘deneme’ satırlarının iki farklı sayfaya yazdırıldığını göreceksiniz. Bu arada, eğer Microsoft Word dosyayı açarken bir hata mesajı gösterirse, o hata mesajına birkaç kez ‘tamam’ diyerek hata penceresini kapatın. Dosya normal bir şekilde açılacaktır.
Dediğimiz gibi, bu kaçış dizisi artık pek kullanılmıyor. Ama yine de bu kaçış dizisine karşı da uyanık olmalısınız. Çünkü bu kaçış dizisi de beklemediğiniz çıktılar almanıza yol açabilir. Mesela şu örneğe bir bakalım:
>>> "\fırat"
'\x0cırat'
Gördüğünüz gibi, siz aslında ‘\fırat’ yazmak isterken, Python bu kelimenin baş tarafındaki \f karakter dizisini bir kaçış dizisi olarak değerlendirip ona göre bir çıktı verdi.
Bütün bu anlattıklarımızın ardından, kaçış dizilerinin, birleştirildikleri karakterlerin farklı bir anlam yüklenmesini sağlayan birtakım işaretler olduğunu anlıyoruz. Örneğin \ işareti ‘ (tek tırnak) işareti ile bir araya gelerek, tek tırnak işaretinin karakter dizisi tanımlama dışında başka bir anlam yüklenmesini sağlıyor. Aynı şekilde yine \ işareti “ (çift tırnak) işareti ile birleşerek çift tırnak işaretinin de karakter dizisi tanımlama dışında bir anlama kavuşmasını sağlıyor. Böylece tırnak işaretlerini karakter dizileri içinde rahatlıkla kullanabiliyoruz.
Ya da yine \ işareti ‘n’ harfi ile bir araya gelip, bu harfin satır başına geçilmesini sağlayan bir kaçış dizisi oluşturmasını mümkün kılıyor. Veya aynı işaret ‘t’ harfiyle birleşip, öğeler arasında sekme oluşturulmasını sağlayabiliyor. Bu araçlar sayesinde ekrana yazdırdığımız bir metnin akışını kontrol etme imkanına kavuşuyoruz.
Kaçış Dizilerine Toplu Bakış¶
Biraz sonra bu önemli konuyu kapatacağız. Ama dilerseniz kapatmadan önce, bu bölümde öğrendiğimiz kaçış dizilerini şöyle bir topluca görelim:
Kaçış Dizisi |
Anlamı |
---|---|
\’ |
Karakter dizisi içinde tek tırnak işaretini kullanabilmemizi sağlar. |
\” |
Karakter dizisi içinde çift tırnak işaretini kullanabilmemizi sağlar. |
\\ |
Karakter dizisi içinde \ işaretini kullanabilmemizi sağlar. |
\n |
Yeni bir satıra geçmemizi sağlar. |
\t |
Karakterler arasında sekme boşluğu bırakmamızı sağlar. |
\u |
UNICODE kod konumlarını gösterebilmemizi sağlar. |
\U |
UNICODE kod konumlarını gösterebilmemizi sağlar. |
\N |
Karakterleri UNICODE adlarına göre kullanabilmemizi sağlar. |
\x |
Onaltılı sistemdeki bir sayının karakter karşılığını gösterebilmemizi sağlar. |
\a |
Destekleyen sistemlerde, kasa hoparlöründen bir ‘bip’ sesi verilmesini sağlar. |
\r |
Aynı satırın başına dönülmesini sağlar. |
\v |
Destekleyen sistemlerde düşey sekme oluşturulmasını sağlar. |
\b |
İmlecin sola doğru kaydırılmasını sağlar |
\f |
Yeni bir sayfaya geçilmesini sağlar. |
r |
Karakter dizisi içinde kaçış dizilerini kullanabilmemizi sağlar. |
Kaçış dizileriyle ilgili son olarak şunu söyleyebiliriz: Kaçış dizileri, görmezden gelebileceğiniz, ‘öğrenmesem de olur,’ diyebileceğiniz önemsiz birtakım işaretler değildir. Bu konu boyunca verdiğimiz örneklerden de gördüğünüz gibi, kaçış dizileri, kullanıcıya göstereceğiniz metinlerin biçimini doğrudan etkiliyor. Bütün bu örnekler, bu kaçış dizilerinin yersiz veya yanlış kullanılmasının ya da bunların bir metin içinde gözden kaçmasının, yazdığınız programların hata verip çökmesine, yani programınızın durmasına sebep olabileceğini de gösteriyor bize.
Böylece bir bölümü daha bitirmiş olduk. Artık Python’la ‘gerçek’ programlar yazmamızın önünde hiçbir engel kalmadı.
Programları Kaydetme ve Çalıştırma¶
Bu noktaya kadar bütün işlerimizi Python’ın etkileşimli kabuğu üzerinden hallettik. Her ne kadar etkileşimli kabuk son derece kullanışlı bir ortam da olsa, bizim asıl çalışma alanımız değildir. Daha önce de dediğimiz gibi, etkileşimli kabuğu genellikle ufak tefek Python kodlarını test etmek için kullanacağız. Ama asıl programlarımızı tabii ki etkileşimli kabuğa değil, program dosyasına yazacağız.
Ne dedik? Özellikle küçük kod parçaları yazıp bunları denemek için etkileşimli kabuk mükemmel bir ortamdır. Ancak kodlar çoğalıp büyümeye başlayınca bu ortam yetersiz gelmeye başlayacaktır. Üstelik tabii ki yazdığınız kodları bir yere kaydedip saklamak isteyeceksiniz. İşte burada metin düzenleyiciler devreye girecek.
Python kodlarını yazmak için istediğiniz herhangi bir metin düzenleyiciyi kullanabilirsiniz. Hatta Notepad bile olur. Ancak Python kodlarını ayırt edip renklendirebilen bir metin düzenleyici ile yola çıkmak her bakımdan hayatınızı kolaylaştıracaktır.
Not
Python kodlarınızı yazmak için Microsoft Word veya OpenOffice.Org OOWriter gibi, belgeleri ikili (binary) düzende kaydeden programlar uygun değildir. Kullanacağınız metin düzenleyici, belgelerinizi düz metin (plain text) biçiminde kaydedebilmeli.
Biz bu bölümde farklı işletim sistemlerinde, metin düzenleyici kullanılarak Python programlarının nasıl yazılacağını ve bunların nasıl çalıştırılacağını tek tek inceleyeceğiz.
Daha önce de söylediğimiz gibi, hangi işletim sistemini kullanıyor olursanız olun, hem Windows hem de GNU/Linux başlığı altında yazılanları okumalısınız.
Dilerseniz önce GNU/Linux ile başlayalım:
GNU/Linux¶
Eğer kullandığınız sistem GNU/Linux’ta Unity veya GNOME masaüstü ortamı ise başlangıç düzeyi için Gedit adlı metin düzenleyici yeterli olacaktır.
Eğer kullandığınız sistem GNU/Linux’ta KDE masaüstü ortamı ise Kwrite veya Kate adlı metin düzenleyicilerden herhangi birini kullanabilirsiniz. Şu aşamada kullanım kolaylığı ve sadeliği nedeniyle Kwrite önerilebilir.
İşe yeni bir Gedit belgesi açarak başlayalım. Yeni bir Gedit belgesi açmanın en kolay yolu Alt+F2 tuşlarına bastıktan sonra çıkan ekranda:
gedit
yazıp Enter düğmesine basmaktır.
Eğer Gedit yerine mesela Kwrite kullanıyorsanız, yeni bir Kwrite belgesi oluşturmak için Alt+F2 tuşlarına bastıktan sonra:
kwrite
komutunu vermelisiniz. Elbette kullanacağınız metin düzenleyiciye, komut vermek yerine, dağıtımınızın menüleri aracılığıyla da ulaşabilirsiniz.
Python kodlarımızı, karşımıza çıkan bu boş metin dosyasına yazıp kaydedeceğiz.
Aslında kodları metin dosyasına yazmakla etkileşimli kabuğa yazmak arasında çok fazla fark yoktur. Dilerseniz hemen bir örnek vererek ne demek istediğimizi anlatmaya çalışalım:
1. Boş bir Gedit ya da Kwrite belgesi açıyoruz ve bu belgeye şu kodları eksiksiz bir şekilde yazıyoruz:
tarih = "02.01.2012"
gün = "Pazartesi"
vakit = "öğleden sonra"
print(tarih, gün, vakit, "buluşalım", end=".\n")
2. Bu kodları yazıp bitirdikten sonra dosyayı masaüstüne randevu.py adıyla kaydedelim.
3. Sonra işletim sistemimize uygun bir şekilde komut satırına ulaşalım.
4. Ardından komut satırı üzerinden masaüstüne gelelim. (Bunun nasıl yapılacağını hatırlıyorsunuz, değil mi?)
5. Son olarak şu komutla programımızı çalıştıralım:
python3 randevu.py
Şöyle bir çıktı almış olmalıyız:
02.01.2012 Pazartesi öğleden sonra buluşalım.
Eğer bu çıktı yerine bir hata mesajı alıyorsanız bunun birkaç farklı sebebi olabilir:
Kodlarda yazım hatası yapmış olabilirsiniz. Bu ihtimali bertaraf etmek için yukarıdaki kodlarla kendi yazdığınız kodları dikkatlice karşılaştırın.
Kodlarınızı kaydettiğiniz randevu.py adlı dosyanın adını yanlış yazmış olabilirsiniz. Dolayısıyla
python3 randevu.py
komutu, var olmayan bir dosyaya atıfta bulunuyor olabilir.python3 randevu.py
komutunu verdiğiniz dizin konumu ile randevu.py dosyasının bulunduğu dizin konumu birbirinden farklı olabilir. Yani siz randevu.py dosyasını masaüstüne kaydetmişsinizdir, amapython3 randevu.py
komutunu yanlışlıkla başka bir dizin altında veriyor olabilirsiniz. Bu ihtimali ortadan kaldırmak için, önceki derslerde öğrendiğimiz yöntemleri kullanarak hangi dizin altında bulunduğunuzu kontrol edin. O anda içinde bulunduğunuz dizinin içeriğini listeleyerek, randevu.py dosyasının orada görünüp görünmediğini kontrol edebilirsiniz. Eğer program dosyanız bu listede görünmüyorsa, elbettepython3 randevu.py
komutu çalışmayacaktır.Geçen derslerde anlattığımız şekilde Python3’ü kaynaktan root haklarıyla derlemenize rağmen, derleme sonrasında /usr/bin/ dizini altına python3 adlı bir sembolik bağ oluşturmadığınız için
python3
komutu çalışmıyor olabilir.Eğer Python3’ü yetkisiz kullanıcı olarak derlediyseniz, $HOME/python/bin/ dizini altında hem
python3
adlı bir sembolik bağ oluşturmuş, hem de $HOME/python/bin/ dizinini YOL’a (PATH) eklemiş olmanız gerekirken bunları yapmamış olabilirsiniz.Asla unutmayın, Python’ın etkileşimli kabuğunu başlatmak için hangi komutu kullanıyorsanız, randevu.py dosyasını çalıştırmak için de aynı komutu kullanacaksınız. Yani eğer Python’ın etkileşimli kabuğunu
python3.7
gibi bir komutla çalıştırıyorsanız, programınızı dapython3.7
randevu.py
şeklinde çalıştırmanız gerekir. Aynı şekilde, eğer etkileşimli kabuğu meselapython
(veyapy3
) gibi bir komutla çalıştırıyorsanız, programınızı dapython randevu.py
(veyapy3 randevu.py
) şeklinde çalıştırmalısınız. Neticede etkileşimli kabuğu çalıştırırken de, bir program dosyası çalıştırırken de aslında temel olarak Python programlama dilini çalıştırmış oluyorsunuz. Python programını çalıştırırken bir dosya adı belirtmezseniz, yani Python’ı başlatan komutu tek başına kullanırsanız etkileşimli kabuk çalışmaya başlar. Ama eğer Python’ı başlatan komutla birlikte bir program dosyası ismi de belirtirseniz, o belirttiğiniz program dosyası çalışmaya başlar.
Kodlarınızı düzgün bir şekilde çalıştırabildiğinizi varsayarak yolumuza devam edelim…
Gördüğünüz gibi, kod dosyamızı çalıştırmak için python3
komutundan
yararlanıyoruz. Bu arada tekrar etmekte fayda var: Python’ın etkileşimli
kabuğunu çalıştırmak için hangi komutu kullanıyorsanız, dosyaya kaydettiğiniz
programlarınızı çalıştırmak için de aynı komutu kullanacaksınız.
Gelelim Windows kullanıcılarına…
Windows¶
Daha önce de söylediğimiz gibi, Python kodlarımızı yazmak için istediğimiz bir metin düzenleyiciyi kullanabiliriz. Hatta Notepad’i bile kullansak olur. Ancak Notepad’den biraz daha gelişmiş bir metin düzenleyici ile başlamak işinizi kolaylaştıracaktır.
Python programlama dilini öğrenmeye yeni başlayan Windows kullanıcıları için en uygun metin düzenleyici IDLE’dır. Başlat > Tüm Programlar > Python3.7 > IDLE (Python GUI) yolunu takip ederek IDLE’a ulaşabilirsiniz.
IDLE’ı açtığınızda şöyle bir ekranla karşılaşacaksınız:
Aslında bu ekran size bir yerlerden tanıdık geliyor olmalı. Dikkat ederseniz beyaz ekranın en sonunda bordo renkli bir >>> işareti var. Evet, tahmin ettiğiniz gibi, burası aslında Python’ın etkileşimli kabuğudur. Yani o siyah etkileşimli kabuk ekranında ne yapabilirseniz burada da aynı şeyi yapabilirsiniz. Dilerseniz kendi kendinize bazı denemeler yapın. Ama şu anda biz IDLE’ın bu özelliğini değil, metin düzenleyici olma özelliğini kullanacağız. O yüzden yolumuza devam ediyoruz.
Not
Dediğimiz gibi, yukarıda görünen ekran aslında Python’ın etkileşimli kabuğudur. Dolayısıyla biraz sonra göstereceğimiz kodları buraya yazmayacağız. Python programlama diline yeni başlayanların en sık yaptığı hatalardan biri de, kaydetmek istedikleri kodları yukarıda görünen ekrana yazmaya çalışmalarıdır. Unutmayın, Python’ın etkileşimli kabuğunda ne yapabiliyorsanız, IDLE’ı açtığınızda ilk karşınıza çıkan ekranda da onu yapabilirsiniz. Python’ın etkileşimli kabuğunda yazdığınız kodlar etkileşimli kabuğu kapattığınızda nasıl kayboluyorsa, yukarıdaki ekrana yazdığınız kodlar da IDLE’ı kapattığınızda kaybolur…
Bir önceki ekranda sol üst köşede File [Dosya] menüsü görüyorsunuz. Oraya tıklayın ve menü içindeki New Window [Yeni Pencere] düğmesine basın. Şöyle bir ekranla karşılaşacaksınız:
İşte Python kodlarımızı bu beyaz ekrana yazacağız. Şimdi bu ekrana şu satırları yazalım:
tarih = "02.01.2012"
gün = "Pazartesi"
vakit = "öğleden sonra"
print(tarih, gün, vakit, "buluşalım", end=".\n")
Bu noktadan sonra yapmamız gereken şey dosyamızı kaydetmek olacak. Bunun için File > Save as yolunu takip ederek programımızı masaüstüne randevu.py adıyla kaydediyoruz.
Şu anda programımızı yazdık ve kaydettik. Artık programımızı çalıştırabiliriz. Bunun için IDLE’da Run > Run Module yolunu takip etmeniz veya kısaca F5 tuşuna basmanız yeterli olacaktır. Bu iki yöntemden birini kullanarak programınızı çalıştırdığınızda şöyle bir çıktı elde edeceksiniz:
02.01.2012 Pazartesi öğleden sonra buluşalım.
Tebrikler! İlk Python programınızı yazıp çalıştırdınız… Eğer çalıştıramadıysanız veya yukarıdaki çıktı yerine bir hata mesajı aldıysanız muhtemelen kodları yazarken yazım hatası yapmışsınızdır. Kendi yazdığınız kodları buradaki kodlarla dikkatlice karşılaştırıp tekrar deneyin.
Şimdi gelin isterseniz yukarıda yazdığımız kodları şöyle bir kısaca inceleyelim.
Programımızda üç farklı değişken tanımladığımıza dikkat edin. Bu değişkenler
tarih, gün ve vakit adlı değişkenlerdir. Daha sonra bu değişkenleri
birbiriyle birleştiriyoruz. Bunun için print()
fonksiyonundan nasıl
yararlandığımızı görüyorsunuz. Ayrıca print()
fonksiyonunu kullanış
biçimimize de dikkat edin. Buradaki end parametresinin anlamını ve bunun ne
işe yaradığını artık gayet iyi biliyorsunuz. end parametresi yardımıyla
cümlenin en sonuna bir adet nokta yerleştirip, \n adlı kaçış dizisi
yardımıyla da bir alt satıra geçiyoruz.
Böylece basit bir Python programının temel olarak nasıl yazılıp bir dosyaya kaydedileceğini ve bu programın nasıl çalıştırılacağını öğrenmiş olduk.
Çalışma Ortamı Tavsiyesi¶
Bu bölümde, Python programları geliştirirken rahat bir çalışma ortamı elde edebilmek için yapmanız gerekenleri sıralayacağız. Öncelikle Windows kullanıcılarından başlayalım.
Windows Kullanıcıları¶
Windows’ta bir Python programı yazıp kaydettikten sonra bu programı komut
satırından çalıştırabilmek için, MS-DOS’u açıp, öncelikle cd
komutuyla
programın bulunduğu dizine ulaşmamız gerekir. İlgili dizine ulaştıktan sonra
programımızı python program_adı
komutuyla çalıştırabiliriz. Ancak bir süre
sonra, programı çalıştırmak için her defasında programın bulunduğu dizine
ulaşmaya çalışmak sıkıcı bir hal alacaktır. Ama bu konuda çaresiz değiliz.
Windows 7, istediğimiz dizin altında bir MS-DOS ekranı açabilmemiz için bize çok güzel bir kolaylık sunuyor. Normal şartlar altında mesela masaüstünde bir MS-DOS ekranı açabilmek için şu yolu izlemeniz gerekiyor:
Windows logolu tuşa ve R tuşuna birlikte bas,
Açılan pencereye
cmd
yazıp Enter düğmesine bas,Bu şekilde ulaştığın MS-DOS ekranında
cd Desktop
komutunu ver.
Bu üç adımla, MS-DOS ekranı üzerinden masaüstüne ulaşmış oluyoruz. Ama aslında bunun çok daha kolay bir yolu var: Masaüstüne sağ tıklarken Shift tuşunu da basılı tutarsanız, sağ-tık menüsünde ‘Komut penceresini burada aç’ adlı bir satır görürsünüz. İşte bu satıra tıklayarak, MS-DOS komut satırını tek harekette masaüstü konumunda çalıştırabilirsiniz. Elbette bu özellik sadece masaüstü için değil, bütün konumlar için geçerlidir. Yani bilgisayarınızda herhangi bir yere sağ tıklarken Shift tuşunu da basılı tutarak o konumda bir MS-DOS penceresi açabilirsiniz.
Ayrıca, herhangi bir klasör açıkken dosya tarayıcısının adres çubuğuna cmd
yazıp Enter düğmesine basarak da, o klasörün bulunduğu konumda bir komut
ekranı açabilirsiniz. Örneğin eğer o anda önünüzde ‘İndirilenler’ (veya
‘Karşıdan Yüklenenler’) dizini açıksa, adres çubuğuna (aşağıdaki resimde kırmızı
ile gösterilen bölge) cmd
yazarak C:\Users\Kullanıcı\Downloads>
konumunda bir komut ekranı açabilirsiniz.
İkinci olarak, çalışma kolaylığı açısından Windows’ta dosya uzantılarının her zaman görünmesini sağlamanızı da tavsiye ederim. Windows ilk kurulduğunda hiçbir dosyanın uzantısı görünmez. Yani mesela deneme.txt adlı bir dosya Windows ilk kurulduğunda deneme şeklinde görünecektir. Bu durumda, bir dosyanın uzantısını değiştirmek istediğinizde bazı sıkıntılar yaşarsınız. Örneğin, masaüstünde bir metin dosyası oluşturduğunuzu varsayalım. Diyelim ki amacınız bu dosyanın içine bir şeyler yazıp daha sonra mesela bu dosyanın uzantısını .bat veya .py yapmak olsun. Böyle bir durumda, dosya uzantılarını göremediğiniz için, metin dosyasının uzantısını değiştirmeye çalıştığınızda deneme.bat.txt gibi bir dosya adı elde edebilirsiniz. Tabii ki bu dosya bir .bat dosyası değil, bir .txt, yani metin dosyasıdır. Dolayısıyla aslında dosya uzantısını değiştirememiş oluyorsunuz.
Yukarıdaki nedenlerden ötürü, ben size şu yolu takip ederek dosya uzantılarını her zaman görünür hale getirmenizi öneririm:
Başlat > Denetim Masası yolunu takip ederek denetim masasına ulaşın,
Denetim masasında ‘Görünüm ve Kişiselleştirme’ seçeneğine tıklayın,
Açılan menünün sağ tarafında ‘Klasör Seçenekleri’ satırına tıklayın,
Açılan pencerede ‘Görünüm’ sekmesine tıklayın,
‘Gelişmiş Ayarlar’ listesinde ‘Bilinen dosya türleri için uzantıları gizle’ seçeneğinin yanındaki onay işaretini kaldırın,
Uygula ve Tamam düğmelerine basarak bütün pencereleri kapatın,
Artık bütün dosyalarınızın uzantısı da görüneceği için, uzantı değiştirme işlemlerini çok daha kolay bir şekilde halledebilirsiniz.
GNU/Linux Kullanıcıları¶
Eğer KDE temelli bir GNU/Linux dağıtımı kullanıyorsanız, yazıp kaydettiğiniz Python programını barındıran dizin açıkken F4 tuşuna bastığınızda, komut satırı o dizin altında açılacaktır.
Unity ve GNOME kullanıcılarının ise benzer bir kolaylığa ulaşmak için nautilus-open-terminal adlı betiği sistemlerine kurmaları gerekiyor. Eğer Ubuntu kullanıyorsanız bu betiği şu komutla kurabilirsiniz:
sudo apt-get install nautilus-open-terminal
Bu betiği kurduktan sonra bilgisayarınızı yeniden başlatın veya şu komutu verin:
killall nautilus
Artık komut satırını hangi dizin altında başlatmak istiyorsanız o dizine sağ tıklayın. Menüler arasında Open in Terminal [Uçbirimde aç] adlı bir seçenek göreceksiniz. Buna tıkladığınızda o dizin altında bir komut satırı penceresi açılacaktır.
Metin Düzenleyici Ayarları¶
Daha önce de söylediğimiz gibi, Python ile program yazmak için istediğiniz metin düzenleyiciyi kullanabilirsiniz. Ama kodlarınızın kusursuz görünmesi ve hatasız çalışması için kullandığınız metin düzenleyicide birtakım ayarlamalar yapmanız gerekir. İşte bu bölümde bu ayarların neler olduğunu göstereceğiz.
Eğer programlarınızı IDLE ile yazıyorsanız aslında bir şey yapmanıza gerek yok. IDLE Python ile program yazmak üzere tasarlanmış bir düzenleyici olduğu için bu programın bütün ayarları Python ile uyumludur. Ama eğer IDLE dışında bir metin düzenleyici kullanıyorsanız bu düzenleyicide temel olarak şu ayarları yapmanız gerekir:
Sekme genişliğini [TAB width] 4 olarak ayarlayın.
Girinti genişliğini [Indent width] 4 olarak ayarlayın.
Girintilemede sekme yerine boşluk kullanmayı tercih edin [Use spaces instead of tabs]
Tercih edilen kodlama biçimini [Preferred encoding] utf-8 olarak ayarlayın.
Özellikle son söylediğimiz ‘kodlama biçimi’ ayarı çok önemlidir. Bu ayarın yanlış olması halinde, yazdığınız programı çalıştırmak istediğinizde şöyle bir hata alabilirsiniz:
SyntaxError: Non-UTF-8 code starting with '\xfe' in file deneme.py on line 1,
but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
Eğer yazdığınız bir program böyle bir hata mesajı üretiyorsa, ilk olarak metin düzenleyicinizin kodlama biçimi (encoding) ayarlarını kontrol edin. Metin düzenleyiciler genellikle tercih edilen kodlama biçimini aşağıdaki örnek resimde görüldüğü gibi, durum çubuğunda sürekli olarak gösterir.
Ancak kodlama biçimi doğru bir şekilde utf-8 olarak ayarlanmış metin düzenleyicilerde, özellikle internet üzerinden kod kopyalanıp yapıştırılması sırasında bu ayar siz farkında olmadan değişebilir. Böyle bir durumda da program çalışırken yukarıda bahsedilen hatayı alabilirsiniz. Dolayısıyla, programınızı yazdığınız metin düzenleyicinin kodlama ayarlarının siz farkında olmadan değişme ihtimaline karşı uyanık olmanız gerekir.
Elbette piyasada yüzlerce metin düzenleyici olduğu için yukarıda bahsedilen ayarların her metin düzenleyicide nasıl yapılacağını tek tek göstermemiz mümkün değil. Ancak iyi bir metin düzenleyicide yukarıdaki ayarların hepsi bulunur. Tek yapmanız gereken, bu ayarların, kullandığınız metin düzenleyicide nereden yapıldığını bulmak. Eğer kullandığınız metin düzenleyiciyi ayarlamakta zorlanıyorsanız, her zamanki gibi yazbel adresinde sıkıntınızı dile getirebilirsiniz.
‘Kodlama biçimi’ kavramından söz etmişken, Python’la ilgili önemli bir konuya daha değinelim. En başta da söylediğimiz gibi, şu anda piyasada Python iki farklı seri halinde geliştiriliyor. Bunlardan birinin 2.x serisi, öbürünün de 3.x serisi olduğunu biliyoruz. Python’ın 2.x serisinde Türkçe karakterlerin gösterimi ile ilgili çok ciddi problemler vardı. Örneğin Python’ın 2.x serisinde şöyle bir kod yazamıyorduk:
print("Günaydın Şirin Baba!")
Bu kodu bir dosyaya kaydedip, Python’ın 2.x serisine ait bir sürümle çalıştırmak istediğimizde Python bize şöyle bir hata mesajı veriyordu:
SyntaxError: Non-ASCII character '\xc3' in file
test.py on line 1, but no encoding declared;
see http://www.python.org/peps/pep-0263.html for details
Bunun sebebi, Python’ın 2.x sürümlerinde ASCII adlı kodlama biçiminin kullanılıyor olmasıdır. Zaten hata mesajına baktığımızda da, Python’ın ASCII olmayan karakterlerin varlığından şikayet ettiğini görüyoruz.
Yukarıdaki kodların çalışabilmesi için programımıza şöyle bir ekleme yapmamız gerekiyordu:
# -*- coding: utf-8 -*-
print("Günaydın Şirin Baba!")
Buradaki ilk satıra dikkat edin. Bu kodlarla yaptığımız şey, Python’ın ASCII adlı kodlama biçimi yerine UTF-8 adlı kodlama biçimini kullanmasını sağlamaktır. ASCII adlı kodlama biçimi Türkçe karakterleri gösteremez, ama UTF-8 adlı kodlama biçimi Türkçe karakterleri çok rahat bir şekilde gösterebilir.
Not
Kodlama biçimlerinden, ileride ayrıntılı bir şekilde söz edeceğiz. O yüzden bu anlattıklarımızda eğer anlamadığınız yerler olursa bunlara takılmanıza gerek yok.
Python’ın 3.x serisinin gelişi ile birlikte Python’da öntanımlı olarak ASCII
yerine UTF-8 kodlama biçimi kullanılmaya başlandı. Dolayısıyla yazdığımız
programlara # -*- coding: utf-8 -*-
satırını eklememize gerek kalmadı. Çünkü
zaten Python UTF-8 kodlama biçimini öntanımlı olarak kendisi kullanıyor. Ama
eğer UTF-8 dışında başka bir kodlama biçimine ihtiyaç duyarsanız yine bu
satırdan yararlanabilirsiniz.
Örneğin GNU/Linux dağıtımlarının geleneksel olarak UTF-8 kodlama biçimi ile arası iyidir. Dolayısıyla eğer GNU/Linux üzerinde Python programları geliştiriyorsanız bu satırı hiç yazmadan bir ömür geçirebilirsiniz. Ama Windows işletim sistemleri UTF-8’i desteklemekle birlikte, bu destek GNU/Linux’taki kadar iyi değildir. Dolayısıyla zaman zaman Windows’ta UTF-8 dışında başka bir kodlama biçimini kullanmanız gerekebilir. Örneğin yazdığınız bir programda Türkçe karakterleri göremiyorsanız, programınızın ilk satırını şöyle düzenleyebilirsiniz:
# -*- coding: cp1254 -*-
Burada UTF-8 yerine cp1254 adlı kodlama biçimini kullanmış oluyoruz. Windows işletim sisteminde cp1254 adlı kodlama biçimi UTF-8’e kıyasla daha fazla desteklenir.
MS-DOS Komut Satırı Ayarları¶
Eğer yukarıda anlattığımız bütün ayarları doğru bir şekilde yapmanıza rağmen, özellikle MS-DOS komut satırında hala Türkçe karakterleri düzgün görüntüleyemiyorsanız, kullandığınız Windows sürümünün komut satırı, öntanımlı olarak Türkçe karakterleri gösteremeyen bir yazı tipine ayarlanmış olabilir. Dolayısıyla Türkçe karakterleri gösterebilmek için öncelikle uygun bir yazı tipi seçmeniz gerekir. Bunun için şu basamakları takip ediyoruz:
Komut satırını açıyoruz,
Açılan pencerenin başlık çubuğuna sağ tıklayarak, ‘özellikler’ menüsüne giriyoruz,
‘Yazı tipi’ sekmesinde yazı tipi olarak ‘Lucida Console’u (veya varsa ‘Consolas’ı) seçiyoruz,
‘Tamam’ düğmesine basıyoruz.
Eğer önünüze bir onay penceresi açılırsa, ‘Özellikleri aynı başlıkla ileride oluşturulacak pencereler için kaydet’ seçeneğini işaretleyip ‘Tamam’a bastıktan sonra çıkıyoruz.
Bu işlemin nasıl yapılacağını gösteren bir videoyu http://media.istihza.com/videos/ms-dos.swf adresinden izleyebilirsiniz.
Böylece MS-DOS komut satırı için Türkçe karakterleri gösterebilen bir yazı tipi belirlemiş olduk. Ancak bu, Türkçe karakterleri düzgün görüntülemeye yetmeyebilir. Eğer Türkçe karakterler hala düzgün görünmüyorsa, kullandığınız sistemde MS-DOS’un dil kodlaması Türkçe karakterleri görüntülemeye uygun olmayabilir. Türkçe karakterleri gösterebilen bir dil kodlaması belirlemek için komut satırında şu komutu verin:
chcp 1254
CP1254, Türkçe karakterleri de içeren bir dil kodlamasıdır. Bu komutu verdikten sonra artık Türkçe karakterleri düzgün görüntüleyebiliyor olmanız lazım.
Program Örnekleri¶
Yukarıda Python ve programlamaya ilişkin pek çok teknik bilgi verdik. Bunları öğrenmemiz, işlerimizi kuru kuruya ezberleyerek değil, anlayarak yapmamızı sağlaması açısından büyük önem taşıyordu. Ancak yukarıda pratiğe yönelik pek bir şey sunamadık. İşte bu bölümde pratik eksikliğimizi biraz olsun kapamaya dönük örnekler yapacağız.
Hatırlarsanız Python’la tanışmamızı sağlayan ilk örneğimiz ekrana basit bir “Merhaba Zalim Dünya!” cümlesi yazdırmaktı. Bu ilk örneği etkileşimli kabukta verdiğimizi hatırlıyorsunuz:
>>> "Merhaba Zalim Dünya!"
Ama artık programlarımızı dosyaya kaydetmeyi öğrendiğimize göre bu kodları etkileşimli kabuğa yazmak yerine bir dosyaya yazmayı tercih edebiliriz. Bu sayede yazdığımız kodlar kalıcılık kazanacaktır.
Hemen bir deneme yapalım. Boş bir metin belgesi açıp oraya şu satırı yazalım:
"Merhaba Zalim Dünya!"
Şimdi de bu dosyayı daha önce anlattığımız şekilde masaüstüne deneme.py adıyla kaydedip programımızı çalıştıralım.
Ne oldu? Programınız hiçbir çıktı vermeden kapandı, değil mi?
Hemen hatırlayacağınız gibi, print()
fonksiyonu içine alınmayan ifadelerin
ekrana çıktı olarak verilebilmesi sadece etkileşimli kabuğa özgü bir durumdur.
Programlarımızı dosyadan çalıştırırken, print()
fonksiyonu içine alınmayan
ifadeler ekranda görünmeyecektir. Yukarıdaki örnek bu durumun bir göstergesidir.
Dolayısıyla yukarıdaki ifadenin ekrana çıktı olarak verilebilmesi için o kodu
şöyle yazmamız gerekiyor:
print("Merhaba Zalim Dünya!")
Programınızı bu şekilde tekrar çalıştırdığınızda şöyle bir çıktı alıyoruz:
Merhaba Zalim Dünya!
Bu oldukça basit bir örnekti. Şimdi biraz daha karmaşık bir örnek verelim.
Yine hatırlayacağınız gibi, önceki bölümlerden birinde aylık yol masrafımızı hesaplayan bir program yazmıştık.
Orada elimizdeki verilerin şunlar olduğunu varsaymıştık:
Cumartesi-Pazar günleri çalışmıyoruz.
Dolayısıyla ayda 22 gün çalışıyoruz.
Evden işe gitmek için kullandığımız vasıtanın ücreti 1.5 TL
İşten eve dönmek için kullandığımız vasıtanın ücreti 1.4 TL
Elimizdeki bu bilgilere göre aylık yol masrafımızı hesaplamak için de şöyle bir formül üretmiştik:
masraf = gün sayısı x (gidiş ücreti + dönüş ücreti)
Gelin şimdi yukarıdaki bilgileri kullanarak programımızı dosyaya yazalım:
gün = 22
gidiş_ücreti = 1.5
dönüş_ücreti = 1.4
masraf = gün * (gidiş_ücreti + dönüş_ücreti)
print(masraf)
Tıpkı öncekiler gibi, bu programı da masaüstüne deneme.py adıyla kaydedelim ve
komut satırında masaüstünün bulunduğu konuma giderek python3 deneme.py
komutuyla programımızı çalıştıralım. Programı çalıştırdığımızda şöyle bir çıktı
alıyoruz:
63.8
Programımız gayet düzgün çalışıyor. Ancak gördüğünüz gibi, elde ettiğimiz çıktı çok yavan. Ama eğer isterseniz yukarıdaki programa daha profesyonel bir görünüm de kazandırabilirsiniz. Dikkatlice inceleyin:
gün = 22
gidiş_ücreti = 1.5
dönüş_ücreti = 1.4
masraf = gün * (gidiş_ücreti + dönüş_ücreti)
print("-"*30)
print("çalışılan gün sayısı\t:", gün)
print("işe gidiş ücreti\t:", gidiş_ücreti)
print("işten dönüş ücreti\t:", dönüş_ücreti)
print("-"*30)
print("AYLIK YOL MASRAFI\t:", masraf)
Bu defa programımız şöyle bir çıktı verdi:
------------------------------
çalışılan gün sayısı : 22
işe gidiş ücreti : 1.5
işten dönüş ücreti : 1.4
------------------------------
AYLIK YOL MASRAFI : 63.8
Gördüğünüz gibi, bu kodlar sayesinde kullanıcıya daha ayrıntılı bilgi vermiş olduk. Üstelik elde ettiğimiz çıktı daha şık görünüyor.
Yukarıdaki kodlarda şimdiye kadar öğrenmediğimiz hiçbir şey yok. Yukarıdaki kodların tamamını anlayabilecek kadar Python bilgimiz var. Bu kodlarda çok basit parçaları bir araya getirerek istediğimiz çıktıyı nasıl elde ettiğimizi dikkatlice inceleyin. Mesela elde etmek istediğimiz çıktının görünüşünü güzelleştirmek için iki yerde şu satırı kullandık:
print("-"*30)
Böylece 30 adet - işaretini yan yana basmış olduk. Bu sayede elde ettiğimiz çıktı daha derli toplu bir görünüme kavuştu. Ayrıca kodlarımız içinde \t adlı kaçış dizisinden de yararlandık. Böylelikle ekrana basılan çıktılar alt alta düzgün bir şekilde hizalanmış oldu.
Bu arada, yukarıdaki kodlar sayesinde değişken kullanımının işlerimizi ne kadar kolaylaştırdığına da birebir tanık olduk. Eğer değişkenler olmasaydı yukarıdaki kodları şöyle yazacaktık:
print("-"*30)
print("çalışılan gün sayısı\t:", 22)
print("işe gidiş ücreti\t:", 1.5)
print("işten dönüş ücreti\t:", 1.4)
print("-"*30)
print("AYLIK YOL MASRAFI\t:", 22 * (1.5 + 1.4))
Eğer günün birinde mesela çalışılan gün sayısı değişirse yukarıdaki kodların iki farklı yerinde değişiklik yapmamız gerekecekti. Bu kodların çok büyük bir programın parçası olduğunu düşünün. Kodların içinde değer arayıp bunları tek tek değiştirmeye kalkışmanın ne kadar hataya açık bir yöntem olduğunu tahmin edebilirsiniz. Ama değişkenler sayesinde, sadece tek bir yerde değişiklik yaparak kodlarımızı güncel tutabiliriz. Mesela çalışılan gün sayısı 20’ye düşmüş olsun:
gün = 20
gidiş_ücreti = 1.5
dönüş_ücreti = 1.4
masraf = gün * (gidiş_ücreti + dönüş_ücreti)
print("-"*30)
print("çalışılan gün sayısı\t:", gün)
print("işe gidiş ücreti\t:", gidiş_ücreti)
print("işten dönüş ücreti\t:", dönüş_ücreti)
print("-"*30)
print("AYLIK YOL MASRAFI\t:", masraf)
Gördüğünüz gibi, sadece en baştaki gün adlı değişkenin değerini değiştirerek istediğimiz sonucu elde ettik.
Kendiniz isterseniz yukarıdaki örnekleri çeşitlendirebilirsiniz.
Gördüğünüz gibi, Python’da az da olsa işe yarar bir şeyler yazabilmek için çok şey bilmemize gerek yok. Sırf şu ana kadar öğrendiklerimizi kullanarak bile ufak tefek programlar yazabiliyoruz.
Yorum ve Açıklama Cümleleri¶
Python’la ilgili şimdiye kadar öğrendiğimiz bilgileri kullanarak yazabileceğimiz en karmaşık programlardan biri herhalde şöyle olacaktır:
isim = "Fırat"
soyisim = "Özgül"
işsis = "Ubuntu"
şehir = "İstanbul"
print("isim : ", isim, "\n",
"soyisim : ", soyisim, "\n",
"işletim sistemi: ", işsis, "\n",
"şehir : ", şehir, "\n",
sep="")
Yukarıdaki kodları rahatlıkla anlayabildiğinizi zannediyorum. Ama isterseniz yine de bu kodları satır satır inceleyelim:
İlk olarak isim, soyisim, işsis ve şehir adında dört farklı değişken tanımladık. Bu değişkenlerin değeri sırasıyla Fırat, Özgül, Ubuntu ve İstanbul.
Daha sonra da tanımladığımız bu değişkenleri belli bir düzen içinde
kullanıcılarımıza gösterdik, yani ekrana yazdırdık. Elbette bu iş için
print()
fonksiyonunu kullandık. Bildiğiniz gibi, print()
birden fazla
parametre alabilen bir fonksiyondur. Yani print()
fonksiyonunun parantezleri
içine istediğimiz sayıda öğe yazabiliriz.
Eğer print()
fonksiyonunun yukarıdaki kullanımı ilk bakışta gözünüze
anlaşılmaz göründüyse, fonksiyonda geçen ve ne işe yaradığını anlayamadığınız
öğeleri, bir de çıkartarak yazmayı deneyebilirsiniz bu fonksiyonu.
Python’la yazılmış herhangi bir programın tam olarak nasıl işlediğini anlamanın
en iyi yolu program içindeki kodlarda bazı değişiklikler yaparak ortaya çıkan
sonucu incelemektir. Örneğin print()
fonksiyonunda sep parametresinin
değerini boş bir karakter dizisi yapmamızın nedenini anlamak için, fonksiyondaki
bu sep parametresini kaldırıp, programı bir de bu şekilde çalıştırmayı
deneyebilirsiniz.
Yukarıdaki örnekte bütün öğeleri tek bir print()
fonksiyonu içine yazdık.
Ama tabii eğer isterseniz birden fazla print()
fonksiyonu da
kullanabilirsiniz. Şöyle:
isim = "Fırat"
soyisim = "Özgül"
işsis = "Ubuntu"
şehir = "İstanbul"
print("isim : ", isim)
print("soyisim : ", soyisim)
print("işletim sistemi: ", işsis)
print("şehir : ", şehir)
Yukarıdaki kodlarla ilgili birkaç noktaya daha dikkatinizi çekmek istiyorum:
Birincisi, gördüğünüz gibi kodları yazarken biraz şekil vererek yazdık. Bunun sebebi kodların görünüş olarak anlaşılır olmasını sağlamak. Daha önce de dediğimiz gibi, Python’da doğru kod yazmak kadar, yazdığınız kodların anlaşılır olması da önemlidir. Bu sebepten, Python’la kod yazarken, mesela kodlarımızdaki her bir satırın uzunluğunun 79 karakteri geçmemesine özen gösteriyoruz. Bunu sağlamak için, kodlarımızı yukarıda görüldüğü şekilde belli noktalardan bölmemiz gerekebilir.
Esasında yukarıdaki kodları şöyle de yazabilirdik:
isim = "Fırat"
soyisim = "Özgül"
işsis = "Ubuntu"
şehir = "İstanbul"
print("isim: ", isim, "\n", "soyisim: ", soyisim, "\n",
"işletim sistemi: ", işsis, "\n", "şehir: ", şehir, "\n", sep="")
Ancak bu şekilde kod yapısı biraz karmaşık görünüyor. Ayrıca parantez içindeki öğeleri yan yana yazdığımız için, isim:, soyisim:, işletim sistemi: ve şehir: ifadelerini alt alta düzgün bir şekilde hizalamak da kolay olmayacaktır.
Belki bu basit kodlarda çok fazla dikkati çekmiyordur, ama özellikle büyük boyutlu programlarda kodlarımızı hem yapı hem de görüntü olarak olabildiğince anlaşılır bir hale getirmek hem kodu okuyan başkaları için, hem de kendimiz için büyük önem taşır. Unutmayın, bir programı yazdıktan 5-6 ay sonra geri dönüp baktığınızda kendi yazdığınız kodlardan siz dahi hiçbir şey anlamadığınızı farkedebilirsiniz!
Bir program yazarken kodların olabildiğince okunaklı olmasını sağlamanın bir kaç yolu vardır. Biz bunlardan bazılarını yukarıda gördük. Ancak bir programı okunaklı hale getirmenin en iyi yolu kodlar içine bazı yorum cümleleri ekleyerek kodları açıklamaktır.
İşte bu bölümde, Python programlama dili ile yazdığımız kodlara nasıl yorum ve açıklama cümleleri ekleyeceğimizi inceleyeceğiz.
Yorum İşareti¶
Programcılıkta en zor şey başkasının yazdığı kodları okuyup anlamaktır. Hatta yazılmış bir programı düzeltmeye çalışmak, bazen o programı sıfırdan yazmaktan daha zor olabilir. Bunun nedeni, program içindeki kodların ne işe yaradığını anlamanın zorluğudur. Programı yazan kişi kendi düşünüşüne göre bir yol izlemiş ve programı geliştirirken karşılaştığı sorunları çözmek için kimi yerlerde enteresan çözümler üretmiş olabilir. Ancak kodlara dışarıdan bakan birisi için o programın mantık düzenini ve içindeki kodların tam olarak ne yaptığını anlamak bir hayli zor olacaktır. Böyle durumlarda, kodları okuyan programcının en büyük yardımcısı, programı geliştiren kişinin kodlar arasına eklediği notlar olacaktır. Tabii programı geliştiren kişi kodlara yorum ekleme zahmetinde bulunmuşsa…
Python’da yazdığımız kodları başkalarının da anlayabilmesini sağlamak için, programımızın yorumlarla desteklenmesi tavsiye edilir. Elbette programınızı yorumlarla desteklemeseniz de programınız sorunsuz bir şekilde çalışacaktır. Ama programı yorumlarla desteklemek en azından nezaket gereğidir.
Ayrıca işin başka bir boyutu daha var. Sizin yazdığınız kodları nasıl başkaları okurken zorlanıyorsa, kendi yazdığınız kodları okurken siz bile zorlanabilirsiniz. Özellikle uzun süredir ilgilenmediğiniz eski programlarınızı gözden geçirirken böyle bir sorunla karşılaşabilirsiniz. Programın içindeki bir kod parçası, programın ilk yazılışının üzerinden 5-6 ay geçtikten sonra size artık hiçbir şey ifade etmiyor olabilir. Kodlara bakıp, ‘Acaba burada ne yapmaya çalışmışım?’ diye düşündüğünüz zamanlar da olacaktır. İşte bu tür sıkıntıları ortadan kaldırmak veya en aza indirmek için kodlarımızın arasına açıklayıcı notlar ekleyeceğiz.
Python’da yorumlar # işareti ile gösterilir. Mesela bu bölümün ilk başında verdiğimiz kodları yorumlarla destekleyelim:
isim = "Fırat"
soyisim = "Özgül"
işsis = "Ubuntu" #işletim sistemi
şehir = "İstanbul"
#isim, soyisim, işsis ve şehir adlı değişkenleri
#alt alta, düzgün bir şekilde ekrana basıyoruz.
#Uygun yerlerde alt satıra geçebilmek için "\n"
#adlı kaçış dizisini kullanıyoruz.
print("isim : ", isim, "\n",
"soyisim : ", soyisim, "\n",
"işletim sistemi: ", işsis, "\n",
"şehir : ", şehir, "\n",
sep="") #parametreler arasında boşluk bırakmıyoruz.
Burada dikkat edeceğimiz nokta her yorum satırının başına # işaretini koymayı unutmamaktır.
Yazdığımız yorumlar Python’a hiç bir şey ifade etmez. Python bu yorumları tamamen görmezden gelecektir. Bu yorumlar bilgisayardan ziyade kodları okuyan kişi için bir anlam taşır.
Elbette yazdığınız yorumların ne kadar faydalı olacağı, yazdığınız yorumların kalitesine bağlıdır. Dediğimiz gibi, yerli yerinde kullanılmış yorumlar bir programın okunaklılığını artırır, ama her tarafı yorumlarla kaplı bir programı okumak da bazen hiç yorum girilmemiş bir programı okumaktan daha zor olabilir! Dolayısıyla Python’da kodlarımıza yorum eklerken önemli olan şey, kaş yapmaya çalışırken göz çıkarmamaktır. Yani yorumlarımızı, bir kodun okunaklılığını artırmaya çalışırken daha da bozmayacak şekilde yerleştirmeye dikkat etmeliyiz.
Yorum İşaretinin Farklı Kullanımları¶
Yukarıda yorum (#) işaretini kullanarak, yazdığımız Python kodlarını nasıl açıklayacağımızı öğrendik. Python’da yorum işaretleri çoğunlukla bu amaç için kullanılır. Yani kodları açıklamak, bu kodları hem kendimiz hem de kodları okuyan başkaları için daha anlaşılır hale getirmek için… Ama Python’da # işareti asıl amacının dışında bazı başka amaçlara da hizmet edebilir.
Etkisizleştirme Amaçlı¶
Dediğimiz gibi, yorum işaretinin birincil görevi, tabii ki, kodlara açıklayıcı notlar eklememizi sağlamaktır. Ama bu işaret başka amaçlar için de kullanılabilir. Örneğin, diyelim ki yazdığımız programa bir özellik eklemeyi düşünüyoruz, ama henüz bu özelliği yeni sürüme eklemek istemiyoruz. O zaman şöyle bir şey yapabiliriz:
isim = "Fırat"
soyisim = "Özgül"
işsis = "Ubuntu"
şehir = "İstanbul"
#uyruğu = "T.C"
print("isim : ", isim, "\n",
"soyisim : ", soyisim, "\n",
"işletim sistemi: ", işsis, "\n",
"şehir : ", şehir, "\n",
#"uyruğu : ", uyruğu, "\n",
sep="")
Burada, programa henüz eklemek istemediğimiz bir özelliği, yorum içine alarak
şimdilik iptal ediyoruz yani etkisizleştiriyoruz (İngilizcede bu yorum içine
alma işlemine comment out deniyor). Python yorum içinde bir kod bile yer alsa
o kodları çalıştırmayacaktır. Çünkü Python # işareti ile başlayan satırların
içeriğini görmez (#!/usr/bin/env python3
ve # -*- coding: utf-8 -*-
satırları hariç).
Peki eklemek istemediğimiz özelliği yorum içine almaktansa doğrudan silsek olmaz mı? Elbette olur. Ama programın daha sonraki bir sürümüne ilave edeceğimiz bir özelliği yorum içine almak yerine silecek olursak, vakti geldiğinde o özelliği nasıl yaptığımızı hatırlamakta zorlanabiliriz! Hatta bir süre sonra programımıza hangi özelliği ekleyeceğimizi dahi unutmuş olabiliriz. ‘Hayır, ben hafızama güveniyorum!’ diyorsanız karar sizin.
Yorum içine alarak iptal ettiğiniz bu kodları programa ekleme vakti geldiğinde yapacağınız tek şey, kodların başındaki # işaretlerini kaldırmak olacaktır. Hatta bazı metin düzenleyiciler bu işlemi tek bir tuşa basarak da gerçekleştirme yeteneğine sahiptir. Örneğin IDLE ile çalışıyorsanız, yorum içine almak istediğiniz kodları fare ile seçtikten sonra Alt+3 tuşlarına basarak ilgili kodları yorum içine alabilirsiniz. Bu kodları yorumdan kurtarmak için ise ilgili alanı seçtikten sonra Alt+4 tuşlarına basmanız yeterli olacaktır (yorumdan kurtarma işlemine İngilizcede uncomment diyorlar).
Süsleme Amaçlı¶
Bütün bunların dışında, isterseniz yorum işaretini kodlarınızı süslemek için dahi kullanabilirsiniz:
#######################################################
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# FALANCA v.1 #
# Yazan: Keramet Su #
# Lisans: GPL v2 #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#######################################################
isim = "Fırat"
soyisim = "Özgül"
işsis = "Ubuntu"
şehir = "İstanbul"
print("isim : ", isim, "\n",
"soyisim : ", soyisim, "\n",
"işletim sistemi: ", işsis, "\n",
"şehir : ", şehir, "\n",
sep="")
Yani kısaca, Python’un görmesini, çalıştırmasını istemediğimiz her şeyi yorum içine alabiliriz. Unutmamamız gereken tek şey, yorumların yazdığımız programların önemli bir parçası olduğu ve bunları mantıklı, makul bir şekilde kullanmamız gerektiğidir.
Kullanıcıdan Bilgi Almak¶
Şimdiye kadar Python programlama dili ile ilgili epey bilgi edindik. Ama muhtemelen buraya kadar öğrendiklerimiz sizi heyecanlandırmaktan bir hayli uzaktı. Zira şu ana kadar hep tek yönlü bir programlama faaliyeti yürüttük.
Mesela şimdiye kadar öğrendiklerimizi kullanarak ancak şöyle bir program yazabildik:
isim = "Mübeccel"
print("Merhaba", isim, end="!\n")
Bu programı çalıştırdığımızda şöyle bir çıktı alacağımızı biliyorsunuz:
Merhaba Mübeccel!
Bu programın ne kadar sıkıcı olduğunu herhalde söylemeye gerek yok. Bu programda isim değişkenini doğrudan kendimiz yazdığımız için programımız hiçbir koşulda Merhaba Mübeccel dışında bir çıktı veremez. Çünkü bu program, tek yönlü bir programlama faaliyetinin ürünüdür.
Halbuki bu değişkenin değerini kendimiz yazmasak, bu değeri kullanıcıdan alsak ne hoş olurdu, değil mi?
Python’da kullanıcıdan herhangi bir veri alıp, yazdığımız programları tek
taraflı olmaktan kurtarmak için input()
adlı bir fonksiyondan
faydalanıyoruz.
İşte biz bu bölümde, programcılık maceramızı bir üst seviyeye taşıyacak çok
önemli bir araç olan bu input()
fonksiyonunu derinlemesine inceleyeceğiz.
Ama bu bölümde sadece bu fonksiyonu ele almayacağız elbette. Burada kullanıcıdan
veri almanın yanısıra, aldığımız bu veriyi nasıl dönüştüreceğimizi ve bu veriyi,
yazdığımız programlarda nasıl kullanacağımızı da derin derin inceleyeceğiz.
İlkin input()
fonksiyonunu anlatarak yola koyulalım.
input() Fonksiyonu¶
input()
da daha önce öğrendiğimiz type()
, len()
ve print()
gibi
bir fonksiyondur. Esasında biz bu fonksiyonu ilk kez burada görmüyoruz. Windows
ve GNU/Linux kullanıcıları, yazdıkları bir programı çift tıklayarak
çalıştırabilmek için bu fonksiyonu kullandıklarını hatırlıyor olmalılar. Mesela
şu programı ele alalım:
#!/usr/bin/env python3
kartvizit = """
İstihza Anonim Şirketi
Fırat Özgül
Tel: 0212 123 23 23
Faks: 0212 123 23 24
e.posta: kistihza@yahoo.com
"""
print(kartvizit)
Bu programı yazıp kaydettikten sonra bu programın simgesi üzerine çift tıkladığımızda siyah bir komut ekranının çok hızlı bir şekilde açılıp kapandığını görürüz. Aslında programımız çalışıyor, ama programımız yapması gereken işi yaptıktan hemen sonra kapandığı için biz program penceresini görmüyoruz.
Programımızın çalıştıktan sonra hemen kapanmamasını sağlamak için son satıra bir
input()
fonksiyonu yerleştirmemiz gerektiğini biliyoruz:
#!/usr/bin/env python3
kartvizit = """
İstihza Anonim Şirketi
Fırat Özgül
Tel: 0212 123 23 23
Faks: 0212 123 23 24
e.posta: kistihza@yahoo.com
"""
print(kartvizit)
input()
Bu sayede programımız kullanıcıdan bir giriş bekleyecek ve o girişi alana kadar da kapanmayacaktır. Programı kapatmak için Enter düğmesine basabiliriz.
input()
bir fonksiyondur dedik. Henüz fonksiyon kavramının ayrıntılarını
öğrenmemiş olsak da, şimdiye kadar pek çok fonksiyon gördüğümüz için artık bir
fonksiyonla karşılaştığımızda bunun nasıl kullanılacağını az çok tahmin
edebiliyoruz. Tıpkı düşündüğünüz ve yukarıdaki örnekten de gördüğünüz gibi,
birer fonksiyon olan type()
, print()
, len()
ve open()
fonksiyonlarını nasıl kullanıyorsak input()
fonksiyonunu da öyle
kullanacağız.
Dilerseniz lafı daha fazla uzatmadan örnek bir program yazalım:
isim = input("İsminiz nedir? ")
print("Merhaba", isim, end="!\n")
Bu programı kaydedip çalıştırdığınızda, sorulan soruya verdiğiniz cevaba göre çıktı farklı olacaktır. Örneğin eğer bu soruya ‘Niyazi’ cevabını vermişseniz çıktınız Merhaba Niyazi! şeklinde olacaktır.
Görüyorsunuz ya, tıpkı daha önce gördüğümüz fonksiyonlarda olduğu gibi,
input()
fonksiyonunda da parantez içine bir parametre yazıyoruz. Bu
fonksiyona verilen parametre, kullanıcıdan veri alınırken kullanıcıya sorulacak
soruyu gösteriyor. Gelin isterseniz bir örnek daha yapalım elimizin alışması
için:
yaş = input("Yaşınız: ")
print("Demek", yaş, "yaşındasın.")
print("Genç mi yoksa yaşlı mı olduğuna karar veremedim.")
input()
fonksiyonunun ne kadar kullanışlı bir araç olduğu ortada. Bu
fonksiyon sayesinde, şimdiye kadar tek sesli bir şekilde yürüttüğümüz
programcılık faaliyetlerimizi çok sesli bir hale getirebileceğiz. Mesela önceki
bölümlerden birinde yazdığımız, daire alanı hesaplayan programı hatırlarsınız. O
zaman henüz dosyalarımızı kaydetmeyi ve input()
fonksiyonunu öğrenmediğimiz
için o programı etkileşimli kabukta şu şekilde yazmıştık:
>>> çap = 16
>>> yarıçap = çap / 2
>>> pi = 3.14159
>>> alan = pi * (yarıçap * yarıçap)
>>> alan
201.06176
Ama artık hem dosyalarımızı kaydetmeyi biliyoruz, hem de input()
fonksiyonunu öğrendik. Dolayısıyla yukarıdaki programı şu şekilde yazabiliriz:
#Kullanıcıdan dairenin çapını girmesini istiyoruz.
çap = input("Dairenin çapı: ")
#Kullanıcının verdiği çap bilgisini kullanarak
#yarıçapı hesaplayalım. Buradaki int() fonksiyonunu
#ilk kez görüyoruz. Biraz sonra bunu açıklayacağız
yarıçap = int(çap) / 2
#pi sayımız sabit
pi = 3.14159
#Yukarıdaki bilgileri kullanarak artık
#dairenin alanını hesaplayabiliriz
alan = pi * (yarıçap * yarıçap)
#Son olarak, hesapladığımız alanı yazdırıyoruz
print("Çapı", çap, "cm olan dairenin alanı: ", alan, "cm2'dir")
Gördüğünüz gibi, input()
fonksiyonunu öğrenmemiz sayesinde artık yavaş yavaş
işe yarar programlar yazabiliyoruz.
Ancak burada, daha önce öğrenmediğimiz bir fonksiyon dikkatinizi çekmiş olmalı.
Bu fonksiyonun adı int()
. Bu yeni fonksiyon dışında, yukarıdaki bütün
kodları anlayabilecek kadar Python bilgisine sahibiz.
int()
fonksiyonunun ne işe yaradığını anlamak için isterseniz ilgili satırı
yarıçap = çap / 2
şeklinde yazarak çalıştırmayı deneyin bu programı.
Dediğim gibi, eğer o satırdaki int()
fonksiyonunu kaldırarak programı
çalıştırdıysanız şuna benzer bir hata mesajı almış olmalısınız:
Traceback (most recent call last):
File "deneme.py", line 8, in <module>
yarıçap = çap / 2
TypeError: unsupported operand type(s) for /: 'str' and 'int'
Gördüğünüz gibi programımız bölme işlemini yapamadı. Buradan anlıyoruz ki, bu
int()
fonksiyonu programımızdaki aritmetik işlemin düzgün bir şekilde
yapılabilmesini sağlıyor. Gelelim bu fonksiyonun bu işlevi nasıl yerine
getirdiğini incelemeye.
Tip Dönüşümleri¶
Bir önceki bölümün sonunda verdiğimiz örnek programda int()
adlı bir
fonksiyon görmüş, bu fonksiyonu anlatmayı o zaman ertelemiştik. Çok gecikmeden,
bu önemli fonksiyonun ne işe yaradığını öğrenmemiz gerekiyor. İsterseniz bir
örnek üzerinden gidelim.
Diyelim ki kullanıcıdan aldığı sayının karesini hesaplayan bir program yazmak istiyoruz. Öncelikle şöyle bir şey deneyelim:
sayı = input("Lütfen bir sayı girin: ")
#Girilen sayının karesini bulmak için sayı değişkeninin 2.
#kuvvetini alıyoruz. Aynı şeyi pow() fonksiyonu ile de
#yapabileceğimizi biliyorsunuz. Örn.: pow(sayı, 2)
print("Girdiğiniz sayının karesi: ", sayı ** 2)
Bu kodları çalıştırdığımız zaman, programımız kullanıcıdan bir sayı girmesini isteyecek, ancak kullanıcı bir sayı girip Enter tuşuna bastığında şöyle bir hata mesajıyla karşılaşacaktır:
Traceback (most recent call last):
File "test.py", line 5, in <module>
print("Girdiğiniz sayının karesi: ", sayı ** 2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
Hata mesajına baktığınızda, ‘TypeError’ ifadesinden, bunun veri tipine ilişkin bir hata olduğunu tahmin edebilirsiniz. Eğer İngilizce biliyorsanız yukarıdaki hata mesajının anlamını rahatlıkla çıkarabilirsiniz. İngilizce bilmeseniz de en sondaki ‘str’ ve ‘int’ kelimeleri size karakter dizisi ve sayı adlı veri tiplerini hatırlatacaktır. Demek ki ortada veri tiplerini ilgilendiren bir sorun var…
Peki burada tam olarak neler dönüyor?
Hatırlayacaksınız, geçen derslerden birinde len()
fonksiyonunu anlatırken
şöyle bir şey söylemiştik:
Biz henüz kullanıcıdan nasıl veri alacağımızı bilmiyoruz. Ama şimdilik şunu söyleyebiliriz: Python’da kullanıcıdan herhangi bir veri aldığımızda, bu veri bize bir karakter dizisi olarak gelecektir.
Gelin isterseniz yukarıda anlattığımız durumu teyit eden bir program yazalım:
#Kullanıcıdan herhangi bir veri girmesini istiyoruz
sayı = input("Herhangi bir veri girin: ")
#Kullanıcının girdiği verinin tipini bir
#değişkene atıyoruz
tip = type(sayı)
#Son olarak kullanıcının girdiği verinin tipini
#ekrana basıyoruz.
print("Girdiğiniz verinin tipi: ", tip)
Bu programı çalıştırdığımızda ne tür bir veri girersek girelim, girdiğimiz
verinin tipi str, yani karakter dizisi olacaktır. Demek ki gerçekten de,
kullanıcıdan veri almak için kullandığımız input()
fonksiyonu bize her
koşulda bir karakter dizisi veriyormuş.
Geçen derslerde şöyle bir şey daha söylemiştik:
Python’da, o anda elinizde bulunan bir verinin hangi tipte olduğunu bilmek son derece önemlidir. Çünkü bir verinin ait olduğu tip, o veriyle neler yapıp neler yapamayacağınızı belirler.
Şu anda karşı karşıya olduğumuz durum da buna çok güzel bir örnektir. Eğer o anda elimizde bulunan verinin tipini bilmezsek tıpkı yukarıda olduğu gibi, o veriyi programımızda kullanmaya çalışırken programımız hata verir ve çöker.
Her zaman üstüne basa basa söylediğimiz gibi, aritmetik işlemler yalnızca
sayılarla yapılır. Karakter dizileri ile herhangi bir aritmetik işlem yapılamaz.
Dolayısıyla, input()
fonksiyonundan gelen veri bir karakter dizisi olduğu
için ve biz de programımızda girilen sayının karesini hesaplamak amacıyla bu
fonksiyondan gelen verinin 2. kuvvetini, yani karesini hesaplamaya
çalıştığımız için programımız hata verecektir.
Yukarıdaki programda neler olup bittiğini daha iyi anlayabilmek için Python’ın etkileşimli kabuğunda şu işlemleri 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'
Gördüğünüz gibi, programımızdan aldığımız hata ile yukarıdaki hata tamamen aynı
(hata mesajlarında bizi ilgilendiren kısım en son satırdır). Tıpkı burada olduğu
gibi, hata veren programda da ‘Lütfen bir sayı girin: ‘ sorusuna örneğin 23
cevabını verdiğimizde programımız aslında "23" ** 2
gibi bir işlem yapmaya
çalışıyor. Bir karakter dizisinin kuvvetini hesaplamak mümkün olmadığı, kuvvet
alma işlemi yalnızca sayılarla yapılabileceği için de hata vermekten başka
çaresi kalmıyor.
Ancak bazen öyle durumlarla karşılaşırsınız ki, programınız hiçbir hata vermez, ama elde edilen sonuç aslında tamamen beklentinizin dışındadır. Mesela şu basit örneği inceleyelim:
sayı1 = input("Toplama işlemi için ilk sayıyı girin: ")
sayı2 = input("Toplama işlemi için ikinci sayıyı girin: ")
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
Bu kodları çalıştırdığımızda şöyle bir manzarayla karşılaşırız:
input()
fonksiyonunun alttan alta neler çevirdiğini bu örnek yardımıyla çok
daha iyi anladığınızı zannediyorum. Gördüğünüz gibi yukarıdaki program herhangi
bir hata vermedi. Ama beklediğimiz çıktıyı da vermedi. Zira biz programımızın
iki sayıyı toplamasını istiyorduk. O ise kullanıcının girdiği sayıları yan yana
yazmakla yetindi. Yani bir aritmetik işlem yapmak yerine, verileri birbiriyle
bitiştirdi. Çünkü, dediğim gibi, input()
fonksiyonunun kullanıcıdan aldığı
şey bir karakter dizisidir. Dolayısıyla bu fonksiyon yukarıdaki gibi bir durumla
karşılaştığı zaman karakter dizileri arasında bir birleştirme işlemi
gerçekleştirir. Tıpkı ilk derslerimizde etkileşimli kabukta verdiğimiz şu
örnekte olduğu gibi:
>>> "23" + "23"
2323
Bu son örnekten ayrıca şunu çıkarıyoruz: Yazdığınız bir programın herhangi bir hata vermemesi o programın doğru çalıştığı anlamına gelmeyebilir. Dolayısıyla bu tür durumlara karşı her zaman uyanık olmanızda fayda var.
Peki yukarıdaki gibi durumlarla karşılaşmamak için ne yapacağız?
İşte bu noktada devreye tip dönüştürücü adını verdiğimiz birtakım fonksiyonlar girecek.
int()¶
Dediğimiz gibi, input()
fonksiyonundan gelen veri her zaman bir karakter
dizisidir. Dolayısıyla bu fonksiyondan gelen veriyle herhangi bir aritmetik
işlem yapabilmek için öncelikle bu veriyi bir sayıya dönüştürmemiz gerekir. Bu
dönüştürme işlemi için int()
adlı özel bir dönüştürücü fonksiyondan
yararlanacağız. Gelin isterseniz Python’ın etkileşimli kabuğunda bu fonksiyonla
bir kaç deneme yaparak bu fonksiyonun ne işe yaradığını ve nasıl kullanıldığını
anlamaya çalışalım. Zira etkileşimli kabuk bu tür deneme işlemleri için biçilmiş
kaftandır:
>>> karakter_dizisi = "23"
>>> sayı = int(karakter_dizisi)
>>> print(sayı)
23
Burada öncelikle “23” adlı bir karakter dizisi tanımladık. Ardından da
int()
fonksiyonunu kullanarak bu karakter dizisini bir tamsayıya (integer)
dönüştürdük. İsminden de anlayacağınız gibi int()
fonksiyonu İngilizce
integer (tamsayı) kelimesinin kısaltmasıdır ve bu fonksiyonun görevi bir
veriyi tamsayıya dönüştürmektir.
Ancak burada dikkat etmemiz gereken bir şey var. Herhangi bir verinin sayıya dönüştürülebilmesi için o verinin sayı değerli bir veri olması gerekir. Örneğin “23”, sayı değerli bir karakter dizisidir. Ama mesela “elma” sayı değerli bir karakter dizisi değildir. Bu yüzden “elma” karakter dizisi sayıya dönüştürülemez:
>>> 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'
Gördüğünüz gibi, sayı değerli olmayan bir veriyi sayıya dönüştürmeye çalıştırdığımızda Python bize bir hata mesajı gösteriyor. Yazdığımız programlarda bu duruma özellikle dikkat etmemiz gerekiyor.
Şimdi bu bölümün başında yazdığımız ve hata veren programımıza dönelim yine:
sayı = input("Lütfen bir sayı girin: ")
print("Girdiğiniz sayının karesi: ", sayı ** 2)
Bu kodların hata vereceğini biliyoruz. Ama artık, öğrendiğimiz int()
dönüştürücüsünü kullanarak programımızı hata vermeyecek şekilde yeniden
yazabiliriz:
veri = input("Lütfen bir sayı girin: ")
#input() fonksiyonundan gelen karakter dizisini
#sayıya dönüştürüyoruz.
sayı = int(veri)
print("Girdiğiniz sayının karesi: ", sayı ** 2)
Artık programımız hatasız bir şekilde çalışıyor.
Bir de öteki örneğimizi ele alalım:
sayı1 = input("Toplama işlemi için ilk sayıyı girin: ")
sayı2 = input("Toplama işlemi için ikinci sayıyı girin: ")
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
Bu kodların beklediğimiz çıktıyı vermeyeceğini biliyoruz. Ama eğer bu kodları şöyle yazarsak işler değişir:
v1 = input("Toplama işlemi için ilk sayıyı girin: ")
v2 = input("Toplama işlemi için ikinci sayıyı girin: ")
sayı1 = int(v1) #v1 adlı karakter dizisini sayıya dönüştürüyoruz.
sayı2 = int(v2) #v2 adlı karakter dizisini sayıya dönüştürüyoruz.
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
Gördüğünüz gibi, input()
fonksiyonundan gelen karakter dizilerini sayıya
dönüştürerek istediğimiz çıktıyı alabiliyoruz.
str()¶
Python’daki tip dönüştürücüleri elbette sadece int()
fonksiyonuyla sınırlı
değildir. Gördüğünüz gibi, int()
fonksiyonu sayı değerli verileri (mesela
karakter dizilerini) tam sayıya dönüştürüyor. Bunun bir de tersi mümkündür. Yani
karakter dizisi olmayan verileri karakter dizisine dönüştürmemiz de mümkündür.
Bu işlem için str()
adlı başka bir tip dönüştürücüden yararlanıyoruz:
>>> sayı = 23
>>> kardiz = str(sayı)
>>> print(kardiz)
23
>>> print(type(kardiz))
<class 'str'>
Gördüğünüz gibi, bir tam sayı olan 23’ü str()
adlı bir fonksiyondan
yararlanarak karakter dizisi olan “23” ifadesine dönüştürdük. Son satırda da,
elde ettiğimiz şeyin bir karakter dizisi olduğundan emin olmak için type()
fonksiyonunu kullanarak verinin tipini denetledik.
Yukarıdaki örneklerden gördüğümüz gibi, aritmetik işlemler yapmak istediğimizde
karakter dizilerini sayıya çevirmemiz gerekiyor. Peki acaba hangi durumlarda
bunun tersini yapmamız, yani sayıları karakter dizilerine çevirmemiz gerekir?
Python bilginiz ve tecrübeniz arttıkça bunların hangi durumlar olduğunu kendiniz
de göreceksiniz. Mesela biz daha şimdiden, sayıları karakter dizisine çevirmemiz
gereken bir durumla karşılaştık. Hatırlarsanız, len()
fonksiyonunu
anlatırken, bu fonksiyonun sayılarla birlikte kullanılamayacağını söylemiştik:
>>> len(12343423432)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
Peki ya yazdığınız programda bir sayının kaç haneden oluştuğunu hesaplamanız gerekirse ne yapacaksınız? Yani mesela yukarıdaki sayının 11 haneli olduğunu bilmeniz gerekiyorsa ne olacak?
İşte böyle bir durumda str()
fonksiyonundan yararlanabilirsiniz:
>>> sayı = 12343423432
>>> kardiz = str(sayı)
>>> len(kardiz)
11
Bildiğiniz gibi, len()
fonksiyonu, şu ana kadar öğrendiğimiz veri tipleri
içinde sadece karakter dizileri üzerinde işlem yapabiliyor. Biz de bu yüzden,
sayımızın kaç haneli olduğunu öğrenebilmek için, öncelikle bu sayıyı bir
karakter dizisine çeviriyoruz. Daha sonra da elde ettiğimiz bu karakter dizisini
len()
fonksiyonuna parametre olarak veriyoruz. Böylece sayının kaç haneli
olduğu bilgisini elde etmiş oluyoruz.
Bu arada elbette yukarıdaki işlemi tek satırda da halledebilirsiniz:
>>> len(str(12343423432))
11
Bu şekilde iç içe geçmiş fonksiyonlar yazdığımızda, Python fonksiyonları içten
dışa doğru tek tek değerlendirecektir. Mesela yukarıdaki örnekte Python önce
str(12343423432)
ifadesini değerlendirecek ve çıkan sonucu len()
fonksiyonuna gönderecektir. İç içe geçmiş fonksiyonları yazarken dikkat etmemiz
gereken önemli bir nokta da, açtığımız her bir parantezi tek tek kapatmayı
unutmamaktır.
float()¶
Hatırlarsanız ilk bölümlerde sayılardan söz ederken tamsayıların (integer)
dışında kayan noktalı sayıların (float) da olduğundan söz etmiştik. İşte eğer
bir tamsayıyı veya sayı değerli bir karakter dizisini kayan noktalı sayıya
dönüştürmek istersek float()
adlı başka bir dönüştürücüden yararlanacağız:
>>> a = 23
>>> type(a)
<class 'int'>
>>> float(a)
23.0
Gördüğünüz gibi, 23 tamsayısı, float()
fonksiyonu sayesinde 23.0’a yani
bir kayan noktalı sayıya dönüştü.
Aynı şeyi, sayı değerli karakter dizileri üzerine uygulamak da mümkündür:
>>> b = "23"
>>> type(b)
<class 'str'>
>>> float(b)
23.0
complex()¶
Sayılardan söz ederken, eğer matematikle çok fazla içli dışlı değilseniz pek karşılaşmayacağınız, ‘karmaşık sayı’ adlı bir sayı türünden de bahsetmiştik. Karmaşık sayılar Python’da ‘complex’ ifadesiyle gösteriliyor. Mesela şunun bir karmaşık sayı olduğunu biliyoruz:
>>> 12+0j
Kontrol edelim:
>>> type(12+0j)
<class 'complex'>
İşte eğer herhangi bir sayıyı karmaşık sayıya dönüştürmeniz gerekirse
complex()
adlı bir fonksiyondan yararlanabilirsiniz. Örneğin:
>>> complex(15)
(15+0j)
Böylece Python’daki bütün sayı dönüştürücüleri öğrenmiş olduk.
Gelin isterseniz, bu bölümde anlattığımız konuları şöyle bir tekrar ederek bilgilerimizi sağlamlaştırmaya çalışalım.
>>> a = 56
Bu sayı bir tamsayıdır. İngilizce olarak ifade etmek gerekirse, integer. Bunun bir tamsayı olduğunu şu şekilde teyit edebileceğimizi gayet iyi biliyorsunuz:
>>> type(a)
<class 'int'>
Burada aldığımız <class int> çıktısı, bize a değişkeninin tuttuğu sayının bir tamsayı olduğunu söylüyor. ‘int’ ifadesi, integer (tamsayı) kelimesinin kısaltmasıdır.
Bir de şu sayıya bakalım:
>>> b = 34.5
>>> type(b)
<class 'float'>
Bu çıktı ise bize 34.5 sayısının bir kayan noktalı sayı olduğunu söylüyor. float kelimesi Floats veya Floating Point Number ifadesinin kısaltmasıdır. Yani ‘kayan noktalı sayı’ demektir.
Bu arada, bu type()
adlı fonksiyonu sadece sayılara değil, başka şeylere de
uygulayabileceğimizi biliyorsunuz. Mesela bir örnek vermek gerekirse:
>>> meyve = "karpuz"
>>> type(meyve)
<class 'str'>
Gördüğünüz gibi, type()
fonksiyonu bize meyve adlı değişkenin değerinin
bir ‘str’ yani string yani karakter dizisi olduğunu bildirdi.
Bu veri tipleri arasında, bazı özel fonksiyonları kullanarak dönüştürme işlemi yapabileceğimizi öğrendik. Mesela:
>>> sayı = 45
sayı adlı değişkenin tuttuğu verinin değeri bir tamsayıdır. Biz bu tamsayıyı kayan noktalı sayıya dönüştürmek istiyoruz. Yapacağımız işlem çok basit:
>>> float(sayı)
45.0
Gördüğünüz gibi, 45 adlı tamsayıyı, 45.0 adlı bir kayan noktalı sayıya
dönüştürdük. Şimdi type(45.0)
komutu bize <class ‘float’> çıktısını
verecektir.
Eğer kayan noktalı bir sayıyı tamsayıya çevirmek istersek şu komutu veriyoruz. Mesela kayan noktalı sayımız, 56.5 olsun:
>>> int(56.5)
56
Yukarıdaki örneği tabii ki şöyle de yazabiliriz:
>>> a = 56.5
>>> int(a)
56
Dönüştürme işlemini sayılar arasında yapabileceğimiz gibi, sayılar ve karakter dizileri arasında da yapabiliriz. Örneğin şu bir karakter dizisidir:
>>> nesne = "45"
Yukarıdaki değeri tırnak içinde belirttiğimiz için bu değer bir karakter dizisidir. Şimdi bunu bir tamsayıya çevireceğiz:
>>> int(nesne)
45
Dilersek, aynı karakter dizisini kayan noktalı sayıya da çevirebiliriz:
>>> float(nesne)
45.0
Hatta bir sayıyı karakter dizisine de çevirebiliriz. Bunun için string (karakter dizisi) kelimesinin kısaltması olan str ifadesini kullanacağız:
>>> s = 6547
>>> str(s)
'6547'
Bir örnek de kayan noktalı sayılarla yapalım:
>>> s = 65.7
>>> str(s)
'65.7'
Yalnız şunu unutmayın: Bir karakter dizisinin sayıya dönüştürülebilmesi için o karakter dizisinin sayı değerli olması lazım. Yani “45” değerini sayıya dönüştürebiliriz. Çünkü “45” değeri, tırnaklardan ötürü bir karakter dizisi de olsa, neticede sayı değerli bir karakter dizisidir. Ama mesela “elma” karakter dizisi böyle değildir. Dolayısıyla, şöyle bir maceraya girişmek bizi hüsrana uğratacaktır:
>>> nesne = "elma"
>>> int(nesne)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'elma'
Gördüğünüz gibi, Python böyle bir işlem denemesi karşısında hata veriyor…
Bu bölümde pek çok yeni şey öğrendik. Bu bölümün en önemli getirisi input()
fonksiyonunu öğrenmemiz oldu. Bu fonksiyon sayesinde kullanıcıyla iletişim
kurmayı başardık. Artık kullanıcıdan veri alıp, bu verileri programlarımız
içinde işleyebiliyoruz.
Yine bu bölümde dikkatinizi çektiğimiz başka bir konu da sayılar ve karakter
dizileri arasındaki ilişkiydi. input()
fonksiyonuyla elde edilen çıktının
bir karakter dizisi olduğunu öğrendik. Bildiğimiz gibi, aritmetik işlemler ancak
sayılar arasında yapılabilir. Dolayısıyla input()
fonksiyonuyla gelen
karakter dizisini bir sayıyla çarpmaya kalkarsak hata alıyoruz. Burada yapmamız
gereken şey, elimizdeki verileri dönüştürmek. Yani input()
fonksiyonundan
gelen karakter dizisini bir sayıyla çarpmak istiyorsak, öncelikle aldığımız
karakter dizisini sayıya dönüştürmemiz gerekiyor. Dönüştürme işlemleri için
kullandığımız fonksiyonlar şunlardı:
int()
Sayı değerli bir karakter dizisini veya kayan noktalı sayıyı tamsayıya (integer) çevirir.
float()
Sayı değerli bir karakter dizisini veya tamsayıyı kayan noktalı sayıya (float) çevirir.
str()
Bir tamsayı veya kayan noktalı sayıyı karakter dizisine (string) çevirir.
complex()
Herhangi bir sayıyı veya sayı değerli karakter dizisini karmaşık sayıya (complex) çevirir.
Ayrıca bu bölümde öğrendiklerimiz, şöyle önemli bir tespitte bulunmamıza da olanak tanıdı:
Her tamsayı ve/veya kayan noktalı sayı bir karakter dizisine dönüştürülebilir. Ama her karakter dizisi tamsayıya ve/veya kayan noktalı sayıya dönüştürülemez.
Örneğin, 5654 gibi bir tamsayıyı veya 543.34 gibi bir kayan noktalı sayıyı
str()
fonksiyonu yardımıyla karakter dizisine dönüştürebiliriz:
>>> str(5654)
>>> str(543.34)
“5654” karakter dizisini int()
fonksiyonu ile tamsayıya, float()
fonksiyonu ile de
bir kayan noktalı sayıya dönüştürebiliriz:
>>> int("5654")
>>> float("5654")
veya “543.34” gibi bir karakter dizisini float()
fonksiyonu yardımıyla kayan noktalı sayıya dönüştürebiliriz:
>>> float("543.34")
Ancak “543.34” karakter dizisini int() fonksiyonu ile birlikte kullanırsak hata alırız, çünkü 543.34 bir tamsayı olamaz. Eğer amacımız “543.34” karakter dizisini sayısal değer gibi düşünüp aşağı yuvarlamak olsaydı şöyle bir şey yapabilirdik:
>>> x = float("543.34")
>>> x
543.34
>>> int(x)
543
>>>
Aşağı değil de yukarı yuvarlamak istersek en son elde ettiğimiz 543 değerine bir eklemek yeterli olurdu.
Ama “elma” gibi bir karakter dizisini ne int()
ne de float()
fonksiyonuyla tamsayıya veya kayan noktalı sayıya dönüştürebiliriz! Çünkü
“elma” verisi sayı değerli değildir.
Bu bölümü kapatmadan önce, dilerseniz şimdiye kadar öğrendiklerimizi de içeren örnek bir program yazalım. Bu program, Python maceramız açısından bize yeni kapılar da açacak.
Önceki derslerimizin birinde verdiğimiz doğalgaz faturası hesaplayan programı
hatırlarsınız. İşte artık input()
fonksiyonu sayesinde bu doğalgaz faturası
hesaplama programını da daha ilginç bir hale getirebiliriz:
#Her bir ayın kaç gün çektiğini tanımlıyoruz
ocak = mart = mayıs = temmuz = ağustos = ekim = aralık = 31
nisan = haziran = eylül = kasım = 30
şubat = 28
#Doğalgazın vergiler dahil metreküp fiyatı
birimFiyat = 0.79
#Kullanıcı ayda ne kadar doğalgaz tüketmiş?
aylıkSarfiyat = input("Aylık doğalgaz sarfiyatınızı metreküp olarak giriniz: ")
#Kullanıcı hangi aya ait faturasını öğrenmek istiyor?
dönem = input("""Hangi aya ait faturayı hesaplamak istersiniz?
(Lütfen ay adını tamamı küçük harf olacak şekilde giriniz)\n""")
#Yukarıdaki input() fonksiyonundan gelen veriyi
#Python'ın anlayabileceği bir biçime dönüştürüyoruz
ay = eval(dönem)
#Kullanıcının günlük doğalgaz sarfiyatı
günlükSarfiyat = int(aylıkSarfiyat) / ay
#Fatura tutarı
fatura = birimFiyat * günlükSarfiyat * ay
print("günlük sarfiyatınız: \t", günlükSarfiyat, " metreküp\n",
"tahmini fatura tutarı: \t", fatura, " TL", sep="")
Burada yine bilmediğimiz bir fonksiyonla daha karşılaştık. Bu fonksiyonun adı
eval()
. Biraz sonra eval()
fonksiyonunu derinlemesine inceleyeceğiz. Ama
bu fonksiyonu anlatmaya geçmeden önce dilerseniz yukarıdaki kodları biraz
didikleyelim.
İlk satırların ne işe yaradığını zaten biliyorsunuz. Bir yıl içindeki bütün ayların kaç gün çektiğini gösteren değişkenlerimizi tanımladık. Burada her bir değişkeni tek tek tanımlamak yerine değişkenleri topluca tanımladığımıza dikkat edin. İsteseydik tabii ki yukarıdaki kodları şöyle de yazabilirdik:
#Her bir ayın kaç gün çektiğini tanımlıyoruz
ocak = 31
şubat = 28
mart = 31
nisan = 30
mayıs = 31
haziran = 30
temmuz = 31
ağustos = 31
eylül = 30
ekim = 31
kasım = 30
aralık = 31
#Doğalgazın vergiler dahil m3 fiyatı
birimFiyat = 0.79
#Kullanıcı ayda ne kadar doğalgaz tüketmiş?
aylıkSarfiyat = input("Aylık doğalgaz sarfiyatınızı m3 olarak giriniz: ")
#Kullanıcı hangi aya ait faturasını öğrenmek istiyor?
dönem = input("""Hangi aya ait faturayı hesaplamak istersiniz?
(Lütfen ay adını tamamı küçük harf olacak şekilde giriniz)\n""")
#Yukarıdaki input() fonksiyonundan gelen veriyi
#Python'ın anlayabileceği bir biçime dönüştürüyoruz
ay = eval(dönem)
#Kullanıcının günlük doğalgaz sarfiyatı
günlükSarfiyat = int(aylıkSarfiyat) / ay
#Fatura tutarı
fatura = birimFiyat * günlükSarfiyat * ay
print("günlük sarfiyatınız: \t", günlükSarfiyat, " metreküp\n",
"tahmini fatura tutarı: \t", fatura, " TL", sep="")
Ama tabii ki, değişkenleri tek tek tanımlamak yerine topluca tanımlamak, daha az kod yazmanızı sağlamasının yanısıra, programınızın çalışma performansı açısından da daha iyidir. Yani değişkenleri bu şekilde tanımladığınızda programınız daha hızlı çalışır.
Programımızı incelemeye devam edelim…
Değişkenleri tanımladıktan sonra doğalgazın vergiler dahil yaklaşık birim fiyatını da bir değişken olarak tanımladık. 0.79 değerini zaten birkaç bölüm önce hesaplayıp bulduğumuz için, aynı işlemleri tekrar programımıza eklememize gerek yok. Doğrudan nihai değeri programımıza yazsak yeter…
Birim fiyatı belirledikten sonra kullanıcıya aylık doğalgaz sarfiyatını
soruyoruz. Kullanıcının bu değeri m3 olarak girmesini bekliyoruz.
Elbette bu veriyi kullanıcıdan alabilmek için input()
fonksiyonunu
kullanıyoruz.
Daha sonra kullanıcıya hangi aya ait doğalgaz faturasını ödemek istediğini
soruyoruz. Bu bilgi, bir sonraki satırda günlük doğalgaz sarfiyatını hesaplarken
işimize yarayacak. Çünkü kullanıcının girdiği ayın çektiği gün sayısına bağlı
olarak günlük sarfiyat değişecektir. Günlük sarfiyatı hesaplamak için aylık
sarfiyatı, ilgili ayın çektiği gün sayısına bölüyoruz. Bu arada bir önceki
satırda dönem değişkenini eval()
adlı bir fonksiyonla birlikte
kullandığımızı görüyorsunuz. Bunu biraz sonra inceleyeceğiz. O yüzden bu
satırları atlayıp son satıra gelelim.
Son satırda print()
fonksiyonunu kullanarak, kullanıcıdan aldığımız verileri
düzgün bir şekilde kendisine gösteriyoruz. Programımız kullanıcıya günlük
doğalgaz sarfiyatını ve ay sonunda karşılaşacağı tahmini fatura tutarını
bildiriyor. print()
fonksiyonu içinde kullandığımız kaçış dizilerine
özellikle dikkatinizi çekmek istiyorum. Burada düzgün bir çıktı elde etmek için
\t ve \n adlı kaçış dizilerinden nasıl yararlandığımızı görüyorsunuz. Bu
kaçış dizilerinin buradaki işlevini tam olarak anlayabilmek için, bu kodları bir
de bu kaçış dizileri olmadan yazmayı deneyebilirsiniz.
Bu bilgileri, önemlerinden ötürü aklımızda tutmaya çalışalım. Buraya kadar anlatılan konular hakkında zihnimizde belirsizlikler varsa veya bazı noktaları tam olarak kavrayamadıysak, şimdiye kadar öğrendiğimiz konuları tekrar gözden geçirmemiz bizim için epey faydalı olacaktır. Zira bundan sonraki bölümlerde, yeni bilgilerin yanısıra, buraya kadar öğrendiğimiz şeyleri de yoğun bir şekilde pratiğe dökeceğiz. Bundan sonraki konuları takip edebilmemiz açısından, buraya kadar verdiğimiz temel bilgileri iyice sindirmiş olmak işimizi bir hayli kolaylaştıracaktır.
eval() ve exec() Fonksiyonları¶
Bir önceki bölümün son örnek programında eval()
adlı bir fonksiyonla
karşılaşmıştık. İşte şimdi bu önemli fonksiyonun ne işe yaradığını anlamaya
çalışacağız. Ancak eval()
fonksiyonunu anlatmaya başlamadan önce şu uyarıyı
yapalım:
Bunun neden böyle olduğunu hem biz anlatacağız, hem de zaten bu fonksiyonu
tanıdıkça neden eval()
’e karşı dikkatli olmanız gerektiğini kendiniz de
anlayacaksınız.
Dilerseniz işe basit bir eval()
örneği vererek başlayalım:
print("""
Basit bir hesap makinesi uygulaması.
İşleçler:
+ toplama
- çıkarma
* çarpma
/ bölme
Yapmak istediğiniz işlemi yazıp ENTER
tuşuna basın. (Örneğin 23 ve 46 sayılarını
çarpmak için 23 * 46 yazdıktan sonra
ENTER tuşuna basın.)
""")
veri = input("İşleminiz: ")
hesap = eval(veri)
print(hesap)
İngilizcede evaluate diye bir kelime bulunur. Bu kelime, ‘değerlendirmeye tabi
tutmak, işleme sokmak, işlemek’ gibi anlamlar taşır. İşte eval()
fonksiyonundaki eval kelimesi bu evaluate kelimesinin kısaltmasıdır. Yani bu
fonksiyonun görevi, kendisine verilen karakter dizilerini değerlendirmeye tabi
tutmak ya da işlemektir. Peki bu tam olarak ne anlama geliyor?
Aslında yukarıdaki örnek programı çalıştırdığımızda bu sorunun yanıtını kendi
kendimize verebiliyoruz. Bu programı çalıştırarak, “İşleminiz: “ ifadesinden
sonra, örneğin, 45 * 76
yazıp Enter tuşuna basarsak programımız bize
3420 çıktısı verecektir. Yani programımız hesap makinesi işlevini yerine
getirip 45 sayısı ile 76 sayısını çarpacaktır. Dolayısıyla, yukarıdaki
programı kullanarak her türlü aritmetik işlemi yapabilirsiniz. Hatta bu program,
son derece karmaşık aritmetik işlemlerin yapılmasına dahi müsaade eder.
Peki programımız bu işlevi nasıl yerine getiriyor? İsterseniz kodların üzerinden tek tek geçelim.
Öncelikle programımızın en başına kullanım kılavuzuna benzer bir metin
yerleştirdik ve bu metni print()
fonksiyonu yardımıyla ekrana bastık.
Daha sonra kullanıcıdan alacağımız komutları veri adlı bir değişkene atadık.
Tabii ki kullanıcıyla iletişimi her zaman olduğu gibi input()
fonksiyonu
yardımıyla sağlıyoruz.
Ardından, kullanıcıdan gelen veriyi eval()
fonksiyonu yardımıyla
değerlendirmeye tabi tutuyoruz. Yani kullanıcının girdiği komutları işleme
sokuyoruz. Örneğin, kullanıcı 46 / 2
gibi bir veri girdiyse, biz eval()
fonksiyonu yardımıyla bu 46 / 2
komutunu işletiyoruz. Bu işlemin sonucunu da
hesap adlı başka bir değişken içinde depoluyoruz.
Eğer burada eval()
fonksiyonunu kullanmazsak, programımız, kullanıcının
girdiği 45 * 76
komutunu hiçbir işleme sokmadan dümdüz ekrana basacaktır.
Yani:
print("""
Basit bir hesap makinesi uygulaması.
İşleçler:
+ toplama
- çıkarma
* çarpma
/ bölme
Yapmak istediğiniz işlemi yazıp ENTER
tuşuna basın. (Örneğin 23 ve 46 sayılarını
çarpmak için 23 * 46 yazdıktan sonra
ENTER tuşuna basın.)
""")
veri = input("İşleminiz: ")
print(veri)
Eğer programımızı yukarıdaki gibi, eval()
fonksiyonu olmadan yazarsak,
kullanıcımız 45 * 76
gibi bir komut girdiğinde alacağı cevap dümdüz bir 45
* 76 çıktısı olacaktır. İşte eval()
fonksiyonu, kullanıcının girdiği her
veriyi bir Python komutu olarak algılar ve bu veriyi işleme sokar. Yani 45 *
76
gibi bir şey gördüğünde, bu şeyi doğrudan ekrana yazdırmak yerine, işlemin
sonucu olan 3420 sayısını verir.
eval()
fonksiyonunun, yukarıda anlattığımız özelliklerini okuduktan sonra,
‘Ne güzel bir fonksiyon! Her işimi görür bu!’ dediğinizi duyar gibiyim. Ama
aslında durum hiç de öyle değil. Neden mi?
print("""
Basit bir hesap makinesi uygulaması.
İşleçler:
+ toplama
- çıkarma
* çarpma
/ bölme
Yapmak istediğiniz işlemi yazıp ENTER
tuşuna basın. (Örneğin 23 ve 46 sayılarını
çarpmak için 23 * 46 yazdıktan sonra
ENTER tuşuna basın.)
""")
veri = input("İşleminiz: ")
hesap = eval(veri)
print(hesap)
Şimdi yukarıdaki programı tekrar çalıştırın ve “İşleminiz: “ ifadesinden sonra şu cevabı verin:
print("Merhaba Python!")
Bu komut şöyle bir çıktı vermiş olmalı:
Merhaba Python!
None
Not
Buradaki None değerini görmezden gelin. Bunu fonksiyonlar konusunu anlatırken inceleyeceğiz.
Gördüğünüz gibi, yazdığımız program, kullanıcının girdiği Python komutunun işletilmesine sebep oldu. Bu noktada, ‘Eee, ne olmuş!’ demiş olabilirsiniz. Gelin bir de şuna bakalım. Şimdi programı tekrar çalıştırıp şu cevabı verin:
open("deneme.txt", "w")
Bu cevap, bilgisayarınızda deneme.txt adlı bir dosya oluşturulmasına sebep
oldu. Belki farkındasınız, belki farkında değilsiniz, ama aslında şu anda kendi
yazdığınız program sizin kontrolünüzden tamamen çıktı. Siz aslında bir hesap
makinesi programı yazmıştınız. Ama eval()
fonksiyonu nedeniyle kullanıcıya
rastgele Python komutlarını çalıştırma imkanı verdiğiniz için programınız sadece
aritmetik işlemleri hesaplamak için kullanılmayabilir. Böyle bir durumda kötü
niyetli (ve bilgili) bir kullanıcı size çok büyük zarar verebilir. Mesela
kullanıcının, yukarıdaki programa şöyle bir cevap verdiğini düşünün:
__import__("os").system("dir")
Burada anlamadığınız şeyleri şimdilik bir kenara bırakıp, bu komutun sonuçlarına odaklanın. Gördüğünüz gibi, yukarıdaki programa bu cevabı vererek mevcut dizin altındaki bütün dosyaları listeleyebildik. Yani programımız bir anda amacını aştı. Artık bu aşamadan sonra bu programı şeytani bir amaca yönelik olarak kullanmak tamamen programı kullanan kişiye kalmış… Bu programın, bir web sunucusu üzerinde çalışan bir uygulama olduğunu ve bu programı kullananların yukarıdaki gibi masumane bir şekilde dizin içindeki dosyaları listeleyen bir komut yerine, dizin içindeki dosyaları ve hatta sabit disk üzerindeki her şeyi silen bir komut yazdığını düşünün… Yanlış yazılmış bir program yüzünden bütün verilerinizi kaybetmeniz işten bile değildir. (Bahsettiğim o, ‘bütün sabit diski silen komutu’ kendi sisteminizde vermemeniz gerektiğini söylememe gerek yok, değil mi?)
Eğer SQL Injection kavramını biliyorsanız, yukarıdaki kodların yol açtığı
güvenlik açığını gayet iyi anlamış olmalısınız. Zaten internet üzerinde yaygın
bir şekilde kullanılan ve web sitelerini hedef alan SQL Injection tarzı
saldırılar da aynı mantık üzerinden gerçekleştiriliyor. SQL Injection
metoduyla bir web sitesine saldıran cracker’lar, o web sitesini programlayan
kişinin (çoğunlukla farkında olmadan) kullanıcıya verdiği rastgele SQL komutu
işletme yetkisini kötüye kullanarak gizli ve özel bilgileri ele
geçirebiliyorlar. Örneğin SQL Injection metodu kullanılarak, bir web sitesine
ait veritabanının içeriği tamamen silinebilir. Aynı şekilde, yukarıdaki
eval()
fonksiyonu da kullanıcılarınıza rastgele Python komutlarını
çalıştırma yetkisi verdiği için kötü niyetli bir kullanıcının programınıza
sızmasına yol açabilecek potansiyele sahiptir.
Peki eval()
fonksiyonunu asla kullanmayacak mıyız? Elbette kullanacağız. Bu
fonksiyonun kullanımını gerektiren durumlarla da karşılaşabilirsiniz. Ama şunu
asla aklınızdan çıkarmayın: eval()
fonksiyonu her ne kadar son derece
yetenekli ve güçlü bir araç da olsa yanlış ellerde yıkıcı sonuçlar doğurabilir.
Program yazarken, eğer eval()
kullanmanızı gerektiren bir durumla karşı
karşıya olduğunuzu düşünüyorsanız, bir kez daha düşünün. eval()
ile elde
edeceğiniz etkiyi muhtemelen başka ve çok daha iyi yöntemlerle de elde
edebilirsiniz. Üstelik performans açısından eval()
pek iyi bir tercih
değildir, çünkü bu fonksiyon (çoğu durumda farketmeseniz de) aslında yavaş
çalışır. O yüzden, eval()
fonksiyonunu kullanacağınız zaman, bunun artı ve
eksilerini çok iyi tartın: Bu fonksiyonu kullanmak size ne kazandırıyor, ne
kaybettiriyor?
Ayrıca eval()
fonksiyonu kullanılacağı zaman, kullanıcıdan gelen veri bu
fonksiyona parametre olarak verilmeden önce sıkı bir kontrolden geçirilir. Yani
kullanıcının girdiği veri eval()
aracılığıyla doğrudan değerlendirmeye tabi
tutulmaz. Araya bir kontrol mekanizması yerleştirilir. Örneğin, yukarıdaki hesap
makinesi programında kullanıcının gireceği verileri sadece sayılar ve işleçlerle
sınırlandırabilirsiniz. Yani kullanıcınızın, izin verilen değerler harici bir
değer girmesini engelleyebilirsiniz. Bu durumu somutlaştırmak için şöyle bir
diyagram çizebiliriz:
Yukarıdaki diyagram eval()
fonksiyonunun yanlış uygulanış biçimini
gösteriyor. Gördüğünüz gibi, veri doğrudan eval()
fonksiyonuna gidiyor ve
çıktı olarak veriliyor. Böyle bir durumda, eval()
fonksiyonu kullanıcıdan
gelen verinin ne olduğuna bakmadan, veriyi doğrudan komut olarak değerlendirip
işleteceği için programınızı kullanıcının insafına terketmiş oluyorsunuz.
Aşağıdaki diyagram ise eval()
fonksiyonunun doğru uygulanış biçimini
gösteriyor:
Burada ise, veri eval()
fonksiyonuna ulaşmadan önce kontrolden geçiriliyor.
Eğer veri ancak kontrol aşamasından geçerse eval()
fonksiyona ulaşabilecek
ve oradan da çıktı olarak verilebilecektir. Böylece kullanıcıdan gelen komutları
süzme imkanına sahip oluyoruz.
Gördüğünüz gibi, Python eval()
gibi bir fonksiyon yardımıyla karakter
dizileri içinde geçen Python kodlarını ayıklayıp bunları çalıştırabiliyor. Bu
sayede, mesela bize input()
fonksiyonu aracılığıyla gelen bir karakter
dizisi içindeki Python kodlarını işletme imkanına sahip olabiliyoruz. Bu
özellik, dikkatli kullanıldığında, işlerinizi epey kolaylaştırabilir.
Python’da eval()
fonksiyonuna çok benzeyen exec()
adlı başka bir
fonksiyon daha bulunur. eval()
ile yapamadığımız bazı şeyleri exec()
ile
yapabiliriz. Bu fonksiyon yardımıyla, karakter dizileri içindeki çok kapsamlı
Python kodlarını işletebilirsiniz.
Örneğin eval()
fonksiyonu bir karakter dizisi içindeki değişken tanımlama
işlemini yerine getiremez. Yani eval()
ile şöyle bir şey yapamazsınız:
>>> eval("a = 45")
Ama exec()
ile böyle bir işlem yapabilirsiniz:
>>> exec("a = 45")
Böylece a adlı bir değişken tanımlamış olduk. Kontrol edelim:
>>> print(a)
45
eval()
ve exec()
fonksiyonları özellikle kullanıcıdan alınan verilerle
doğrudan işlem yapmak gereken durumlarda işinize yarar. Örneğin bir hesap
makinesi yaparken eval()
fonksiyonundan yararlanabilirsiniz.
Aynı şekilde mesela insanlara Python programlama dilini öğreten bir program
yazıyorsanız exec()
fonksiyonunu şöyle kullanabilirsiniz:
d1 = """
Python'da ekrana çıktı verebilmek için print() adlı bir
fonksiyondan yararlanıyoruz. Bu fonksiyonu şöyle kullanabilirsiniz:
>>> print("Merhaba Dünya")
Şimdi de aynı kodu siz yazın!
>>> """
girdi = input(d1)
exec(girdi)
d2 = """
Gördüğünüz gibi print() fonksiyonu, kendisine
parametre olarak verilen değerleri ekrana basıyor.
Böylece ilk dersimizi tamamlamış olduk. Şimdi bir
sonraki dersimize geçebiliriz."""
print(d2)
Burada exec()
ile yaptığımız işi eval()
ile de yapabiliriz. Ama mesela
eğer bir sonraki derste ‘Python’da değişkenler’ konusunu öğretecekseniz,
eval()
yerine exec()
fonksiyonunu kullanmak durumunda kalabilirsiniz.
eval()
fonksiyonunu anlatırken güvenlik ile ilgili olarak söylediğimiz her
şey exec()
fonksiyonu için de geçerlidir. Dolayısıyla bu iki fonksiyonu çok
dikkatli bir şekilde kullanmanız ve bu fonksiyonların doğurduğu güvenlik
açığının bilincinde olmanız gerekiyor.
Henüz Python bilgilerimiz çok kısıtlı olduğu için eval()
ve exec()
fonksiyonlarını bütün ayrıntılarıyla inceleyemiyoruz. Ama bilgimiz arttıkça bu
fonksiyonların ne kadar güçlü (ve tehlikeli) araçlar olduğunu siz de
göreceksiniz.
format() Metodu¶
Python programlama dili içindeki çok temel bazı araçları incelediğimize göre, bu noktada Python’daki küçük ama önemli bir konuya değinelim bu bölümü kapatmadan önce.
İnternette dolaşırken mutlaka şuna benzer bir sayfayla karşılaşmış olmalısınız:
Burada belli ki adres çubuğuna fdkgd.com
diye bir URL
yazmışız, ama böyle bir internet adresi olmadığı için, kullandığımız internet
tarayıcısı bize şöyle bir mesaj vermiş:
Hata! Google Chrome fdkgd.com sitesini bulamadı
Şimdi de dadasdaf.com
adresini arayalım…
Yine böyle bir adres olmadığı için, bu defa tarayıcımız bize şöyle bir uyarı gösterecek:
Hata! Google Chrome dadasdaf.com sitesini bulamadı
Gördüğünüz gibi, hata mesajlarında değişen tek yer, aradığımız sitenin adresi. Yani internet tarayıcımız bu hata için şöyle bir taslağa sahip:
Hata! Google Chrome ... sitesini bulamadı
Burada … ile gösterdiğimiz yere, bulunamayan URL yerleştiriliyor. Peki böyle bir şeyi Python programlama dili ile nasıl yapabiliriz?
Çok basit:
#Öncelikle kullanıcıdan bir internet adresi girmesini istiyoruz
url = input("Lütfen ulaşmak istediğiniz sitenin adresini yazın: ")
#Şimdi de bu adresin bulunamadığı konusunda kullanıcıyı bilgilendiriyoruz
print("Hata! Google Chrome", url, "sitesini bulamadı")
Gördüğünüz gibi, şimdiye kadar öğrendiğimiz bilgileri kullanarak böyle bir programı rahatlıkla yazabiliyoruz.
Peki ya biz kullanıcının girdiği internet adresini mesela tırnak içinde göstermek istersek ne olacak? Yani örneğin şöyle bir çıktı vermek istersek:
Hata! Google Chrome 'fdsfd.com' sitesini bulamadı
Bunun için yine karakter dizisi birleştirme yönteminden yararlanabilirsiniz:
#Öncelikle kullanıcıdan bir internet adresi girmesini istiyoruz
url = input("Lütfen ulaşmak istediğiniz sitenin adresini yazın: ")
#Şimdi de bu adresin bulunamadığı konusunda kullanıcıyı bilgilendiriyoruz
print("Hata! Google Chrome", "'" + url + "'", "sitesini bulamadı")
Burada, + işaretlerini kullanarak, kullanıcının girdiği adresin sağına ve soluna birer tırnak işaretini nasıl yerleştirdiğimize dikkat edin.
Gördüğünüz gibi bu yöntem işe yarıyor, ama ortaya çıkan karakter dizisi de
oldukça karmaşık görünüyor. İşte bu tür ‘karakter dizisi biçimlendirme’
işlemleri için Python bize çok faydalı bir araç sunuyor. Bu aracın adı
format()
.
Bu aracı şöyle kullanıyoruz:
#Öncelikle kullanıcıdan bir internet adresi girmesini istiyoruz
url = input("Lütfen ulaşmak istediğiniz sitenin adresini yazın: ")
#Şimdi de bu adresin bulunamadığı konusunda kullanıcıyı bilgilendiriyoruz
print("Hata! Google Chrome {} sitesini bulamadı".format(url))
Bir de bulunamayan internet adresini tırnak içine alalım:
print("Hata! Google Chrome '{}' sitesini bulamadı".format(url))
Görüyorsunuz ya, biraz önce karakter dizisi birleştirme yöntemini kullanarak
gerçekleştirdiğimiz işlemi, çok daha basit bir yolla gerçekleştirme imkanı
sunuyor bize bu format()
denen araç…
Peki format()
nasıl çalışıyor?
Bunu anlamak için şu basit örneklere bir bakalım:
>>> print("{} ve {} iyi bir ikilidir".format("Python", "Django"))
'Python ve Django iyi bir ikilidir'
>>> print("{} {}'yi seviyor!".format("Ali", "Ayşe"))
'Ali Ayşe'yi seviyor!'
>>> print("{} {} yaşında bir {}dur".format("Ahmet", "18", "futbolcu"))
'Ahmet 18 yaşında bir futbolcudur'
Elbette bu örnekleri şöyle de yazabilirdik:
>>> metin = "{} ve {} iyi bir ikilidir"
>>> metin.format("Python", "Django")
'Python ve Django iyi bir ikilidir'
>>> metin = "{} {}'yi seviyor!"
>>> metin.format("Ali", "Ayşe")
'Ali Ayşe'yi seviyor!'
>>> metin = "{} {} yaşında bir {}dur"
>>> metin.format("Ahmet", "18", "futbolcu")
'Ahmet 18 yaşında bir futbolcudur'
Burada taslak metni doğrudan format()
metoduna parametre olarak vermeden
önce bir değişkene atadık. Böylece bu metni daha kolay bir şekilde
kullanabildik.
Bu örneklerin, format()
denen aracı anlamak konusunda size epey fikir
verdiğini zannediyorum. Ama isterseniz bu aracın ne olduğunu ve nasıl
çalıştığını daha ayrıntılı olarak incelemeye geçmeden önce başka bir örnek daha
verelim.
Varsayalım ki kullanıcıdan aldığı bilgiler doğrultusunda, özel bir konu üzerine dilekçe oluşturan bir program yazmak istiyorsunuz.
Dilekçe taslağımız şu şekilde olsun:
tarih:
T.C.
... ÜNİVERSİTESİ
... Fakültesi Dekanlığına
Fakülteniz ..........Bölümü ......... numaralı öğrencisiyim. Ekte sunduğum
belgede belirtilen mazeretim gereğince ....... Eğitim-Öğretim Yılı .........
yarıyılında öğrenime ara izni (kayıt dondurma) istiyorum.
Bilgilerinizi ve gereğini arz ederim.
İmza
Ad-Soyadı :
T.C. Kimlik No. :
Adres :
Tel. :
Ekler :
Amacınız bu dilekçedeki boşluklara gelmesi gereken bilgileri kullanıcıdan alıp, eksiksiz bir dilekçe ortaya çıkarmak.
Kullanıcıdan bilgi alma kısmı kolay. input()
fonksiyonunu kullanarak gerekli
bilgileri kullanıcıdan alabileceğimizi biliyorsunuz:
tarih = input("tarih: ")
üniversite = input("üniversite adı: ")
fakülte = input("fakülte adı: ")
bölüm = input("bölüm adı: ")
öğrenci_no = input("öğrenci no. :")
öğretim_yılı = input("öğretim yılı: ")
yarıyıl = input("yarıyıl: ")
ad = input("öğrencinin adı: ")
soyad = input("öğrencinin soyadı: ")
tc_kimlik_no = input("TC Kimlik no. :")
adres = input("adres: ")
tel = input("telefon: ")
ekler = input("ekler: ")
Bilgileri kullanıcıdan aldık. Peki ama bu bilgileri dilekçe taslağı içindeki boşluklara nasıl yerleştireceğiz?
Şu ana kadar öğrendiğimiz print()
fonksiyonunu ve \t ve \n gibi kaçış
dizilerini kullanarak istediğiniz çıktıyı elde etmeyi deneyebilirsiniz. Ama
denediğinizde siz de göreceksiniz ki, bu tür yöntemleri kullanarak yukarıdaki
dilekçe taslağını doldurmak inanılmaz zor ve vakit alıcı olacaktır. Halbuki
bunların hiçbirine gerek yok. Çünkü Python bize bu tür durumlarda kullanılmak
üzere çok pratik bir araç sunuyor. Şimdi çok dikkatlice inceleyin şu kodları:
dilekçe = """
tarih: {}
T.C.
{} ÜNİVERSİTESİ
{} Fakültesi Dekanlığına
Fakülteniz {} Bölümü {} numaralı öğrencisiyim. Ekte sunduğum belgede
belirtilen mazeretim gereğince {} Eğitim-Öğretim Yılı {}.
yarıyılında öğrenime ara izni (kayıt dondurma) istiyorum.
Bilgilerinizi ve gereğini arz ederim.
İmza
Ad : {}
Soyad : {}
T.C. Kimlik No. : {}
Adres : {}
Tel. : {}
Ekler : {}
"""
tarih = input("tarih: ")
üniversite = input("üniversite adı: ")
fakülte = input("fakülte adı: ")
bölüm = input("bölüm adı: ")
öğrenci_no = input("öğrenci no. :")
öğretim_yılı = input("öğretim yılı: ")
yarıyıl = input("yarıyıl: ")
ad = input("öğrencinin adı: ")
soyad = input("öğrencinin soyadı: ")
tc_kimlik_no = input("TC Kimlik no. :")
adres = input("adres: ")
tel = input("telefon: ")
ekler = input("ekler: ")
print(dilekçe.format(tarih, üniversite, fakülte, bölüm,
öğrenci_no, öğretim_yılı, yarıyıl,
ad, soyad, tc_kimlik_no,
adres, tel, ekler))
Bu kodlara (ve bundan önceki örneklere) bakarak birkaç tespitte bulunalım:
Taslak metinde kullanıcıdan alınacak bilgilerin olduğu yerlere birer {} işareti yerleştirdik.
Taslaktaki eksiklikleri tamamlayacak verileri
input()
fonksiyonu yardımıyla kullanıcıdan tek tek aldık.Son olarak,
print()
fonksiyonu yardımıyla metni tam bir şekilde ekrana çıktı olarak verdik.
Şimdi son tespitimizi biraz açıklayalım. Gördüğünüz gibi, print()
fonksiyonu
içinde dilekçe.format()
gibi bir yapı var. Burada dilekçe değişkenine
nokta işareti ile bağlanmış format()
adlı, fonksiyon benzeri bir araç
görüyoruz. Bu araca teknik dilde ‘metot’ adı verilir. format()
metodunun
parantezleri içinde ise, kullanıcıdan alıp birer değişkene atadığımız veriler
yer alıyor.
Dilerseniz yukarıda olan biteni daha net anlayabilmek için bu konunun başına verdiğimiz örneklere geri dönelim.
İlk olarak şöyle bir örnek vermiştik:
#Öncelikle kullanıcıdan bir internet adresi girmesini istiyoruz
url = input("Lütfen ulaşmak istediğiniz sitenin adresini yazın: ")
#Şimdi de bu adresin bulunamadığı konusunda kullanıcıyı bilgilendiriyoruz
print("Hata! Google Chrome {} sitesini bulamadı".format(url))
Burada kullanıcının gireceği internet adresinin yerini tutması için {} işaretlerinden yararlanarak şöyle bir karakter dizisi oluşturduk:
"Hata! Google Chrome {} sitesini bulamadı"
Gördüğünüz gibi, {} işareti karakter dizisi içinde URL’nin geleceği yeri
tutuyor. Bu {} işaretinin yerine neyin geleceğini format()
metodunun
parantezleri içinde belirtiyoruz. Dikkatlice bakın:
print("Hata! Google Chrome {} sitesini bulamadı".format(url))
Elbette eğer istersek yukarıdaki örneği şöyle de yazabilirdik:
url = input("Lütfen ulaşmak istediğiniz sitenin adresini yazın: ")
#Kullanıcıya gösterilecek hata için bir taslak metin oluşturuyoruz
hata_taslağı = "Hata! Google Chrome {} sitesini bulamadı"
print(hata_taslağı.format(url))
Burada hata metnini içeren karakter dizisini doğrudan format()
metoduna
bağlamak yerine, bunu bir değişkene atayıp, format()
metodunu bu değişkene
bağladık.
Bunun dışında şu örnekleri de vermiştik:
>>> metin = "{} ve {} iyi bir ikilidir"
>>> metin.format("Python", "Django")
'Python ve Django iyi bir ikilidir
>>> metin = "{} {}'yi seviyor!"
>>> metin.format("Ali", "Ayşe")
'Ali Ayşe'yi seviyor!'
>>> metin = "{} {} yaşında bir {}dur"
>>> metin.format("Ahmet", "18", "futbolcu")
'Ahmet 18 yaşında bir futbolcudur'
Burada da, gördüğüz gibi, öncelikle bir karakter dizisi tanımlıyoruz. Bu
karakter dizisi içindeki değişken değerleri ise {} işaretleri ile
gösteriyoruz. Daha sonra format()
metodunu alıp bu karakter dizisine
bağlıyoruz. Karakter dizisi içindeki {} işaretleri ile gösterdiğimiz yerlere
gelecek değerleri de format()
metodunun parantezleri içinde gösteriyoruz.
Yalnız burada şuna dikkat etmemiz lazım: Karakter dizisi içinde kaç tane {}
işareti varsa, format()
metodunun parantezleri içinde de o sayıda değer
olması gerekiyor.
Bu yapının, yazdığımız programlarda işimizi ne kadar kolaylaştıracağını tahmin
edebilirsiniz. Kısa karakter dizilerinde pek belli olmayabilir, ama özellikle
çok uzun ve boşluklu karakter dizilerini biçimlendirirken format()
metodunun
hayat kurtardığına kendiniz de şahit olacaksınız.
İlerleyen derslerimizde format()
metodunu ve karakter dizisi biçimlendirme
konusunu çok daha ayrıntılı bir şekilde inceleyeceğiz. Ancak yukarıda verdiğimiz
bilgiler format()
metodunu verimli bir şekilde kullanabilmenizi sağlamaya
yetecek düzeydedir.
Koşullu Durumlar¶
Artık Python programlama dilinde belli bir noktaya geldik sayılır. Ama eğer farkettiyseniz, yine de elimizi kolumuzu bağlayan, istediğimiz şeyleri yapmamıza engel olan bir şeyler var. İşte bu bölümde, Python programlama dilinde hareket alanımızı bir hayli genişletecek araçları tanıyacağız.
Aslında sadece bu bölümde değil, bu bölümü takip eden her bölümde, hareket alanımızı kısıtlayan duvarları tek tek yıktığımıza şahit olacaksınız. Özellikle bu bölümde inceleyeceğimiz ‘koşullu durumlar’ konusu, tabir yerindeyse, Python’da boyut atlamamızı sağlayacak.
O halde hiç vakit kaybetmeden yola koyulalım…
Şimdiye kadar öğrendiğimiz Python bilgilerini kullanarak şöyle bir program yazabileceğimizi biliyorsunuz:
yaş = 15
print("""Programa hoşgeldiniz!
Programımızı kullanabilmek için en az
13 yaşında olmalısınız.""")
print("Yaşınız: ", yaş)
Burada yaptığımız şey çok basit. Öncelikle, değeri 15 olan, yaş adlı bir değişken tanımladık. Daha sonra, programımızı çalıştıran kullanıcılar için bir hoşgeldin mesajı hazırladık. Son olarak da yaş değişkeninin değerini ekrana yazdırdık.
Bu programın özelliği tek sesli bir uygulama olmasıdır. Yani bu programda kullanıcıyla herhangi bir etkileşim yok. Burada bütün değerleri/değişkenleri programcı olarak kendimiz belirliyoruz. Bu programın ne kadar yavan olduğunu herhalde söylemeye gerek yok.
Ancak yine önceki derslerde öğrendiğimiz input()
fonksiyonu yardımıyla
yukarıdaki programın üzerindeki yavanlığı bir nebze de olsa atabilir, bu
programı rahatlıkla çok sesli bir hale getirebilir, yani kullanıcıyla etkileşim
içine girebiliriz.
Yukarıdaki tek sesli uygulamayı, input()
fonksiyonunu kullanarak çok sesli
bir hale nasıl getireceğimizi gayet iyi bildiğinize eminim:
print("""Programa hoşgeldiniz!
Programımızı kullanabilmek için en az
13 yaşında olmalısınız.""")
print("Lütfen yaşınızı girin.\n")
yaş = input("Yaşınız: \t")
print("Yaşınız: ", yaş)
Tıpkı bir önceki uygulamada olduğu gibi, burada da yaptığımız şey çok basit. İlk örnekte yaş değişkeninin değerini kendimiz elle yazmıştık. İkinci örnekte ise bu yaş değişkenini kullanıcıdan alıyoruz ve tıpkı ilk örnekte olduğu gibi, bu değişkenin değerini ekrana yazdırıyoruz.
Bu arada, yukarıdaki uygulamada yer verdiğimiz \n ve \t adlı kaçış dizileri de artık sizin için oldukça tanıdık. \n kaçış dizisi yardımıyla bir alt satıra geçtiğimizi, \t adlı kaçış dizisi yardımıyla da bir sekmelik boşluk bıraktığımızı biliyorsunuz.
Gördüğünüz gibi, şu ana kadar öğrendiklerimizle ancak kullanıcıdan gelen yaş
bilgisini ekrana yazdırabiliyoruz. Öğrendiğimiz input()
fonksiyonu bize
kullanıcıdan bilgi alma imkanı sağlıyor. Ama kullanıcıdan gelen bu bilgiyi
şimdilik ancak olduğu gibi kullanabiliyoruz. Yani mesela yukarıdaki örneği
dikkate alarak konuşacak olursak, kullanıcının yaşı eğer 13’ün üzerindeyse onu
programa kabul edecek, yok eğer 13 yaşın altındaysa da programdan atacak bir
mekanizma üretemiyoruz. Yapabildiğimiz tek şey, kullanıcının girdiği veriyi
ekrana yazdırmak.
Yukarıda verdiğimiz örneklerle nereye varmaya çalıştığımızı az çok tahmin etmişsinizdir. Dikkat ederseniz yukarıda sözünü ettiğimiz şey koşullu bir durum. Yani aslında yapmak istediğimiz şey, kullanıcının yaşını denetleyip, onun programa kabul edilmesini 13 yaşından büyük olma koşuluna bağlamak.
İsterseniz tam olarak neden bahsettiğimizi anlayabilmek için, birkaç vaka örneği verelim.
Diyelim ki Google’ın Gmail hizmeti aracılığıyla bir e.posta hesabı aldınız. Bu hesaba gireceğiniz zaman Gmail size bir kullanıcı adı ve parola sorar. Siz de kendinize ait kullanıcı adını ve parolayı sayfadaki kutucuklara yazarsınız. Eğer yazdığınız kullanıcı adı ve parola doğruysa hesabınıza erişebilirsiniz. Ama eğer kullanıcı adınız ve parolanız doğru değilse hesabınıza erişemezsiniz. Yani e.posta hesabınıza erişmeniz, kullanıcı adı ve parolayı doğru girme koşuluna bağlıdır.
Ya da şu vaka örneğini düşünelim: Diyelim ki Pardus’ta komut satırı aracılığıyla
güncelleme işlemi yapacaksınız. sudo pisi up
komutunu verdiğiniz zaman
güncellemelerin listesi size bildirilecek, bu güncellemeleri yapmak isteyip
istemediğiniz sorulacaktır. Eğer evet cevabı verirseniz güncelleme işlemi
başlar. Ama eğer hayır cevabı verirseniz güncelleme işlemi başlamaz. Yani
güncelleme işleminin başlaması kullanıcının evet cevabı vermesi koşuluna
bağlıdır.
İşte bu bölümde biz bu tür koşullu durumlardan söz edeceğiz.
Koşul Deyimleri¶
Hiç kuşkusuz, koşula bağlı durumlar Python’daki en önemli konulardan biridir. Giriş bölümünde bahsettiğimiz koşullu işlemleri yapabilmek için ‘koşul deyimleri’ adı verilen birtakım araçlardan yararlanacağız. Gelin şimdi bu araçların neler olduğunu görelim.
if¶
Python programlama dilinde koşullu durumları belirtmek için üç adet deyimden yararlanıyoruz:
if
elif
else
İsterseniz önce if
deyimi ile başlayalım…
Eğer daha önceden herhangi bir programlama dilini az da olsa kurcalama
fırsatınız olduysa, bir programlama dilinde if
deyimlerinin ne işe
yaradığını az çok biliyorsunuzdur. Daha önceden hiç programcılık deneyiminiz
olmamışsa da ziyanı yok. Zira bu bölümde if
deyimlerinin ne işe yaradığını
ve nerelerde kullanıldığını enine boyuna tartışacağız.
İngilizce bir kelime olan ‘if’, Türkçede ‘eğer’ anlamına gelir. Anlamından da
çıkarabileceğimiz gibi, bu kelime bir koşul bildiriyor. Yani ‘eğer bir şey
falanca ise…’ ya da ‘eğer bir şey filanca ise…’ gibi… İşte biz
Python’da bir koşula bağlamak istediğimiz durumları if
deyimi aracılığıyla
göstereceğiz.
Gelin isterseniz bu deyimi nasıl kullanacağımıza dair ufacık bir örnek vererek işe başlayalım:
Öncelikle elimizde şöyle bir değişken olsun:
n = 255
Yukarıda verdiğimiz değişkenin değerinin bir karakter dizisi değil, aksine bir sayı olduğunu görüyoruz. Şimdi bu değişkenin değerini sorgulayalım:
if n > 10:
Burada sayının 10’dan büyük olup olmadığına bakıyoruz.
Burada gördüğümüz > işaretinin ne demek olduğunu açıklamaya gerek yok sanırım. Hepimizin bildiği ‘büyüktür’ işareti Python’da da aynen bildiğimiz şekilde kullanılıyor. Mesela ‘küçüktür’ demek isteseydik, < işaretini kullanacaktık. İsterseniz hemen şurada araya girip bu işaretleri yeniden hatırlayalım:
İşleç
Anlamı
>
büyüktür
<
küçüktür
>=
büyük eşittir
<=
küçük eşittir
==
eşittir
!=
eşit değildir
Gördüğünüz gibi hiçbiri bize yabancı gelecek gibi değil. Yalnızca en sondaki ‘eşittir’ (==) ve ‘eşit değildir’ (!=) işaretleri biraz değişik gelmiş olabilir. Burada ‘eşittir’ işaretinin = olmadığına dikkat edin. Python’da = işaretini değer atama işlemleri için kullanıyoruz. == işaretini ise iki adet değerin birbirine eşit olup olmadığını denetlemek için… Mesela:
>>> a = 26
Burada değeri 26 olan a adlı bir değişken belirledik. Yani a değişkenine değer olarak 26 sayısını atadık. Ayrıca burada, değer atama işleminin ardından Enter tuşuna bastıktan sonra Python hiçbir şey yapmadan bir alt satıra geçti. Bir de şuna bakalım:
>>> a == 26
True
Burada ise yaptığımız şey a değişkeninin değerinin 26 olup olmadığını
sorgulamak a == 26
komutunu verdikten sonra Python bize True diye bir
çıktı verdi. Bu çıktının anlamını biraz sonra öğreneceğiz. Ama şimdi isterseniz
konuyu daha fazla dağıtmayalım. Biz şimdilik sadece = ve == işaretlerinin
birbirinden tamamen farklı anlamlara geldiğini bilelim yeter.
Ne diyorduk?
if n > 10:
Bu ifadeyle Python’a şöyle bir şey demiş oluyoruz:
Eğer n sayısının değeri 10’dan büyükse…
Burada kullandığımız işaretlere dikkat edin. En sonda bir adet : işaretinin olduğunu gözden kaçırmıyoruz. Bu tür işaretler Python için çok önemlidir. Bunları yazmayı unutursak Python gözümüzün yaşına bakmayacaktır.
Dedik ki, if n > 10:
ifadesi, ‘eğer n değişkeninin değeri 10’dan büyükse…’
anlamına gelir. Bu ifadenin eksik olduğu apaçık ortada. Yani belli ki bu
cümlenin bir de devamı olması gerekiyor. O halde biz de devamını getirelim:
if n > 10:
print("sayı 10'dan büyüktür!")
Burada çok önemli bir durumla karşı karşıyayız. Dikkat ederseniz, ikinci satırı ilk satıra göre girintili yazdık. Elbette bunu şirinlik olsun diye yapmadık. Python programlama dilinde girintiler çok büyük önem taşır. Hatta ne kadarlık bir girinti verdiğiniz bile önemlidir. Eğer Python kodlarına duyarlı bir metin düzenleyici kullanıyorsanız, kullandığınız metin düzenleyici çoğu durumda sizin yerinize uygun bir şekilde girintilemeyi yapacaktır. Mesela IDLE adlı geliştirme ortamını kullananlar, ilk satırdaki : işaretini koyup Enter tuşuna bastıklarında otomatik olarak girinti verildiğini farkedeceklerdir. Eğer kullandığınız metin düzenleyici, satırları otomatik olarak girintilemiyorsa sizin bu girintileme işlemini elle yapmanız gerekecektir. Yalnız elle girintilerken, ne kadar girinti vereceğimize dikkat etmeliyiz. Genel kural olarak 4 boşlukluk bir girintileme uygun olacaktır. Girintileme işlemini klavyedeki sekme (Tab) tuşuna basarak da yapabilirsiniz. Ama aynı program içinde sekmelerle boşlukları karıştırmayın. Yani eğer girintileme işlemini klavyedeki boşluk (Space) tuşuna basarak yapıyorsanız, program boyunca aynı şekilde yapın. (Ben size girinti verirken Tab tuşu yerine Space tuşunu kullanmanızı tavsiye ederim). Kısaca söylemek gerekirse; Python’da girintileme ve girintilemede tutarlılık çok önemlidir. Özellikle büyük programlarda, girintilemeler açısından tutarsızlık gösterilmesi programın çalışmamasına sebep olabilir.
Not
Python’da girintileme konusuyla ilgili daha ayrıntılı bilgi için: http://www.istihza.com/blog/python-ve-metin-duzenleyiciler.html (arşiv linki)
Eğer yukarıdaki if
bloğunu bir metin düzenleyici içine değil de doğrudan
etkileşimli kabuğa yazmışsanız bazı şeyler dikkatinizi çekmiş olmalı.
Etkileşimli kabukta if sayı > 10:
satırını yazıp Enter tuşuna bastığınızda
şöyle bir görüntüyle karşılaşmış olmalısınız:
>>> if n > 10:
...
Dikkat ederseniz, >>> işareti, … işaretine dönüştü. Eğer bu noktada herhangi bir şey yazmadan Enter tuşuna basacak olursanız Python size şöyle bir hata mesajı verecektir:
File "<stdin>", line 2
^
IndentationError: expected an indented block
Hata mesajında da söylendiği gibi, Python bizden girintilenmiş bir blok
beklerken, biz onun bu beklentisini karşılamamışız. Dolayısıyla bize yukarıdaki
hata mesajını göstermiş. … işaretini gördükten sonra yapmamız gereken şey,
dört kez boşluk (Space) tuşuna basarak girinti oluşturmak ve if
bloğunun
devamını yazmak olmalıydı. Yani şöyle:
>>> if n > 10:
... print("sayı 10'dan büyüktür!")
...
Gördüğünüz gibi, print()
fonksiyonunu yazıp Enter tuşuna bastıktan sonra
yine … işaretini gördük. Python burada bizden yeni bir satır daha bekliyor.
Ama bizim yazacak başka bir kodumuz olmadığı için tekrar Enter tuşuna
basıyoruz ve nihai olarak şöyle bir görüntü elde ediyoruz:
>>> if n > 10:
... print("sayı 10'dan büyüktür!")
...
sayı 10'dan büyüktür!
>>>
Demek ki 255 sayısı 10’dan büyükmüş! Ne büyük bir buluş! Merak etmeyin, daha çok şey öğrendikçe daha mantıklı programlar yazacağız. Burada amacımız işin temelini kavramak. Bunu da en iyi, (çok mantıklı olmasa bile) basit programlar yazarak yapabiliriz.
Şimdi metin düzenleyicimizi açarak daha mantıklı şeyler yazmaya çalışalım. Zira
yukarıdaki örnekte değişkeni kendimiz belirlediğimiz için, bu değişkenin
değerini if
deyimleri yardımıyla denetlemek pek akla yatkın görünmüyor. Ne
de olsa değişkenin değerinin ne olduğunu biliyoruz. Dolayısıyla bu değişkenin
10 sayısından büyük olduğunu da biliyoruz! Bunu if
deyimiyle kontrol etmek
çok gerekli değil. Ama şimdi daha makul bir iş yapacağız. Değişkeni biz
belirlemek yerine kullanıcıya belirleteceğiz:
sayı = int(input("Bir sayı giriniz: "))
if sayı > 10:
print("Girdiğiniz sayı 10'dan büyüktür!")
if sayı < 10:
print("Girdiğiniz sayı 10'dan küçüktür!")
if sayı == 10:
print("Girdiğiniz sayı 10'dur!")
Gördüğünüz gibi, art arda üç adet if
bloğu kullandık. Bu kodlara göre, eğer
kullanıcının girdiği sayı 10’dan büyükse, ilk if
bloğu işletilecek; eğer
sayı 10’dan küçükse ikinci if
bloğu işletilecek; eğer sayı 10’a eşit ise
üçüncü if
bloğu işletilecektir. Peki ya kullanıcı muziplik yapıp sayı yerine
harf yazarsa ne olacak? Böyle bir ihtimal için programımıza herhangi bir
denetleyici yerleştirmedik. Dolayısıyla eğer kullanıcı sayı yerine harf girerse
programımız hata verecek, yani çökecektir. Bu tür durumlara karşı nasıl önlem
alacağımızı ilerleyen derslerimizde göreceğiz. Biz şimdilik bildiğimiz yolda
yürüyelim.
Yukarıdaki örnekte input()
ile gelen karakter dizisini, int()
fonksiyonu
yardımıyla bir sayıya dönüştürdüğümüze dikkat edin. Kullanıcıdan gelen veriyi
büyüklük-küçüklük ölçütüne göre inceleyeceğimiz için, gelen veriyi bir sayıya
dönüştürmemiz gerekiyor. Bunu da int()
fonksiyonu ile yapabileceğimizi
biliyorsunuz.
Elbette yukarıdaki dönüştürme işlemini şöyle de yapabilirdik:
sayı = input("Bir sayı giriniz: ")
sayı = int(sayı)
Burada önce input()
fonksiyonuyla veriyi aldık, daha sonra bu veriyi ayrı
bir yerde sayıya dönüştürüp tekrar sayı adlı değişkene atadık.
if
deyimlerini kullanıcı adı veya parola denetlerken de kullanabiliriz.
Mesela şöyle bir program taslağı yazabiliriz:
print("""
Dünyanın en gelişmiş e.posta hizmetine
hoşgeldiniz. Yalnız hizmetimizden
yararlanmak için önce sisteme giriş
yapmalısınız.
""")
parola = input("Parola: ")
if parola == "12345678":
print("Sisteme Hoşgeldiniz!")
Gördüğünüz gibi, programın başında üç tırnak işaretlerinden yararlanarak uzun bir metni kullanıcıya gösterdik. Bu bölümü, kendiniz göze hoş gelecek bir şekilde süsleyebilirsiniz de. Eğer kullanıcı, kendisine parola sorulduğunda cevap olarak “12345678” yazarsa kullanıcıyı sisteme alıyoruz.
Yukarıdaki örnekte, kullanıcının girdiği parola “12345678” ise kendisine “Sisteme Hoşgeldiniz!” mesajını gösteriyoruz. Mantık olarak bunun tersini yapmak da mümkündür. Yani:
if parola != "12345678":
print("Ne yazık ki yanlış parola girdiniz!")
Burada ise bir önceki örneğin mantığını ters çevirdik. Önceki örnekte parola
değişkeni “12345678” adlı karakter dizisine eşitse (if parola ==
"12345678"
) bir işlem yapıyorduk. Yukarıdaki örnekte ise parola değişkeni
“12345678” adlı karakter dizisine eşit değilse (if parola != "12345678"
)
bir işlem yapıyoruz.
Bu iki örneğin de aslında aynı kapıya çıktığını görüyorsunuz. Tek değişiklik, kullanıcıya gösterilen mesajlardadır.
Böylece Python’daki koşullu durumlar üzerindeki incelememizin ilk ve en önemli
aşamasını geride bırakmış olduk. Dikkat ettiyseniz if
deyimi sayesinde
programlarımıza karar vermeyi öğrettik. Bu deyim yardımıyla, kullanıcıdan
aldığımız herhangi bir verinin niteliği üzerinde kapsamlı bir karar verme işlemi
yürütebiliyoruz. Yani artık programlarımız kullanıcıdan alınan veriyi olduğu
gibi kabul etmekle yetinmiyor. Kullanıcının girdiği verinin ne olduğuna bağlı
olarak programlarımızın farklı işlemler yapmasını da sağlayabiliyoruz.
Daha önce de söylediğimiz gibi, if
deyimi dışında Python’da koşullu
durumları ifade etmek için kullandığımız, elif
ve else
adlı iki deyim
daha vardır. Bunlar if
ile birlikte kullanılırlar. Gelin isterseniz bu iki
deyimden, adı elif
olana bakalım.
elif¶
Python’da, if
deyimleriyle birlikte kullanılan ve yine koşul belirten bir
başka deyim de elif
deyimidir. Buna şöyle bir örnek verebiliriz:
yaş = int(input("Yaşınız: "))
if yaş == 18:
print("18 iyidir!")
elif yaş < 0:
print("Yok canım, daha neler!...")
elif yaş < 18:
print("Genç bir kardeşimizsin!")
elif yaş > 18:
print("Eh, artık yaş yavaş yavaş kemale eriyor!")
Yukarıdaki örneği şöyle yazmayı da deneyebilirsiniz:
yaş = int(input("Yaşınız: "))
if yaş == 18:
print("18 iyidir!")
if yaş < 0:
print("Yok canım, daha neler!...")
if yaş < 18:
print("Genç bir kardeşimizsin!")
if yaş > 18:
print("Eh, artık yaş yavaş yavaş kemale eriyor!")
Bu iki programın da aynı işlevi gördüğünü düşünebilirsiniz. Ancak ilk bakışta
pek belli olmasa da, aslında yukarıdaki iki program birbirinden farklı
davranacaktır. Örneğin ikinci programda eğer kullanıcı eksi değerli bir sayı
girerse hem if yaş < 0
bloğu, hem de if yaş < 18
bloğu çalışacaktır.
İsterseniz yukarıdaki programı çalıştırıp, cevap olarak eksi değerli bir sayı
verin. Ne demek istediğimiz gayet net anlaşılacaktır.
Bu durum if
ile elif
arasındaki çok önemli bir farktan kaynaklanır. Buna
göre if
bize olası bütün sonuçları listeler, elif
ise sadece doğru olan
ilk sonucu verir. Bu soyut tanımlamayı biraz daha somutlaştıralım:
a = int(input("Bir sayı giriniz: "))
if a < 100:
print("verdiğiniz sayı 100'den küçüktür.")
if a < 50:
print("verdiğiniz sayı 50'den küçüktür.")
if a == 100:
print("verdiğiniz sayı 100'dür.")
if a > 100:
print("verdiğiniz sayı 100'den büyüktür.")
if a > 150:
print("verdiğiniz sayı 150'den büyüktür.")
Yukarıdaki kodları çalıştırdığımızda, doğru olan bütün sonuçlar listelenecektir. Yani mesela kullanıcı 40 sayısını girmişse, ekrana verilecek çıktı şöyle olacaktır:
verdiğiniz sayı 100'den küçüktür.
verdiğiniz sayı 50'den küçüktür.
Burada 40 sayısı hem 100’den, hem de 50’den küçük olduğu için iki sonuç da çıktı olarak verilecektir. Ama eğer yukarıdaki kodları şöyle yazarsak:
a = int(input("Bir sayı giriniz: "))
if a < 100:
print("verdiğiniz sayı 100'den küçüktür.")
elif a < 50:
print("verdiğiniz sayı 50'den küçüktür.")
elif a == 100:
print("verdiğiniz sayı 100'dür.")
elif a > 150:
print("verdiğiniz sayı 150'den büyüktür.")
elif a > 100:
print("verdiğiniz sayı 100'den büyüktür.")
Kullanıcının 40 sayısını girdiğini varsaydığımızda, bu defa programımımız yalnızca şu çıktıyı verecektir:
verdiğiniz sayı 100'den küçüktür.
Gördüğünüz gibi, elif
deyimlerini kullandığımız zaman, ekrana yalnızca doğru
olan ilk sonuç veriliyor. Yukarıda 40 sayısı hem 100’den hem de 50’den
küçük olduğu halde, Python bu sayının 100’den küçük olduğunu görür görmez
sonucu ekrana basıp, öteki koşul bloklarını incelemeyi bırakıyor. if
deyimlerini arka arkaya sıraladığımızda ise, Python bütün olasılıkları tek tek
değerlendirip, geçerli olan bütün sonuçları ekrana döküyor.
Bir sonraki bölümde else
deyimini öğrendiğimiz zaman, elif
’in tam olarak
ne işe yaradığını çok daha iyi anlamanızı sağlayacak bir örnek vereceğiz.
Not
Şimdiye kadar verdiğimiz örneklerden de rahatlıkla anlayabileceğiniz
gibi, ilk koşul bloğunda asla elif
deyimi kullanılamaz. Bu deyimin
kullanılabilmesi için kendisinden önce en az bir adet if
bloğu olmalıdır.
Yani Python’da koşullu durumları ifade ederken ilk koşul bloğumuz her zaman
if
deyimi ile başlamalıdır.
elif
’i de incelediğimize göre, koşul bildiren deyimlerin sonuncusuna göz
atabiliriz: else
else¶
Şimdiye kadar Python’da koşul bildiren iki deyimi öğrendik. Bunlar if
ve
elif
idi. Bu bölümde ise koşul deyimlerinin sonuncusu olan else
deyimini
göreceğiz. Öğrendiğimiz şeyleri şöyle bir gözden geçirecek olursak, temel olarak
şöyle bir durumla karşı karşıya olduğumuzu görürüz:
if falanca:
bu işlemi yap
if filanca:
şu işlemi yap
Veya şöyle bir durum:
if falanca:
bu işlemi yap
elif filanca:
şu işlemi yap
if
ile elif
arasındaki farkı biliyoruz. Eğer if
deyimlerini art arda
sıralayacak olursak, Python doğru olan bütün sonuçları listeleyecektir. Ama eğer
if
deyiminden sonra elif
deyimini kullanırsak, Python doğru olan ilk
sonucu listelemekle yetinecektir.
Bu bölümde göreceğimiz else
deyimi, yukarıdaki tabloya bambaşka bir boyut
kazandırıyor. Dikkat ederseniz şimdiye kadar öğrendiğimiz deyimleri
kullanabilmek için ilgili bütün durumları tanımlamamız gerekiyordu. Yani:
eğer böyle bir durum varsa:
bunu yap
eğer şöyle bir durum varsa:
şunu yap
eğer filancaysa:
şöyle git
eğer falancaysa:
böyle gel
gibi…
Ancak her durum için bir if
bloğu yazmak bir süre sonra yorucu ve sıkıcı
olacaktır. İşte bu noktada devreye else
deyimi girecek. else
’in anlamı
kabaca şudur:
Eğer yukarıdaki koşulların hiçbiri gerçekleşmezse…
Gelin isterseniz bununla ilgili şöyle bir örnek verelim:
soru = input("Bir meyve adı söyleyin bana:")
if soru == "elma":
print("evet, elma bir meyvedir...")
elif soru == "karpuz":
print("evet, karpuz bir meyvedir...")
elif soru == "armut":
print("evet, armut bir meyvedir...")
else:
print(soru, "gerçekten bir meyve midir?")
Eğer kullanıcı soruya ‘elma’, ‘karpuz’ veya ‘armut’ cevabı verirse, evet, …
bir meyvedir çıktısı verilecektir. Ama eğer kullanıcı bu üçü dışında bir cevap
verirse, … gerçekten bir meyve midir? çıktısını görürüz. Burada else
deyimi, programımıza şu anlamı katıyor:
Eğer kullanıcı yukarıda belirlenen meyve adlarından hiç birini girmez, bunların yerine bambaşka bir şey yazarsa, o zaman
else
bloğu içinde belirtilen işlemi gerçekleştir.
Dikkat ederseniz yukarıdaki kodlarda if
deyimlerini art arda sıralamak
yerine ilk if
’ten sonra elif
ile devam ettik. Peki şöyle bir şey
yazarsak ne olur?
soru = input("Bir meyve adı söyleyin 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, "gerçekten bir meyve midir?")
Bu kodlar beklediğiniz sonucu vermeyecektir. İsterseniz yukarıdaki kodları
çalıştırıp ne demek istediğimizi daha iyi anlayabilirsiniz. Eğer yukarıda olduğu
gibi if
deyimlerini art arda sıralar ve son olarak da bir else
bloğu
tanımlarsak, ekrana ilk bakışta anlamsız gibi görünen bir çıktı verilecektir:
evet, elma bir meyvedir...
elma gerçekten bir meyve midir?
Burada olan şey şu:
Soruya ‘elma’ cevabını verdiğimizi düşünelim. Bu durumda, Python ilk olarak ilk
if
bloğunu değerlendirecek ve soruya verdiğimiz cevap ‘elma’ olduğu için
evet, elma bir meyvedir… çıktısını verecektir.
if
ile elif
arasındaki farkı anlatırken, hatırlarsanız art arda gelen if
bloklarında Python’ın olası bütün sonuçları değerlendireceğini söylemiştik. İşte burada da böyle bir durum söz konusu. Gördüğünüz gibi, ilk if
bloğundan sonra yine bir if
bloğu geliyor. Bu nedenle Python olası bütün sonuçları değerlendirebilmek için blokları okumaya devam edecek ve sorunun cevabı ‘karpuz’ olmadığı için ikinci if
bloğunu atlayacaktır.
Sonraki blok yine bir if
bloğu olduğu için Python kodları okumaya devam
ediyor. Ancak sorunun cevabı ‘armut’ da olmadığı için, Python sonraki if
bloğunu da geçiyor ve böylece else
bloğuna ulaşıyor.
Yukarıda verdiğimiz örnekteki gibi art arda if
deyimlerinin sıralanıp en
sona else
deyiminin yerleştirildiği durumlarda else
deyimi sadece bir
önceki if
deyimini dikkate alarak işlem yapar. Yani yukarıdaki örnekte
kullanıcının verdiği cevap ‘armut’ olmadığı için else
deyiminin olduğu blok
çalışmaya başlar. Yukarıdaki örneğe ‘armut’ cevabını verirseniz ne demek
istediğimi biraz daha iyi anlayabilirsiniz. ‘armut’ cevabı verilmesi durumunda
sadece if soru == "armut"
ifadesinin olduğu blok çalışır, else
bloğu ise
çalışmaz. Çünkü dediğim gibi, eğer else
bloğundan önce art arda gelen if
blokları varsa, else
deyimi yalnızca kendisinden önceki son if
bloğunu
dikkate alır ve sanki yukarıdaki örnek şöyleymiş gibi davranır:
if soru == "armut":
print("evet, armut bir meyvedir...")
else:
print(soru, "gerçekten bir meyve midir?")
Bu tür durumlarda else
deyimi bir önceki if
bloğundan önce gelen bütün
if
bloklarını görmezden gelir ve böylece şu anlamsız görünen çıktı elde
edilir:
evet, elma bir meyvedir...
elma gerçekten bir meyve midir?
Sözün özü, kullanıcının cevabı ‘elma’ olduğu için, yukarıdaki çıktıda yer alan
ilk cümle ilk if
bloğunun çalışması sonucu ekrana basılıyor. İkinci cümle
ise else
bloğundan bir önceki if
bloğu kullanıcının cevabıyla uyuşmadığı
için ekrana basılıyor.
Yalnız bu dediğimizden, else
ifadesi if
ile birlikte kullanılmaz, anlamı
çıkarılmamalı. Mesela şöyle bir örnek yapılabilir:
soru = input("Programdan çıkmak istediğinize emin misiniz? \
Eminseniz 'e' harfine basın : ")
if soru == "e":
print("Güle güle!")
else:
print("Peki, biraz daha sohbet edelim!")
Burada eğer kullanıcının cevabı ‘e’ ise if
bloğu işletilecek, eğer cevap ‘e’
dışında herhangi bir şey ise else
bloğu çalışacaktır. Gayet mantıklı bir
süreç. Ama eğer yukarıdaki örneğe bir if
bloğu daha eklerseniz işler
beklediğiniz gibi gitmez:
soru = input("Programdan çıkmak istediğinize emin misiniz? \
Eminseniz 'e' harfine basın : ")
if soru == "e":
print("Güle güle!")
if soru == "b":
print("Kararsız kaldım şimdi!")
else:
print("Peki, biraz daha sohbet edelim!")
Bu soruya ‘e’ cevabı verdiğimizi düşünelim. Bu cevap ilk if
bloğuyla
uyuşuyor ve böylece ekrana Güle güle! çıktısı veriliyor. İlk if
bloğundan
sonra tekrar bir if
bloğu daha geldiği için Python bütün olasılıkları
değerlendirmek amacıyla blokları okumaya devam ediyor ve cevap ‘b’ olmadığı için
ikinci if
bloğunu atlıyor ve böylece else
bloğuna ulaşıyor. Bir önceki
örnekte de söylediğimiz gibi, else
bloğu art arda gelen if
blokları
gördüğünde sadece bir önceki if
bloğunu dikkate aldığı ve kullanıcının
cevabı da ‘b’ olmadığı için ekrana Peki, biraz daha sohbet edelim! çıktısını
veriyor ve ilk bakışta tuhaf görünen şöyle bir çıktı üretiyor:
Güle güle!
Peki, biraz daha sohbet edelim!
Dolayısıyla, eğer programınızda bir else
bloğuna yer verecekseniz, ondan
önce gelen koşullu durumların ilkini if
ile sonrakileri ise elif
ile
bağlayın. Yani:
if koşul_1:
sonuç_1
elif koşul_2:
sonuç_2
elif koşul_3:
sonuç_3
else:
sonuç_4
Ama eğer else
bloğundan önce sadece tek bir koşul bloğu yer alacaksa bunu
if
ile bağlayın. Yani:
if koşul_1:
sonuç_1
else:
sonuç_2
Programlarımızın doğru çalışması ve istediğimiz sonucu verebilmesi için bu tür ayrıntılara olabildiğince dikkat etmemiz gerekiyor. Neticede koşullu durumlar mantıkla ilgilidir. Dolayısıyla koşullu durumlarla muhatap olurken mantığınızı hiçbir zaman devre dışı bırakmamalısınız.
Bir önceki bölümde elif
deyiminin tam olarak ne işe yaradığını anlamamızı
sağlayacak bir örnek vereceğimizi söylemiştik. Şimdi bu örneğe bakalım:
boy = int(input("boyunuz kaç cm?"))
if boy < 170:
print("boyunuz kısa")
elif boy < 180:
print("boyunuz normal")
else:
print("boyunuz uzun")
Yukarıda yedi satırla hallettiğimiz işi sadece if
deyimleriyle yapmaya
çalışırsanız bunun ne kadar zor olduğunu göreceksiniz. Diyelim ki kullanıcı
‘165’ cevabını verdi. Python bu 165 sayısının 170’ten küçük olduğunu görünce
boyunuz kısa cevabını verecek, öteki satırları değerlendirmeyecektir. 165
sayısı, elif
ile gösterdiğimiz koşullu duruma da uygun olduğu halde (165 <
180
), koşul ilk blokta karşılandığı için ikinci blok değerlendirmeye
alınmayacaktır.
Kullanıcının ‘175’ cevabını verdiğini varsayalım: Python 175 sayısını görünce
önce ilk koşula bakacak, verilen 175 sayısının ilk koşulu karşılamadığını
görecektir (175 > 170
). Bunun üzerine Python kodları incelemeye devam edecek
ve elif
bloğunu değerlendirmeye alacaktır. 175 sayısının 180’den küçük
olduğunu görünce de çıktı olarak boyunuz normal cevabını verecektir.
Peki ya kullanıcı ‘190’ cevabını verirse ne olacak? Python yine önce ilk if
bloğuna bakacak ve 190 cevabının bu bloğa uymadığını görecektir. Dolayısıyla
ilk bloğu bırakıp ikinci bloğa bakacaktır. 190 cevabının bu bloğa da
uymadığını görünce, bir sonraki bloğu değerlendirmeye alacaktır. Bir sonraki
blokta ise else
deyimimiz var. Bu bölümde öğrendiğimiz gibi, else
deyimi, ‘eğer kullanıcının cevabı yukarıdaki koşulların hiçbirine uymazsa bu
bloğu çalıştır,’ anlamına geliyor. Kullanıcının girdiği 190 cevabı ne birinci
ne de ikinci bloktaki koşula uyduğu için, normal bir şekilde else
bloğu
işletilecek, dolayısıyla da ekrana boyunuz uzun çıktısı verilecektir.
Böylece Python’da if
, elif
ve else
deyimlerini incelemiş olduk.
Ancak tabii ki bu deyimlerle işimiz henüz bitmedi. Elimizdeki bilgiler şimdilik
bu deyimleri ancak bu kadar incelememize yetiyor, ama ilerleyen sayfalarda bazı
başka araçları da bilgi dağarcığımıza kattıktan sonra bu deyimlerin daha farklı
yönlerini öğrenme imkanına kavuşacağız.
Örnek Uygulama¶
Önceki derslerimizde len()
fonksiyonunu anlatırken şöyle bir program
tasarısından bahsetmiştik hatırlarsanız:
Diyelim ki sisteme kayıt için kullanıcı adı ve parola belirlenmesini isteyen bir program yazıyorsunuz. Yazacağınız bu programda, belirlenebilecek kullanıcı adı ve parolanın toplam uzunluğu 40 karakteri geçmeyecek.
O zaman henüz koşullu durumları öğrenmemiş olduğumuz için, yukarıda bahsettiğimiz programın ancak şu kadarlık kısmını yazabilmiştik:
kullanıcı_adı = input("Kullanıcı adınız: ")
parola = input("Parolanız : ")
toplam_uzunluk = len(kullanıcı_adı) + len(parola)
Burada yapabildiğimiz tek şey, kullanıcıdan kullanıcı adı ve parola bilgilerini alıp, bu bilgilerin karakter uzunluğunu ölçebilmekti. Ama artık koşullu durumları öğrendiğimize göre bu programı eksiksiz olarak yazabiliriz. Şu kodları dikkatlice inceleyin:
kullanıcı_adı = input("Kullanıcı adınız: ")
parola = input("Parolanız : ")
toplam_uzunluk = len(kullanıcı_adı) + len(parola)
mesaj = "Kullanıcı adı ve parolanız toplam {} karakterden oluşuyor!"
print(mesaj.format(toplam_uzunluk))
if toplam_uzunluk > 40:
print("Kullanıcı adınız ile parolanızın ",
"toplam uzunluğu 40 karakteri geçmemeli!")
else:
print("Sisteme hoşgeldiniz!")
Burada öncelikle kullanıcıdan kullanıcı adı ve parola bilgilerini alıyoruz. Daha
sonra da kullanıcıdan gelen bu bilgilerin toplam karakter uzunluğunu
hesaplıyoruz. Bunun için len()
fonksiyonundan yararlanmamız gerektiğini
hatırlıyor olmalısınız.
Eğer toplam uzunluk 40 karakterden fazla ise, if
bloğunda verilen mesajı
gösteriyoruz. Bunun dışındaki bütün durumlarda ise else
bloğunu devreye
sokuyoruz.
İşleçler¶
Bu bölümde, aslında pek de yabancısı olmadığımız ve hatta önceki derslerimizde üstünkörü de olsa değindiğimiz bir konuyu çok daha ayrıntılı bir şekilde ele alacağız. Burada anlatacağımız konu size yer yer sıkıcı gelebilir. Ancak bu konuyu hakkıyla öğrenmenizin, programcılık maceranız açısından hayati önemde olduğunu rahatlıkla söyleyebilirim.
Gelelim konumuza…
Bu bölümün konusu işleçler. Peki nedir bu ‘işleç’ denen şey?
İngilizce’de operator adı verilen işleçler, sağında ve solunda bulunan değerler arasında bir ilişki kuran işaretlerdir. Bir işlecin sağında ve solunda bulunan değerlere ise işlenen (operand) adı veriyoruz.
Not
Türkçede işleç yerine operatör, işlenen yerine de operant dendiğine tanık olabilirsiniz.
Biz bu bölümde işleçleri altı başlık altında inceleyeceğiz:
Aritmetik İşleçler
Karşılaştırma İşleçleri
Bool İşleçleri
Değer Atama İşleçleri
Bitwise (Bitsel) İşleçleri
Aitlik İşleçleri
Kimlik İşleçleri
Gördüğünüz gibi, işlememiz gereken konu çok, gitmemiz gereken yol uzun. O halde hiç vakit kaybetmeden, aritmetik işleçlerle yolculuğumuza başlayalım.
Aritmetik İşleçler¶
Dedik ki, sağında ve solunda bulunan değerler arasında bir ilişki kuran işaretlere işleç (operator) adı verilir. Önceki derslerimizde temel işleçlerin bazılarını öğrenmiştik. İsterseniz bunları şöyle bir hatırlayalım:
+
toplama
-
çıkarma
*
çarpma
/
bölme
**
kuvvet
Bu işleçlere aritmetik işleçler adı verilir. Aritmetik işleçler; matematikte kullanılan ve sayılarla aritmetik işlemler yapmamızı sağlayan yardımcı araçlardır.
Dilerseniz bu tanımı bir örnekle somutlaştıralım:
>>> 45 + 33
78
Burada 45 ve 33 değerlerine işlenen (operand) adı verilir. Bu iki değer arasında yer alan + işareti ise bir işleçtir (operator). Dikkat ederseniz + işleci 45 ve 33 adlı işlenenler arasında bir toplama ilişkisi kuruyor.
Bir örnek daha verelim:
>>> 23 * 46
1058
Burada da 23 ve 46 değerleri birer işlenendir. Bu iki değer arasında yer alan * işareti ise, işlenenler arasında bir çarpma ilişkisi kuran bir işleçtir.
Ancak bir noktaya özellikle dikkatinizi çekmek istiyorum. Daha önceki derslerimizde de değindiğimiz gibi, + ve * işleçleri Python’da birden fazla anlama gelir. Örneğin yukarıdaki örnekte + işleci, işlenenler arasında bir toplama ilişkisi kuruyor. Ama aşağıdaki durum biraz farklıdır:
>>> "istihza" + ".com"
'istihza.com'
Burada + işleci işlenenler (“istihza” ve “.com”) arasında bir birleştirme ilişkisi kuruyor.
Tıpkı + işlecinde olduğu gibi, * işleci de Python’da birden fazla anlama gelir. Bu işlecin, çarpma ilişkisi kurma işlevi dışında tekrar etme ilişkisi kurma işlevi de vardır. Yani:
>>> "hızlı " * 2
'hızlı hızlı '
…veya:
>>> "-" * 30
'------------------------------'
Burada * işlecinin, sayılar arasında çarpma işlemi yapmak dışında bir görev üstlendiğini görüyoruz.
Python’da bu tür farklar, yazacağınız programın sağlıklı çalışabilmesi açısından büyük önem taşır. O yüzden bu tür farklara karşı her zaman uyanık olmamız gerekiyor.
+ ve * işleçlerinin aksine / ve - işleçleri ise işlenenler arasında sadece bölme ve çıkarma ilişkisi kurar. Bu işleçler tek işlevlidir:
>>> 25 / 4
6.25
>>> 10 - 5
5
Önceki derslerde gördüğümüz ve yukarıda da tekrar ettiğimiz dört adet temel aritmetik işlece şu iki aritmetik işleci de ekleyelim:
%
modülüs
//
taban bölme
İlk önce modülüsün ne olduğunu ve ne işe yaradığını anlamaya çalışalım.
Şu bölme işlemine bir bakın:
Burada 02 sayısı bölme işleminin kalanıdır. İşte modülüs denen işleç de bölme işleminden kalan bu değeri gösterir. Yani:
>>> 30 % 4
2
Gördüğünüz gibi modülüs işleci (%) gerçekten de bölme işleminden kalan sayıyı gösteriyor… Peki bu bilgi ne işimize yarar?
Mesela bu bilgiyi kullanarak bir sayının tek mi yoksa çift mi olduğunu tespit edebiliriz:
sayı = int(input("Bir sayı girin: "))
if sayı % 2 == 0:
print("Girdiğiniz sayı bir çift sayıdır.")
else:
print("Girdiğiniz sayı bir tek sayıdır.")
Eğer bir sayı 2’ye bölündüğünde kalan değer 0 ise o sayı çifttir. Aksi halde o sayı tektir. Mesela:
>>> 14 % 2
0
Gördüğünüz gibi, bir çift sayı olan 14’ü 2’ye böldüğümüzde kalan sayı 0 oluyor. Çünkü çift sayılar 2’ye tam bölünürler.
Bir de şuna bakalım:
>>> 15 % 2
1
Bir tek sayı olan 15 ise 2’ye bölündüğünde kalan sayı 1 oluyor. Yani 15 sayısı 2’ye tam bölünmüyor. Bu bilgiden yola çıkarak 15 sayısının bir tek sayı olduğunu söyleyebiliyoruz.
Bir sayının tek mi yoksa çift mi olduğunu tespit etme işlemini küçümsememenizi tavsiye ederim. Bir sayının tek mi yoksa çift mi olduğu bilgisinin, arayüz geliştirirken dahi işinize yarayacağından emin olabilirsiniz.
Elbette modülüs işlecini bir sayının yalnızca 2’ye tam bölünüp bölünmediğini denetlemek için kullanmıyoruz. Bu işleci kullanarak herhangi bir sayının herhangi bir sayıya tam bölünüp bölünmediğini de denetleyebilirsiniz. Örneğin:
>>> 45 % 4
1
>>> 36 % 9
0
Bu bilgiyi kullanarak mesela şöyle bir program yazabilirsiniz:
bölünen = int(input("Bir sayı girin: "))
bölen = int(input("Bir sayı daha girin: "))
şablon = "{} sayısı {} sayısına tam".format(bölünen, bölen)
if bölünen % bölen == 0:
print(şablon, "bölünüyor!")
else:
print(şablon, "bölünmüyor!")
Programımız, kullanıcının girdiği ilk sayının ikinci sayıya tam bölünüp bölünmediğini hesaplıyor ve sonuca göre kullanıcıyı bilgilendiriyor. Bu kodlarda özellikle şu satıra dikkat edin:
if bölünen % bölen == 0:
...
Programımızın temelini bu kod oluşturuyor. Çünkü bir sayının bir sayıya tam bölünüp bölünmediğini bu kodla belirliyoruz. Eğer bir sayı başka bir sayıya bölündüğünde kalan değer, yani modülüs 0 ise, o sayı öbür sayıya tam bölünüyor demektir.
Ayrıca bir sayının son basamağını elde etmek için de modülüsten yararlanabilirsiniz. Herhangi bir tamsayı 10’a bölündüğünde kalan (yani modülüs), bölünen sayının son basamağı olacaktır:
>>> 65 % 10
5
>>> 543 % 10
3
Programlama tecrübeniz arttıkça, aslında modülüsün ne kadar faydalı bir araç olduğunu kendi gözlerinizle göreceksiniz.
Modülüs işlecini örnekler eşliğinde ayrıntılı bir şekilde incelediğimize göre sıra geldi taban bölme işlecini açıklamaya…
Öncelikle şu örneği inceleyelim:
>>> 5 / 2
2.5
Burada, bildiğimiz bölme işlecini (/) kullanarak basit bir bölme işlemi yaptık. Elde ettiğimiz sonuç doğal olarak 2.5.
Matematikte bölme işleminin sonucunun kesirli olması durumuna ‘kesirli bölme’ adı verilir. Bunun tersi ise tamsayılı bölme veya taban bölmedir. Eğer herhangi bir sebeple kesirli bölme işlemi değil de taban bölme işlemi yapmanız gerekirse // işlecinden yararlanabilirsiniz:
>>> 5 // 2
2
Gördüğünüz gibi, // işleci sayesinde bölme işleminin sonucu kesirli değil, tamsayı olarak elde ediliyor.
Yukarıda yaptığımız taban bölme işlemi şununla aynı anlama gelir:
>>> int(5 / 2)
2
Daha açık ifade etmemiz gerekirse:
>>> a = 5 / 2
>>> a
2.5
>>> int(a)
2
Burada olan şu: 5 / 2
işleminin sonucu bir kayan noktalı sayıdır (2.5).
Bunu şu şekilde teyit edebiliriz:
>>> a = 5 / 2
>>> type(a)
<class 'float'>
Buradaki float çıktısının floating point number, yani kayan noktalı sayı anlamına geldiğini biliyorsunuz.
Bu kayan noktalı sayının sadece tabanını elde etmek için bu sayıyı tamsayıya (integer) çevirmemiz yeterli olacaktır. Yani:
>>> int(a)
2
Bu arada yeri gelmişken round()
adlı bir gömülü fonksiyondan bahsetmeden
geçmeyelim. Eğer bir sayının değerini yuvarlamanız gerekirse round()
fonksiyonundan yararlanabilirsiniz. Bu fonksiyon şöyle kullanılır:
>>> round(2.55)
3
Gördüğünüz gibi, round()
fonksiyonuna parametre olarak bir sayı veriyoruz.
Bu fonksiyon da bize o sayının yuvarlanmış halini döndürüyor. Bu fonksiyonu
kullanarak yuvarlanacak sayının noktadan sonraki hassasiyetini de
belirleyebilirsiniz. Örneğin:
>>> round(2.55, 1)
2.5
Burada ikinci parametre olarak 1 sayısını verdiğimiz için, noktadan sonraki bir basamak görüntüleniyor. Bir de şuna bakalım:
>>> round(2.68, 1)
2.7
Burada da yuvarlama işlemi yapılırken noktadan sonra bir basamak korunuyor. Eğer 1 sayısı yerine 2 sayısını kullanırsanız, yukarıdaki örnek şu çıktıyı verir:
>>> round(2.68, 2)
2.68
round()
fonksiyonunun çalışma prensibini anlamak için kendi kendinize
örnekler yapabilirsiniz.
Şimdiye kadar öğrendiğimiz ve yukarıdaki tabloda andığımız bir başka aritmetik işleç de kuvvet işleci (**) idi. Mesela bu işleci kullanarak bir sayının karesini hesaplayabileceğimizi biliyorsunuz:
>>> 25 ** 2
625
Bir sayının 2. kuvveti o sayının karesidir. Bir sayının 0.5. kuvveti ise o sayının kareköküdür:
>>> 625 ** 0.5
25.0
Bu arada, eğer karekökün kayan noktalı sayı cinsinden olması hoşunuza
gitmediyse, bu sayıyı int()
fonksiyonu ile tam sayıya çevirebileceğinizi
biliyorsunuz:
>>> int(625 ** 0.5)
25
Kuvvet hesaplamaları için ** işlecinin yanısıra pow()
adlı bir
fonksiyondan da yararlanabileceğimizi öğrenmiştik:
>>> pow(25, 2)
625
Bildiğiniz gibi pow()
fonksiyonu aslında toplam üç parametre alabiliyor:
>>> pow(25, 2, 5)
0
Bu işlemin şununla aynı anlama geliyor:
>>> (25 ** 2) % 5
0
Yani pow(25, 2, 5)
gibi bir komut verdiğimizde, 25 sayısının 2.
kuvvetini alıp, elde ettiğimiz sayının 5’e bölünmesinden kalan sayıyı
hesaplamış oluyoruz.
Böylece aritmetik işleçleri tamamlamış olduk. Artık karşılaştırma işleçlerini inceleyebiliriz.
Karşılaştırma İşleçleri¶
Adından da anlaşılacağı gibi, karşılaştırma işleçleri, işlenenler (operands) arasında bir karşılaştırma ilişkisi kuran işleçlerdir. Bu işleçleri şöyle sıralayabiliriz:
==
eşittir
!=
eşit değildir
>
büyüktür
<
küçüktür
>=
büyük eşittir
<=
küçük eşittir
Bu işleçlerin hiçbiri size yabancı değil, zira bunların hepsini aslında daha önceki derslerde verdiğimiz örneklerde kullanmıştık. Burada da bunlarla ilgili basit bir örnek vererek yolumuza devam edelim:
parola = "xyz05"
soru = input("parolanız: ")
if soru == parola:
print("doğru parola!")
elif soru != parola:
print("yanlış parola!")
Burada soru değişkeniyle kullanıcıdan alınan verinin, programın başında
tanımladığımız parola değişkeninin değerine eşit olup olmadığını sorguluyoruz.
Buna göre, eğer kullanıcıdan gelen veri parolayla eşleşiyorsa (if soru ==
parola
), kullanıcıyı parolanın doğru olduğu konusunda bilgilendiriyoruz
(print("doğru parola!")
). Ama eğer kullanıcıdan gelen veri parolayla
eşleşmiyorsa (elif soru != parola
), o zaman da kullanıcıya parolanın yanlış
olduğunu bildiriyoruz (print("yanlış parola!")
).
Yukarıdaki örnekte == (eşittir) ve != (eşit değildir) işleçlerinin kullanımını örneklendirdik. Öteki karşılaştırma işleçlerinin de nasıl kullanıldığını biliyorsunuz. Basit bir örnek verelim:
sayı = input("sayı: ")
if int(sayı) <= 100:
print("sayı 100 veya 100'den küçük")
elif int(sayı) >= 100:
print("sayı 100 veya 100'den büyük")
Böylece karşılaştırma işleçlerini de incelemiş olduk. O halde gelelim bool işleçlerine…
Bool İşleçleri¶
Bu bölümde bool işleçlerinden söz edeceğiz, ancak bool işleçlerine geçmeden önce biraz bool kavramından bahsetmemiz yerinde olacaktır.
Nedir bu bool denen şey?
Bilgisayar bilimi iki adet değer üzerine kuruludur: 1 ve 0. Yani sırasıyla True ve False. Bilgisayar biliminde herhangi bir şeyin değeri ya True, ya da False’tur. İşte bu True ve False olarak ifade edilen değerlere bool değerleri adı verilir (George Boole adlı İngiliz matematikçi ve filozofun adından). Türkçe olarak söylemek gerekirse, True değerinin karşılığı Doğru, False değerinin karşılığı ise Yanlış’tır.
Örneğin:
>>> a = 1
Burada a adlı bir değişken tanımladık. Bu değişkenin değeri 1. Şimdi bu değişkenin değerini sorgulayalım:
>>> a == 1 #a değeri 1'e eşit mi?
True
Gördüğünüz gibi, a == 1 sorgusu True (Doğru) çıktısı veriyor. Çünkü a değişkeninin değeri gerçekten de 1. Bir de şunu deneyelim:
>>> a == 2
False
Burada da a değişkeninin değerinin 2 sayısına eşdeğer olup olmadığını sorguladık. a değişkeninin değeri 2 olmadığı için de Python bize False (Yanlış) çıktısı verdi.
Gördüğünüz gibi, bool işleçleri herhangi bir ifadenin doğruluğunu veya yanlışlığını sorgulamak için kullanılabiliyor. Buna göre, eğer bir sorgulamanın sonucu doğru ise True, eğer yanlış ise False çıktısı alıyoruz.
Bool işleçleri sadece yukarıda verdiğimiz örneklerdeki gibi, salt bir doğruluk-yanlışlık sorgulamaya yarayan araçlar değildir. Bilgisayar biliminde her şeyin bir bool değeri vardır. Bununla ilgili genel kuralımız şu: 0 değeri ve boş veri tipleri False’tur. Bunlar dışında kalan her şey ise True’dur.
Bu durumu bool()
adlı özel bir fonksiyondan yararlanarak teyit edebiliriz:
>>> bool(3)
True
>>> bool("elma")
True
>>> bool(" ")
True
>>> bool(" ")
True
>>> bool("fdsdfsdg")
True
>>> bool("0")
True
>>> bool(0)
False
>>> bool("")
False
Gördüğünüz gibi, gerçekten de 0 sayısının ve boş karakter dizilerinin bool değeri False’tur. Geri kalan her şey ise True’dur.
Not
0’ın bir sayı, “0”’ın ise bir karakter dizisi olduğunu unutmayın. Sayı olan 0’ın bool değeri False’tur, ama karakter dizisi olan “0”’ın değeri True’dur.
Yukarıdaki örneklere göre, içinde herhangi bir değer barındıran karakter dizileri (0 hariç) True çıktısı veriyor. Burada söylediğimiz şey bütün veri tipleri için geçerlidir. Eğer herhangi bir veri tipi herhangi bir değer içermiyorsa o veri tipi False çıktısı verir.
Peki bu bilgi bizim ne işimize yarar? Yani mesela boş veri tiplerinin False, içinde bir veri barındıran veri tiplerinin ise True olması bizim için neden bu kadar önemli? Bunu birazdan açıklayacağız. Ama önce isterseniz, bool değerleri ile ilgili çok önemli bir konuya değinelim.
Belki kendiniz de farketmişsinizdir; bool değerleri Python’da koşul belirten
if
, elif
ve else
deyimlerinin de temelini oluşturur. Şu örneği ele
alalım mesela:
isim = input("İsminiz: ")
if isim == "Ferhat":
print("Ne güzel bir isim bu!")
else:
print(isim, "ismini pek sevmem!")
Burada if isim == "Ferhat"
dediğimizde, aslında Python’a şu emri vermiş
oluyoruz:
Eğer
isim == "Ferhat"
ifadesi True ise…
Bunu teyit etmek için şöyle bir kod yazabilirsiniz:
isim = input("İsminiz: ")
print(isim == "Ferhat")
Eğer burada kullanıcı ‘Ferhat’ ismini girecek olursa programımız True çıktısı verir. Ama eğer kullanıcı başka bir isim girerse bu kez False çıktısını alırız. İşte koşul bildiren deyimler, karar verme görevini, kendilerine verilen ifadelerin bool değerlerine bakarak yerine getirir. Dolayısıyla yukarıdaki örneği şu şekilde Türkçeye çevirebiliriz:
Eğer
isim == "Ferhat"
ifadesinin bool değeri True ise, Ne güzel bir isim bu! çıktısı ver! Ama eğerisim == "Ferhat"
ifadesinin bool değeri True dışında herhangi bir şey ise (yani False ise), … ismini pek sevmem! çıktısı ver!
Koşul bildiren deyimlerle bool değerleri arasındaki ilişkiyi daha iyi anlamak için bir örnek daha verelim:
Hatırlarsanız içi boş veri tiplerinin bool değerinin her zaman False olacağını söylemiştik. Yani:
>>> a = ""
>>> bool(a)
False
Herhangi bir değere sahip veri tiplerinin bool değeri ise her zaman True olur (0 hariç):
>>> a = "gdfg"
>>> bool(a)
True
İçi boş veri tiplerinin bool değerinin her zaman False olacağı bilgisini kullanarak şöyle bir uygulama yazabiliriz:
kullanıcı = input("Kullanıcı adınız: ")
if bool(kullanıcı) == True:
print("Teşekkürler!")
else:
print("Kullanıcı adı alanı boş bırakılamaz!")
Burada şöyle bir emir verdik:
“Eğer kullanıcı değişkeninin bool değeri True ise Teşekkürler! çıktısı ver! Değilse Kullanıcı adı alanı boş bırakılamaz! uyarısını göster!
Eğer kullanıcı, kullanıcı adına herhangi bir şey yazdıktan sonra Enter tuşuna
basarsa kullanıcı değişkeni, kullanıcının girdiği değeri gösterecek ve böylece
bool(kullanıcı)
komutu True çıktısı verecektir. Bu sayede de kodlarımızın
içindeki if
bloğu çalışmaya başlayacaktır.
Ama eğer kullanıcı, kullanıcı adını yazmadan Enter tuşuna basarsa, kullanıcı
değişkeni boş kalacağı için (yani kullanıcı = ""
gibi bir durum ortaya
çıkacağı için) bool(kullanıcı)
komutu False çıktısı verecek ve böylece
else
bloğu çalışacaktır.
Yalnız bu noktada şöyle bir uyarı yapalım. Yukarıdaki komutlar sözdizimi açısından tamamen doğru olsa da, etrafta yukarıdakine benzer bir kullanımı pek görmezsiniz. Aynı iş için genellikle şöyle bir şeyler yazılır:
kullanıcı = input("Kullanıcı adınız: ")
if kullanıcı:
print("Teşekkürler!")
Gördüğünüz gibi, if bool(kullanıcı) == True:
kodunu if kullanıcı:
şeklinde kısaltabiliyoruz. Bu ikisi tamamen aynı anlama gelir. Yani ikisi de
‘kullanıcı değişkeninin bool değeri True ise…’ demektir.
Bool kavramına aşinalık kazandığımıza göre şimdi bool işleçlerini incelemeye başlayabiliriz.
Bool işleçleri, bool değerlerinden birini elde etmemizi sağlayan işleçlerdir. Bu işleçler şunlardır:
and
or
not
Eğer mantık dersleri aldıysanız bu işleçler size hiç yabancı gelmeyecektir. Eğer lisede mantık dersleri almadıysanız veya aldığınız derslerden hiçbir şey hatırlamıyorsanız, yine de ziyanı yok. Biz burada bu işleçleri bütün ayrıntılarıyla inceleyeceğiz.
Önce and ile başlayalım…
Türkçe söylemek gerekirse and ‘ve’ anlamına gelir. Peki bu and ne işimize yarar? Çok basit bir örnek verelim:
Hatırlarsanız geçen bölümde koşullu durumlara örnek verirken şöyle bir durumdan bahsetmiştik:
Diyelim ki Google’ın Gmail hizmeti aracılığıyla bir e.posta hesabı aldınız. Bu hesaba gireceğiniz zaman Gmail size bir kullanıcı adı ve parola sorar. Siz de kendinize ait kullanıcı adını ve parolayı sayfadaki kutucuklara yazarsınız. Eğer yazdığınız kullanıcı adı ve parola doğruysa hesabınıza erişebilirsiniz. Ama eğer kullanıcı adınız ve parolanız doğru değilse hesabınıza erişemezsiniz. Yani e.posta hesabınıza erişmeniz, kullanıcı adı ve parolayı doğru girme koşuluna bağlıdır.
Burada çok önemli bir nokta var. Kullanıcının Gmail sistemine girebilmesi için hem kullanıcı adını hem de parolayı doğru yazması gerekiyor. Yani kullanıcı adı veya paroladan herhangi biri yanlış ise sisteme giriş mümkün olmayacaktır.
Yukarıdaki durumu taklit eden bir programı, şu ana kadar olan bilgilerimizi kullanarak şöyle yazabiliyoruz:
kullanıcı_adı = input("Kullanıcı adınız: ")
parola = input("Parolanız: ")
if kullanıcı_adı == "aliveli":
if parola == "12345678":
print("Programa hoşgeldiniz")
else:
print("Yanlış kullanıcı adı veya parola!")
else:
print("Yanlış kullanıcı adı veya parola!")
Burada yeni bir bilgiyle daha karşılaşıyoruz. Gördüğünüz gibi, burada if
deyimlerini iç içe kullandık. Python’da istediğiniz kadar iç içe geçmiş if
deyimi kullanabilirsiniz. Ancak yazdığınız bir programda eğer üçten fazla iç içe
if
deyimi kullandıysanız, benimsediğiniz yöntemi yeniden gözden geçirmenizi
tavsiye ederim. Çünkü iç içe geçmiş if
deyimleri bir süre sonra anlaşılması
güç bir kod yapısı ortaya çıkarabilir. Neyse… Biz konumuza dönelim.
Yukarıdaki yazdığımız programda kullanıcının sisteme giriş yapabilmesi için hem kullanıcı adını hem de parolayı doğru girmesi gerekiyor. Kullanıcı adı ve paroladan herhangi biri yanlışsa sisteme girişe izin verilmiyor. Ancak yukarıdaki yöntem dolambaçlıdır. Halbuki aynı işlevi yerine getirmenin, Python’da çok daha kolay bir yolu var. Bakalım:
kullanıcı_adı = input("Kullanıcı adınız: ")
parola = input("Parolanız: ")
if kullanıcı_adı == "aliveli" and parola == "12345678":
print("Programa hoşgeldiniz")
else:
print("Yanlış kullanıcı adı veya parola!")
Burada and işlecini nasıl kullandığımızı görüyorsunuz. Bu işleci kullanarak iki farklı ifadeyi birbirine bağladık. Böylece kullanıcının sisteme girişini hem kullanıcı adının hem de parolanın doğru olması koşuluna dayandırdık.
Peki and işlecinin çalışma mantığı nedir? Dediğim gibi, and Türkçede ‘ve’ anlamına geliyor. Bu işleci daha iyi anlayabilmek için şu cümleler arasındaki farkı düşünün:
Toplantıya Ali ve Veli katılacak.
Toplantıya Ali veya Veli katılacak.
İlk cümlede ‘ve’ bağlacı kullanıldığı için, bu cümlenin gereğinin yerine getirilebilmesi, hem Ali’nin hem de Veli’nin toplantıya katılmasına bağlıdır. Sadece Ali veya sadece Veli’nin toplantıya katılması durumunda bu cümlenin gereği yerine getirilememiş olacaktır.
İkinci cümlede ise toplantıya Ali ve Veli’den herhangi birisinin katılması yeterlidir. Toplantıya sadece Ali’nin katılması, sadece Veli’nin katılması veya her ikisinin birden katılması, bu cümlenin gereğinin yerine getirilebilmesi açısından yeterlidir.
İşte Python’daki and işleci de aynı bu şekilde işler. Şu örneklere bir bakalım:
>>> a = 23
>>> b = 10
>>> a == 23
True
>>> b == 10
True
>>> a == 23 and b == 10
True
Burada değeri 23 olan bir adet a değişkeni ve değeri 10 olan bir adet b
değişkeni tanımladık. Daha sonra bu iki değişkenin değerini tek tek sorguladık
ve bunların gerçekten de sırasıyla 23 ve 10 sayısına eşit olduğunu gördük. Son
olarak da bunları and işleci ile birbirine bağlayarak sorguladık. a
değişkeninin değeri 23, b değişkeninin değeri de 10 olduğu için, yani and
ile bağlanan her iki önerme de True çıktısı verdiği için a == 23 and b ==
10
ifadesi True değeri verdi.
Bir de şuna bakalım:
>>> a = 23
>>> b = 10
>>> a == 23
True
>>> b == 54
False
>>> a == 23 and b == 54
False
Burada ise a değişkenin değeri 23’tür. Dolayısıyla a == 23
ifadesi
True çıktısı verir. Ancak b değişkeninin değeri 54 değildir. O yüzden de
b == 54
komutu False çıktısı verir. Gördüğünüz gibi, and işleci ile
bağlanan önermelerden herhangi biri False olduğunda çıktımız da False
oluyor. Unutmayın: and işlecinin True çıktısı verebilmesi için bu işleç
tarafından bağlanan her iki önermenin de True olması gerekir. Eğer
önermelerden biri bile True değilse çıktı da True olmayacaktır.
Tahmin edebileceğiniz gibi, and işleci en yaygın if
deyimleriyle birlikte
kullanılır. Mesela yukarıda kullanıcıdan kullanıcı adı ve parola alırken de bu
and işlecinden yararlanmıştık.
Gelelim or işlecine…
Tıpkı and gibi bir bool işleci olan or’un Türkçede karşılığı ‘veya’dır. Yukarıda ‘Toplantıya Ali veya Veli katılacak.’ cümlesini tartışırken aslında bu or kelimesinin anlamını açıklamıştık. Hatırlarsanız and işlecinin True çıktısı verebilmesi için bu işleçle bağlanan bütün önermelerin True değerine sahip olması gerekiyordu. or işlecinin True çıktısı verebilmesi için ise or işleciyle bağlanan önermelerden herhangi birinin True çıktısı vermesi yeterli olacaktır. Söylediğimiz bu şeyleri birkaç örnek üzerinde somutlaştıralım:
>>> a = 23
>>> b = 10
>>> a == 23
True
>>> b == 10
True
>>> a == 11
False
>>> a == 11 or b == 10
True
Gördüğünüz gibi, a == 11
ifadesinin bool değeri False olduğu halde, b ==
10
ifadesinin bool değeri True olduğu için a == 11 or b == 10
ifadesi
True değerini veriyor.
and ve or işleçlerini öğrendiğimize göre, bir sınavdan alınan notların harf karşılıklarını gösteren bir uygulama yazabiliriz:
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Böyle bir not yok")
elif x >= 90 and x <= 100:
print("A aldınız.")
elif x >= 80 and x <= 89:
print("B aldınız.")
elif x >= 70 and x <= 79:
print("C aldınız.")
elif x >= 60 and x <= 69:
print("D aldınız.")
elif x >= 0 and x <= 59:
print("F aldınız.")
Bu programda eğer kullanıcı 100’den büyük ya da 0’dan küçük bir sayı girerse Böyle bir not yok uyarısı alacaktır. 0-100 arası notlarda ise, her bir not aralığına karşılık gelen harf görüntülenecektir. Eğer isterseniz yukarıdaki kodları şu şekilde de kısaltabilirsiniz:
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Böyle bir not yok")
elif x >= 90 <= 100:
print("A aldınız.")
elif x >= 80 <= 89:
print("B aldınız.")
elif x >= 70 <= 79:
print("C aldınız.")
elif x >= 60 <= 69:
print("D aldınız.")
elif x >= 0 <= 59:
print("F aldınız.")
Gördüğünüz gibi, and x
kısımlarını çıkardığımızda da bir önceki kodlarla
aynı anlamı yakalayabiliyoruz.
Hatta yukarıdaki kodları şöyle de yazabilirsiniz:
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Böyle bir not yok")
#90 sayısı x'ten küçük veya x'e eşit,
#x sayısı 100'den küçük veya 100'e eşit ise,
#Yani x, 90 ile 100 arasında bir sayı ise
elif 90 <= x <= 100:
print("A aldınız.")
#80 sayısı x'ten küçük veya x'e eşit,
#x sayısı 89'dan küçük veya 89'a eşit ise,
#Yani x, 80 ile 89 arasında bir sayı ise
elif 80 <= x <= 89:
print("B aldınız.")
elif 70 <= x <= 79:
print("C aldınız.")
elif 60 <= x <= 69:
print("D aldınız.")
elif 0 <= x <= 59:
print("F aldınız.")
Bu kodlar bir öncekiyle aynı işi yapar. Yorumlardan da göreceğiniz gibi, bu iki kod arasında sadece mantık farkı var.
Hatta, daha da ileri giderek aynı kodu çok daha basit hale getirmek isterseniz, aşağıdaki koda bakabilirsiniz.
x = int(input("Notunuz: "))
if x > 100 or x < 0:
print("Böyle bir not yok")
elif x >= 90:
print("A aldınız.")
elif x >= 80:
print("B aldınız.")
elif x >= 70:
print("C aldınız.")
elif x >= 60:
print("D aldınız.")
elif x >= 0:
print("F aldınız.")
Son bool işlecimiz not. Bu kelimenin İngilizce’deki anlamı ‘değil’dir. Bu işleci şöyle kullanıyoruz:
>>> a = 23
>>> not a
False
>>> a = ""
>>> not a
True
Bu işleç, özellikle kullanıcı tarafından bir değişkene veri girilip girilmediğini denetlemek için kullanılabilir. Örneğin:
parola = input("parola: ")
if not parola:
print("Parola boş bırakılamaz!")
Eğer kullanıcı herhangi bir parola belirlemeden doğrudan Enter tuşuna basacak
olursa parola değişkeninin değeri boş bir karakter dizisi olacaktır. Yani
parola = ""
. Boş veri tiplerinin bool değerinin False olacağını biliyoruz.
Dolayısıyla, yukarıdaki gibi bir örnekte, kullanıcı parolayı boş geçtiğinde
not parola
kodu True verecek ve böylece ekrana “Parola boş bırakılamaz!”
karakter dizisi yazdırılacaktır. Eğer yukarıdaki örneğin mantığını kavramakta
zorluk çekiyorsanız şu örnekleri incelemenizi de öneririm:
>>> parola = ""
>>> bool(parola)
False
>>> bool(not parola)
True
>>> parola = "1243"
>>> bool(parola)
True
>>> bool(not parola)
False
Aslında yukarıdaki örneklerde şuna benzer sorular sormuş gibi oluyoruz:
>>> parola = ""
>>> bool(parola) #parola boş bırakılmamış, değil mi?
>>> False #Hayır, parola boş bırakılmış.
>>> bool(not parola) #parola boş bırakılmış, değil mi?
>>> True #Evet, parola boş bırakılmış
Kendi kendinize pratik yaparak bu işlecin görevini daha iyi anlayabilirsiniz.
Böylece kısmen çetrefilli bir konu olan bool işleçlerini de geride bırakmış olduk. Sırada değer atama işleçleri var.
Değer Atama İşleçleri¶
Bu noktaya kadar yaptığımız çalışmalarda sadece tek bir değer atama işleci gördük. Bu işleç = işlecidir. Adından da anlaşılacağı gibi, bu işlecin görevi bir değişkene değer atamaktır. Mesela:
>>> a = 23
Burada = işleci a değişkenine 23 değerini atama işlevi görüyor.
Python’daki tek değer atama işleci elbette = değildir. Bunun dışında başka değer atama işleçleri de bulunur. Tek tek inceleyelim:
+= işleci
Bu işlecin ne işe yaradığını anlamak için şöyle bir örnek düşünün:
>>> a = 23
a değerine mesela 5 ekleyip bu değeri 28’e eşitlemek için ne yapmamız lazım? Tabii ki şunu:
>>> a = a + 5
>>> print(a)
28
Burada yaptığımız şey çok basit: a değişkeninin taşıdığı değere 5 ilave ediyoruz ve daha sonra bu değeri tekrar a değişkenine atıyoruz. Aynı işlemi çok daha kolay bir şekilde de yapabiliriz:
>>> a += 5
>>> print(a)
28
Bu kod, yukarıdakiyle tamamen aynı anlama gelir. Ama bir önceki koda göre çok
daha verimlidir. Çünkü a += 5
kodunda Python a değişkeninin değerini
sadece bir kez kontrol ettiği için, işlemi a = a + 5
koduna göre daha hızlı
yapacaktır.
-= işleci
Bir önceki += işleci toplama işlemi yapıp, ortaya çıkan değeri tekrar aynı değişkene atıyordu. -= işleci de buna benzer bir işlem gerçekleştirir:
>>> a = 23
>>> a -= 5
>>> print(a)
18
Yukarıdaki kullanım şununla tamamen aynıdır:
>>> a = 23
>>> a = a - 5
>>> print(a)
18
Ancak tıpkı += işlecinde olduğu gibi, -= işleci de alternatifine göre daha hızlı çalışan bir araçtır.
/= işleci
Bu işlecin çalışma mantığı da yukarıdaki işleçlerle aynıdır:
>>> a = 30
>>> a /= 3
>>> print(a)
10
Yukarıdaki işlem de şununla tamamen aynıdır:
>>> a = 30
>>> a = a / 3
>>> print(a)
10
*= işleci
Bu da ötekiler gibi, çarpma işlemi yapıp, bu işlemin sonucunu aynı değişkene atar:
>>> a = 20
>>> a *= 2
>>> print(a)
40
Bu işlecin eşdeğeri de şudur:
>>> a = 20
>>> a = a * 2
>>> print(a)
40
%= işleci
Bu işlecimiz ise bölme işleminden kalan sayıyı aynı değişkene atar:
>>> a = 40
>>> a %= 3
>>> print(a)
1
Bu işleç de şuna eşdeğerdir:
>>> a = 40
>>> a = a % 3
>>> print(a)
1
**= işleci
Bu işlecin ne yaptığını tahmin etmek zor değil. Bu işlecimiz, bir sayının kuvvetini hesapladıktan sonra çıkan değeri aynı değişkene atıyor:
>>> a = 12
>>> a **= 2
>>> print(a)
144
Eşdeğeri:
>>> a = 12
>>> a = a ** 2
>>> print(a)
144
//= işleci
Değer atama işleçlerinin sonuncusu olan //= işlecinin görevi ise taban bölme işleminin sonucunu aynı değişkene atamaktır:
>>> a = 5
>>> a //= 2
>>> print(a)
2
Eşdeğeri:
>>> a = 5
>>> a = a // 2
>>> print(a)
2
Bu işleçler arasından, özellikle += ve -= işleçleri işinize bir hayli yarayacak.
Bu arada eğer bu işleçleri kullanırken mesela += mi yoksa =+ mı yazacağınızı karıştırıyorsanız, şöyle düşünebilirsiniz:
>>> a = 5
>>> a += 5
>>> print(a)
10
Burada, değeri 5 olan bir a değişkenine 5 daha ekleyip, çıkan sonucu tekrar a değişkenine atadık. Böylece değeri 10 olan bir a değişkeni elde ettik. += işlecinin doğru kullanımı yukarıdaki gibidir. Bir de yukarıdaki örneği şöyle yazmayı deneyelim:
>>> a = 5
>>> a =+ 5
>>> print(a)
5
Burada + işleci ile = işlecinin yerini değiştirdik.
a =+ 5
satırına dikkatlice bakın. Aslında burada yaptığımız şeyin a = +5
işlemi olduğunu, yani a değişkenine +5 gibi bir değer verdiğimizi
göreceksiniz. Durum şu örnekte daha net görünecektir:
>>> a = 5
>>> a =- 5
>>> print(a)
>>> -5
Gördüğünüz gibi, a =- 5
yazdığımızda, aslında yaptığımız şey a değişkenine
-5 değerini vermekten ibarettir. Yani a = -5
.
:= işleci
Not
Walrus operatörü olarak da bilinen bu işleç, Python’un 3.8 versiyonu ile
eklenmiştir. Bundan önceki versiyonlarda bulunmamaktadır ve çalışmayacaktır.
SyntaxError
hatası verecektir.
Bu işleç biraz garip gözüküyor olabilir. Ne yaptığını bakarak kestirmek de biraz zor. En iyisi bir örnekle başlayalım:
giriş = len(input("Adın ne? "))
if giriş < 4:
print("Adın kısaymış.")
elif giriş < 6:
print("Adın biraz uzunmuş.")
else:
print("Çok uzun bir adın var.")
Gördüğünüz gibi girilen karakter dizisinin uzunluğuna göre ekrana bir çıktı yazdırmaktayız.
Python3.8’e sahipseniz vereceğimiz örnekleri kendiniz de deneyebilirsiniz.
Bir de :=
işleci ile bu kodu nasıl yazabileceğimize bakalım:
if ( giriş := len(input("Adın ne? ")) ) < 4:
print("Adın kısaymış.")
elif giriş < 6:
print("Adın biraz uzunmuş.")
else:
print("Çok uzun bir adın var.")
Burada giriş
değişkenine değer atamayı if
ifadesinin içinde yaptık.
Normalde böyle bir işlemi =
ile yapamazdık:
>>> if ( giriş = len(input("Adın ne? ")) ) < 4:
SyntaxError: invalid syntax
Fark edebileceğiniz gibi walrus operatörü bizi bir satır fazladan yazmaktan
kurtardı. Kullanıcıdan alınan bilginin giriş değişkenine nasıl atandığına dikkat
edin. giriş
değişkeninden sonra :=
işlecini kullanıyoruz ve aynı zamanda
değişken atamasını yaptığımız bölümün tamamını parantez içine alıyoruz. Peki bu
parantezi koymaz isek ne olur? Gelin bir örnek ile de onu deneyelim:
if giriş := len(input("Adın ne? ")) < 4:
print(giriş)
Eğer bu kodu çalıştırsanız ekrana True
yazıldığını veya hiçbir şey yazılmadığını
görebilirsiniz. Oysa önceki parantez kullandığımız kodda giriş
değişkeni bir
int
’di. Bu örneğimizde ise ilk önce len(input("Adın ne? ")) < 4
kısmı
çalışıyor ve bunun sonucu daha sonra giriş
değişkenimize atanıyor. Bu yüzden giriş
değişkenimiz True
veya False
, yani bir bool
oluyor. Eğer giriş
değişkeni
True
olursa ekrana yazılıyor, ancak eğer False
olursa ekrana yazılmıyor. Çünkü
if
ifadesinin değeri de False
oluyor. if
ifadesinin kontrol ettiği yer
len(input("Adın ne? ")) < 4
kısmı olduğu için if
deyiminin içine girilmiyor.
Çok önemli bir işleç olmayabilir ama bazen aynı fonksiyonu iki defa çağırmak yerine bir defa çağırmak gibi kolaylıklar sağlamaktadır. Bu konu ile alakalı daha fazla örnek için buraya bakabilirsiniz
Bitwise (Bitsel) İşleçleri¶
Bu bölümde bitwise işleçlerinden söz edeceğiz, ancak bitwise işleçlerini anlayabilmek için öncelikle ikili sayı sistemi hakkında bilgi sahibi olmanız gerekecek. Görüldüğü üzere, bitwise işleçleri ikili sayılar temelinde işlemler yapmamıza yarar sağlar.
Peki, nedir bu ikili sayma sistemi?
İkili sayı sistemi, bilgisayarların verileri temsil etmek için kullandığı temel sayı sistemidir. Her yerde duyduğunuz gibi, ekrandaki her şey size ne kadar karmaşık gelse de, bilgisayarlarımız bunları ikili (binary) tabanda temsil eder. Örneğin, “10” sayısının ikili tabanda gösterimi “1010” şeklindedir. İkili sayma sisteminde, bir sayıyı oluşturan rakamlar 2’nin kuvvetleri olarak hesaplanır. Bu sayıyı 2’nin kuvvetlerini kullanarak şu şekilde hesaplayabiliriz:
>>> (0 * (2 ** 0)) + (1 * (2 ** 1)) + (0 * (2 ** 2)) + (1 * (2 ** 3))
10
Tabii, daha fazlasını dokümanın ileri bölümlerinde anlatacağız. Şimdilik bunları bilseniz yeterli.
&
Mantıksal And
|
Mantıksal Or
>>
Kaydırma
<<
Kaydırma
^
Mantıksal XOR
~
Tümleme
Şunu da söylemeden geçmeyelim, yukarıda gördüğünüz bu işleçler çoğumuzun lise matematik derslerinde gördüğü veya göreceği sembolik mantık (namıdeğer matematiksel mantık) ilkelerine dayandığından, her işleçte sembolik mantık derslerindeki karşılıklarını da göstereceğiz. Tabii, daha önce sembolik mantıktan haberdar olmayanlar için başlamadan önce ilerde işimize yarayacak olan önermelerin ne olduğuna bir bakalım. Eğer daha detaylı olarak öğrenmek isterseniz, Wikipedia’ya bakmanız yeterli.
Önermeler
Siz hiç farketmemiş olsanız da Python’da birçok kez önerme kullandınız. Hemen birini gösterelim:
a = 10
if a == 10:
...
Yukarıda gördüğünüz kodda a == 10 bir önermedir. Peki önerme dediğimiz şeyi tanımlasak nasıl olur? Mantıkta doğrulanabilir ya da yanlışlanabilir olmak zorunda olan ifadelere önerme denir. Bayağı hiçbir şey ifade etmeyen kelimeler grubu gibi duran bu cümleyi biraz açıklayalım. Demek istediğimiz şey şu: Herhangi bir cümlemiz olsun, doğru ya da yanlış olması umrumuzda bile değil ama yanlış ya da doğru olabilmesi onun bize bir önerme olabileceğini gösteriyor. Mesela Mertcan adında bir arkadaşımız olsun. Bu arkadaş Keloğlan izlemeyi seviyor olsun. Mertcan’ın bir arkadaşına şöyle bir şey diyelim:
Mertcan Keloğlan izlemeyi sevmiyor.
Bu cümle bir önermedir ancak bu önerme doğru değildir. Sembolik olarak değerini göstermek istersek, 0 ile göstermemiz gerekecektir.
if a == 10:
...
O zaman ilk örneğimize dönersek, gerçekten de a = 10 olduğu için önerme doğrudur, yani if bloğumuz güzelce çalışır. Son olarak, neyin önerme olduğunu söylediğimiz gibi, neyin önerme olmadığını da belirtelim. Mesela:
Bugün hava çok güzel.
Bence en güzel şehir Erzincan’dır.
Bu iki cümleyi inceleyelim. Bugün hava sana göre güzel olabilir ama bana göre olmayabilir. Ya da bir başkası en güzel şehrin İstanbul olduğunu düşünüyor olabilir. Yani bu cümlelerin doğruluğunu ya da yanlışlığını kesin olarak belirleyemeyiz. Demek ki bu iki örnekteki gibi öznel cümlelerden önerme olmaz.
Bence önermeleri herkes anladı. Meraklısı için internet emrinize amade.
Mantiksal AND (ve) İşleci (&)
Bu işleç her iki tarafındaki değişkenin bitleri üzerinde mantıksal and işlemi uygular. Aslında önceki bölümde gördüğünüz and işleci ile aynı işlemi karşılıklı bitler üzerinde yapar. Mesela buna bir örnek verelim.
if (True and False): # 1 = True, 0 = False
...
Daha önceki örneklerimizde anlatıldığı üzere bu ifade False olacağından if bloğumuz çalışmayacaktır. Mantıksal And işlecimiz de aynı işlemi karşılıklı bitler üzerinde yapacak.
1 & 1
= 1
1 & 0
= 0
0 & 1
= 0
0 & 0
= 0
Örnek üzerinden anlatmak bu tarz işleçlerin işlevini anlayabilmek için daha uygun olacaktır.
a = 10 # 0000 1010 = 10
b = 20 # 0001 0100 = 20
print(a & b) # 0000 0000 = 0
0
c = 10 # 0000 1010 = 10
d = 22 # 0001 0110 = 22
print(c & d) # 0000 0010 = 2
2
Örneklerde de gördüğünüz gibi mantıksal And işleci karşılıklı bitlerde işlem yapar. And işlemi ile karşılaştırılmış iki bitten biri bile 0 olsa; 0 sonucunu alırsınız. 1 sonucu alabilmek için her iki bitin de 1 olması gerek.
Mantıksal OR (veya) İşleci (|)
Bu işleç, her iki tarafındaki değişkenin bitleri üzerinde mantıksal or (veya) işlemi yapar. Bu işleç, önceki bölümde gördüğünüz or işleci ile aynı işlemi karşılıklı bitler üzerinde yapar.
if (True or False): # 1 = True, 0 = False
...
Bu örneğimizde parantez içi ifademiz True değerine eşit olacağından if bloğumuz çalışacaktır. Mantıksal or da aynı prensibe dayalıdır.
1 | 1
= 1
1 | 0
= 1
0 | 1
= 1
0 | 0
= 0
Hemen güzide örneğimizi getirelim.
a = 10 # 0000 1010 = 10
b = 20 # 0001 0100 = 20
print(a | b) # 0001 1110 = 30
30
a = 10 # 0000 1010 = 10
b = 22 # 0001 0110 = 22
print(a | b) # 0001 1110 = 30
30
Örneğimizi inceleyelim, alt alta bitlerde eğer sadece bir tane ‘1’ varsa, o bit karşılaştırma sonrasında 1’e eşit olur. Zaten yukarıdaki tablomuzda belirtilmiş. Eğer karşılaştırma sonucunun 0 olmasını istiyor isek her iki bitinde 0 değerini alması lazım.
Mantıksal XOR (ya da) İşleci (^)
Bu işleçten önceki bütün işleçlerin adı sembolik mantıktaki karşılığı ile aynıydı ancak burada durum biraz farklı. Sembolik mantık derslerinde biz XOR işlecine ‘ya da’ deriz. Bu işleç de her iki tarafındaki değişkenin bitleri üzerinde ‘XOR’ işlemi yapar. Tabii bu derslerde “ya da”nın işlevini daha önce görmedik. O zaman “ya da”yı gösterelim
1 ^ 1
= 0
1 ^ 0
= 1
0 ^ 1
= 1
0 ^ 0
= 0
XOR (ya da) ile bağlanan iki basit önermenin doğru olabilmesi için iki önermenin de değerinin birbirinden farklı olması gerekmektedir. Yani XOR (ya da) ile karşılaştırma işleminin 1 (doğru) olabilmesi için önermelerin birbirinden farklı doğruluk değerlerine sahip olması gerekmektedir. Tabloyu güzelce incelerseniz aklınıza kazınacaktır.
Örneğimiz üzerinden de bir görelim isterseniz.
a = 10 # 0000 1010 = 10
b = 20 # 0001 0100 = 20
print(a^b) # 0001 1110 = 30
30
a = 10 # 0000 1010 = 10
b = 22 # 0001 0110 = 22
print(a^b) # 0001 1100 = 28
28
Örnekte de görüldüğü gibi alt alta olan bitlerde eğer bit değeri aynı ise karşılaştırma sonrası o bitin değeri 0 olacaktır. Eğer bu durum gerçekleşmezse bitimizin değeri 1 olacaktır.
Tümleme (Invert) İşleci (~)
Tümleme işleci diğer işleçlerden farklı olarak 2 değer arasında karşılaştırma yapmaz. Bu işlece sembolik mantıkta “Değil” denir. Bu işlecin görevi aldığı değeri tersine çevirmektir.
~1
= 0
~0
= 1
Tablodan da anlaşılacağı gibi tümleme işleci aldığını tersine çevirip bize veriyor. Bu işlevin aynısını verdiğimiz değere de yapacak.
Hemen bir örnek getirelim:
a = 1 # 0000 0001 = 1
print(~a) # 1111 1110 = -2
-2
b = 19 # 0001 0011 = 19
print(~b) # 1110 1100 = -20
-20
Hay aksi sanki buradaki çıktılarda bir garipilik var değil mi? Evet var. Hemen açıklayalım. Şöyle ki bir bit dizisinde son bit karakterin (ya da sayının) işaretini temsil eder. Geçmiş örneklerimizde son bit hep 0 olduğu için sayımız pozitif değerdeydi. Bu örneğimizde ise ‘~’ işaretinin etkisiyle bu değerimiz 1 oldu yani negatif değerli tam sayıyı temsil etti. Ama iş burası ile de kalmıyor. Biz tümleme işlemi yaptığımız zaman aslında bitlerin değerini başka şekilde hesaplıyoruz. Bir kere 1 ile 0 değerlerinin işlevelemini değiştirmiş oluyoruz. Yani ikilinin katlarını artık 0’a göre yazıyoruz. Bu değerleri en sonunda toplayıp -1’den çıkarıyoruz. İşte böylece tümleme işlemimiz sonucu çıkan bitin değerini hesaplayabiliriz. Ama bu kısım o kadar da önemli değil sadece formüle etmek de yeter.
n - (2n + 1)
İşte size tümleme işleminin sonucunu gösteren güzide formül.
Shifting (kaydırma) İşleçleri (`>>` `<<`)
Kaydırma işleçlerinin sembolik mantıkta bir karşılığı yoktur. Bunlar tamamen programlamaya özgüdür. Bu işleçler için bir tabloya da ihtiyaç duymayacağız. Hemen bir örnek verelim ve açıklamasını yapalım.
a = 64 # 0100 0000 = 64
print(a >> 3) # 0000 1000 = 8
8
b = 16 # 0001 0000 = 16
print(b << 2) # 0100 0000 = 64
64
Zaten az çok örneklerden ne olduğu ortaya çıkıyor. Okların solundaki sayının bitlerini okların sağındaki sayı kadar okların yönünde kaydırıyoruz. Ancak bu işleçte bazı püf noktalarımız var, onu hemen gösterelim.
a = 64
print(a << 1) # ... 1000 0000 = 128
Evet, burada önceki işleçte gösterdiğimiz negatif-pozitif olayını yaşamadık. Peki neden? Şu ana kadar ki örneklerimizde hep 8 bit üzerinden örnekler yaptık ancak Python’da bu genellikle böyle olmuyor. Bunu şöyle kontrol edebiliriz.
import sys
a = 1
sys.getsizeof(a) # 28
28
Yukarıdaki kodda anlamadığınız yerler varsa takılmayın. Sadece şunu bilmeniz yeterli. Bu kod parçası size elinizdeki değişkenin boyutunu söyler. Gördüğünüz gibi ‘a’ değişkenin boyutu 28miş. Demek ki bu değişken 28 bitten oluşuyormuş. Peki şöyle birşey yapsaydık.
import sys
a = 1
a <<= 30
sys.getsizeof(a) # 32
32
Gördüğünüz gibi değişkenimiz boyut değişikliğine uğradı. Yani bit kaydırma işleminde sola giderken değişkenimizin gidebileceği başka yeri kalmayınca boyutunu değiştirebiliyor. Ancak bunu tümeleme işleminde yapmıyor çünkü tümeleme işleminin amacına uygun değil. Bir başka püf nokta ise şöyle:
Not
Değer atama işleçleri bölümünde gördüğünüz “+=”, “-=” gibi ifadeleri bitsel işleçler ile de kullanabilirsiniz. (Yukarıda gördüğünüz gibi)
a = 15 # 0000 1111 = 15
print(a >> 3) # 0000 0001 = 1
1
Gördüğünüz gibi bit kaydırma işleminde eğer sağda yer yoksa o değer atılır. Çünkü bitlerde değer artırımı sol tarafa ekleme yaparak olur ki zaten mantıklısı da bu.
Not
Bu kısım eğer programlamaya yeni başlıyorsanız biraz zor gelebilir. Anlayamadığınız kısım olursa telaşlanmayın ve ilerlemeye devam edin. Biraz daha temelinizi sağlamlaştırınca tekrar buraya dönebilirsiniz. Emin olun, o zaman her şey daha güzelce oturur.
Bitsel İşleçleri Kullanmanın Avantajları ve Dezavantajları
Şimdi bitsel işleçlerimizin avantajlarını ve dezavantajlarını görelim.
Avantajlar:
Performans: Bitsel işlemler genellikle daha hızlıdır çünkü bilgisayarlar üzerinde doğrudan donanım seviyesinde gerçekleştirilirler. Özellikle büyük veri setleri üzerinde çalışırken performansı artırabilirler.
Bellek Kullanımı: Bitsel işlemler genellikle daha az bellek kullanır. Bu, özellikle çok büyük veri yapıları üzerinde işlem yaparken bellek kullanımını azaltmaya yardımcı olabilir.
Dezavantajlar:
Okunabilirlik: Bitsel işlemler, genellikle kodun okunabilirliğini azaltabilir. Bit seviyesinde yapılan işlemler, kodun ne yaptığını anlamak için daha fazla çaba gerektirebilir.
Hata Yapma Olasılığı: Bitsel işlemlerle çalışırken, yanlış operatörler veya yanlış bit işlemleri yapma olasılığı daha yüksektir. Bu, hataların bulunması ve düzeltilmesi için daha fazla zaman harcanmasına neden olabilir.
Not
Asıl dezavantajı görünür kılmak için buraya koydum. Bitwise ile yapılan işlemler Python dilinin amacına uygun değildir. Python yazılım dilinin amacı kullanıcı kolaylığıdır. Pythonda performans ve bellek kullanımı çok önemsenmez. Eğer böyle ihtiyaçlarınız varsa başka dillerle ilgilenmeniz daha doğru olacaktır. Ama bu söylediklerimden “Şimdi ben bu bölümü boşuna mı okudum?” diye bir sonuç çıkarmayın. Burada gösterdiğimiz şeyler neredeyse bütün programlama dillerinde mevcut. Ayrıca yaptığınız bütün işlemler dayanağını bu işleçlerden alıyor. Bu kısma özellikle dikkat etmenizi rica ediyorum. Emin olun bu yolculukta öğrendiğiniz hiçbir şey boşuna olmayacak.
Aitlik İşleçleri¶
Aitlik işleçleri, bir karakter dizisi ya da sayının, herhangi bir veri tipi içinde bulunup bulunmadığını sorgulamamızı sağlayan işleçlerdir.
Python’da bir tane aitlik işleci bulunur. Bu işleç de in işlecidir. Bu işleci şöyle kullanıyoruz:
>>> a = "abcd"
>>> "a" in a
True
>>> "f" in a
False
Gördüğünüz gibi, in adlı bu işleç, bir öğenin, veri tipi içinde bulunup bulunmadığını sorguluyor. Eğer bahsedilen öğe, veri tipi içinde geçiyorsa True çıktısı, eğer geçmiyorsa False çıktısı alıyoruz.
Henüz bu in işlecini verimli bir şekilde kullanmamızı sağlayacak araçlardan yoksunuz. Ancak birkaç sayfa sonra öğreneceğimiz yeni araçlarla birlikte bu işleci çok daha düzgün ve verimli bir şekilde kullanabilecek duruma geleceğiz.
Kimlik İşleçleri¶
Python’da her şeyin (ya da başka bir deyişle her nesnenin) bir kimlik numarası (identity) vardır. Kabaca söylemek gerekirse, bu kimlik numarası denen şey esasında o nesnenin bellekteki adresini gösterir.
Peki bir nesnenin kimlik numarasına nasıl ulaşırız?
Python’da bu işi yapmamızı sağlayacak id()
adlı bir fonksiyon bulunur
(İngilizcedeki identity (kimlik) kelimesinin kısaltması). Şimdi bir örnek
üzerinde bu id()
fonksiyonunu nasıl kullanacağımıza bakalım:
>>> a = 100
>>> id(a)
137990748
Çıktıda gördüğümüz 137990748 sayısı a değişkeninin tuttuğu 100 sayısının kimlik numarasını gösteriyor.
Bir de şu örneklere bakalım:
>>> a = 50
>>> id(a)
505494576
>>> kardiz = "Elveda Zalim Dünya!"
>>> id(kardiz)
14461728
Gördüğünüz gibi, Python’daki her nesnenin kimliği eşşiz, tek ve benzersizdir.
Yukarıda verdiğimiz ilk örnekte bir a değişkeni tanımlayıp bunun değerini
100 olarak belirlemiş ve id(a)
komutuyla da bu nesnenin kimlik numarasına
ulaşmıştık. Yani:
>>> a = 100
>>> id(a)
137990748
Bir de şu örneğe bakalım:
>>> b = 100
>>> id(b)
137990748
Gördüğünüz gibi, Python a ve b değişkenlerinin değeri için aynı kimlik numarasını gösterdi. Bu demek oluyor ki, Python iki adet 100 sayısı için bellekte iki farklı nesne oluşturmuyor. İlk kullanımda önbelleğine aldığı sayıyı, ikinci kez ihtiyaç olduğunda bellekten alıp kullanıyor. Bu tür bir önbellekleme mekanizmasının gerekçesi performansı artırmaktır.
Ama bir de şu örneklere bakalım:
>>> a = 1000
>>> id(a)
15163440
>>> b = 1000
>>> id(b)
14447040
>>> id(1000)
15163632
Bu defa Python a değişkeninin tuttuğu 1000 sayısı, b değişkeninin tuttuğu 1000 sayısı ve tek başına yazdığımız 1000 sayısı için farklı kimlik numaraları gösterdi. Bu demek oluyor ki, Python a değişkeninin tuttuğu 1000 sayısı için, b değişkeninin tuttuğu 1000 sayısı için ve doğrudan girdiğimiz 1000 sayısı için bellekte üç farklı nesne oluşturuyor. Yani bu üç adet 1000 sayısı Python açısından birbirinden farklı…
Yukarıdaki durumu görebileceğimiz başka bir yöntem de Python’daki is adlı kimlik işlecini kullanmaktır. Deneyelim:
>>> a is 1000
False
>>> b is 1000
False
Gördüğünüz gibi, Python False (Yanlış) çıktısını suratımıza bir tokat gibi çarptı… Peki bu ne anlama geliyor?
Bu şu anlama geliyor: Demek ki görünüşte aynı olan iki nesne aslında birbirinin aynı olmayabiliyor. Bunun neden bu kadar önemli olduğunu ilerleyen derslerde çok daha iyi anlayacağız.
Yukarıdaki durumun bir başka yansıması daha vardır. Özellikle Python’a yeni başlayıp da bu dilde yer alan is işlecini öğrenenler, bu işlecin == işleciyle aynı işleve sahip olduğu yanılgısına kapılabiliyor ve is işlecini kullanarak iki nesne arasında karşılaştırma işlemi yapmaya kalkışabiliyor.
Ancak Python’da is işlecini kullanarak iki nesne arasında karşılaştırma yapmak güvenli değildir. Yani is ve == işleçleri birbirleriyle aynı işlevi görmez. Bu iki işleç nesnelerin farklı yönlerini sorgular: is işleci nesnelerin kimliklerine bakıp o nesnelerin aynı nesneler olup olmadığını kontrol ederken, == işleci nesnelerin içeriğine bakarak o nesnelerin aynı değere sahip olup olmadıklarını sorgular. Bu iki tanım arasındaki ince farka dikkat edin.
Yani:
>>> a is 1000
False
Ama:
>>> a == 1000
True
Burada is işleci a değişkeninin tuttuğu veri ile 1000 sayısının aynı kimlik numarasına sahip olup olmadığını sorgularken, == işleci a değişkeninin tuttuğu verinin 1000 olup olmadığını denetliyor. Yani is işlecinin yaptığı şey kabaca şu oluyor:
>>> id(a) == id(1000)
False
Şimdiye kadar denediğimiz örnekler hep sayıydı. Şimdi isterseniz bir de karakter dizilerinin durumuna bakalım:
>>> a = "python"
>>> a is "python"
True
Burada True çıktısını aldık. Bir de == işleci ile bir karşılaştırma yapalım:
>>> a == "python"
True
Bu da normal olarak True çıktısı veriyor. Ama şu örneğe bakarsak:
>>> a = "python güçlü ve kolay bir programlama dilidir"
>>> a is "python güçlü ve kolay bir programlama dilidir"
False
Ama:
>>> a == "python güçlü ve kolay bir programlama dilidir"
True
is ve == işleçlerinin nasıl da farklı sonuçlar verdiğini görüyorsunuz. Çünkü bunlardan biri nesnelerin kimliğini sorgularken, öbürü nesnelerin içeriğini sorguluyor. Ayrıca burada dikkatimizi çekmesi gereken başka bir nokta da “python” karakter dizisinin önbelleğe alınıp gerektiğinde tekrar tekrar kullanılıyorken, “python güçlü ve kolay bir programlama dilidir” karakter dizisinin ise önbelleğe alınmıyor olmasıdır. Aynı karakter dizisinin tekrar kullanılması gerektiğinde Python bunun için bellekte yeni bir nesne daha oluşturuyor.
Peki neden Python, örneğin, 100 sayısını ve “python” karakter dizisini önbelleklerken 1000 sayısını ve “python güçlü ve kolay bir programlama dilidir” karakter dizisini önbelleğe almıyor. Sebebi şu: Python kendi iç mekanizmasının işleyişi gereğince ‘ufak’ nesneleri önbelleğe alırken ‘büyük’ nesneler için her defasında yeni bir depolama işlemi yapıyor. Peki ufak ve büyük kavramlarının ölçütü nedir? İsterseniz Python açısından ufak kavramının sınırının ne olabileceğini şöyle bir kod yardımıyla sorgulayabiliriz:
>>> for k in range(-1000, 1000):
... for v in range(-1000, 1000):
... if k is v:
... print(k)
Not
Burada henüz öğrenmediğimiz şeyler var. Bunları birkaç bölüm sonra ayrıntılı bir şekilde inceleyeceğiz.
Bu kod -1000 ve 1000 aralığındaki iki sayı grubunu karşılaştırıp, kimlikleri aynı olan sayıları ekrana döküyor. Yani bir bakıma Python’un hangi sayıya kadar önbellekleme yaptığını gösteriyor. Buna göre -5 ile 257 arasında kalan sayılar Python tarafından ufak olarak değerlendiriliyor ve önbelleğe alınıyor. Bu aralığın dışında kalan sayılar için ise bellekte her defasında ayrı bir nesne oluşturuluyor.
Burada aldığımız sonuca göre şöyle bir denetleme işlemi yapalım:
>>> a = 256
>>> a is 256
True
>>> a = 257
>>> a is 257
False
>>> a = -5
>>> a is -5
True
>>> a = -6
>>> a is -6
False
Böylece Python’daki kimlik işleçlerini de incelemiş olduk. Belki programcılık
maceranız boyunca id()
fonksiyonunu hiç kullanmayacaksınız, ancak bu
fonksiyonun arkasındaki mantığı anlamak, Python’ın kimi yerlerde alttan alta
neler çevirdiğini çok daha kolay kavramanızı sağlayacaktır.
Not
https://web.archive.org/web/20161121150306/http://forum.ceviz.net/t/sozluklerin-dinamik-olarak-kopyalanmasi-ve-clear-isleci.81605/ adresindeki tartışmaya bakınız.
Böylece Python’daki bütün işleçleri ayrıntılı bir şekilde incelemiş olduk. Dilerseniz şimdi bu konuyla ilgili birkaç uygulama örneği yapalım.
Uygulama Örnekleri¶
Basit Bir Hesap Makinesi¶
Şu ana kadar Python’da pek çok şey öğrendik. Bu öğrendiğimiz şeylerle artık
kısmen yararlı bazı programlar yazabiliriz. Elbette henüz yazacağımız programlar
pek yetenekli olamayacak olsa da, en azından bize öğrendiklerimizle pratik yapma
imkanı sağlayacak. Bu bölümde, if
, elif
, else
yapılarını ve
öğrendiğimiz temel aritmetik işleçleri kullanarak çok basit bir hesap makinesi
yapmayı deneyeceğiz. Bu arada, bu derste yeni şeyler öğrenerek ufkumuzu ve
bilgimizi genişletmeyi de ihmal etmeyeceğiz.
İsterseniz önce kullanıcıya bazı seçenekler sunarak işe başlayalım:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) kare kök hesapla
"""
print(giriş)
Burada kullanıcıya bazı seçenekler sunduk. Bu seçenekleri ekrana yazdırmak için üç tırnak işaretlerinden yararlandığımıza dikkat edin. Birden fazla satıra yayılmış bu tür ifadeleri en kolay üç tırnak işaretleri yardımıyla yazdırabileceğimizi biliyorsunuz artık.
Biz burada bütün seçenekleri tek bir değişken içine yerleştirdik. Esasında her bir seçenek için ayrı bir değişken tanımlamak da mümkündür. Yani aslında yukarıdaki kodları şöyle de yazabiliriz:
seçenek1 = "(1) topla"
seçenek2 = "(2) çıkar"
seçenek3 = "(3) çarp"
seçenek4 = "(4) böl"
seçenek5 = "(5) karesini hesapla"
seçenek6 = "(6) karekök hesapla"
print(seçenek1, seçenek2, seçenek3, seçenek4, seçenek5)
Yalnız burada dikkat ederseniz, seçenekler hep yan yana diziliyor. Eğer programınızda yukarıdaki şekli kullanmak isterseniz, bu seçeneklerin yan yana değil de, alt alta görünmesini sağlamak için, önceki derslerimizde öğrendiğimiz sep parametresini kullanabilirsiniz:
seçenek1 = "(1) topla"
seçenek2 = "(2) çıkar"
seçenek3 = "(3) çarp"
seçenek4 = "(4) böl"
seçenek5 = "(5) karesini hesapla"
seçenek6 = "(6) karekök hesapla"
print(seçenek1, seçenek2, seçenek3, seçenek4, seçenek5, seçenek6, sep="\n")
Burada sep parametresinin değeri olarak \n kaçış dizisini belirlediğimize dikkat edin. \n kaçış dizisinin ne işe yaradığını hatırlıyorsunuz. Bu dizi, satır başına geçmemizi sağlıyordu. Burada, ayraç olarak satır başı kaçış dizisini belirlediğimiz için her bir seçenek yan yana değil, alt alta görünecektir. Elbette sep parametresi için istediğiniz değeri belirleyebilirsiniz. Mesela her bir seçeneği satır başı işaretiyle ayırmak yerine, çift tire gibi bir işaretle ayırmayı da tercih edebilirsiniz:
print(seçenek1, seçenek2, seçenek3, seçenek4, seçenek5, sep="--")
Programınızda nasıl bir giriş paragrafı belirleyeceğiniz konusunda özgürsünüz. Gelin isterseniz biz birinci şekille yolumuza devam edelim:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) karekök hesapla
"""
print(giriş)
Burada giriş adlı bir değişken oluşturduk. Bu değişkenin içinde barındırdığı
değeri kullanıcıların görebilmesi için print()
fonksiyonu yardımıyla bu
değişkeni ekrana yazdırıyoruz. Devam edelim:
soru = input("Yapmak istediğiniz işlemin numarasını girin: ")
Bu kod yardımıyla kullanıcıya bir soru soruyoruz. Kullanıcıdan yapmasını istediğimiz şey, yukarıda belirlediğimiz giriş seçenekleri içinden bir sayı seçmesi. Kullanıcı 1, 2, 3, 4, 5 veya 6 seçeneklerinden herhangi birini seçebilir. Kullanıcıyı, seçtiği numaranın karşısında yazan işleme yönlendireceğiz. Yani mesela eğer kullanıcı klavyedeki 1 tuşuna basarsa hesap makinemiz toplama işlemi yapacaktır. 2 tuşu ise kullanıcıyı çıkarma işlemine yönlendirir…
input()
fonksiyonunu işlediğimiz bölümde, bu fonksiyonun değer olarak her
zaman bir karakter dizisi (string) verdiğini söylemiştik. Yukarıdaki kodun
çıktısı da doğal olarak bir karakter dizisi olacaktır. Bizim şu aşamada
kullanıcıdan karakter dizisi almamızın bir sakıncası yok. Çünkü kullanıcının
gireceği 1, 2, 3, 4, 5 veya 6 değerleriyle herhangi bir aritmetik
işlem yapmayacağız. Kullanıcının gireceği bu değerler, yalnızca bize onun hangi
işlemi yapmak istediğini belirtecek. Dolayısıyla input()
fonksiyonunu
yukarıdaki şekilde kullanıyoruz.
İsterseniz şimdiye kadar gördüğümüz kısma topluca bakalım:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) karekök hesapla
"""
print(giriş)
soru = input("Yapmak istediğiniz işlemin numarasını girin: ")
Bu kodları çalıştırdığımızda, ekranda giriş paragrafımız görünecek ve kullanıcıya, yapmak istediği işlemin ne olduğu sorulacaktır. Henüz kodlarımız eksik olduğu için, kullanıcı hangi sayıyı girerse girsin, programımız hiç bir iş yapmadan kapanacaktır. O halde yolumuza devam edelim:
if soru == "1":
Böylece ilk if
deyimimizi tanımlamış olduk. Buradaki yazım şekline çok
dikkat edin. Bu kodlarla Python’a şu emri vermiş oluyoruz:
Eğer soru adlı değişkenin değeri 1 ise, yani eğer kullanıcı klavyede 1 tuşuna basarsa…
if
deyimlerinin en sonuna : işaretini koymayı unutmuyoruz. Python’a yeni
başlayanların en çok yaptığı hatalardan birisi, sondaki bu : işaretini koymayı
unutmalarıdır. Bu işaret bize çok ufak bir ayrıntıymış gibi görünse de Python
için manevi değeri çok büyüktür! Python’un bize öfkeli mesajlar göstermesini
istemiyorsak bu işareti koymayı unutmayacağız. Bu arada, burada == işaretini
kullandığımıza da dikkat edin. Bunun ne anlama geldiğini önceki derslerimizde
öğrenmiştik. Bu işaret, iki şeyin aynı değere sahip olup olmadığını
sorgulamamızı sağlıyor. Biz burada soru adlı değişkenin değerinin 1 olup
olmadığını sorguladık. soru değişkeninin değeri kullanıcı tarafından
belirleneceği için henüz bu değişkenin değerinin ne olduğunu bilmiyoruz. Bizim
programımızda kullanıcı klavyeden 1, 2, 3, 4, 5 veya 6 değerlerinden
herhangi birini seçebilir. Biz yukarıdaki kod yardımıyla, eğer kullanıcı
klavyede 1 tuşuna basarsa ne yapılacağını belirleyeceğiz. O halde devam
edelim:
if soru == "1":
sayı1 = int(input("Toplama işlemi için ilk sayıyı girin: "))
sayı2 = int(input("Toplama işlemi için ikinci sayıyı girin: "))
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
Böylece ilk if
bloğumuzu tanımlamış olduk.
if
deyimimizi yazdıktan sonra ne yaptığımız çok önemli. Buradaki
girintileri, programımız güzel görünsün diye yapmıyoruz. Bu girintilerin Python
için bir anlamı var. Eğer bu girintileri vermezsek programımız çalışmayacaktır.
Eğer Python kodlarına duyarlı bir metin düzenleyici kullanıyorsanız, :
işaretini koyup Enter tuşuna bastıktan sonra otomatik olarak girinti
verilecektir. Eğer kullandığınız metin düzenleyici size böyle bir kolaylık
sunmuyorsa Enter tuşuna bastıktan sonra klavyedeki boşluk (SPACE) tuşunu
kullanarak dört vuruşluk bir girinti oluşturabilirsiniz. Bu girintiler, ilk
satırda belirlediğimiz if
deyimiyle gösterilecek işlemlere işaret ediyor.
Dolayısıyla burada yazılan kodları Pythoncadan Türkçeye çevirecek olursak şöyle
bir şey elde ederiz:
eğer sorunun değeri '1' ise:
Toplama işlemi için ilk sayı girilsin. Bu değere 'sayı1' diyelim.
Sonra ikinci sayı girilsin. Bu değere de 'sayı2' diyelim.
En son, 'sayı1', '+' işleci, 'sayı2', '=' işleci ve 'sayı1 + sayı2'
ekrana yazdırılsın...
Gelin isterseniz buraya kadar olan bölümü yine topluca görelim:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) karekök hesapla
"""
print(giriş)
soru = input("Yapmak istediğiniz işlemin numarasını girin: ")
if soru == "1":
sayı1 = int(input("Toplama işlemi için ilk sayıyı girin: "))
sayı2 = int(input("Toplama işlemi için ikinci sayıyı girin: "))
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
Bu kodları çalıştırıp, klavyede 1 tuşuna bastığımızda, bizden bir sayı girmemiz istenecektir. İlk sayımızı girdikten sonra bize tekrar bir sayı girmemiz söylenecek. Bu emre de uyup Enter tuşuna basınca, girdiğimiz bu iki sayının toplandığını göreceğiz. Fena sayılmaz, değil mi?
Şimdi programımızın geri kalan kısmını yazıyoruz. İşin temelini kavradığımıza göre birden fazla kod bloğunu aynı anda yazabiliriz:
elif soru == "2":
sayı3 = int(input("Çıkarma işlemi için ilk sayıyı girin: "))
sayı4 = int(input("Çıkarma işlemi için ikinci sayıyı girin: "))
print(sayı3, "-", sayı4, "=", sayı3 - sayı4)
elif soru == "3":
sayı5 = int(input("Çarpma işlemi için ilk sayıyı girin: "))
sayı6 = int(input("Çarpma işlemi için ikinci sayıyı girin: "))
print(sayı5, "x", sayı6, "=", sayı5 * sayı6)
elif soru == "4":
sayı7 = int(input("Bölme işlemi için ilk sayıyı girin: "))
sayı8 = int(input("Bölme işlemi için ikinci sayıyı girin: "))
print(sayı7, "/", sayı8, "=", sayı7 / sayı8)
elif soru == "5":
sayı9 = int(input("Karesini hesaplamak istediğiniz sayıyı girin: "))
print(sayı9, "sayısının karesi =", sayı9 ** 2)
elif soru == "6":
sayı10 = int(input("Karekökünü hesaplamak istediğiniz sayıyı girin: "))
print(sayı10, "sayısının karekökü = ", sayı10 ** 0.5)
Bunlarla birlikte kodlarımızın büyük bölümünü tamamlamış oluyoruz. Bu bölümdeki
tek fark, ilk if
bloğunun aksine, burada elif
bloklarını kullanmış
olmamız. Eğer burada bütün blokları if
kullanarak yazarsanız, biraz sonra
kullanacağımız else
bloğu her koşulda çalışacağı için beklentinizin dışında
sonuçlar elde edersiniz.
Yukarıdaki kodlarda az da olsa farklılık gösteren tek yer son iki elif
bloğumuz. Esasında buradaki fark da pek büyük bir fark sayılmaz. Neticede tek
bir sayının karesini ve karekökünü hesaplayacağımız için, kullanıcıdan yalnızca
tek bir giriş istiyoruz.
Şimdi de son bloğumuzu yazalım. Az evvel çıtlattığımız gibi, bu son blok bir
else
bloğu olacak:
else:
print("Yanlış giriş.")
print("Aşağıdaki seçeneklerden birini giriniz:", giriş)
Çok basit bir else
bloğu ile işimizi bitirdik. Bu bloğun ne işe yaradığını
biliyorsunuz:
Eğer kullanıcının girdiği değer yukarıdaki bloklardan hiç birine uymuyorsa bu else bloğunu işlet!
gibi bir emir vermiş oluyoruz bu else
bloğu yardımıyla. Mesela kullanıcımız
1, 2, 3, 4, 5 veya 6 seçeneklerini girmek yerine 7 yazarsa, bu
blok işletilecek.
Gelin isterseniz son kez kodlarımızı topluca bir görelim:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) karekök hesapla
"""
print(giriş)
soru = input("Yapmak istediğiniz işlemin numarasını girin: ")
if soru == "1":
sayı1 = int(input("Toplama işlemi için ilk sayıyı girin: "))
sayı2 = int(input("Toplama işlemi için ikinci sayıyı girin: "))
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
elif soru == "2":
sayı3 = int(input("Çıkarma işlemi için ilk sayıyı girin: "))
sayı4 = int(input("Çıkarma işlemi için ikinci sayıyı girin: "))
print(sayı3, "-", sayı4, "=", sayı3 - sayı4)
elif soru == "3":
sayı5 = int(input("Çarpma işlemi için ilk sayıyı girin: "))
sayı6 = int(input("Çarpma işlemi için ikinci sayıyı girin: "))
print(sayı5, "x", sayı6, "=", sayı5 * sayı6)
elif soru == "4":
sayı7 = int(input("Bölme işlemi için ilk sayıyı girin: "))
sayı8 = int(input("Bölme işlemi için ikinci sayıyı girin: "))
print(sayı7, "/", sayı8, "=", sayı7 / sayı8)
elif soru == "5":
sayı9 = int(input("Karesini hesaplamak istediğiniz sayıyı girin: "))
print(sayı9, "sayısının karesi =", sayı9 ** 2)
elif soru == "6":
sayı10 = int(input("Karekökünü hesaplamak istediğiniz sayıyı girin: "))
print(sayı10, "sayısının karekökü = ", sayı10 ** 0.5)
else:
print("Yanlış giriş.")
print("Aşağıdaki seçeneklerden birini giriniz:", giriş)
Genel olarak baktığımızda, bütün programın aslında basit bir ‘if, elif, else’
yapısından ibaret olduğunu görüyoruz. Ayrıca bu kodlardaki simetriye de
dikkatinizi çekmek isterim. Gördüğünüz gibi her ‘paragraf’ bir if
, elif
veya else
bloğundan oluşuyor ve her blok kendi içinde girintili bir yapı
sergiliyor. Temel olarak şöyle bir şeyle karşı karşıyayız:
Eğer böyle bir durum varsa:
şöyle bir işlem yap
Yok eğer şöyle bir durum varsa:
böyle bir işlem yap
Eğer bambaşka bir durum varsa:
şöyle bir şey yap
Böylelikle şirin bir hesap makinesine sahip olmuş olduk! Hesap makinemiz pek yetenekli değil, ama olsun… Henüz bildiklerimiz bunu yapmamıza müsaade ediyor. Yine de başlangıçtan bu noktaya kadar epey yol katettiğimizi görüyorsunuz.
Şimdi bu programı çalıştırın ve neler yapabildiğine göz atın. Bu arada kodları da iyice inceleyin. Programı yeterince anladıktan sonra, program üzerinde kendinize göre bazı değişiklikler yapın, yeni özellikler ekleyin. Eksikliklerini, zayıf yönlerini bulmaya çalışın. Böylece bu dersten azami faydayı sağlamış olacaksınız.
Sürüme Göre İşlem Yapan Program¶
Bildiğiniz gibi, şu anda piyasada iki farklı Python serisi bulunuyor: Python2 ve Python3. Daha önce de söylediğimiz gibi, Python’ın 2.x serisi ile çalışan bir program Python’ın 3.x serisi ile muhtemelen çalışmayacaktır. Aynı şekilde bunun tersi de geçerlidir. Yani 3.x ile çalışan bir program 2.x ile büyük ihtimalle çalışmayacaktır.
Bu durum, yazdığınız programların farklı Python sürümleri ile çalıştırılma ihtimaline karşı bazı önlemler almanızı gerektirebilir. Örneğin yazdığınız bir programda kullanıcılarınızdan beklentiniz, programınızı Python’ın 3.x sürümlerinden biri ile çalıştırmaları olabilir. Eğer programınız Python’ın 2.x sürümlerinden biri ile çalıştırılırsa kullanıcıya bir uyarı mesajı göstermek isteyebilirsiniz.
Hatta yazdığınız bir program, aynı serinin farklı sürümlerinde dahi çalışmayı
engelleyecek özellikler içeriyor olabilir. Örneğin print()
fonksiyonunun
flush adlı parametresi dile 3.3 sürümü ile birlikte eklendi. Dolayısıyla bu
parametreyi kullanan bir program, kullanıcının 3.3 veya daha yüksek bir Python
sürümü kullanmasını gerektirir. Böyle bir durumda, programınızı çalıştıran
Python sürümünün en düşük 3.3 olmasını temin etmeniz gerekir.
Peki bunu nasıl yapacaksınız?
Burada aklınızda ilk olarak, kodlarınıza #!/usr/bin/env python3.3 veya #! python3.3 gibi bir satır eklemek gelmiş olabilir. Ama unutmayın, bu çözüm ancak kısıtlı bir işlevsellik sunabilir. Programımıza böyle bir satır eklediğimizde, programımızın Python’ın 3.3 sürümü ile çalıştırılması gerektiğini belirtiyoruz. Ama 3.3 dışı bir sürümle çalıştırıldığında ne olacağını belirtmiyoruz. Böyle bir durumda, eğer programımız 3.3 dışı bir sürümle çalıştırılırsa çökecektir. Bizim burada daha kapsamlı ve esnek bir çözüm bulmamız gerekiyor.
Hatırlarsanız önceki derslerden birinde sys adlı bir modülden söz etmiştik.
Bildiğiniz gibi, bu modül içinde pek çok yararlı değişken ve fonksiyon
bulunuyor. Önceki derslerimizde, bu modül içinde bulunan exit()
fonksiyonu
ile stdout ve version değişkenlerini gördüğümüzü hatırlıyor olmalısınız.
sys modülü içinde bulunan exit()
fonksiyonunun programdan çıkmamızı
sağladığını, stdout değişkeninin standart çıktı konumu bilgisini tuttuğunu ve
version değişkeninin de kullandığımız Python sürümü hakkında bilgi verdiğini
biliyoruz. İşte yukarıda bahsettiğimiz programda da bu sys modülünden
yararlanacağız.
Bu iş için, version değişkenine çok benzeyen version_info adlı bir değişkeni kullanacağız.
Bu değişkenin nasıl kullanıldığına etkileşimli kabukta beraberce bakalım…
sys modülü içindeki araçları kullanabilmek için öncelikle bu modülü içe aktarmamız gerektiğini biliyorsunuz:
>>> import sys
Şimdi de bu modül içindeki version_info adlı değişkene erişelim:
>>> sys.version_info
Bu komut bize şöyle bir çıktı verir:
sys.version_info(major=|major3|, minor=|minor3|, micro=|micro3|, releaselevel='final', serial=0)
Gördüğünüz gibi, bu değişken de bize tıpkı version adlı değişken gibi, kullandığımız Python sürümü hakkında bilgi veriyor.
Ben yukarıdaki komutu Python3’te verdiğinizi varsaydım. Eğer yukarıdaki komutu Python3 yerine Python2’de verseydik şöyle bir çıktı alacaktık:
sys.version_info(major=|major2|, minor=|minor2|, micro=|micro2|, releaselevel='final', serial=0)
version_info ve version değişkenlerinin verdikleri çıktının birbirlerinden farklı yapıda olduğuna dikkat edin. version değişkeni, version_info değişkeninden farklı olarak şöyle bir çıktı verir:
'3.7.0 (default, 19.08.2024, 12:24:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
version_info değişkeninin verdiği çıktı bizim şu anda yazmak istediğimiz programa daha uygun. Bunun neden böyle olduğunu biraz sonra siz de anlayacaksınız.
Gördüğünüz gibi, version_info değişkeninin çıktısında major ve minor gibi bazı değerler var. Çıktıdan da rahatlıkla anlayabileceğiniz gibi, major, kullanılan Python serisinin ana sürüm numarasını; minor ise alt sürüm numarasını verir. Çıktıda bir de micro adlı bir değer var. Bu da kullanılan Python serisinin en alt sürüm numarasını verir.
Bu değere şu şekilde erişiyoruz:
>>> sys.version_info.major
Öteki değerlere de aynı şekilde ulaşıyoruz:
>>> sys.version_info.minor
>>> sys.version_info.micro
İşte bu çıktılardaki major (ve yerine göre bununla birlikte minor ve micro) değerini kullanarak, programımızın hangi Python sürümü ile çalıştırılması gerektiğini kontrol edebiliriz. Şimdi programımızı yazalım:
import sys
_2x_metni = """
Python'ın 2.x sürümlerinden birini kullanıyorsunuz.
Programı çalıştırabilmek için sisteminizde Python'ın
3.x sürümlerinden biri kurulu olmalı."""
_3x_metni = "Programa hoşgeldiniz."
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)
Gelin isterseniz öncelikle bu kodları biraz inceleyelim.
İlk olarak modülümüzü içe aktarıyoruz. Bu modül içindeki araçları kullanabilmemiz için bunu yapmamız şart:
import sys
Ardından Python’ın 2.x sürümlerinden herhangi birini kullananlar için bir uyarı metni oluşturuyoruz:
_2x_metni = """
Python'ın 2.x sürümlerinden birini kullanıyorsunuz.
Programı çalıştırabilmek için sisteminizde Python'ın
3.x sürümlerinden biri kurulu olmalı."""
Bildiğiniz gibi Python’da değişken adları bir sayıyla başlamaz. O yüzden değişken isminin başına bir tane alt çizgi işareti koyduğumuza dikkat edin.
Bu da Python3 kullanıcıları için:
_3x_metni = "Programa hoşgeldiniz."
Artık sürüm kontrolü kısmına geçebiliriz. Eğer major parametresinin değeri 3’ten küçükse _2x_metnini yazdırıyoruz. Bunun dışındaki bütün durumlar için ise _3x_metnini basıyoruz:
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)
Gördüğünüz gibi, kullanılan Python sürümünü kontrol etmek ve eğer program istenmeyen bir Python sürümüyle çalıştırılıyorsa ne yapılacağını belirlemek son derece kolay.
Yukarıdaki çok basit bir kod parçası olsa da bize Python programlama diline ve bu dilin farklı sürümlerine dair son derece önemli bazı bilgiler veriyor.
Eğer bu programı Python’ın 3.x sürümlerinden biri ile çalıştırdıysanız şu çıktıyı alacaksınız:
Programa hoşgeldiniz.
Ama eğer bu programı Python’ın 2.x sürümlerinden biri ile çalıştırdıysanız, beklentinizin aksine, şöyle bir hata mesajı alacaksınız:
File "test.py", line 5
SyntaxError: Non-ASCII character '\xc4' in file test.py on line 6, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details
Biz _2x_metni adlı değişkenin ekrana basılmasını beklerken Python bize bir hata mesajı gösterdi. Aslında siz bu hata mesajına hiç yabancı değilsiniz. Bunu daha önce de görmüştünüz. Hatırlarsanız önceki derslerimizde karakter kodlamalarından bahsederken, Python’ın 2.x sürümlerinde öntanımlı karakter kodlamasının ASCII olduğundan söz etmiştik. Bu yüzden programlarımızda Türkçe karakterleri kullanırken bazı ilave işlemler yapmamız gerekiyordu.
Burada ilk olarak karakter kodlamasını UTF-8 olarak değiştirmemiz gerekiyor. Bunun nasıl yapılacağını biliyorsunuz. Programımızın ilk satırına şu kodu ekliyoruz:
# -*- coding: utf-8 -*-
Bu satır Python3 için gerekli değil. Çünkü Python3’te öntanımlı karakter kodlaması zaten UTF-8. Ama Python2’de öntanımlı karakter kodlaması ASCII. O yüzden Python2 kullanıcılarını da düşünerek UTF-8 kodlamasını açıkça belirtiyoruz. Böylece programımızın Python’ın 2.x sürümlerinde Türkçe karakterler yüzünden çökmesini önlüyoruz.
Ama burada bir problem daha var. Programımız Türkçe karakterler yüzünden çökmüyor çökmemesine ama, bu defa da Türkçe karakterleri düzgün göstermiyor:
Python'ın 2.x sürümlerinden birini kullanıyorsunuz.
Programı çalıştırabilmek için sisteminizde Python'ın
3.x sürümlerinden biri kurulu olmalı.
Programımızı Python’ın 2.x sürümlerinden biri ile çalıştıranların uyarı mesajını düzgün bir şekilde görüntüleyebilmesini istiyorsanız, Türkçe karakterler içeren karakter dizilerinin en başına bir ‘u’ harfi eklemelisiniz. Yani _2x_metni adlı değişkeni şöyle yazmalısınız:
_2x_metni = u"""
Python'ın 2.x sürümlerinden birini kullanıyorsunuz.
Programı çalıştırabilmek için sisteminizde Python'ın
3.x sürümlerinden biri kurulu olmalı."""
Bu karakter dizisinin en başına bir ‘u’ harfi ekleyerek bu karakter dizisini ‘unicode’ olarak tanımlamış olduk. Eğer ‘unicode’ kavramını bilmiyorsanız endişe etmeyin. İlerde bu kavramdan bolca söz edeceğiz. Biz şimdilik, içinde Türkçe karakterler geçen karakter dizilerinin Python2 kullanıcıları tarafından düzgün görüntülenebilmesi için başlarına bir ‘u’ harfi eklenmesi gerektiğini bilelim yeter.
Eğer siz bir Windows kullanıcısıysanız ve bütün bu işlemlerden sonra bile Türkçe karakterleri düzgün görüntüleyemiyorsanız, bu durum muhtemelen MS-DOS komut satırının kullandığı yazı tipinin Türkçe karakterleri gösterememesinden kaynaklanıyordur. Bu problemi çözmek için MS-DOS komut satırının başlık çubuğuna sağ tıklayıp ‘özellikler’ seçeneğini seçerek yazı tipini ‘Lucida Console’ olarak değiştirin. Bu işlemin ardından da komut satırında şu komutu verin:
chcp 1254
Böylece Türkçe karakterleri düzgün görüntüleyebilirsiniz.
Not
MS-DOS’taki Türkçe karakter problemi hakkında daha ayrıntılı bilgi için https://web.archive.org/web/20150516030259/http://www.istihza.com/py2/python-programlarini-kaydetmek.html#ms-dos-ta-turkce-karakter-problemi adresindeki makalemizi inceleyebilirsiniz.
Şimdiye kadar anlattıklarımızdan öğrendiğiniz gibi, sys modülü içinde sürüm denetlemeye yarayan iki farklı değişken var. Bunlardan biri version, öbürü ise version_info.
Python3’te bu değişkenlerin şu çıktıları verdiğiniz biliyoruz:
version:
'3.7.0 (default, 19.08.2024, 12:24:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
version_info:
sys.version_info(major=|major3|, minor=|minor3|, micro=|micro3|, releaselevel='final', serial=0)
Gördüğünüz gibi, çıktıların hem yapıları birbirinden farklı, hem de verdikleri bilgiler arasında bazı farklar da var. Mesela version değişkeni, kullandığımız Python sürümünün hangi tarih ve saatte, hangi işletim sistemi üzerinde derlendiği bilgisini de veriyor. Ancak kullanılan Python sürümünün ne olduğunu tespit etmek konusunda version_info biraz daha pratik görünüyor. Bu değişkenin bize major, minor ve micro gibi parametreler aracılığıyla sunduğu sayı değerli verileri işleçlerle birlikte kullanarak bu sayılar üzerinde aritmetik işlemler yapıp, kullanılan Python sürümünü kontrol edebiliyoruz.
version değişkeni bize bir karakter dizisi verdiği için, bu değişkenin değerini kullanarak herhangi bir aritmetik işlem yapamıyoruz. Mesela version_info değişkeniyle yukarıda yaptığımız büyüktür-küçüktür sorgulamasını version değişkeniyle tabii ki yapamayız.
Yukarıdaki örnekte seriler arası sürüm kontrolünü nasıl yapacağımızı gördük. Bunun için kullandığımız kod şuydu:
if sys.version_info.major < 3:
...
Burada kullanılan Python serisinin 3.x’ten düşük olduğu durumları sorguladık. Peki aynı serinin farklı sürümlerini denetlemek istersek ne yapacağız? Mesela Python’ın 3.2 sürümünü sorgulamak istersek nasıl bir kod kullanacağız?
Bunun için şöyle bir şey yazabiliriz:
if sys.version_info.major == 3 and sys.version_info.minor == 2:
...
Gördüğünüz gibi burada version_info değişkeninin hem major hem de minor parametrelerini kullandık. Ayrıca hem ana sürüm, hem de alt sürüm için belli bir koşul talep ettiğimizden ötürü and adlı Bool işlecinden de yararlandık. Çünkü koşulun gerçekleşmesi, ana sürümün 3 ve alt sürümün 2 olmasına bağlı.
Yukarıdaki işlem için version değişkenini de kullanabilirdik. Dikkatlice bakın:
if "3.2" in sys.version:
...
Bildiğiniz gibi, version değişkeni Python’ın 3.x sürümlerinde şuna benzer bir çıktı veriyor:
'3.7.0 (default, 19.08.2024, 12:24:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
İşte biz burada in işlecini kullanarak, version değişkeninin verdiği karakter dizisi içinde ‘3.2’ diye bir ifade aradık.
Bu konuyu daha iyi anlamak için kendi kendinize bazı denemeler yapmanızı tavsiye ederim. Ne kadar çok örnek kod yazarsanız, o kadar çok tecrübe kazanırsınız.
Döngüler (Loops)¶
Şimdiye kadar öğrendiklerimiz sayesinde Python’la ufak tefek programlar yazabilecek düzeye geldik. Mesela öğrendiğimiz bilgiler yardımıyla bir önceki bölümde çok basit bir hesap makinesi yazabilmiştik. Yalnız o hesap makinesinde farkettiyseniz çok önemli bir eksiklik vardı. Hesap makinemizle hesap yaptıktan sonra programımız kapanıyor, yeni hesap yapabilmek için programı yeniden başlatmamız gerekiyordu.
Hesap makinesi programındaki sorun, örneğin, aşağıdaki program için de geçerlidir:
tuttuğum_sayı = 23
bilbakalım = int(input("Aklımdan bir sayı tuttum. Bil bakalım kaç tuttum? "))
if bilbakalım == tuttuğum_sayı:
print("Tebrikler! Bildiniz...")
else:
print("Ne yazık ki tuttuğum sayı bu değildi...")
Burada tuttuğum_sayı adlı bir değişken belirledik. Bu değişkenin değeri 23. Kullanıcıdan tuttuğumuz sayıyı tahmin etmesini istiyoruz. Eğer kullanıcının verdiği cevap tuttuğum_sayı değişkeninin değeriyle aynıysa (yani 23 ise), ekrana ‘Tebrikler!…’ yazısı dökülecektir. Aksi halde ‘Ne yazık ki…’ cümlesi ekrana dökülecektir.
Bu program iyi, hoş, ama çok önemli bir eksiği var. Bu programı yalnızca bir kez kullanabiliyoruz. Yani kullanıcı yalnızca bir kez tahminde bulunabiliyor. Eğer kullanıcı bir kez daha tahminde bulunmak isterse programı yeniden çalıştırması gerekecek. Bunun hiç iyi bir yöntem olmadığı ortada. Halbuki yazdığımız bir program, ilk çalışmanın ardından kapanmasa, biz bu programı tekrar tekrar çalıştırabilsek, programımız sürekli olarak başa dönse ve program ancak biz istediğimizde kapansa ne iyi olurdu değil mi? Yani mesela yukarıdaki örnekte kullanıcı bir sayı tahmin ettikten sonra, eğer bu sayı bizim tuttuğumuz sayıyla aynı değilse, kullanıcıya tekrar tahmin etme fırsatı verebilsek çok hoş olurdu…
Yukarıda açıklamaya çalıştığımız süreç, yani bir sürecin tekrar tekrar devam etmesi Python’da ‘döngü’ (loop) olarak adlandırılır.
İşte bu bölümde, programlarımızın sürekli olarak çalışmasını nasıl sağlayabileceğimizi, yani programlarımızı bir döngü içine nasıl sokabileceğimizi öğreneceğiz.
Python’da programlarımızı tekrar tekrar çalıştırabilmek için döngü adı verilen bazı ifadelerden yararlanacağız.
Python’da iki tane döngü bulunur: while
ve for
Dilerseniz işe while
döngüsü ile başlayalım.
while Döngüsü¶
İngilizce bir kelime olan while, Türkçede ‘… iken, … olduğu sürece’ gibi
anlamlara gelir. Python’da while
bir döngüdür. Bir önceki bölümde
söylediğimiz gibi, döngüler sayesinde programlarımızın sürekli olarak
çalışmasını sağlayabiliriz.
Bu bölümde Python’da while
döngüsünün ne olduğunu ve ne işe yaradığını
anlamaya çalışacağız. Öncelikle while
döngüsünün temellerini kavrayarak işe
başlayalım.
Basit bir while
döngüsü kabaca şuna benzer:
a = 1
while a == 1:
Burada a adlı bir değişken oluşturduk. Bu değişkenin değeri 1. Bir sonraki
satırda ise while a == 1:
gibi bir ifade yazdık. En başta da söylediğimiz
gibi while kelimesi, ‘… iken, olduğu sürece’ gibi anlamlar taşıyor. Python
programlama dilindeki anlamı da buna oldukça yakındır. Burada while a == 1
ifadesi programımıza şöyle bir anlam katıyor:
a değişkeninin değeri 1 olduğu sürece…
Gördüğünüz gibi cümlemiz henüz eksik. Yani belli ki bunun bir de devamı olacak.
Ayrıca while
ifadesinin sonundaki : işaretinden anladığımız gibi, bundan
sonra gelecek satır girintili yazılacak. Devam edelim:
a = 1
while a == 1:
print("bilgisayar çıldırdı!")
Burada Python’a şu emri vermiş olduk:
a değişkeninin değeri 1 olduğu sürece, ekrana ‘bilgisayar çıldırdı!’ yazısını dök!
Bu programı çalıştırdığımızda Python verdiğimiz emre sadakatle uyacak ve a değişkeninin değeri 1 olduğu müddetçe de bilgisayarımızın ekranına ‘bilgisayar çıldırdı!’ yazısını dökecektir. Programımızın içinde a değişkeninin değeri 1 olduğu ve bu değişkenin değerini değiştirecek herhangi bir şey bulunmadığı için Python hiç sıkılmadan ekrana ‘bilgisayar çıldırdı!’ yazısını basmaya devam edecektir. Eğer siz durdurmazsanız bu durum sonsuza kadar devam edebilir. Bu çılgınlığa bir son vermek için klavyenizde Ctrl+C veya Ctrl+Z tuşlarına basarak programı durmaya zorlayabilirsiniz.
Burada programımızı sonsuz bir döngüye sokmuş olduk (infinite loop). Esasında sonsuz döngüler genellikle bir program hatasına işaret eder. Yani çoğu durumda programcının arzu ettiği şey bu değildir. O yüzden doğru yaklaşım, döngüye soktuğumuz programlarımızı durduracak bir ölçüt belirlemektir. Yani öyle bir kod yazmalıyız ki, a değişkeninin 1 olan değeri bir noktadan sonra artık 1 olmasın ve böylece o noktaya ulaşıldığında programımız dursun. Kullanıcının Ctrl+C tuşlarına basarak programı durdurmak zorunda kalması pek hoş olmuyor. Gelin isterseniz bu soyut ifadeleri biraz somutlaştıralım.
Öncelikle şu satırı yazarak işe başlıyoruz:
a = 1
Burada normal bir şekilde a değişkenine 1 değerini atadık. Şimdi devam ediyoruz:
a = 1
while a < 10:
while
ile verdiğimiz ilk örnekte while a == 1
gibi bir ifade
kullanmıştık. Bu ifade;
a’nın değeri 1 olduğu müddetçe…
gibi bir anlama geliyordu.
while a < 10
ifadesi ise;
a’nın değeri 10’dan küçük olduğu müddetçe…
anlamına gelir. İşte burada programımızın sonsuz döngüye girmesini engelleyecek bir ölçüt koymuş olduk. Buna göre, a değişkeninin şimdiki değeri 1’dir. Biz, a’nın değeri 10’dan küçük olduğu müddetçe bir işlem yapacağız. Devam edelim:
a = 1
while a < 10:
print("bilgisayar yine çıldırdı!")
Ne oldu? İstediğimizi elde edemedik, değil mi? Programımız yine sonsuz döngüye girdi. Bu sonsuz döngüyü kırmak için Ctrl+C (veya Ctrl+Z)’ye basmamız gerekecek yine…
Sizce buradaki hata nereden kaynaklandı? Yani neyi eksik yaptık da programımız sonsuz döngüye girmekten kurtulamadı? Aslında bunun cevabı çok basit. Biz yukarıdaki kodları yazarak Python’a şu emri vermiş olduk:
a’nın değeri 10’dan küçük olduğu müddetçe ekrana ‘bilgisayar yine çıldırdı!’ yazısını bas!
a değişkeninin değeri 1. Yani 10’dan küçük. Dolayısıyla Python’ın ekrana o çıktıyı basmasını engelleyecek herhangi bir şey yok…
Şimdi bu problemi nasıl aşacağımızı görelim:
a = 1
while a < 10:
a += 1
print("bilgisayar yine çıldırdı!")
Burada a += 1
satırını ekledik kodlarımızın arasına. += işlecini
anlatırken söylediğimiz gibi, bu satır, a değişkeninin değerine her defasında
1 ekliyor ve elde edilen sonucu tekrar a değişkenine atıyor. En sonunda
a’nın değeri 10’a ulaşınca da, Python ekrana ‘bilgisayar yine çıldırdı!’
cümlesini yazmayı bırakıyor. Çünkü while
döngüsü içinde belirttiğimiz ölçüte
göre, programımızın devam edebilmesi için a değişkeninin değerinin 10’dan
küçük olması gerekiyor. a’nın değeri 10’a ulaştığı anda bu ölçüt
bozulacaktır. Gelin isterseniz bu kodları Python’ın nasıl algıladığına bir
bakalım:
Python öncelikle
a = 1
satırını görüyor ve a’nın değerini 1 yapıyor.Daha sonra a’nın değeri 10’dan küçük olduğu müddetçe… (
while a < 10
) satırını görüyor.Ardından a’nın değerini, 1 artırıyor (
a += 1
) ve a’nın değeri 2 oluyor.a’nın değeri (yani 2) 10’dan küçük olduğu için Python ekrana ilgili çıktıyı veriyor.
İlk döngüyü bitiren Python başa dönüyor ve a’nın değerinin 2 olduğunu görüyor.
a’nın değerini yine 1 artırıyor ve a’yı 3 yapıyor.
a’nın değeri hâlâ 10’dan küçük olduğu için ekrana yine ilgili çıktıyı veriyor.
İkinci döngüyü de bitiren Python yine başa dönüyor ve a’nın değerinin 3 olduğunu görüyor.
Yukarıdaki adımları tekrar eden Python, a’nın değeri 9 olana kadar ilerlemeye devam ediyor.
a’nın değeri 9’a ulaştığında Python a’nın değerini bir kez daha artırınca bu değer 10’a ulaşıyor.
Python a’nın değerinin artık 10’dan küçük olmadığını görüyor ve programdan çıkıyor.
Yukarıdaki kodları şöyle yazarsak belki durum daha anlaşılır olabilir:
a = 1
while a < 10:
a += 1
print(a)
Burada Python’un arkada ne işler çevirdiğini daha net görebiliyoruz. Kodlarımız
içine eklediğimiz while
döngüsü sayesinde Python her defasında a
değişkeninin değerini kontrol ediyor ve bu değer 10’dan küçük olduğu müddetçe
a değişkeninin değerini 1 artırıp, yeni değeri ekrana basıyor. Bu değişkenin
değeri 10’a ulaştığında ise, bu değerin artık 10’dan küçük olmadığını
anlayıp bütün işlemleri durduruyor.
Gelin isterseniz bu while
döngüsünü daha önce yazdığımız hesap makinemize
uygulayalım:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) karekök hesapla
"""
print(giriş)
anahtar = 1
while anahtar == 1:
soru = input("Yapmak istediğiniz işlemin numarasını girin (Çıkmak için q): ")
if soru == "q":
print("çıkılıyor...")
anahtar = 0
elif soru == "1":
sayı1 = int(input("Toplama işlemi için ilk sayıyı girin: "))
sayı2 = int(input("Toplama işlemi için ikinci sayıyı girin: "))
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
elif soru == "2":
sayı3 = int(input("Çıkarma işlemi için ilk sayıyı girin: "))
sayı4 = int(input("Çıkarma işlemi için ikinci sayıyı girin: "))
print(sayı3, "-", sayı4, "=", sayı3 - sayı4)
elif soru == "3":
sayı5 = int(input("Çarpma işlemi için ilk sayıyı girin: "))
sayı6 = int(input("Çarpma işlemi için ikinci sayıyı girin: "))
print(sayı5, "x", sayı6, "=", sayı5 * sayı6)
elif soru == "4":
sayı7 = int(input("Bölme işlemi için ilk sayıyı girin: "))
sayı8 = int(input("Bölme işlemi için ikinci sayıyı girin: "))
print(sayı7, "/", sayı8, "=", sayı7 / sayı8)
elif soru == "5":
sayı9 = int(input("Karesini hesaplamak istediğiniz sayıyı girin: "))
print(sayı9, "sayısının karesi =", sayı9 ** 2)
elif soru == "6":
sayı10 = int(input("Karekökünü hesaplamak istediğiniz sayıyı girin: "))
print(sayı10, "sayısının karekökü = ", sayı10 ** 0.5)
else:
print("Yanlış giriş.")
print("Aşağıdaki seçeneklerden birini giriniz:", giriş)
Burada ilave olarak şu satırları görüyorsunuz:
anahtar = 1
while anahtar == 1:
soru = input("Yapmak istediğiniz işlemin numarasını girin (Çıkmak için q): ")
if soru == "q":
print("çıkılıyor...")
anahtar = 0
Bu kodlarda yaptığımız şey aslında çok basit. Öncelikle değeri 1 olan
anahtar adlı bir değişken tanımladık. Bir alt satırda ise, programımızın
sürekli olarak çalışmasını sağlayacak olan while
döngümüzü yazıyoruz.
Programımız, anahtar değişkeninin değeri 1 olduğu müddetçe çalışmaya devam
edecek. Daha önce de dediğimiz gibi, eğer bu anahtar değişkeninin değerini
programın bir noktasında değiştirmezsek programımız sonsuza kadar çalışmaya
devam edecektir. Çünkü biz programımızı anahtar değişkeninin değeri 1 olduğu
sürece çalışmaya ayarladık. İşte programımızın bu tür bir sonsuz döngüye
girmesini önlemek için bir if
bloğu oluşturuyoruz. Buna göre, eğer kullanıcı
klavyede q tuşuna basarsa programımız önce çıkılıyor… çıktısı verecek,
ardından da anahtar değişkeninin 1 olan değerini 0 yapacaktır. Böylece
artık anahtar’ın değeri 1 olmayacağı için programımız çalışmaya son
verecektir.
Buradaki mantığın ne kadar basit olduğunu görmenizi isterim. Önce bir değişken tanımlıyoruz, ardından bu değişkenin değeri aynı kaldığı müddetçe programımızı çalışmaya ayarlıyoruz. Bu döngüyü kırmak için de başta tanımladığımız o değişkene başka bir değer atıyoruz. Burada anahtar değişkenine atadığımız 1 ve 0 değerleri tamamen tesadüfidir. Yani siz bu değerleri istediğiniz gibi değiştirebilirsiniz. Mesela yukarıdaki kodları şöyle de yazabilirsiniz:
anahtar = "hoyda bre!"
#anahtar'ın değeri 'hoyda bre!' olduğu müddetçe aşağıdaki bloğu
#çalıştırmaya devam et.
while anahtar == "hoyda bre!":
soru = input("Yapmak istediğiniz işlemin numarasını girin (Çıkmak için q): ")
if soru == "q":
print("çıkılıyor...")
anahtar = "dur yolcu!"
#anahtar'ın değeri artık 'hoyda bre!' değil, 'dur yolcu'
#olduğu için döngüden çık ve böylece programı sona erdirmiş ol.
Gördüğünüz gibi, amaç herhangi bir değişkene herhangi bir değer atamak ve o değer aynı kaldığı müddetçe programın çalışmaya devam etmesini sağlamak. Kurduğumuz bu döngüyü kırmak için de o değişkene herhangi başka bir değer atamak…
Yukarıda verdiğimiz son örnekte önce anahtar adlı bir değişken atayıp,
while
döngüsünün işleyişini bu değişkenin değerine göre yapılandırdık. Ama
aslında yukarıdaki kodları çok daha basit bir şekilde de yazabiliriz. Dikkatlice
bakın:
while True:
soru = input("Yapmak istediğiniz işlemin numarasını girin (Çıkmak için q): ")
if soru == "q":
print("çıkılıyor...")
break
Bu yapıyı hesap makinemize uygulayalım:
giriş = """
(1) topla
(2) çıkar
(3) çarp
(4) böl
(5) karesini hesapla
(6) karekök hesapla
"""
print(giriş)
while True:
soru = input("Yapmak istediğiniz işlemin numarasını girin (Çıkmak için q): ")
if soru == "q":
print("çıkılıyor...")
break
elif soru == "1":
sayı1 = int(input("Toplama işlemi için ilk sayıyı girin: "))
sayı2 = int(input("Toplama işlemi için ikinci sayıyı girin: "))
print(sayı1, "+", sayı2, "=", sayı1 + sayı2)
elif soru == "2":
sayı3 = int(input("Çıkarma işlemi için ilk sayıyı girin: "))
sayı4 = int(input("Çıkarma işlemi için ikinci sayıyı girin: "))
print(sayı3, "-", sayı4, "=", sayı3 - sayı4)
elif soru == "3":
sayı5 = int(input("Çarpma işlemi için ilk sayıyı girin: "))
sayı6 = int(input("Çarpma işlemi için ikinci sayıyı girin: "))
print(sayı5, "x", sayı6, "=", sayı5 * sayı6)
elif soru == "4":
sayı7 = int(input("Bölme işlemi için ilk sayıyı girin: "))
sayı8 = int(input("Bölme işlemi için ikinci sayıyı girin: "))
print(sayı7, "/", sayı8, "=", sayı7 / sayı8)
elif soru == "5":
sayı9 = int(input("Karesini hesaplamak istediğiniz sayıyı girin: "))
print(sayı9, "sayısının karesi =", sayı9 ** 2)
elif soru == "6":
sayı10 = int(input("Karekökünü hesaplamak istediğiniz sayıyı girin: "))
print(sayı10, "sayısının karekökü = ", sayı10 ** 0.5)
else:
print("Yanlış giriş.")
print("Aşağıdaki seçeneklerden birini giriniz:", giriş)
Bu yapı sayesinde anahtar gibi bir değişken atama zorunluluğundan kurtulmuş olduk. Yukarıdaki kodların nasıl çalıştığını açıklayalım:
while True ifadesi şöyle bir anlama gelir:
True olduğu müddetçe…
Peki ne True olduğu müddetçe? Burada neyin True olması gerektiğini belirtmediğimiz için, aslında bu kod parçası şu anlama geliyor:
Aksi belirtilmediği sürece çalışmaya devam et!
Eğer yukarıdaki açıklamayı biraz bulanık bulduysanız şu örneği inceleyebilirsiniz:
while True:
print("Bilgisayar çıldırdı!")
Bu kodları çalıştırdığınızda ekrana sürekli olarak Bilgisayar çıldırdı! çıktısı verilecektir. Bu döngüden çıkabilmek için Ctrl+C tuşlarına basmanız gerekiyor. Yukarıdaki kodların sonsuz döngüye girmesinin sorumlusu while True satırıdır. Çünkü burada biz Python’a;
Aksi belirtilmediği sürece çalışmaya devam et!
emri veriyoruz. Python da bu emrimizi sadakatle yerine getiriyor. Böyle bir durumda sonsuz döngüyü engellemek için programımızın bir yerinde Python’a bu döngüden çıkmasını sağlayacak bir emir vermemiz gerekiyor. Biz hesap makinesi programımızda bu döngüyü şu şekilde kırdık:
if soru == "q":
print("çıkılıyor...")
break
Dikkat ederseniz burada break
adlı yeni bir araç görüyoruz. Bu aracın tam
olarak ne işe yaradığını ilerleyen sayfalarda inceleyeceğiz. Şimdilik yalnızca
şunu bilelim: break kelimesi İngilizce’de ‘kırmak, koparmak, bozmak’ gibi
anlamlara gelir. Bu aracın yukarıdaki görevi döngüyü ‘kırmak’tır. Dolayısıyla
kullanıcı klavyede q tuşuna bastığında, while True
ifadesi ile çalışmaya
başlayan döngü kırılacak ve programımız sona erecektir.
Bu yapıyı daha iyi anlayabilmek için şöyle basit bir örnek daha verelim:
#Aksi belirtilmediği sürece kullanıcıya
#aşağıdaki soruyu sormaya devam et!
while True:
soru = input("Nasılsınız, iyi misiniz?")
#Eğer kullanıcı 'q' tuşuna basarsa...
if soru == "q":
break #döngüyü kır ve programdan çık.
Görüyorsunuz, aslında mantık gayet basit:
Bir döngü oluştur ve bu döngüden çıkmak istediğinde, programın bir yerinde bu döngüyü sona erdirecek bir koşul meydan getir.
Bu mantığı yukarıdaki örneğe şu şekilde uyguladık:
while True: ifadesi yardımıyla bir döngü oluştur ve kullanıcı bu döngüden çıkmak istediğinde (yani q tuşuna bastığında), döngüyü kır ve programı sona erdir.
Gelin isterseniz bu konuyu daha net kavramak için bir örnek daha verelim:
tekrar = 1
while tekrar <= 3:
tekrar += 1
input("Nasılsınız, iyi misiniz?")
Burada programımız kullanıcıya üç kez ‘Nasılsınız, iyi misiniz?’ sorusunu
soracak ve ardından kapanacaktır. Bu kodlarda while
döngüsünü nasıl
kullandığımıza dikkat edin. Aslında programın mantığı çok basit:
Öncelikle değeri 1 olan tekrar adlı bir değişken tanımlıyoruz.
Bu değişkenin değeri 3’e eşit veya 3’ten küçük olduğu müddetçe (
while tekrar <= 3
) değişkenin değerine 1 ekliyoruz (tekrar += 1
).Başka bir deyişle
bool(tekrar <= 3)
ifadesi True olduğu müddetçe değişkenin değerine 1 ekliyoruz.tekrar değişkenine her 1 ekleyişimizde kullanıcıya ‘Nasılsınız, iyi misiniz?’ sorusunu soruyoruz (
input("Nasılsınız, iyi misiniz?")
).tekrar değişkeninin değeri 3’ü aştığında
bool(tekrar <= 3)
ifadesi artık False değeri verdiği için programımız sona eriyor.
Yukarıdaki uygulamada Python’ın alttan alta neler çevirdiğini daha iyi görmek için bu uygulamayı şöyle yazmayı deneyin:
tekrar = 1
while tekrar <= 3:
print("tekrar: ", tekrar)
tekrar += 1
input("Nasılsınız, iyi misiniz?")
print("bool değeri: ", bool(tekrar <= 3))
Daha önce de dediğimiz gibi, bir Python programının nasıl çalıştığını anlamanın
en iyi yolu, program içinde uygun yerlere print()
fonksiyonları
yerleştirerek arka planda hangi kodların hangi çıktıları verdiğini izlemektir.
İşte yukarıda da bu yöntemi kullandık. Yani tekrar değişkenininin değerini ve
bool(tekrar <= 3)
ifadesinin çıktısını ekrana yazdırarak arka tarafta neler
olup bittiğini canlı canlı görme imkanına kavuştuk.
Yukarıdaki programı çalıştırdığımızda şuna benzer çıktılar görüyoruz:
tekrar: 1
Nasılsınız, iyi misiniz? evet
bool değeri: True
tekrar: 2
Nasılsınız, iyi misiniz? evet
bool değeri: True
tekrar: 3
Nasılsınız, iyi misiniz? evet
bool değeri: False
Gördüğünüz gibi, tekrar değişkeninin değeri her döngüde 1 artıyor. tekrar
<= 3
ifadesinin bool değeri, tekrar adlı değişkenin değeri 3’ü aşana kadar
hep True olacaktır. Bu değişkenin değeri 3’ü aştığı anda tekrar <= 3
ifadesinin bool değeri False’a dönüyor ve böylece while
döngüsü sona
eriyor.
Peki size şöyle bir soru sorsam: Acaba while
döngüsünü kullanarak 1’den
100’e kadar olan aralıktaki çift sayıları nasıl bulursunuz?
Çok basit:
a = 0
while a < 100:
a += 1
if a % 2 == 0:
print(a)
Gördüğünüz gibi, while
döngüsünün içine bir adet if
bloğu yerleştirdik.
Yukarıdaki kodları şu şekilde Türkçeye çevirebiliriz:
a değişkeninin değeri 100’den küçük olduğu müddetçe a değişkeninin değerini 1 artır. Bu değişkenin değerini her artırışında yeni değerin 2’ye tam bölünüp bölünmediğini kontrol et. Eğer
a modülüs 2
değeri 0 ise (if a % 2 == 0
), yani a’nın değeri bir çift sayı ise, bu değeri ekrana yazdır.
Gördüğünüz gibi, while
döngüsü son derece kullanışlı bir araçtır. Üstelik
kullanımı da son derece kolaydır. Bu döngüyle bol bol pratik yaparak bu döngüyü
rahatça kullanabilecek duruma gelebilirsiniz.
En başta da söylediğimiz gibi, Python’da while
dışında bir de for
döngüsü vardır. En az while
kadar önemli bir döngü olan for
döngüsünün
nasıl kullanıldığını anlamaya çalışalım şimdi de.
for Döngüsü¶
Etrafta yazılmış Python programlarının kaynak kodlarını incelediğinizde, içinde
for
döngüsü geçmeyen bir program kolay kolay bulamazsınız. Belki while
döngüsünün kullanılmadığı programlar vardır. Ancak for
döngüsü Python’da o
kadar yaygındır ve o kadar geniş bir kullanım alanına sahiptir ki, hemen hemen
bütün Python programları bu for
döngüsünden en az bir kez yararlanır.
Peki nedir bu for
döngüsü denen şey?
for
da tıpkı while
gibi bir döngüdür. Yani tıpkı while
döngüsünde
olduğu gibi, programlarımızın birden fazla sayıda çalışmasını sağlar. Ancak
for
döngüsü while
döngüsüne göre biraz daha yeteneklidir. while
döngüsü ile yapamayacağınız veya yaparken çok zorlanacağınız şeyleri for
döngüsü yardımıyla çok kolay bir şekilde halledebilirsiniz.
Yalnız, söylediğimiz bu cümleden, for
döngüsünün while
döngüsüne bir
alternatif olduğu sonucunu çıkarmayın. Evet, while
ile yapabildiğiniz bir
işlemi for
ile de yapabilirsiniz çoğu zaman, ama bu döngülerin, belli
vakalar için tek seçenek olduğu durumlar da vardır. Zira bu iki döngünün çalışma
mantığı birbirinden farklıdır.
Şimdi gelelim for
döngüsünün nasıl kullanılacağına…
Dikkatlice bakın:
tr_harfler = "şçöğüİı"
for harf in tr_harfler:
print(harf)
Burada öncelikle tr_harfler adlı bir değişken tanımladık. Bu değişken Türkçeye
özgü harfleri tutuyor. Daha sonra bir for
döngüsü kurarak, tr_harfler adlı
değişkenin her bir öğesini tek tek ekrana yazdırdık.
Peki bu for
döngüsünü nasıl kurduk?
for
döngülerinin söz dizimi şöyledir:
for değişken_adı in değişken:
yapılacak_işlem
Bu söz dizimini Türkçe olarak şöyle ifade edebiliriz:
değişken içindeki her bir öğeyi değişken_adı olarak adlandır:
ve bu öğelerle bir işlem yap.
Bu soyut yapıları kendi örneğimize uygulayarak durumu daha net anlamaya çalışalım:
tr_harfler adlı değişken içindeki her bir öğeyi harf olarak adlandır:
ve harf olarak adlandırılan bu öğeleri ekrana yazdır.
Yukarıdaki örnekte bir for
döngüsü yardımıyla tr_harfler adlı değişken
içindeki her bir öğeyi ekrana yazdırdık. Esasında for
döngüsünün
yeteneklerini düşündüğümüzde bu örnek pek heyecan verici değil. Zira aynı işi
aslında print()
fonksiyonu ile de yapabilirdik:
tr_harfler = "şçöğüİı"
print(*tr_harfler, sep="\n")
Aslında bu işlemi while
ile de yapmak mümkün (Bu kodlardaki, henüz
öğrenmediğimiz kısmı şimdilik görmezden gelin):
tr_harfler = "şçöğüİı"
a = 0
while a < len(tr_harfler):
print(tr_harfler[a], sep="\n")
a += 1
while
döngüsü kullanıldığında işi uzattığımızı görüyorsunuz. Dediğimiz gibi,
for
döngüsü while
döngüsüne göre biraz daha yeteneklidir ve while
ile yapması daha zor (veya uzun) olan işlemleri for
döngüsü ile çok daha
kolay bir şekilde yapabiliriz. Ayrıca for
döngüsü ile while
döngüsünün
çalışma mantıkları birbirinden farklıdır. for
döngüsü, üzerinde döngü
kurulabilecek veri tiplerinin her bir öğesinin üzerinden tek tek geçer ve bu
öğelerin her biri üzerinde bir işlem yapar. while
döngüsü ise herhangi bir
ifadenin bool değerini kontrol eder ve bu değerin bool değeri False olana
kadar, belirlenen işlemi yapmayı sürdürür.
Bu arada, biraz önce ‘üzerinde döngü kurulabilecek veri tipleri’ diye bir kavramdan söz ettik. Örneğin karakter dizileri, üzerinde döngü kurulabilecek bir veri tipidir. Ama sayılar öyle değildir. Yani sayılar üzerinde döngü kuramayız. Mesela:
>>> sayılar = 123456789
>>> for sayı in sayılar:
... print(sayı)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Buradaki hata mesajından da göreceğiniz gibi int (tam sayı) türündeki nesneler üzerinde döngü kuramıyoruz. Hata mesajında görünen not iterable (üzerinde döngü kurulamaz) ifadesiyle kastedilen de budur.
Gelin isterseniz for
döngüsü ile bir örnek daha vererek durumu iyice
anlamaya çalışalım:
sayılar = "123456789"
for sayı in sayılar:
print(int(sayı) * 2)
Burada sayılar adlı değişkenin her bir öğesini sayı olarak adlandırdıktan
sonra, int()
fonksiyonu yardımıyla bu öğeleri tek tek sayıya çevirdik ve
her bir öğeyi 2 ile çarptık.
for
döngüsünün mantığını az çok anlamış olmalısınız. Bu döngü bir değişken
içindeki her bir öğeyi tek tek ele alıp, iki nokta üst üste işaretinden sonra
yazdığımız kod bloğunu bu öğelere tek tek uyguluyor.
for kelimesi İngilizcede ‘için’ anlamına gelir. Döngünün yapısı içinde geçen in ifadesini de tanıyorsunuz. Biz bu ifadeyi ‘Aitlik İşleçleri’ konusunu işlerken de görmüştük. Hatırlarsanız in işleci bir öğenin bir veri tipi içinde bulunup bulunmadığını sorguluyordu. Mesela:
>>> a = "istihza.com"
>>> "h" in a
True
“h” öğesi “istihza.com” adlı karakter dizisi içinde geçtiği için "h" in
a
kodu True çıktısı veriyor. Bir de şuna bakın:
>>> "b" in a
False
“b” öğesi “istihza.com” karakter dizisi içinde bulunmuyor. Dolayısıyla "b"
in a
sorgulaması False çıktısı veriyor.
in kelimesi İngilizcede ‘içinde’ anlamına geliyor. Dolayısıyla for falanca
in filanca:
yazdığımızda aslında şöyle bir şey demiş oluyoruz:
filanca içinde falanca adını verdiğimiz her bir öğe için…
Yani şu kod:
for s in "istihza":
print(s)
Şu anlama geliyor:
- “istihza” karakter dizisi içinde s adını verdiğimiz her bir öğe için:
s öğesini ekrana basma işlemi gerçekleştir!
Ya da şu kod:
sayılar = "123456789"
for i in sayılar:
if int(i) > 3:
print(i)
Şu anlama geliyor:
- sayılar değişkeni içinde i adını verdiğimiz her bir öğe için:
- eğer sayıya dönüştürülmüş i değeri 3’ten büyükse:
i öğesini ekrana basma işlemi gerçekleştir!
Yukarıdaki temsili kodların Türkçesi bozuk olsa da for
döngüsünün çalışma
mantığını anlamaya yardımcı olacağını zannediyorum. Ama yine de, eğer bu
döngünün mantığını henüz kavrayamadıysanız hiç endişe etmeyin. Zira bu döngüyü
oldukça sık bir biçimde kullanacağımız için, siz istemeseniz de bu döngü
kafanızda yer etmiş olacak.
Bu for
döngüsünü biraz daha iyi anlayabilmek için son bir örnek yapalım:
tr_harfler = "şçöğüİı"
parola = input("Parolanız: ")
for karakter in parola:
if karakter in tr_harfler:
print("parolada Türkçe karakter kullanılamaz")
Bu program, kullanıcıya bir parola soruyor. Eğer kullanıcının girdiği parola
içinde Türkçe karakterlerden herhangi biri varsa kullanıcıyı Türkçe karakter
kullanmaması konusunda uyarıyor. Buradaki for
döngüsünü nasıl kurduğumuzu
görüyorsunuz. Aslında burada şu Türkçe cümleyi Pythonca’ya çevirmiş olduk:
- parola değişkeni içinde karakter adını verdiğimiz her bir öğe için:
- eğer karakter değişkeni tr_harfler adlı değişken içinde geçiyorsa:
‘parolada Türkçe karakter kullanılamaz’ uyarısını göster!
Burada kullandığımız for
döngüsü sayesinde kullanıcının girdiği parola
adlı değişken içindeki bütün karakterlere tek tek bakıp, eğer bakılan karakter
tr_harfler adlı değişken içinde geçiyorsa kullanıcıyı uyarıyoruz.
Aslında for
döngüsüyle ilgili söyleyeceklerimiz bu kadar değil. Ama henüz bu
döngüyle kullanılan önemli araçları tanımıyoruz. Gerçi zaten bu döngüyü bundan
sonra sık sık kullandığımızı göreceksiniz.
Gelin isterseniz yeni bir konuya geçmeden önce döngülerle ilgili ufak bir örnek verelim:
Örneğin kullanıcıya bir parola belirletirken, belirlenecek parolanın 8 karakterden uzun, 3 karakterden kısa olmamasını sağlayalım:
while True:
parola = input("Bir parola belirleyin: ")
if not parola:
print("parola bölümü boş geçilemez!")
elif len(parola) > 8 or len(parola) < 3:
print("parola 8 karakterden uzun 3 karakterden kısa olmamalı")
else:
print("Yeni parolanız", parola)
break
Burada öncelikle, programınızın sürekli olarak çalışmasını sağlamak için bir
while
döngüsü oluşturduk. Buna göre, aksi belirtilmedikçe (while True
)
programımız çalışmaya devam edecek.
while
döngüsünü kurduktan sonra kullanıcıya bir parola soruyoruz (parola =
input("Bir parola belirleyin: ")
)
Eğer kullanıcı herhangi bir parola belirlemeden doğrudan Enter tuşuna basarsa,
yani parola değişkeninin bool değeri False olursa (if not parola
),
kullanıcıya ‘parola bölümü boş geçilemez!’ uyarısı veriyoruz.
Eğer kullanıcı tarafından belirlenen parolanın uzunluğu 8 karakterden fazlaysa ya da 3 karakterden kısaysa, ‘parola 8 karakterden uzun 3 karakterden kısa olmamalı’ uyarısı veriyoruz.
Yukarıdaki koşullar harici durumlar için ise (else
), belirlenen yeni
parolayı kullanıcıya gösterip döngüden çıkıyoruz (break
).
Bu arada, hatırlarsanız eval()
fonksiyonunu anlatırken şöyle bir örnek
vermiştik:
print("""
Basit bir hesap makinesi uygulaması.
İşleçler:
+ toplama
- çıkarma
* çarpma
/ bölme
Yapmak istediğiniz işlemi yazıp ENTER
tuşuna basın. (Örneğin 23 ve 46 sayılarını
çarpmak için 23 * 46 yazdıktan sonra
ENTER tuşuna basın.)
""")
veri = input("İşleminiz: ")
hesap = eval(veri)
print(hesap)
Bu programdaki eksiklikleri ve riskleri biliyorsunuz. Böyle bir program
yazdığınızda, eval()
fonksiyonunu kontrolsüz bir şekilde kullandığınız için
önemli bir güvenlik açığına sebep olmuş oluyorsunuz. Gelin isterseniz bu derste
öğrendiğimiz bilgileri de kullanarak yukarıdaki eval()
fonksiyonu için basit
bir kontrol mekanizması kuralım:
izinli_karakterler = "0123456789+-/*= "
print("""
Basit bir hesap makinesi uygulaması.
İşleçler:
+ toplama
- çıkarma
* çarpma
/ bölme
Yapmak istediğiniz işlemi yazıp ENTER
tuşuna basın. (Örneğin 23 ve 46 sayılarını
çarpmak için 23 * 46 yazdıktan sonra
ENTER tuşuna basın.)
""")
while True:
veri = input("İşleminiz: ")
if veri == "q":
print("çıkılıyor...")
break
for s in veri:
if s not in izinli_karakterler:
print("Neyin peşindesin?!")
quit()
hesap = eval(veri)
print(hesap)
Burada öncelikle programımızı bir while
döngüsü içine aldık. Böylece
programımızın ne zaman sona ereceğini kendimiz belirleyebileceğiz. Buna göre
eğer kullanıcı klavyede ‘q’ tuşuna basarsa while
döngüsü sona erecek.
Bu programda bizi özellikle ilgilendiren kısım şu:
izinli_karakterler = "0123456789+-/*= "
for s in veri:
if s not in izinli_karakterler:
print("Neyin peşindesin?!")
quit()
hesap = eval(veri)
Gördüğünüz gibi, ilk olarak izinli_karakterler adlı bir değişken tanımladık. Program içinde kullanılmasına izin verdiğimiz karakterleri bu değişken içine yazıyoruz. Buna göre kullanıcı yalnızca 0, 1, 2, 3, 4, 5, 6, 7, 8 ve 9 sayılarını, +, -, /, * ve = işleçlerini, ayrıca boşluk karakterini (’ ‘) kullanabilecek.
Kullanıcının girdiği veri üzerinde bir for
döngüsü kurarak, veri içindeki
her bir karakterin izinli_karakterler değişkeni içinde yer alıp almadığını
denetliyoruz. İzin verilen karakterler dışında herhangi bir karakterin girilmesi
Neyin peşindesin?! çıktısının verilip programdan tamamen çıkılmasına
(quit()
) yol açacaktır.
Eğer kullanıcı izinli karakterleri kullanarak bir işlem gerçekleştirmişse
hesap = eval(veri)
kodu aracılığıyla, kullanıcının yaptığı işlemi eval()
fonksiyonuna gönderiyoruz.
Böylece eval()
fonksiyonunu daha güvenli bir hale getirebilmek için basit
bir kontrol mekanizmasının nasıl kurulabileceğini görmüş olduk. Kurduğumuz
kontrol mekanizmasının esası, kullanıcının girebileceği veri türlerini
sınırlamaya dayanıyor. Böylece kullanıcı mesela şöyle tehlikeli bir komut
giremiyor:
__import__("os").system("dir")
Çünkü bu komutu yazabilmesi için gereken karakterler izinli_karakterler değişkeni içinde tanımlı değil. Kullanıcı yalnızca basit bir hesap makinesinde kullanılabilecek olan sayıları ve işleçleri girebiliyor.
İlgili Araçlar¶
Elbette döngüler tek başlarına bir şey ifade etmezler. Döngülerle işe yarar
kodlar yazabilmemiz için bazı araçlara ihtiyacımız var. İşte bu bölümde
döngüleri daha verimli kullanmamızı sağlayacak bazı fonksiyon ve deyimlerden söz
edeceğiz. İlk olarak range()
adlı bir fonksiyondan bahsedelim.
range Fonksiyonu¶
range kelimesi İngilizcede ‘aralık’ anlamına gelir. Biz Python’da range()
fonksiyonunu belli bir aralıkta bulunan sayıları göstermek için kullanıyoruz.
Örneğin:
>>> for i in range(0, 10):
... print(i)
...
0
1
2
3
4
5
6
7
8
9
Gördüğünüz gibi, range(0, 10)
kodu sayesinde ve for
döngüsünü de
kullanarak, 0 ile 10 (10 hariç) aralığındaki sayıları ekrana yazdırdık.
Yukarıdaki kodda range()
fonksiyonuna 0 ve 10 olmak üzere iki adet
parametre verdiğimizi görüyorsunuz. Burada 0 sayısı, aralıktaki ilk sayıyı,
10 sayısı ise aralıktaki son sayıyı gösteriyor. Yani range()
fonksiyonunun
formülü şöyledir:
range(ilk_sayı, son_sayı)
Bu arada, range(ilk_sayı, son_sayı)
kodunun verdiği çıktıya ilk_sayının
dahil olduğuna, ama son_sayının dahil olmadığına dikkat edin.
Eğer range()
fonksiyonunun ilk parametresi 0 olacaksa, bu parametreyi
belirtmesek de olur. Yani mesela 0’dan 10’a kadar olan sayıları
listeleyeceksek range()
fonksiyonunu şöyle yazmamız yeterli olacaktır:
>>> for i in range(10):
... print(i)
range()
fonksiyonunun ilk_sayı parametresi verilmediğinde Python ilk
parametreyi 0 olarak alır. Yani range(10)
gibi bir kodu Python range(0,
10)
olarak algılar. Elbette, eğer aralıktaki ilk sayı 0’dan farklı olacaksa
bu sayıyı açık açık belirtmek gerekir:
>>> for i in range(3, 20):
... print(i)
Burada 3’ten itibaren 20’ye kadar olan sayılar ekrana dökülecektir.
Hatırlarsanız, biraz önce, kullanıcının 3 karakterden kısa, 8 karakterden
uzun parola belirlemesini engelleyen bir uygulama yazmıştık. O uygulamayı
range()
fonksiyonunu kullanarak da yazabiliriz:
while True:
parola = input("parola belirleyin: ")
if not parola:
print("parola bölümü boş geçilemez!")
elif len(parola) in range(3, 9): #eğer parolanın uzunluğu 3 ile 8 karakter
#aralığında ise...
print("Yeni parolanız", parola)
break
else:
print("parola 8 karakterden uzun 3 karakterden kısa olmamalı")
Bu fonksiyonu kullanarak bir döngünün kaç kez çalışacağını da belirleyebilirsiniz. Aşağıdaki kodları dikkatlice inceleyin:
for i in range(3):
parola = input("parola belirleyin: ")
if not parola:
print("parola bölümü boş geçilemez!")
elif len(parola) in range(3, 8):
print("Yeni parolanız", parola)
break
elif i == 2:
print("parolayı 3 kez yanlış girdiniz.",
"Lütfen 30 dakika sonra tekrar deneyin!")
else:
print("parola 8 karakterden uzun 3 karakterden kısa olmamalı")
Burada if i == 2
kodu sayesinde for
döngüsü içinde belirttiğimiz i
adlı değişkenin değeri 2 olduğu anda ‘parolayı 3 kez yanlış girdiniz…’
uyarısı gösterilecektir. Daha önce de birkaç yerde ifade ettiğimiz gibi, eğer
yukarıdaki kodların çalışma mantığını anlamakta zorlanıyorsanız, programın uygun
yerlerine print()
fonksiyonu yerleştirerek arka planda Python’ın neler
çevirdiğini daha net görebilirsiniz. Örneğin:
for i in range(3):
print(i)
parola = input("parola belirleyin: ")
if not parola:
print("parola bölümü boş geçilemez!")
elif len(parola) in range(3, 8):
print("Yeni parolanız", parola)
break
elif i == 2:
print("parolayı 3 kez yanlış girdiniz.",
"Lütfen 30 dakika sonra tekrar deneyin!")
else:
print("parola 8 karakterden uzun 3 karakterden kısa olmamalı")
Gördüğünüz gibi, i değişkeninin başlangıçtaki değeri 0. Bu değer her döngüde
1 artıyor ve bu değişkenin değeri 2 olduğu anda if i == 2
bloğu devreye
giriyor.
range()
fonksiyonunun yetenekleri yukarıda anlattıklarımızla sınırlı
değildir. Bu fonksiyonun bazı başka maharetleri de bulunur. Hatırlarsanız
yukarıda bu fonksiyonun formülünü şöyle vermiştik:
range(ilk_sayı, son_sayı)
Buna göre range()
fonksiyonu iki parametre alıyor. Ama aslında bu
fonksiyonun üçüncü bir parametresi daha vardır. Buna göre formülümüzü
güncelleyelim:
range(ilk_sayı, son_sayı, atlama_değeri)
Formüldeki son parametre olan atlama_değeri, aralıktaki sayıların kaçar kaçar ilerleyeceğini gösterir. Yani:
>>> for i in range(0, 10, 2):
... print(i)
...
0
2
4
6
8
Gördüğünüz gibi, son parametre olarak verdiğimiz 2 sayısı sayesinde 0’dan 10’a kadar olan sayılar ikişer ikişer atlayarak ekrana dökülüyor.
Bu arada, bir şey dikkatinizi çekmiş olmalı:
range()
fonksiyonu üç farklı parametre alan bir fonksiyon. Eğer ilk
parametre 0 olacaksa bu parametreyi belirtmek zorunda olmadığımızı biliyoruz.
Yani:
>>> range(10)
Python bu kodu range(0, 10)
olarak algılayıp buna göre değerlendiriyor.
Ancak eğer range()
fonksiyonunda üçüncü parametreyi de kullanacaksak, yani
range(0, 10, 2)
gibi bir komut vereceksek, üç parametrenin tamamını da
belirtmemiz gerekiyor. Eğer burada bütün parametreleri belirtmezsek Python hangi
sayının hangi parametreye karşılık geldiğini anlayamaz. Yani mesela 0’dan
10’a kadar olan sayıları ikişer ikişer atlayarak ekrana dökmek için şöyle bir
şey yazmaya çalıştığımızı düşünün:
>>> for i in range(10, 2):
... print(i)
Burada Python ne yapmaya çalıştığınızı anlayamaz. Parantez içinde ilk değer
olarak 10, ikinci değer olarak ise 2 yazdığınız için, Python bu 10
sayısını başlangıç değeri; 2 sayısını ise bitiş değeri olarak algılayacaktır.
Dolayısıyla da Python bu durumda sizin 10’dan 2’ye kadar olan sayıları
listelemek istediğinizi zannedecek, range()
fonksiyonuyla bu şekilde geriye
doğru sayamayacağımız için de boş bir çıktı verecektir. Bu yüzden, Python’un
şaşırmaması için yukarıdaki örneği şu şekilde yazmalıyız:
>>> for i in range(0, 10, 2):
... print(i)
Kısacası, eğer range()
fonksiyonunun kaçar kaçar sayacağını da belirtmek
istiyorsak, parantez içinde, gerekli bütün parametreleri belirtmeliyiz.
Gördüğünüz gibi, range()
fonksiyonunu kullanarak belirli bir aralıktaki
sayıları alabiliyoruz. Peki bu sayıları 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 nasıl yazdığımıza çok dikkat edin. Sayıları
tersten alacağımız için, ilk parametre 10, ikinci parametre ise 0. Üçüncü
parametre olarak ise eksi değerli bir sayı veriyoruz. Eğer sayıları hem tersten,
hem de mesela 3’er 3’er atlayarak yazmak isterseniz şöyle bir komut
verebilirsiniz:
>>> for i in range(10, 0, -3):
... print(i)
...
10
7
4
1
Bu arada, etkileşimli kabukta range(10)
gibi bir komut verdiğinizde
range(0, 10) çıktısı aldığınızı görüyorsunuz. Bu çıktı, verdiğimiz komutun 0
ile 10 arası sayıları elde etmemizi sağlayacağını belirtiyor, ama bu sayıları
o anda bize göstermiyor. Daha önce verdiğimiz örneklerden de anlaşılacağı gibi,
0-10 aralığındaki sayıları görebilmek için range(10)
ifadesi üzerinde
bir for
döngüsü kurmamız gerekiyor. range(10)
ifadesinin taşıdığı
sayıları görebilmek için for
döngüsü kurmak tek seçenek değildir. Bu işlem
için yıldızlı parametrelerden de yararlanabiliriz. print()
fonksiyonunu
incelediğimiz derste yıldızlı parametrelerin nasıl kullanıldığını göstermiştik.
Dilerseniz şimdi bu parametre tipini range()
fonksiyonuna nasıl
uygulayabileceğimizi görelim:
>>> print(*range(10))
0 1 2 3 4 5 6 7 8 9
print()
fonksiyonunun sep parametresi yardımıyla bu çıktıyı istediğiniz
gibi düzenleyebileceğinizi biliyorsunuz. Mesela çıktıdaki sayıları
birbirlerinden virgülle ayırmak için şöyle bir komut verebiliyoruz:
>>> print(*range(10), sep=", ")
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Böylece range()
fonksiyonunu enine boyuna incelemiş ve bu fonksiyonun ne işe
yaradığını, nasıl kullanılacağını anlamamızı sağlayan örnekler vermiş olduk.
Artık başka bir konuyu geçebiliriz.
pass Deyimi¶
pass kelimesi İngilizcede ‘geçmek, pas geçmek’ gibi anlamlara gelir. Python’daki kullanımı da bu anlama oldukça yakındır. Biz bu deyimi Pyhon’da ‘görmezden gel, hiçbir şey yapma’ anlamında kullanacağız.
Dilerseniz pass
deyimini tarif etmeye çalışmak yerine bu deyimi bir örnek
üzerinde açıklamaya çalışalım.
Hatırlarsanız yukarıda şöyle bir örnek vermiştik:
while True:
parola = input("parola belirleyin: ")
if not parola:
print("parola bölümü boş geçilemez!")
elif len(parola) in range(3, 8): #eğer parolanın uzunluğu 3 ile 8 karakter
#aralığında ise...
print("Yeni parolanız", parola)
break
else:
print("parola 8 karakterden uzun 3 karakterden kısa olmamalı")
Burada mesela eğer kullanıcı parolayı boş bırakırsa ‘parola bölümü boş
geçilemez!’ uyarısı gösteriyoruz. Şimdi o if
bloğunu şöyle yazdığımızı
düşünün:
while True:
parola = input("parola belirleyin: ")
if not parola:
pass
elif len(parola) in range(3, 8): #eğer parolanın uzunluğu 3 ile 8 karakter
#aralığında ise...
print("Yeni parolanız", parola)
break
else:
print("parola 8 karakterden uzun 3 karakterden kısa olmamalı")
Burada, eğer kullanıcı parolayı boş bırakırsa programımız hiçbir şey yapmadan
yoluna devam edecektir. Yani burada pass
deyimi yardımıyla programımıza şu
emri vermiş oluyoruz:
Eğer kullanıcı parolayı boş geçerse görmezden gel. Hiçbir şey yapmadan yoluna devam et!
Başka bir örnek daha verelim:
while True:
sayı = int(input("Bir sayı girin: "))
if sayı == 0:
break
elif sayı < 0:
pass
else:
print(sayı)
Burada eğer kullanıcı 0 sayısını girerse programımız sona erer (break
deyimini biraz sonra inceleyeceğiz). Eğer kullanıcı 0’dan küçük bir sayı
girerse, yani kullanıcının girdiği sayı eksi değerli ise, pass
deyimininin
etkisiyle programımız hiçbir şey yapmadan yoluna devam eder. Bu koşulların
dışındaki durumlarda ise programımız kullanıcının girdiği sayıları ekrana
yazdıracaktır.
Yukarıda anlatılan durumların dışında, pass
deyimini kodlarınız henüz taslak
aşamasında olduğu zaman da kullanabilirsiniz. Örneğin, diyelim ki bir kod
yazıyorsunuz. Programın gidişatına göre, bir noktada yapmanız gereken bir işlem
var, ama henüz ne yapacağınıza karar vermediniz. Böyle bir durumda pass
deyiminden yararlanabilirsiniz. Mesela birtakım if
deyimleri yazmayı
düşünüyor olun:
if .....:
böyle yap
elif .....:
şöyle yap
else:
pass
Burada henüz else
bloğunda ne yapılacağına karar vermemiş olduğunuz için,
oraya bir pass
koyarak durumu şimdilik geçiştiriyorsunuz. Program son haline
gelene kadar oraya bir şeyler yazmış olacaksınız.
Sözün özü, pass
deyimlerini, herhangi bir işlem yapılmasının gerekli
olmadığı durumlar için kullanıyoruz. İlerde işe yarar programlar yazdığınızda,
bu pass
deyiminin göründüğünden daha faydalı bir araç olduğunu
anlayacaksınız.
break Deyimi¶
Python’da break
özel bir deyimdir. Bu deyim yardımıyla, devam eden bir
süreci kesintiye uğratabiliriz. Bu deyimin kullanıldığı basit bir örnek
verelim:
>>> while True:
... parola = input("Lütfen bir parola belirleyiniz:")
... if len(parola) < 5:
... print("Parola 5 karakterden az olmamalı!")
... else:
... print("Parolanız belirlendi!")
... break
Burada, eğer kullanıcının girdiği parolanın uzunluğu 5 karakterden azsa,
Parola 5 karakterden az olmamalı! uyarısı gösterilecektir. Eğer kullanıcı 5
karakterden uzun bir parola belirlemişse, kendisine ‘Parolanız belirlendi!’
mesajını gösterip, break
deyimi yardımıyla programdan çıkıyoruz.
Gördüğünüz gibi, break
ifadesinin temel görevi bir döngüyü sona erdirmek.
Buradan anlayacağımız gibi, break
ifadesinin her zaman bir döngü içinde yer
alması gerekiyor. Aksi halde Python bize şöyle bir hata verecektir:
SyntaxError: 'break' outside loop
Yani:
SözDizimiHatası: ``break`` döngü dışında ..
continue Deyimi¶
continue
ilginç bir deyimdir. İsterseniz continue
deyimini anlatmaya
çalışmak yerine bununla ilgili bir örnek verelim:
while True:
s = input("Bir sayı girin: ")
if s == "iptal":
break
if len(s) <= 3:
continue
print("En fazla üç haneli bir sayı girebilirsiniz.")
Burada eğer kullanıcı klavyede iptal yazarsa programdan çıkılacaktır. Bunu;
if s == "iptal":
break
satırıyla sağlamayı başardık.
Eğer kullanıcı tarafından girilen sayı üç haneli veya daha az haneli bir sayı
ise, continue
ifadesinin etkisiyle:
>>> print("En fazla üç haneli bir sayı girebilirsiniz.")
satırı es geçilecek ve döngünün en başına gidilecektir.
Eğer kullanıcının girdiği sayıdaki hane üçten fazlaysa ekrana:
En fazla üç haneli bir sayı girebilirsiniz.
cümlesi yazdırılacaktır.
Dolayısıyla buradan anladığımıza göre, continue
deyiminin görevi kendisinden
sonra gelen her şeyin es geçilip döngünün başına dönülmesini sağlamaktır. Bu
bilgiye göre, yukarıdaki programda eğer kullanıcı, uzunluğu üç karakterden az
bir sayı girerse continue
deyiminin etkisiyle programımız döngünün en başına
geri gidiyor. Ama eğer kullanıcı, uzunluğu üç karakterden fazla bir sayı
girerse, ekrana ‘En fazla üç haneli bir sayı girebilirsiniz,’ cümlesinin
yazdırıldığını görüyoruz.
else Deyimi¶
Biz else
deyimini koşullu durumlarda da görmüştük, ancak else
deyimi
döngüler ile de kullanılabilmektedir. Tabii döngüler ile kullanıldığında
farklı bir işi üstlenmektedir. else
deyimi döngüler ile birlikte
kullanılırken break
deyimi ile birlikte bir anlam kazanır.
Şöyle bir kodumuz olduğunu varsayalım:
for i in range(5):
print(i)
else:
print("else çalıştı.")
Kodumuzu kaydedip çalıştırdığımızda bu çıktıyı alıyoruz:
1
2
3
4
else çalıştı.
>>>
Peki şimdi else
ifadesi ne işe yaradı? Aslında pek de işe yaramadı,
else
ifadesini yazmadan da aynı çıktıları alabilirdik.
Dediğimiz gibi Python’da else
ifadesi döngüler ile birlikte kullanılacaksa
break
ifadesi ile birlikte bir anlam kazanır. Eğer döngü break
ifadesi kullanılarak sonlandırıldı ise else
çalışmaz, döngü break
ifadesi ile sonlandırılmadı ise else
bölümü çalışır.
Yukarıdaki örneğimizde zaten break
deyimi bulunmadığı
için else
bölümü çalıştı. Şimdi çalışmayacağı bir örnek verelim:
a = 0
while True:
a += 1
print(a)
if a==3:
break
else:
print("else çalıştı.")
Şimdi programımızı çalıştırdığımızda şu sonucu almaktayız:
1
2
3
Gördüğünüz gibi a
değişkenimiz 3
olduğunda döngümüz break
ifadesi
ile kırılıyor ve bu yüzden else
çalışmıyor. else
ifadesini
hem for
hem de while
döngüsü ile kullanabileceğimizi unutmayalım.
Şimdi bu konu ile ilgili işe yarar bir örnek verelim. Bir karakter dizimiz
var ve 'a'
harfinin bu dizide bulunup bulunmadığını kontrol
etmek istiyoruz. Eğer bulunuyorsa ekrana bunu belirten bir
yazı yazacağız:
karater_dizisi = "Merhaba Dünya"
for harf in karater_dizisi:
if harf == 'a':
print("a harfi bulundu.")
Ancak bu programı çalıştırdığımızda şöyle bir sonuçla karşılaşıyoruz:
a harfi bulundu.
a harfi bulundu.
a harfi bulundu.
>>>
Gördüğünüz gibi her 'a'
harfi için bir defa a harfi bulundu.
yazılıyor.
Eğer biz bir defa 'a'
harfine rastladığımızda döngüden çıkmak istiyorsak
bunu şu şekilde yazabiliriz:
karater_dizisi = "Merhaba Dünya"
for harf in karater_dizisi:
if harf == 'a':
print("a harfi bulundu.")
break
Kodumuzu çalıştırıyoruz:
a harfi bulundu.
>>>
Peki şimdi 'a'
harfinin bulunmadığı durumda da a harfi bulunmadı.
yazmak istersek bunu nasıl yaparız? Bazı değişkenler oluşturup if
ifadesi ile bunu yapmak mümkündür ancak else
ifadesi ile de
bu işi hemen halledebiliyoruz:
karater_dizisi = "Bu yAzıdA küçük A yok."
for harf in karater_dizisi:
if harf == 'a':
print("a harfi bulundu.")
break
else:
print("a harfi bulunmadı.")
Kodumuzu çalıştırdığımızda break
ifadesi hiç çalışmadığı için else
ifadesinin
çalıştığını görebiliriz:
a harfi bulunmadı.
>>>
Evet, else
ifadesi de Python’da döngüler ile bu şekilde kullanılabiliyor.
Peki olmasa da olur muydu? Olurdu. else
ifadesinin bu kullanım şekli de
Python’daki çoğu kolaylıklardan biri sadece…
Konu ile alakalı daha çok örnek için buraya bakabilirsiniz.
Örnek Uygulamalar¶
Python programlama dilinde döngülerin neye benzediğini öğrendik. Bu bölümde ayrıca döngülerle birlikte kullanabileceğimiz başka araçları da tanıdık. Şimdi dilerseniz bu öğrendiklerimizi pekiştirmek için birkaç ufak çalışma yapalım.
Karakter Dizilerinin İçeriğini Karşılaştırma¶
Diyelim ki elinizde şöyle iki farklı metin var:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
Siz burada, ilk_metin adlı değişken içinde bulunan, ama ikinci_metin adlı değişken içinde bulunmayan öğeleri ayıklamak istiyorsunuz. Yani bu iki metnin içeriğini karşılaştırıp, farklı öğeleri bulmayı amaçlıyorsunuz. Bu işlem için, bu bölümde öğrendiğimiz döngülerden ve daha önce öğrendiğimiz başka araçlardan yararlanabilirsiniz. Şimdi dikkatlice bakın:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
for s in ilk_metin:
if not s in ikinci_metin:
print(s)
Bu kodları bir dosyaya kaydedip çalıştırdığımızda şu çıktıyı alıyoruz:
a
a
ş
ş
a
Demek ki ilk_metin adlı değişkende olup da ikinci_metin adlı değişkende olmayan öğeler bunlarmış…
Bu kodlarda anlayamayacağınız hiçbir şey yok. Ama dilerseniz biz yine de bu kodları tek tek inceleyelim.
İlk olarak değişkenlerimizi tanımladık:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
Amacımız ilk_metin’de olan, ama ikinci_metin’de olmayan öğeleri görmek.
Bunun için ilk_metin’deki öğeleri tek tek ikinci_metin’deki öğelerle
karşılaştırmamız gerekiyor. Tahmin edebileceğiniz gibi, bir metnin bütün
öğelerine tek tek bakabilmenin en iyi yolu for
döngülerini kullanmaktır. O
halde döngümüzü yazalım:
for s in ilk_metin: #ilk_metin'deki, 's' adını verdiğimiz bütün öğeler için
if not s in ikinci_metin: #eğer 's' adlı bu öğe ikinci_metin'de yoksa
print(s) #'s' adlı öğeyi ekrana bas
Gördüğünüz gibi, döngüleri (for
), bool işleçlerini (not) ve aitlik
işleçlerini (in) kullanarak, istediğimiz şeyi rahatlıkla yapabiliyoruz. Burada
kullandığımız if
deyimi, bir önceki satırda for
döngüsü ile üzerinden
geçtiğimiz öğeleri süzmemizi sağlıyor. Burada temel olarak şu üç işlemi
yapıyoruz:
ilk_metin içindeki bütün öğelerin üzerinden geçiyoruz,
Bu öğeleri belli bir ölçüte göre süzüyoruz,
Ölçüte uyan öğeleri ekrana basıyoruz.
Elbette yukarıda yaptığımız işlemin tersini yapmak da mümkündür. Biz yukarıdaki kodlarda ilk_metin’de olan, ama ikinci_metin’de olmayan öğeleri süzdük. Eğer istersek ikinci_metin’de olan, ama ilk_metin’de olmayan öğeleri de süzebiliriz. Mantığımız yine aynı:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
for s in ikinci_metin: #ikinci_metin'deki, 's' adını verdiğimiz bütün öğeler için
if not s in ilk_metin: #eğer 's' adlı bu öğe ilk_metin'de yoksa
print(s) #'s' adlı öğeyi ekrana bas
Bu da bize şu çıktıyı veriyor:
u
ı
o
r
y
e
u
ı
r
u
e
e
e
u
Gördüğünüz gibi, yaptığımız tek şey, ilk_metin ile ikinci_metin’in yerlerini değiştirmek oldu. Kullandığımız mantık ise değişmedi.
Bu arada, yukarıdaki çıktıda bizi rahatsız eden bir durum var. Çıktıda bazı harfler birbirini tekrar ediyor. Aslında temel olarak sadece şu harfler var:
u
ı
o
r
y
e
Ama metin içinde bazı harfler birden fazla sayıda geçtiği için, doğal olarak çıktıda da bu harfler birden fazla sayıda görünüyor. Ama tabii ki, eğer biz istersek farklı olan her harften yalnızca bir tanesini çıktıda görmeyi de tercih edebiliriz. Bunun için şöyle bir kod yazabiliriz:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
fark = ""
for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)
Burada da anlayamayacağımız hiçbir şey yok. Bu kodlardaki bütün parçaları tanıyoruz. Her zamanki gibi öncelikle değişkenlerimizi tanımladık:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
Daha sonra fark adlı boş bir karakter dizisi tanımlıyoruz. Metinler içindeki farklı karakter dizilerini fark adlı bu karakter dizisi içinde depolayacağız.
Ardından da for
döngümüzü yazıyoruz:
for s in ikinci_metin: # ikinci_metin'de 's' dediğimiz bütün öğeler için
if not s in ilk_metin: # eğer 's' ilk_metin'de yoksa
if not s in fark: # eğer 's' fark'ta da yoksa
fark += s # bu öğeyi fark değişkenine ekle
print(fark) # fark değişkenini ekrana bas
Uyguladığımız mantığın ne kadar basit olduğunu görüyorsunuz. Bu kodlarda basitçe şu işlemleri yapıyoruz:
ikinci_metin değişkeni içindeki bütün öğelerin üzerinden tek tek geç,
Eğer bu değişkendeki herhangi bir öğe ilk_metin’de ve fark’ta yoksa o öğeyi fark’a ekle.
Son olarak da fark’ı ekrana bas.
Bu kodlarda dikkatimizi çeken ve üzerinde durmamız gereken bazı noktalar var. Burada özellikle fark değişkenine öğe ekleme işlemini nasıl yaptığımıza dikkat edin.
Python programlama dilinde önceden oluşturduğumuz bir karakter dizisini başka bir karakter dizisi ile birleştirdiğimizde bu işlem ilk oluşturduğumuz karakter dizisini etkilemez. Yani:
>>> a = 'istihza'
>>> a + '.com'
'istihza.com'
Burada sanki a adlı özgün karakter dizisini değiştirmişiz ve ‘istihza.com’ değerini elde etmişiz gibi görünüyor. Ama aslında a’nın durumunda hiçbir değişiklik yok:
>>> a
'istihza'
Gördüğünüz gibi, a değişkeninin değeri hâlâ ‘istihza’. Bu durumun nedeni, birleştirme işlemlerinin bir değiştirme işlemi olmamasıdır. Yani mesela iki karakter dizisini birleştirdiğinizde birleşen karakter dizileri üzerinde herhangi bir değişiklik olmaz. Bu durumda yapabileceğimiz tek şey, karakter dizisine eklemek istediğimiz öğeyi de içeren yeni bir karakter dizisi oluşturmaktır. Yani:
>>> a = 'istihza'
>>> a = a + '.com'
>>> print(a)
istihza.com
Burada sanki değeri ‘istihza’ olan a adlı bir değişkene ‘.com’ değerini eklemişiz gibi görünüyor, ama aslında biz burada a değişkenini yok edip, ‘istihza.com’ değerini içeren, a adlı başka bir değişken tanımladık. Bu durumu nasıl teyit edeceğinizi biliyorsunuz:
>>> a = 'istihza'
>>> id(a)
15063200
>>> a = a + '.com'
>>> id(a)
15067960
Burada id()
fonksiyonunu kullanarak karakter dizilerinin kimliklerini
sorguladık. Gördüğünüz gibi, isimleri aynı da olsa, aslında ortada iki farklı
a değişkeni var. Kimlik numaralarının farklı olmasından anladığımıza göre, ilk
başta tanımladığımız a değişkeni ile a = a + '.com'
satırıyla
oluşturduğumuz a değişkeni birbirinden farklı.
Bu arada, eğer istersek yukarıdaki değer atama işlemini, önceki bölümlerde öğrendiğimiz değer atama işleçleri yardımıyla kısaltabileceğimizi de biliyorsunuz:
>>> a += '.com'
İşte ilk_metin ile ikinci_metin değişkenleri arasındaki farklı harfleri yalnızca birer kez yazdırmak için kullandığımız kodlarda da yukarıdaki işlemi yaptık:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
fark = ''
for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)
Gördüğünüz gibi, önce boş bir fark değişkeni oluşturduk. Daha sonra bu
değişkene for
döngüsü içinde yeni değerler atayabilmek (daha doğrusu
atarmış gibi yapmak) için fark += s
gibi bir kod kullandık. Böylece for
döngüsünün her dönüşünde s adını verdiğimiz her bir öğeyi tek tek fark
değişkenine yolladık. Böylece program sonunda elimizde, farklı öğeleri yalnızca
birer kez içeren fark adlı bir değişken olmuş oldu. Dediğimiz gibi, ilk başta
tanımladığımız boş fark değişkeni ile, program sonunda farklı değerleri içeren
fark değişkeni aslında aynı değil. Yani biz ilk fark değişkenine döngünün
her dönüşünde yeni bir öğe eklemek yerine, döngünün her dönüşünde yeni bir
fark değişkeni oluşturmuş oluyoruz. Ama programın sonunda sanki fark
değişkenine her defasında yeni bir değer atamışız gibi görünüyor ve bu da bizim
işimizi görmemize yetiyor…
Programın başındaki ve sonundaki fark değişkenlerinin aslında birbirinden farklı olduğunu teyit etmek için şu kodları kullanabilirsiniz:
ilk_metin = "asdasfddgdhfjfdgdşfkgjdfklgşjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsuıdoryeuıfsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"
fark = ""
print("fark'ın ilk tanımlandığı 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))
Gördüğünüz gibi, gerçekten de ortada iki farklı fark değişkeni var. Bu durumu
id()
fonksiyonu yardımıyla doğrulayabiliyoruz.
Peki bu bilginin bize ne faydası var?
Şimdilik şu kadarını söyleyelim: Eğer o anda muhatap olduğunuz bir veri tipinin mizacını, huyunu-suyunu bilmezseniz yazdığınız programlarda çok kötü sürprizlerle karşılaşabilirsiniz. Birkaç bölüm sonra başka veri tiplerini de öğrendikten sonra bu durumu daha ayrıntılı bir şekilde inceleyeceğiz.
Bu arada, tahmin edebileceğiniz gibi yukarıdaki for
döngüsünü şöyle de
yazabilirdik:
for s in ikinci_metin:
if not s in ilk_metin and not s in fark:
fark += s
Burada iki farklı if
deyimini iki farklı satırda yazmak yerine, bu deyimleri
and işleci ile birbirine bağladık.
Bu örnek ile ilgili söyleyeceklerimiz şimdilik bu kadar. Gelin biz şimdi isterseniz bilgilerimizi pekiştirmek için başka bir örnek daha yapalım.
Dosyaların İçeriğini Karşılaştırma¶
Bir önceki örnekte karakter dizilerinin içeriğini nasıl karşılaştırabileceğimizi gösteren bir örnek vermiştik. Şimdi de, gerçek hayatta karşınıza çıkması daha olası bir durum olması bakımından, dosyaların içeriğini nasıl karşılaştıracağımıza dair bir örnek verelim.
Esasında karakter dizilerinin içeriğini birbirleriyle nasıl karşılaştırıyorsak, dosyaların içeriğini de benzer şekilde karşılaştırabiliriz. Mesela içeriği şu olan isimler1.txt adlı bir dosyamız olduğunu varsayalım:
Ahmet
Mehmet
Sevgi
Sinan
Deniz
Ege
Efe
Ferhat
Fırat
Zeynep
Hazan
Mahmut
Celal
Cemal
Özhan
Özkan
Yine içeriği şu olan bir de isimler2.txt adlı başka bir dosya daha olduğunu düşünelim:
Gürsel
Mehmet
Sevgi
Sami
Deniz
Ege
Efe
Ferhat
Fırat
Tülay
Derya
Hazan
Mahmut
Tezcan
Cemal
Özhan
Özkan
Özcan
Dilek
Amacımız bu iki dosyanın içeriğini karşılaştırıp, farklı öğeleri ortaya sermek. Dediğimiz gibi, bir önceki örnekte izlediğimiz yolu burada da takip edebiliriz. Dikkatlice bakın:
d1 = open("isimler1.txt") # dosyayı açıyoruz
d1_satırlar = d1.readlines() # satırları okuyoruz
d2 = open("isimler2.txt")
d2_satırlar = d2.readlines()
for i in d2_satırlar:
if not i in d1_satırlar:
print(i)
d1.close()
d2.close()
Gerçekten de mantığın bir önceki örnekle tamamen aynı olduğunu görüyorsunuz. Biz
henüz Python’da dosyaların nasıl işleneceğini öğrenmedik, ama daha önce
gördüğümüz open()
fonksiyonu yardımıyla en azından dosyaları açabilecek
kadar biliyoruz dosya işlemlerinin nasıl yürütüleceğini…
Burada farklı olarak readlines()
adlı bir metot görüyoruz. Biz burada bu
metodun ayrıntılarına inmeyeceğiz, ama şimdilik dosya içeriğinin satırlar
halinde okunmasını sağladığını bilelim yeter.
Bu arada, eğer çıktıda Türkçe karakterleri düzgün görüntüleyemiyorsanız
open()
fonksiyonunun encoding adlı bir parametresi vasıtasıyla içeriği
UTF-8 olarak kodlayabilirsiniz:
d1 = open("isimler1.txt", encoding="utf-8") # dosyayı açıyoruz
d1_satırlar = d1.readlines() # satırları okuyoruz
d2 = open("isimler2.txt", encoding="utf-8")
d2_satırlar = d2.readlines()
for i in d2_satırlar:
if not i in d1_satırlar:
print(i)
d1.close()
d2.close()
Bu şekilde Türkçe karakterleri düzgün bir şekilde görüntüleyebiliyor olmanız lazım. Eğer Windows’ta Türkçe karakterleri hala düzgün görüntüleyemiyorsanız encoding parametresinde ‘utf-8’ yerine ‘cp1254’ adlı dil kodlamasını kullanmayı deneyebilirsiniz:
encoding = "cp1254"
Yukarıdaki örneklerde bir içerik karşılaştırması yapıp, farklı öğeleri ayıkladık. Aynı şekilde benzer öğeleri ayıklamak da mümkündür. Bu işlemin nasıl yapılacağını az çok tahmin ettiğinizi zannediyorum:
d1 = open("isimler1.txt")
d1_satırlar = d1.readlines()
d2 = open("isimler1.txt")
d2_satırlar = d2.readlines()
for i in d2_satırlar:
if i in d1_satırlar:
print(i)
d1.close()
d2.close()
Burada bir öncekinden farklı olarak if not i in d1_satırlar
kodu yerine,
doğal olarak, if i in d1_satırlar
kodunu kullandığımıza dikkat edin.
Dosyalar üzerinde yaptığımız işlemleri tamamladıktan sonra close()
metodu
ile bunları kapatmayı unutmuyoruz:
d1.close()
d2.close()
Karakter Dizisindeki Karakterleri Sayma¶
Yukarıdaki örneklerde içerik karşılaştırmaya ilişkin birkaç örnek verdik. Şimdi yine bilgilerimizi pekiştirmek için başka bir konuya ilişkin örnekler verelim.
Mesela elimizde şöyle bir metin olduğunu varsayalım:
Bu programlama dili Guido Van Rossum adlı Hollandalı bir programcı
tarafından 90’lı yılların başında geliştirilmeye başlanmıştır. Çoğu insan,
isminin Python olmasına aldanarak, bu programlama dilinin, adını piton
yılanından aldığını düşünür. Ancak zannedildiğinin aksine bu programlama
dilinin adı piton yılanından gelmez. Guido Van Rossum bu programlama dilini,
The Monty Python adlı bir İngiliz komedi grubunun, Monty Python’s Flying
Circus adlı gösterisinden esinlenerek adlandırmıştır. Ancak her ne kadar
gerçek böyle olsa da, Python programlama dilinin pek çok yerde bir yılan
figürü ile temsil edilmesi neredeyse bir gelenek halini almıştır.
Yapmamız gereken bir istatistik çalışması gereğince bu metinde her harfin kaç kez geçtiğini hesaplamanız gerekiyor.
Bunun için şöyle bir program yazabiliriz:
metin = """Bu programlama dili Guido Van Rossum adlı Hollandalı bir programcı
tarafından 90’lı yılların başında geliştirilmeye başlanmıştır. Çoğu insan,
isminin Python olmasına aldanarak, bu programlama dilinin, adını piton
yılanından aldığını düşünür. Ancak zannedildiğinin aksine bu programlama dilinin
adı piton yılanından gelmez. Guido Van Rossum bu programlama dilini, The Monty
Python adlı bir İngiliz komedi grubunun, Monty Python’s Flying Circus adlı
gösterisinden esinlenerek adlandırmıştır. Ancak her ne kadar gerçek böyle olsa
da, Python programlama dilinin pek çok yerde bir yılan figürü ile temsil
edilmesi neredeyse bir gelenek halini almıştır."""
harf = input("Sorgulamak istediğiniz harf: ")
sayı = ''
for s in metin:
if harf == s:
sayı += harf
print(len(sayı))
Burada öncelikle metnimizi bir değişken olarak tanımladık. Ardından da kullanıcıya hangi harfi sorgulamak istediğini sorduk.
Bu kodlarda tanımladığımız sayı adlı değişken, sorgulanan harfi, metinde geçtiği sayıda içinde barındıracaktır. Yani mesela metin 5 tane a harfi varsa sayı değişkeninin değeri aaaaa olacaktır.
Sonraki satırlarda for
döngümüzü tanımlıyoruz:
for s in metin: # metin içinde 's' adını verdiğimiz her bir öğe için
if harf == s: # eğer kullanıcıdan gelen harf 's' ile aynıysa
sayı +