2009
10.18

Nesne tabanlı programlamadan sonra bir başka merak ettiğim konu ise: Konsol tabanlı bir program yaptığımda ona verdiğim komutları, hep uzun uzun yazmam gerekiyordu. Mesela bir oyun yaptınız. Konsoldaki haritanızda ileri,geri,sağ ve sola gitmesi için durmadan “ileri,geri …” yazmanız gerekiyor.

Fakat artık direk “WASD” tuşları olsun klavyedeki her tuşla programa komutlar gönderebileceksiniz. Yapmanız gereken “tty” modülünü kullanmak fakat bu modül çok ilginç ki, programı kapattıktan sonra bile sizin klavye komutlarınızı alıyor.  Bunun yerine hem Linux, hem Windows, hem de Macintosh’larda çalışacak bir yöntem ve sadece “tty” modülüyle değil de başka modülleri de kullanmalı. Çünkü tty modülü sadece Linux’da çalışıyor ve stabil değil.

Küçük bir google araması yaptığınızda karşınıza şöyle bir site geliyor. (Macintosh desteğini denemediğim için örneklere yazmayacağım ama o siteden Macintosh desteğine bakabilirsiniz.)

İlk önce tane .py dosyası oluşturun ve onun içine şunları yazın.

# -*- coding: utf-8 -*-
class _Getch(object):
    """Gets a single character from standard input.
       Does not echo to the screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()
 
    def __call__(self):
        return self.impl()
 
class _GetchUnix(object):
    def __init__(self):
        import tty, sys
 
    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch
 
class _GetchWindows(object):
    def __init__(self):
        import msvcrt
 
    def __call__(self):
        import msvcrt
        return msvcrt.getch()
 
getch = _Getch()

Bunu sonra ana programınıza “form dosyanız import *” şeklinde ekleyin. Sonra kullanırken:

from alici import *
while True:
    karakter = getch().upper()
    print "Tıklanan tuş: %s"  % karakter

şeklinde yazabilirsiniz. Burada “getch().upper()” yazarken “upper()” yazmamızdaki mantık, gelen karakterin büyük ya da küçük problemi yaşamamak için hepsini büyük yapıp öyle işlemektir.  Bu yazdığınız “.getch()” bu haliyle Linux’da ve Windows’da çalışabilir.

Ayrıca bu olay PyGame gibi başka kütüphanelerle yapılabilir fakat eğer tamamen konsol tabanlı bir programda bunu istiyorsanız tek çözüm bu.

Not: Son örnekteki döngüden kurtulamazsanız kurtarıcınız “CTRL-C” olsun.

2009
10.08

Python’u ilk duyduğum da, Python’un nesne tabanlı olduğunu üstüne basa basa söylediler ama şu ana kadar uğraştığım birçok projede olsun, yazdığım kodların çoğunda olsun, “Ben bunu nesne tabanlı olsun diye yapıyorum.” diyerek yapmadım ve nesne tabanlı programlamayı da kullanmanın ne kadar büyük bir kolaylık getirdiğinin de farkında değilmişim.

Nesne tabanlı programlamayı basitçe, kendi dünyanıza ekleyeceğiniz nesnelerin yapım aracı olarak düşünebilirsiniz. Ben dünyamda kare istiyorum ve karemin alanı, çevresi belli olsun diyebilirsiniz. Eski bilgilerinizle böyle bir şey isteğiniz de fonksiyonlar yazıp, sonra çağırımlar yapabilirdiniz ama artık nesne tabanlı programlamayla, fonksiyon çağırımlarıyla uğraşmadan direk a = kare(2) (2 burada kenarın uzunluğu)” diyebilirsiniz.  Kafanızda “Nasıl olacak bu iş?” diye bir soru oluştuysa hadi bakalım nasıl oluyormuş.

Şu ana kadar sınıf(class) kullanmadıysanız sınıflara merhaba diyin. Eğer kullandıysanız, (Arayüz falan yazarken) belki de bilmeden kullandınız.(Tıpkı benim gibi :) ) Sınıflar nesneler üretmenin en güzel yoludur. Gelin bir kare nesnesinin sınıfını yazalım.

class kare():
    def __init__(self, kenar):
	self.kenar = kenar
    def cevresi(self):
        return self.kenar*4
    def alani(self):
        return self.kenar*self.kenar

Yaratığımız bu kare sınıfının en çok kafa karıştıran yeri “__init__” kısmı olabilir. Peki nedir “__init__” kısmı ? Basitçe burayı bir kitabın içindekiler bölümü olarak görebilirsiniz. Burada bizim kare için sadece “kenar” yerimiz var.  Bir başka soru neden “self.kenar = kenar” dediğimiz olabilir. self ile sınıf içinde fonksiyonlara ulaşmak için global gibi bir değer kullanmak yerine kolayca fonksiyonlar arasında bu değerleri kullanabiliyoruz.

Peki son olarak gelin a bir kare nesnesi olsun. Bunu yapmak için “raw_input” kullanabiliriz.

b = int(raw_input("Kare'nin kenarı kaç olsun? : "))
a = kare(b)

Bundan sonra yapacağımız kare sınıfındaki fonksiyonları çağırmak olacaktır.  Onu da şöyle halledebiliriz:

print "Çevresi: %s Alanı: %s" % (a.cevresi(), a.alani())

Kare cismimizi yaratarak nesne tabanlı programlama’yı az da olsa öğrenmiş olduk.

Not: Sınıfların içine yazdığımız fonksiyonlarda, __str__ adlı bir fonksiyon olduğunu ve bunla str(a) dediğinizde bir olayı başlatabileceğinizi biliyor muydunuz ? __str__ kısmını __int__ yapabilir ve daha birçok built_in fonksiyonlarla oynayabilirsiniz.

Python, Python, Python :)