Python etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Python etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Python ve Test Güdümlü Yazılım Geliştirme (TDD)

Python'dan bahsediyorum sürekli ya, kullanabiliyor musun derseniz o kadar aktif kullanmaya başladığımı söyleyemem. Yine de kullanmak isteyenlere yardımcı olmaya çalışıyorum bir taraftan (umarım olabiliyorumdur :) ). Bu yazıda da Python ile yazılım geliştirirken önce test yazmak sonra testlere göre kod yazmak isteyenler için ilk adımlardan söz etmek istiyorum.

(Başlamadan önce doctest ile birim test yazımı için şu adresi inceleyebilirsiniz)

Öncelikle Python'da test yazmak için kullanmanız gereken kütüphane Python ile birlikte geliyor, kütüphane unittest kütüphanesi. Oluşturacağımız test sınıflarını da unittest.TestCase sınıfını kalıtarak ("extend" ederek) yazıyoruz. Yazacağımız test_ ile başlayan metotlar da otomatik olarak çalıştırılacak test metotları olarak kabul ediliyor. setUp ve tearDown metotları da kullanamayacağınız isimlere sahip. Bu metotlar testler çalışmadan önce (setUp - kur) ayarlamayı ve testler bittikten sonra (tearDown - yık) ayarlamayı yapan metotlar. Bu metotların sadece self parametresi aldığını da belirttikten sonra ilk örneği yazalım:

import random
import unittest

class TestSequenceFunctions(unittest.TestCase):

    def setUp(self):
        self.seq = range(10)

    def test_shuffle(self):
        # make sure the shuffled sequence does not lose any elements
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, range(10))

        # should raise an exception for an immutable sequence
        self.assertRaises(TypeError, random.shuffle, (1,2,3))

    def test_choice(self):
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)

    def test_sample(self):
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)

if __name__ == '__main__':
    unittest.main()


Sınamalarımızda kullanacağımız savlar ("assertion") JUnit kullananlara tanıdık gelecektir:

assertEqual(beklenenDeger, gercekDeger) metodu parametre olarak verdiğimiz beklediğimiz değerle, üretilen gerçek değerin eşit olup olmadığını sınar. Aynı şekilde kullanılan assertNotEqual(beklenenDeger, gercekDeger) metotu eşit olmama durumunu sınar. assertTrue(deyim) ve assertFalse(deyim) metotları parametre olarak verilen deyimin mantıksal sonucunun doğru (true) veya yanlış (false) olup olmadığını sınayan metotlardır. Bir de bir sınıfın belli bir sınıfın örneği olup olmadığını sınayan assertIsInstance(nesne,sınıf) metodu vardır.

Test durumlarını barındıran dosyaları test* kelimesiyle başlayacak şekilde kaydettiğimizde (örneğin test_tenis.py gibi)  python -m unittest discover komutuyla otomatik olarak bulunabilirler. Ayrıca python -m unittest test_tenis komutuyla dosya olarak çalıştırılabilirler. Tek bir test sınıfını veya metodunu çalıştırmak için de python -m test_tenis.DosyaIsmi, python -m test_tennis.DosyaIsmi.testSkor kullanımlarından yararlanılabilir.

Örnek olarak https://github.com/giorgiosironi/python-tdd-tutorial adresindeki kodlar incelenebilir.

Bu yazı için yararlandığım kaynak biraz daha ayrıntılı olarak kullanımı anlatmaktadır: http://css.dzone.com/articles/tdd-python-5-minutes

Bağlantılar:
http://powertwenty.com/kpd/downloads/TestDrivenDevelopmentInPython.pdf
http://onlamp.com/pub/a/python/2004/12/02/tdd_pyunit.html
http://www.blog.pythonlibrary.org/2011/03/09/python-102-an-intro-to-tdd-and-unittest/
http://www.slideshare.net/Siddhi/test-driven-development-with-python
http://dirtsimple.org/2005/02/making-it-from-scratch-with-tdd-and.html
http://www.givp.org/blog/2010/07/22/test-driven-development-how-do-i-start/

Bilimsel Araştırma için Python - 10 Neden

Python'un önemli bir özelliği bir çok alanda rahatlıkla kullanılıyor olmasıdır. Python; GNU/Linux işletim sistemlerinde sistem ve betik kodlamada kullanıldığı gibi Matlab'ın yerine bilimsel araştırmalarda, deneylerde de kullanılabilen geniş bir uygulama alanı yelpazesine sahiptir.

Yeni gördüğüm bir yazıda, Python deneyimini bilimsel araştırmada 10 neden şeklinde yazıldığını görünce, bir Python "avukatı" olarak (belirteyim ki Oracle'ın Sun'ı satın alması, Google'a karşı Oracle hamleleri beni Java yerine alternatif olarak Python'u daha sık düşünmeye itiyor) yazıyı paylaşmam farz oldu. Yazıda aşağıda özetle verdiğim başlıkların ayrıntısına ulaşabilirsiniz.

1. Özgürlük: Python özgür yazılımdır. Açık kaynak koda sahiptir (özgür yazılım olmanın gereği). Windows, GNU/Linux, Mac OS vb. işletim sistemlerinde rahatça çalıştırılabilir.
2. Okunabilirlik: Python kodları yapısı gereği oldukça rahat okunabilen kodlardır. Söz dizimi tasarlanırken okunabilirlik ana amaçlardan biri olarak düşünülmüştür.
3. Belgelendirme sistemi: epydoc gibi araçlar ve doc string'ler sayesinde kodunuzu yazarken bir taraftan o kodun belgelendirmesi de yapılabilir.
4. Yüksek seviye - düşük seviye: Python'da yüksek seviyeli programlama ile düşük seviye programlama arasında bir denge kurulabilir. Farklı makine kodu üreten araçların yardımıyla neredeyse C kodu kadar hızlı çalışan Python kodu yazmak mümkün.
5. Standart kütüphane: Düzinelerce modül içeren oldukça kapsamlı standart kütüphanesi size gereken neredeyse çoğu şeyi sunmaktadır. Python'un bu konudaki felsefesi "piller dahildir" şeklindedir.
6. Bilimsel çalışma için üçüncü parti açık kaynak kütüphaneler: NumPy, SciPy (birlikte Matlab'ın çoğu işlevselliğini gerçekleştirirler), iPython (geliştirilmiş Python kabuğu - hata ayıklama, kod kesitlendirme vb. şeyleri sağlıyor), Cython - kütüphanelerle ilgili ayrıntılı bilgi için bağlantıyı ziyaret edebilirsiniz.
7. Veri yapıları: Python listeleri, tupleları, kümeleri, sözlükleri, karakter dizilerini, iş parçacığı güvenli kuyrukları, ve bir çok veri tipini destekliyor. NumPy ve SciPy'nin eklenmesiyle n-boyutlu dizi nesnesi (Matlab'ın matrislerinden daha fazla işlevselliğe sahip) desteği de kazandırılabiliyor.
8. Modül sistemi: Python kullandığı modüler programlama sayesinde kodun hiyerarşik bir yapıya kavuşmasını sağlıyor ve kodun tekrar kullanımı da artmış oluyor.
9. Proje ölçeklenebilirliği: Python hem küçük betikler hem de oldukça büyük projeler üretilmesine olanak sağlıyor. Pythonla 20 satırlık bir kod yazabileceğiniz gibi bir çok modülden oluşan ve bir çok modülü kullanan bir büyük proje de yazabilirsiniz.
10. Farklı paradigmaları destekleme: Python fonksiyonel, prosedürel, ve nesne yönelimli programlama paradigmaları arasında rahatlıkla geçiş yapmanızı sağlar.

Kaynak: http://www.stat.washington.edu/~hoytak/blog/whypython.html
Python öğrenmeye başlamak için: http://yzgrafik.ege.edu.tr/~tekrei/dersler/bbgd_p/

Python öğrenme aracı: Acire

Python öğrenmek isteyenler için karşılaştığım bir yazıdaki aracı duyurmak isterim. İngilizce bir araç, ama belki de gönüllü biri Türkçe sürümünü de yapabilir. Acire için karşıma çıkaran yazıyı ve Jono Bacon'un ilgili duyurusunu okuyabilirsiniz.

Google Python Dersi

Google tarafından programlama bilgisine sahip olup Python öğrenmek isteyenler için hazırlanmış (İngilizce) ders: http://code.google.com/edu/languages/google-python-class/

Bilgisayar Bilimcisi Gibi Düşünmek

GÜNCELLEME: Bilgisayar Bilimcisi Gibi Düşünmek: Python ile Öğrenme 3. baskı Özhan Fenerci tarafından çevriliyor.

Bilgisayar Bilimcisi Gibi Düşünmek: Python ile Öğrenme 2. baskının Türkçe çevirisini uzun bir zamandan sonra bitirdim. 3 Ekim 2008'de başlamıştım, araya
giren bir çok iş ve nedenden dolayı 9 Şubat itibariyle bitirdim. Tam bitirdim de sayılmaz aslında, önsöz, giriş, gasp, dizin bölümleri çevrilmeden duruyor. Fırsat bulunca onları da çevireceğim. Yine de yararlı olacağına inanıyorum, Türkçe bir kaynak olarak. Çevirinin PDF haline de aynı sayfadan ve bu bağlantıdan ulaşabilirsiniz.

Çeviriyle ilgili, kitapla ilgili her türlü düşüncenizi bana iletmeyi unutmayın. Yanlışlar, anlaşılmayan yerler, kötü çeviriler gibi. Bunların çevirinin iyileştirilmesi anlamında yararı olacaktır. Kitabın Python öğrenmek isteyen ve Türkçe bir kaynaktan yararlanmak isteyen herkese yararlı olmasını diliyorum.

Ek bağlantıları paylaşıyorum:
http://www.slideshare.net/tekrei/bilgisayar-bilimcisi-gibi-dnmek-python-ile-renme
https://docs.google.com/open?id=0B6Q0hgaZhD5KMTJlNGU1MTItMDgzNS00YWM3LThkZDYtZDg5NDIyY2M3Nzgy
 

Django

Django bir gitaristin adı. Ancak benim bu yazıma konu olan Python tabanlı bir web uygulama geliştirme çerçevesi ("framework"). Bir kaç aydır, özellikle Sunucu Tabanlı Yazılım Geliştirme dersine (asistanlığını yaptığım ders) yönelik olarak Django'yu inceliyordum. Hızlı web uygulaması geliştirmek için önerilen bir çerçeve olarak dikkatimi çekmişti. Ama asıl olarak Python tabanlı olması beni denemeye iten neden oldu. Çok basitçe kurulumunu yaptıktan sonra (Ubuntu'da kolay yazılım kurma :) = sudo aptitude install python-django) (diğer işletim sistemlerine kurmak için) ana sayfasındaki ilk uygulama yazma öğrencesini izleyerek ilk denememi gerçekleştirdim. Gel zaman, git zaman uğraşmaya devam ettim ve geçen hafta SYT dersinde web uygulama çerçevelerini anlattım. Denemeleri arttırmak için de bir yapılacaklar listesi (pyTodo adını verdiğim) projesi gerçekleştirdim. Özetle gerçekten hızlı ve DRY (Django Tasarım Felsefeleri) ("Don't Repeat Yourself"-Kendini Tekrar Etme) mantığına uygun olarak web uygulaması geliştirmek için güzel bir çerçeve. Meraklı herkese denemelerini öneririm.

Bu çerçeveyle nasıl yazılım geliştirilir sorusuna özet bir yanıt verecek olursam, öncelikle projeyi ve uygulamayı yaratıyorsunuz, MVC'ye uygun olarak (MVT var bunda, Model-View-Template) modelinizi tanımlıyorsunuz - models.py modülünde -, verileri işleyen ve ilgili görünümlere aktaran fonksiyonları (view) tanımlıyorsunuz - views.py modülünde -, şablonları tanımlayıp kullanıyorsunuz, url tanımlamalarını düzenli ifadeler yardımıyla tanımlıyorsunuz. Özetle budur. Meraklılarına Türkçe kaynaklar için google araması öneriyorum. Ayrıca İngilizce olan The Django Book başlangıç için yararlı olacaktır.

Reddit neden Python kullanıyor

Bir günlük yazısında gördüğüm bir konuyu paylaşmak istiyorum. PyCon'da Reddit sunumu esnasında Reddit'in neden Lisp'ten Python'a geçiş yaptığına dair bir soru gelmiş. Geçiş amacı çok ilginç olmamakla beraber, reddit geliştiricileri Python'da kalmaları için iki önemli gerekçe sunmuşlar:
  1. Çok sayıda kütüphane barındırması: "Geliştirme esnasında bir çok yeni teknoloji ve mimari öğreniliyor. Örneğin bağlantı havuzlarını anlamadığımız zaman anlayana kadar var olan bir geliştirme havuzu kütüphanesi kullanıyoruz, iyice anlayıp kendi bağlantı havuzumuzu geliştirene kadar kullanmaya devam ediyoruz. Kendi web frameworkümüzü yazana kadar başkasınınkini kullanıyoruz".
  2. Python okunabilirliği ve yazılabilirliği: "Yeni çalışanlar aldığımızda sadece 'yazdığınız herşey Python'da olmalıdır" diyoruz sadece. Böylece sadece okuyabiliyoruz. Odanın diğer köşesinden ekrana bakarak yazdıkları kodun iyi veya kötü olduğunu anlayabiliyoruz, bu muhteşem bir şey. Çünkü iyi Python kodu çok bariz bir yapıya sahip. Bu yaşamımızı kolaylaştıran bir özellik. Python ifade etmesi kolay, okuması kolay, yazması kolay bir dil."
Kaynak: http://brainsik.theory.org/.:./2009/why-reddit-uses-python
(Hızlı bir çeviri yaptım, dileyen İngilizce aslında okuyabilir)

Python bağlantıları

Paylaşmadan duramayacağım bir kaç Python bağlantısı:

MIT OpenCourseWare kapsamındaki A Gentle Introduction to Programming Using Python dersi

(Elektrik mühendisliği ve bilgisayar bilimleri derslerinin hepsine şu adresten ulaşabilirsiniz)

Üç adet python video ders bağlantısı içeren yazı

10 adet ücretsiz python kitabı bağlantısı içeren yazı

The A-Z of programming languages: Python

Neden Python?

Bana sıcak ve kolay geliyordan daha iyi bir cevabım yok :) Artık çoğu ufak programlama işlerimi Python ile yapmaya çalışıyorum. Ubuntu ve Debian içerisinde rahatlıkla çalıştırabildiğim için sorun da yaşamıyorum, yeni bir programlama dili de öğrenmiş oluyorum. Uzman olduğum programlama dilinin Java olduğunu düşünürsek Python ile çalışmak bir bakıma zihin jimnastiği de olmuş oluyor sanırım. Tabi asıl öğrenmek istediğim dil Lisp ne yalan söyleyeyim :S

Python ile yazılmış basit bir Genetik Algoritma örneği

Python kullanılarak yazılmış olan oldukça basit bir genetik algoritma örneği.

Aşağıya da alıyorum:

## {{{ http://code.activestate.com/recipes/199121/ (r1)
#
# genetic.py
#

import random

MAXIMIZE, MINIMIZE = 11, 22

class Individual(object):
    alleles = (0,1)
    length = 30
    seperator = ''
    optimization = MINIMIZE

    def __init__(self, chromosome=None):
        self.chromosome = chromosome or self._makechromosome()
        self.score = None  # set during evaluation
    
    def _makechromosome(self):
        "makes a chromosome from randomly selected alleles."
        return [random.choice(self.alleles) for gene in range(self.length)]

    def evaluate(self, optimum=None):
        "this method MUST be overridden to evaluate individual fitness score."
        pass
    
    def crossover(self, other):
        "override this method to use your preferred crossover method."
        return self._twopoint(other)
    
    def mutate(self, gene):
        "override this method to use your preferred mutation method."
        self._pick(gene) 
    
    # sample mutation method
    def _pick(self, gene):
        "chooses a random allele to replace this gene's allele."
        self.chromosome[gene] = random.choice(self.alleles)
    
    # sample crossover method
    def _twopoint(self, other):
        "creates offspring via two-point crossover between mates."
        left, right = self._pickpivots()
        def mate(p0, p1):
            chromosome = p0.chromosome[:]
            chromosome[left:right] = p1.chromosome[left:right]
            child = p0.__class__(chromosome)
            child._repair(p0, p1)
            return child
        return mate(self, other), mate(other, self)

    # some crossover helpers ...
    def _repair(self, parent1, parent2):
        "override this method, if necessary, to fix duplicated genes."
        pass

    def _pickpivots(self):
        left = random.randrange(1, self.length-2)
        right = random.randrange(left, self.length-1)
        return left, right

    #
    # other methods
    #

    def __repr__(self):
        "returns string representation of self"
        return '<%s chromosome="%s" score=%s>' % \
               (self.__class__.__name__,
                self.seperator.join(map(str,self.chromosome)), self.score)

    def __cmp__(self, other):
        if self.optimization == MINIMIZE:
            return cmp(self.score, other.score)
        else: # MAXIMIZE
            return cmp(other.score, self.score)
    
    def copy(self):
        twin = self.__class__(self.chromosome[:])
        twin.score = self.score
        return twin


class Environment(object):
    def __init__(self, kind, population=None, size=100, maxgenerations=100, 
                 crossover_rate=0.90, mutation_rate=0.01, optimum=None):
        self.kind = kind
        self.size = size
        self.optimum = optimum
        self.population = population or self._makepopulation()
        for individual in self.population:
            individual.evaluate(self.optimum)
        self.crossover_rate = crossover_rate
        self.mutation_rate = mutation_rate
        self.maxgenerations = maxgenerations
        self.generation = 0
        self.report()

    def _makepopulation(self):
        return [self.kind() for individual in range(self.size)]
    
    def run(self):
        while not self._goal():
            self.step()
    
    def _goal(self):
        return self.generation > self.maxgenerations or \
               self.best.score == self.optimum
    
    def step(self):
        self.population.sort()
        self._crossover()
        self.generation += 1
        self.report()
    
    def _crossover(self):
        next_population = [self.best.copy()]
        while len(next_population) < self.size:
            mate1 = self._select()
            if random.random() < self.crossover_rate:
                mate2 = self._select()
                offspring = mate1.crossover(mate2)
            else:
                offspring = [mate1.copy()]
            for individual in offspring:
                self._mutate(individual)
                individual.evaluate(self.optimum)
                next_population.append(individual)
        self.population = next_population[:self.size]

    def _select(self):
        "override this to use your preferred selection method"
        return self._tournament()
    
    def _mutate(self, individual):
        for gene in range(individual.length):
            if random.random() < self.mutation_rate:
                individual.mutate(gene)

    #
    # sample selection method
    #
    def _tournament(self, size=8, choosebest=0.90):
        competitors = [random.choice(self.population) for i in range(size)]
        competitors.sort()
        if random.random() < choosebest:
            return competitors[0]
        else:
            return random.choice(competitors[1:])
    
    def best():
        doc = "individual with best fitness score in population."
        def fget(self):
            return self.population[0]
        return locals()
    best = property(**best())

    def report(self):
        print "="*70
        print "generation: ", self.generation
        print "best:       ", self.best
---------------------------------------------------------------------
#
# onemax.py - useage example
#
# the fittest individual will have a chromosome consisting of 30 '1's
#

import genetic

class OneMax(genetic.Individual):
    optimization = genetic.MAXIMIZE 
    def evaluate(self, optimum=None):
        self.score = sum(self.chromosome)
    def mutate(self, gene):
        self.chromosome[gene] = not self.chromosome[gene] # bit flip
   
if __name__ == "__main__":
    env = genetic.Environment(OneMax, maxgenerations=1000, optimum=30)
    env.run()
## end of http://code.activestate.com/recipes/199121/ }}}

Python Sınıf Örneği

Python'da yeni bir şeyler öğrenmek için sınıfların nasıl oluşturulduğuna dair örnek yaptım. Bir metin dosyasında bulunan sahaları tab karakteriyle ayrılmış olan öğrenci bilgilerini (her satırda bir öğrenci bilgisi olacak şekilde) okuyup Ogrenci sınıfı şeklinde örnekler oluşturan ve bu örnekleri ekrana basan bir proje yaptım.

Aşağıda bu proje için yazmış olduğum sınıfları açıklamalarıyla inceleyebilirsiniz. Java'da yazabileceğimden daha az kod yazdığım bir gerçek. Metin hallerini en alttaki bağlantıdan indirebilirsiniz.

Metin Dosyası Yapısı (ogrenciler.txt)(sahalar \t - tab - karakteriyle ayrılmıştır)

1    Ali Veli Kirkdokuzelli    4    1998
2    Suphi Suphan    3    1999
3    Mustafa Canveren    2    2000
4    Ahmet Bitiveren    1    2001

Ogrenci sınıfı (Ogrenci.py):

#Ogrenci bilgilerini tuttugumuz sinif
class Ogrenci:
    #Yeni ogrenci yaratmak icin ilgili bilgilerini girmek gerekiyor
    #__init__ bu sinifin yapicisi oluyor
    def __init__(self, numara,isim,sinif,girisYili):
        #Basina __ ekleyince private degisken oluyor
        self.__isim = isim
        self.__numara = numara
        self.__sinif = sinif
        self.__girisYili = girisYili

    #Ogrenci bilgileri metin olarak donduren metod
    def toString(self):
        return self.__numara+' '+self.__isim+' '+self.__sinif+' '+self.__girisYili

OgrenciAraclar sınıfı (OgrenciAraclar.py):

from Ogrenci import *
#Bu metodun amaci parametre olarak adi verilen dosyayi acmak
#ve icerisindeki ogrenci bilgilerini bir dizi veri yapisina aktarmaktir
class OgrenciAraclar:
    def ogrencileriOku(self,dosyaAdi):
        #Dosyayi okumak icin aciyoruz
        f=open(dosyaAdi,'r')
        #Dosyadaki tum satirlari okuyoruz
        satirlar =f.readlines()
        #Ogrenci listesini yaratiyoruz
        ogrenciler = []
        #Dosyadan okudugumuz her satir icin
        for ogrenciBilgisi in satirlar:
            #Satirdaki ogrenci bilgisinden ogrenci nesnesini olusturup
            #listemize ekliyoruz
            ogrenciler.append(self.__ogrenciUret(ogrenciBilgisi))
        #ogrenci listemizi donduruyoruz
        return ogrenciler

    #Bu metodun amaci string olarak verilen ogrenci bilgisinden
    #Ogrenci sinifi ornegini olusturup dondurmektir
    def __ogrenciUret(self,ogrenciBilgisi):
        #String icerisindeki satir sonu karakterini yokediyoruz ve bosluklari kaldiriyoruz
        ogrenciBilgisi = ogrenciBilgisi.replace('\n',' ').strip()
        #Ogrenci bilgisi stringini saha parcalarina ayiriyoruz
        tokenler = ogrenciBilgisi.split('\t')
        #yeni ogrenci nesnesini tokenlerden olusturup donduruyoruz
        return Ogrenci(tokenler[0],tokenler[1],tokenler[2],tokenler[3])

AnaProgram sınıfı (AnaProgram.py):

#OgrenciAraclar icerisindeki tum siniflari kullanacagiz
from OgrenciAraclar import *
#Yukaridaki metodu cagirip deniyoruz
ogrenciAraclar = OgrenciAraclar()
ogrenciler = ogrenciAraclar.ogrencileriOku('ogrenciler.txt');
#Okunan ogrenci bilgilerini ekrana yaziyoruz
for ogrenci in ogrenciler:
    print ogrenci.toString()


Bu kaynak kodları sınıf ismini kullanarak ilgili *.py dosyasına yazın (yazılmışını alttaki bağlantıdan indirebilirsiniz), öğrenci bilgilerini ogrenciler.txt dosyasına yazın ve tüm dosyaları aynı dizinde toplayın. python AnaProgram.py komutunu komut satırında girerek projeyi çalıştırabilirsiniz.

Kaynak kodlar için tıklayabilirsiniz.

Not: Biçimlendirme için http://formatmysourcecode.blogspot.com/ kullanıldı.

PyDev Nedir

Python öğrenmeye başladığım zaman ilk aradığım alışkın olduğum Eclipse ortamını Python için kullanabileceğim bir eklenti aramak olmuştu. Ve kısa zamanda PyDev adı verilen Eclipse ortamına Python IDE özelliği sağlayan eklentiyi bulmuştum. O zamandan beri olanaklar elverdiği sürece PyDev ortamını Python kodları yazmak için kullanıyorum. Bu sayede Eclipse sayesinde Python kodlarım için güzel bir IDE'ye sahip olmuş oldum. Yeni bir IDE öğrenmek zorunda da kalmadım.

Bu kadar gevezelikten sonra bu eklentiyi nasıl kuracağınızdan bahsedeyim.

  • İlk olarak standart aşamalar olan JRE kurulumu ve Eclipse kurulumu gibi aşamaları yaptığınızı varsayıyorum.
  • Daha sonra kullanacağınız Python'u kurmanız gerekiyor. Bunu Ubuntu'da sudo apt-get install python komutuyla (veya synaptic paket yöneticisinden python arayıp python paketini kurarak) kolayca yapabilirsiniz. Elbette eğer özel bir python sürümünü kullanmak istiyorsanız ilgili paketi kurmanız gerekmektedir (mesela sudo apt-get install python2.4
    gibi).
  • Python kurulumunu denemek için komut satırına (windows alışkanlığı, buna terminal diyelim) python yazıp çalıştırdığınızda python yorumlayıcısı açılacaktır. Bu yorumlayıcıda print "Merhaba" yazıp çalıştırarak ekranda Merhaba yazısını görebilirsiniz. Eğer herhangi bir yorumlayıcı açılmıyorsa kurulum tamamlanmamış demektir.
  • Eğer Windows kullanıyorsanız şu adresten ilgili çalıştırılabilir dosyayı indirip çalıştırdığınızda ve aşamaları takip ettiğinizde python kurulmuş olacaktır.
  • Python kurduktan sonra şu adresteki resimleri takip ederek PyDev kurulumunu gerçekleştirebilirsiniz. Aynı adresten sonraki sayfalarda PyDev'i ayarlama aşamalarını uygulayabilirsiniz. (Bu verdiğim adresteki öğrence İngilizce olmasına rağmen başlangıç için oldukça faydalıdır.)
Tüm kurulumlar bittikten sonra Eclipse içerisinden Python geliştirme işine başlayabilirsiniz.

Bağlantılar:
PyDev Getting Started
PyDev Ana Sayfa
Python Ana Sayfa
Using the Ruby Development Tools plug-in for Eclipse
(Eclipse için Ruby IDE eklentisinin kullanımı hakkında bir yazı)

Python ve OpenGL

Şimdiye kadar bir kaç kere OpenGL kullanımını gösterdim (En aşağıdaki listeyi inceleyebilirsiniz). Şimdi Python içerisinde OpenGL kullanımını anlatacağım. Öncelikli olarak ben Linux kullandığım için kullanmam oldukça kolay oldu. Python için OpenGL paketini (sudo apt-get install python-opengl) kurmam yetti. Bunu windowsta nasıl yapabilirsiniz hiç bilmiyorum. Eclipse için PyDev eklentisini kullandığım için geliştirme de o kadar zor olmadı. Önceki yazılarımda yapmış olduğum basit üçgen çizdirmeyi bu yazı için de yaptım. Ve aşağıdaki kod oluştu. Aşağıdaki kodu çalıştırdığınız zaman sorunsuz bir şekilde aşağıdaki pencere açılıyorsa başardınız. Şimdi OpenGL konusunda derin araştırmalar yapmaya başlayabilirsiniz.


Kaynak Kod:
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import math
import sys

# Some api in the chain is translating the keystrokes to this octal string
# so instead of saying: ESCAPE = 27, we use the following.
ESCAPE = '\033'

# Genel OpenGL baslangic ayarlama metodu, baslangicta
# yapilmasi gereken tum isler yapiliyor
# Bu metod pencere yaratildiktan hemen sonra cagrilir
def InitGL(Width, Height):
#Arka plan rengini temizliyoruz (siyah oluyor)
glClearColor(0.0, 0.0, 0.0, 0.0)
#Gorunen alani ayarlayacagimiz icin projection
#moduna geciyoruz
glMatrixMode(GL_PROJECTION)
#matrisi resetleyelim
glLoadIdentity()
#2B ortogonal gorunur alani ayarlayalim
gluOrtho2D(-1,1,-1,1)
#Cizim yapacagimiz icin model moduna gecelim
glMatrixMode(GL_MODELVIEW)
#birim matrisi yukleyelim
glLoadIdentity()

# Bu metod pencere boyutunu degistirdigimizde cagriliyor
# eger tam ekran calisiyorsak cagrilmaz :)
def ReSizeGLScene(Width, Height):
#Goruntu penceresini yeni boyuta gore ayarliyoruz
glViewport(0, 0, Width, Height)

# Cizimlerin yapildigi metod
def DrawGLScene():
#Arka plan rengini gri yapiyoruz
glClearColor(0.5,0.5,0.5,1)
#Ekrani temizleyelim
glClear(GL_COLOR_BUFFER_BIT)
#Cizecegimiz sekil yesil olacak
glColor3f(0,1,0)
#ucgen cizecegimiz icin gerekli hesaplamalari yapiyoruz
hypotenus = 0.5/(math.sin(math.radians(60)))
adjacent = 0.5/(math.tan(math.radians(60)))
#3 kenarli poligon cizecegiz
glBegin(GL_POLYGON)
# Ucgeni cizmeye baslayalim
#ust kose
glVertex2f(0,hypotenus)
#sol alt kose
glVertex2f(-0.5,-adjacent)
#sag alt kose
glVertex2f(0.5,-adjacent)
glEnd()
# goruntu ekrana gelsin
#bunu iyice anlamak icin double buffering konusu ogrenilmeli
glutSwapBuffers()

# Bu metod her tusa basildiginda cagirilacaktir
# Asagida bu ayarlamayi yaptik
# Unutulmamasi gereken basilan tusun python tuple olarak
# gecirildigidir ( (key, x, y) seklinde)
def keyPressed(*args):
# Escape tusuna basilinca cikiyoruz
if args[0] == ESCAPE:
sys.exit()

def main():
global window
glutInit(sys.argv)
#Goruntuleme modunu seciyoruz
#double buffering ve alpha destegi olan RGB modu seciliyor
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE )
# pencerenin boyutunu 640 x 480 olarak ayarliyoruz
glutInitWindowSize(640, 480)
# pencere konumunu sol ust kose olarak ayarliyoruz
glutInitWindowPosition(0, 0)
# pencereyi yaratalim
glutCreateWindow("Merhaba Dünya")
# Cizim metodunu ayarliyoruz
glutDisplayFunc(DrawGLScene)
# Tam ekran olmasi icin asagidaki kisim kullanilabilir
# glutFullScreen()
# Yapilacak bir sey yokken ekrani yenileyelim
glutIdleFunc(DrawGLScene)
# Pencerenin yeniden boyutlandirilmasinda asagidaki metod kullanilacak
glutReshapeFunc(ReSizeGLScene)
# Klavyeye basildiginda calisacak olan metod
glutKeyboardFunc(keyPressed)
# Pencereyi ilklemesini tamamliyoruz
InitGL(640, 480)
# Ana dongumuz baslasin
glutMainLoop()

# Mesajimizi ekrana yazalim ve programi baslatalim
print "Çıkmak için ESC tuşunu kullanabilirsiniz."
main()
Ubuntu, Anjuta ve OpenGL
JOGL ne ola ki?
Dev C++ ve Glut
Daha güzel bir örnek incelemek isterseniz

Basit Bir Python Örneği

Bir dizin içerisinde düzenli olarak isimlendirdiğim pdf dosyaları vardı ve ben bu pdf dosyaları arasında kaybolmamak için bir listesini oluşturmaya karar verdim. Başlangıç olarak özyinelemeli olarak dizinleri dolaşıp içerisindeki dosya isimlerini ekrana yazacak basit bir python kodu yazayım dedim. Bu kodu şimdi burada paylaşacağım. Bir sonraki aşaması (zaman bulabilirsem) bu kodun çıktı olarak ya bir xml dosyası ya da bir html dosyası oluşturmasını sağlamak olacaktır diye düşünüyorum (bu günlükte verdiğim sözlerin haddi hesabı yok :) ). Kod içerisindeki yorumların yeterince açıklayıcı olduğunu düşündüğüm için daha fazla gevezelik yapmayacağım. Acemi bir python geliştiricisi olduğumu kabul edip yanlışlarımı, önerilerinizi sakınmadan söyleyebilirsiniz.

import os.path
import sys

class DizinBilgisi:

  #Sinif yapicisi
  def __init__(self):
      #Ekrana yazarken kullanacagimiz sayaci ilkleyelim
      #Basina iki tane alt cizgi koydugumuz degiskenler
      #private degisken oluyormus :?
      self.__sayac = 0;
      #alt dizinleri dolasma varsayilan olarak kapali
      #sadece istenen dizin icerisindeki dosyalari listelesin
      self.__recursive = False;

  #Bu metod icerisindeki dosyalari listeleyecegimiz dizini
  #ayarlamak icin kullaniliyor
  def setDizin(self,_dizin):
      #dolasilacak olan dizin
      #bu saha da private
      self.__dizin=_dizin;

  #alt dizinlerin dolasilip dolasilmayacagini ayarlayan
  #metod
  def setRecursive(self,_recursive):
      self.__recursive=_recursive;

  #ekrana yazma islemini baslatmak icin kullanilan
  #metod
  def ekranaYaz(self,_dizin="",_recursive=""):
      if(_dizin!=""):
          self.__dizin=_dizin
      if(_recursive!=""):
          self.__recursive=_recursive
      #Bu metodun amaci dizinin icerdigi dosyalarin adlarini
      #ekrana yazmak      
      self.__diziniEkranaYaz(self.__dizin)

  #private tanimlanmis ve parametre olarak
  #aldigi dizin icerisindeki dosyalari
  #ekrana yazan metod
  def __diziniEkranaYaz(self,dizinIsmi):
      #Ekrana dizin adini yazalim
      print dizinIsmi
      #dizin seviyesi icin sayaci arttiralim
      self.__sayac+=1
      #dizin icerisindeki dosya listesini alalim
      dosyalar = os.listdir(dizinIsmi)
      #listeyi dolasalim
      for file in dosyalar:
          #dosya ismini uygun sekilde ayarlamaliyiz
          dosyaIsmi = dizinIsmi+"/"+file
          #eger bu dosya bir dizinse
          if os.path.exists(dosyaIsmi) & os.path.isdir(dosyaIsmi):
              #ve alt dizinleri dolasmamiz isteniyorsa
              if self.__recursive==True:
                  #alt dizinleri dolasalim
                  self.__diziniEkranaYaz(dosyaIsmi)
          #bu dosya bir dosya ise
          elif os.path.isfile(dosyaIsmi):
              #bilgisini ekrana yazalim
              self.__dosyaAdiniYaz(file)
          #houston bir problemimiz var
          else:
              print "Dizin parametresinde hata var"
      #dizin seviyesini azaltalim
      self.__sayac-=1

  #bu metodun amaci dosya ismini guzel bir
  #sekilde ekrana yazalim
  def __dosyaAdiniYaz(self,dosyaAdi):
      tabs=""
      #dizinin seviyesi kadar tab ekliyoruz
      for i in range(self.__sayac):
          tabs+="\t"
      #tablarla birlikte dosya adini ekrana yaziyoruz
      print tabs+dosyaAdi

#Programin calistirilma kodu
def main():
  #DizinBilgisi sinifinin bir ornegini yaratalim
  db = DizinBilgisi()
  #girilen arguman sayisina gore islem yapacagiz
  if len(sys.argv)==2:
      #dizin ismi girilmis demek
      db.setDizin(sys.argv[1])
  elif len(sys.argv)==3:
      #dizin ismi ve recursive olup olmadigi girilmis
      db.setDizin(sys.argv[1])
      if sys.argv[2]=='r':
          db.setRecursive(True)
  else:
      print "Arguman olarak en azindan dizin yolunu vermeniz gerekmektedir."
      print "Alt dizinlerin listelenmesi icin dizin yolundan sonra r yazmaniz yeterlidir."
      sys.exit()
  db.ekranaYaz()

if __name__ == "__main__":
  main()


Kod Biçimlendirme için : http://formatmysourcecode.blogspot.com/

----------------
Now playing: Haggard - Chapter III: Awaking The Centuries

Python Bağlantıları

Python ile ilgili yeni bağlantılar buldum;

Python ile ilgili günlük haberleri toplayan bir site : http://www.pythonlovers.com/
Guido van Rossum tarafından hazırlanan Python 3000 soru ve cevapları: http://www.artima.com/weblogs/viewpost.jsp?thread=211200
"ShowMeDo is about learning Open Source by watching it get done, the programming languages which build it, the tools that make those languages more productive and fun to use, and of course the software and applications that mark its achievements" :http://showmedo.com/

Python ve Kabuk (Shell) Programlama

Daha önce yapmış olduğum python örneğini bir kabuk programı (shell script) olarak çalıştırmak isterseniz aşağıdaki gibi yazmanız ve çalıştırma izni vermeniz daha sonra kabuk programları şeklinde çalıştırmanız işe yarayacaktır. Diyelim python'a iyice alıştınız o zaman bash yerine python scriptleri yazmak için kullanabilirsiniz. Hatta python yerine diğer kurulu dilleri de kullanabileceğinizi düşünüyorum.
#!/usr/bin/python
import commands,sys,os

def DU(girdi):
try:
#Parametre olarak verilen dizinin boyutlarini bulacagiz
#Boyut 1024 byte'in katlari seklinde
for dizin in girdi:
komut = commands.getstatusoutput("du -ks '"+dizin+"'")
#komut[0] komutun durumunu, komut[1] ciktisini sakliyor
print komut[1]
except:
print "Unexpected error:", sys.exc_info()[0]
raise
#Programi calistiralim
if(len(sys.argv)>1): DU(sys.argv)
else: DU(["/home/emre"])
sys.exit()

Yukarıdaki kodu (aşağıdaki resimdeki satırların içte olması gibi yazmalısınız python buna göre blokları (mesela for döngüsü) belirlemektedir) mesela DiskUsage adında bir dosyaya yazın (nano DiskUsage diyorsunuz açılan yere kodu yapıştırıp CTRL+X ile çıkıyorsunuz ve kaydetme sorusuna Evet (Yes'te olabilir) diyorsunuz. Dilerseniz gedit veya kwrite tarzı editörler kullanabilirsiniz.).
Daha sonra chmod +x DiskUsage komutunu çalıştırın. ./DiskUsage komutuyla yukarıda yazdığınız komut çalışacaktır. Komuta argüman verip dilediğiniz bir klasörün kullanım bilgilerini de inceleyebilirsiniz. Erişemediğiniz klasörler için sudo komutu işe yarayabilir.
Aşağıda komut satıri resmini inceleyebilirsiniz:
Elbette siz de diğer betik dilleri (mesela ruby falan) için bunu deneyebilirsiniz.
Kaynaklar:
http://www.ibiblio.org/g2swap/byteofpython/read/index.html
Dive Into Python For Loops
Linux altında pratik programlama

"Sağ tarafta Oz dizisinin 1. sezonunun 7. bölümü oynuyordu."

Python ve Mail Gönderme

Bir çalışma için bir dizinin alt dizini içerisindeki dizinlerin toplam boyutunu bulmam ve bu boyut bilgisini yöneticinin posta adresine atmam gerekti. Linux ortamında bunu hızlı bir şekilde yapabilmek için hemen Python'a sarıldım. Kolayca aşağıdaki çalışan kodu yazdım:

Yukarıdaki kodu çalıştırdığınız zaman aşağıdaki çıktıya benzer bir çıktı elde etmelisiniz:

Ve aşağıdaki gibi bir postanın size ulaşması gerekiyor:



import commands,sys,os
def RepositorySize(rep):
try:
#Parametre olarak verilen dizinin boyutlarini bulacagiz
#Boyut 1024 byte'in katlari seklinde
komut = commands.getstatusoutput("du -ks "+rep)
#komut[0] komutun durumunu, komut[1] ciktisini sakliyor
print komut[1]
#Posta gondermek icin sendmail kullanalim
mail = os.popen("/usr/sbin/sendmail -t", "w")
mail.write("To: root@localhost\n")#sistem yoneticisine
mail.write("Subject: Size summary\n")#dizin boyut bilgisi gonderilecek
mail.write("\n") # baslik bilgisi mail govdesinden ayrilsin
mail.write(komut[1])#du komutunun ciktisini gonderelim
sts = mail.close()#sendmail kapansin
#basarili degilse hatayi ekrana yazalim
if sts != 0:
print "Sendmail exit status", sts
except:
print "Unexpected error:", sys.exc_info()[0]
raise
#Programi calistiralim
if(len(sys.argv)>1): RepositorySize(sys.argv[1])
else: RepositorySize("/home/emre/*")
sys.exit()

Python mu Ruby mi?

Kafamı meşgul eden önemli bir soru bu aslında, ama nedense Python'u daha çok seviyorum :S Şurada bu konuda yorumlar yazılmış. Bakalım sanırım ben Python'u daha fazla öğrenmeye karar vereceğim. Ama nedenini sormayın, tamamen duygusal. Ruby'i hiç kullanmadığımı da belirtmeliyim :)

Önemli Not: Açıkçası bazı yorumlara güldüm :)

Bir başka not: Sanırım ubuntu kullanmam ve Blender'ın Python ile yazılmış olması nedeniyle ve daha buna benzer GNU/Linux ile alakalı nedenlerden Python'u tercih ediyor olabilirim. Dediğim gibi tamamen duygusal nedenlerden.