Monday, February 28, 2011

meshgrid

Bu fonksiyon 2 kordinat vektoru alir ve geriye 2 kordinat matrisi dondurur. Diyelim ki 3 boyutlu bir fonksiyon hesaplatacagiz, fonksiyon alani ise x kordinati -5 ve 5 arasinda, y kordinati -3, 3 arasinda olacak. O zaman bu araliktaki her noktanin kombinasyonu bize lazim. Bu kombinasyon [-5,-3], [5.1,-3],..,[-5,-3.1] diye gidecekti.

meshgrid fonksiyonunun yaptigi bu kombinasyonu rahat erisilir hale getirmekten ibaret. meshgrid cagrisindan geri gelecek X ve Y matrislerinde X[1] ve Y[1]'e baktigimizda (her iki tarafta ayni indisi kullandigimizda yani) kombinasyonlardan birini aninda alabilecegiz. Ornek
x = np.arange(-5, 5, 0.1)
y = np.arange(-3, 3, 0.1)
xx, yy = np.meshgrid(x, y)
z = np.sin(xx**2+yy**2)/(xx**2+yy**2)
Not: Bu kodda meshgrid'den gelen xx ve yy uzerinde direk indis kullaniliyormus gibi gozukmuyor, fakat arka planda aslinda kullaniliyor. xx ile yy uzerinde aritmetik islemler kullanilinca, bu otomatik olarak her xx ve yy elemanin teker teker, ayni indiste olanlarinin beraber isleme sokulmasi demektir, +, -, ** gibi islemler perde arkasinda buna gore kodlanmistir.

Kaynak

Sunday, February 27, 2011

Operatorler

Bir class tipi uzerinde islemesini istedigimiz operatorler icin o tipin class'i icindeki "ozel" fonksiyon isimlerini kullanmamiz gerekir. Mesela X adli bir tip icin kucuktur isaretini tanimlamak isteseydik, __lt__ fonksiyonunu tanimlamamiz gerekirdi. Ornek:
class X:
def __init__(self, x):
self.x = x
def __lt__(self, other):
if (other < self.x):
return True
return False

xx = X(10)
yy = X(20)

if (xx < yy): print "kucuk"
if (xx > yy): print "degil"

Esnek Parametre Listesi

Bir fonksiyona gecilecek parametre listesi onceden belli degilse, yildiz isareti, mesela *liste gibi bir kullanimla parametre listesi esnek hale getirilebilir. Mesela gecilen parametreleri sadece ekrana basan bir fonksiyon yazsak:
def f(*list):
for x in list:
print x
Fonksiyon f()'de gecilen parametreler esnek olarak tanimlanmis. Bu fonksiyonu cagirmak icin
f(3,4,5,6)  
ya da
f(3,4)  
kullanilabilir.

imap

Python itertools paketinden bir fonksiyon daha: imap. Bu yardimci cagri adindan anlasilabilecegi uzere "eslestirme" yapar. Iki veya daha fazla parametre alir, birinci parametre her zaman cagirilacak bir fonksiyon F olacaktir (evet fonksiyona parametre olarak fonksiyon geciyoruz), geri kalan parametreler icinde F'e verilecek olan parametrelerin listesi oluyor. Mesela pow cagrisini dusunelim, bu cagri iki parametre alir, pow(2,2) mesela 2 uzeri 2 hesabini yapar, 2^2 = 4. Diyelim ki bunun gibi pek cok sayi var elimizde, ustu alinacak sayilar bir listede, ust degerleri baska bir listede duruyor. imap ile bu isi soyle hallederiz:
from itertools import imap

aa = [2,3,4]
bb = [2,4,6]

for x in imap(pow, aa, bb):
print x
Bu cagri 2^2, 3^4, 4^6 hesaplarini sirasiyla yapar ve sonuclarin "gezilebilir" hale getirilmesini saglar (imap kodlamasinda yield kullanimi var yani).

Fonksiyon Gezmek ve Yield

Bir vektörün, listenin elemanlarını gezebildiğimizi (iteratation) biliyoruz.

Python'un üretici (generatörs) özelliği ile bir fonksiyonu gezmek te mümkün.

Bu nasıl oluyor? Hokus pokus yield adı verilen bir komutta.

Bir fonksiyon return çağrısı ile bir değer döndürebilir. Fakat o noktada o fonksiyondan dışarı çıkmış oluruz yani o fonksiyon ile işimiz biter. Kıyasla yield ile bir değer döndürürüz, geriye bir sonuç gelir ama fonksiyonun yield anındaki hali dondurulur -- yani unutulmaz. Fonksiyondan dışarı çıkmış olsak bile geri dönebiliriz, ve lokal değişkenleri oldukları halde kullanmaya devam edebiliriz: Alttaki fonksiyona bakalım:

def fib():
a, b = 0, 1
while 1:
  yield b
  a, b = b, a+b

Bu fonksiyon Fibonaccı sayılarını üretir, Fibonaccı sayıları 1,1,2,3 diye gider, bir sonraki sayı her zaman önceki iki sayının toplamıdır. Görüldüğü gibi yield ile en son toplamı donduruyoruz, fonksiyondan çıkıyoruz, fakat gezme işlemi bir sonraki değeri istediğinde fib()'e geri dönülüyor ve işlem yield'den bir sonraki satırdan, yani kaldığı yerden devam ediyor. Fonksiyon içindeki tüm lokal değişkenler hala değerlerini koruyorlar.

Kullanmak için fib() çağrısını sanki bir listeymiş gibi çağırabiliriz:

for x in fib(): print x

Yukarıda anlatılan türden değer gezme olanağının faydası nedir? Kod düzenlemesi açısından getirdiği faydalar ötesinde (temizlik gibi, geçici bir liste objesine gerek yok), performans bakımından faydası olabilir. Bir şekilde hesaplanan ve üretilen elemanları gezmek için onların önceden bir listeye doldurulmuş olması gerekmiyor -- her eleman fonksiyon tarafından "gerektiği anda" hesaplanıp teker teker alınıyor, ve bu bir tür "tembel (lazy)" hesaplama olarak görülebilir. CPU bedelini her Fibonaccı sayısını üretirken sadece o sayı için ödüyoruz. 10 tane önceden üretip bir yerde bekletmiyoruz.

Üreticilerin ne kadar kuvvetli özelliklerinin olduğunu tekrar belirtmek iyi olur: içinde yield içeren bir fonksiyonu aslında bir bakıma konumu olan bir obje gibi bile düşünebiliriz, daha doğrusu onlar bir bakıma "konumlu fonksiyonlar" oluyorlar. Mesela azar azar işlem yapan ortamlarda tipik bir ihtiyaç bir dosyanın açılması, ve o dosyadan azar azar satır alınabilmesi.

Üretici yaklaşımı ile bu iş şöyle yapılır, in.csv dosyası şöyle olsun

y,x1,x2
1,6,10
2,5,20
3,4,30
4,3,40
5,2,50

Kod

import csv
def get_row(cols):
    with open("in.csv", 'r') as csvfile:
        rd = csv.reader(csvfile)
        headers = {k: v for v, k in enumerate(next(rd))}
        for row in rd:
            label = float(row[headers['y']])
            # sadece istenen kolonlari al
            rrow = [row[headers[x]] for x in headers if x in cols]
            yield rrow, label

Bu akıllı fonksiyon aynen bir class gibi yaratılıyor, sonra çağrılıyor. Mesela ilgilendiğimiz belli bir kolon listesini verip geziciyi oluşturabiliriz, sonra ondan bir satır isteyebiliriz,

getter = get_row(['x1','x2'])
Y,x = getter.next() 
print Y,x

Şu sonucu görürüz,

['10', '6'] 1.0

Şu anda fonksiyon bekler durumda. Biz başka çağrılar yapabiliriz, gidip kahve içebiliriz, geri geldiğimizde

Y,x = getter.next() 
print Y,x
Y,x = getter.next() 
print Y,x

çağrıları bize iki yeni satır verir. 

['20', '5'] 2.0
['30', '4'] 3.0

Elimizdeki fonksiyon göstergecini başka birini versek o next() çağırsa o da aynı yerden devam ederdi. Ama biz tekrar başa dönmek istiyoruz, problem değil, yeni bir gezici fonksiyon yaratırız, 

getter = get_row(['x1','x2'])
Y,x = getter.next() 
print Y,x

['10', '6'] 1.0

Başa dönmüş olduk.

Üreticilerin gezme işlemini başlatmadan önce bazı hazırlık işleri, atamaları yapmaları en önemli özelliklerinden. Aynen bir obje başlatıldığında onun kurucusunda başlangıç kodları işletilebildiği gibi, ilk yield anına kadar işletilen her şey bir fonksiyonda hazırlık aşaması sayılabilir, ondan sonra bir döngüye girilip daha az mıktarda kod sürekli işlenip yield ile dönülecektir. Üstteki örnekte dosyanın açılması, başlık kolonların okunması, vs gibi işlemlerin hepsi bu başlangıç aşamasında. Bir gezici fonksiyonu ismiyle ve istenen parametreleri ile yarattığımız zaman bu hazırlık kodları işleyecek. 

Kaynaklar

http://www.python.org/dev/peps/pep-0255/

Saturday, February 26, 2011

TyphoonAE

Bu proje tum Google App Engine arayuzlerini destekleyerek GAE'de isleyebilecek Python kodlarinin ayri, sahsa, sirkete ozel makinalarda isletebilmesini sagliyor. GAE bilindigi gibi bir bulut ortamidir ve fiziksel makinalar Google'a aittir. TyphoonAE'nin gelistirme statusu Beta. Proje hakkinda iyi seyler duyduk.

Tuesday, February 8, 2011

Chrome Uygulamasi Hazirlamak

Bir HTML uygulamasini Chrome uygulumasi haline getirmenin en kolay yolu, "URL paketlemek", yani Chrome magazasindan indirilecek uygulamamizin zaten mevcut URL'imize baglanmasini saglamak. Boylece HTML sayfalarini paketlemeye gerek kalmiyor (onun gerekli oldugu durumlar da olabilir tabii, online olmadan en azindan kismen calismasi gereken uygulamalar mesela). Magaza

https://chrome.google.com/webstore/

adresinde. Uyguluma yayinlamak icin Google'a $5 bayilmak lazim. Bundan sonra istendigi kadar uygulama yayini yapilabilir. Parali uygulama yayinlamak icin ABD banka hesabi gerekiyor (simdilik).

URL paketlemek icin bir manifest.json yaratalim. Suna benzer:
{
"name": "Cepteborsa",
"version": "7",
"icons": { "128": "icon_128.png" },
"app": {
"urls": [
"http://cepteborsa.appspot.com/mweb"
],
"launch": {
"web_url": "http://cepteborsa.appspot.com/mweb/index.html"
}
},
"permissions": ["unlimitedStorage"]
}
Ayni dizinde icinde 128x128 boyutunda bir imaj olan bir icon_128.png dosyasi lazim, o dosyada uygulamamizin resmi olacak. "launch" web_url adresi uygulamanin baslangic baglantisi.

Manifest icinde iki URL var. Bu adreslerin ikisinin de "bizim" oldugunu Chrome'a dukkanina ispatlamamiz gerekiyor; o isi Webmaster Tools uzerinden yapmamiz gerekli (Chrome dukkani isi WT'den kontrol ediyor)

http://www.google.com/webmasters/tools

adresinde herhangi bir siteyi, sitenin alt dizinini kayit ettirebiliyoruz. Google'in site tanimasi icin belli teknikleri var, ismi verilen sayfa icine bir kod eklememizin soylenmesi gibi.. Biz bu secenegi kullandik ve http://cepteborsa.appspot.com/mweb/index.html ve http://cepteborsa.appspot.com/mweb/index.html sayfalari icine Google'in istedigi bazi kodlari ekledik. Sayfalar tanindi.

En son islem paketlemek; Paketlemek icin bir zip komutu yeterli

zip /tmp/cepteborsa.zip manifest.json icon_128.png

Sonra bu zip dosyasini Chrome dukkanina yukluyoruz. Yukleme yapilan formda gereken bilgileri giriyoruz, en az bir tane uygulama goruntusu (resim, video) lazim, onu da veriyoruz ve is bitiyor.

Versiyon numaralari kavrami Android'dekine benzemekte, her degisimde versiyon numarasi artmis olmali, bu kontrol ediliyor. Yeni zip yaratirken biz bu numarayi bir arttiriyoruz.

Friday, February 4, 2011

Windows'da Caps'i Control Yapmak

caps-as-ctrl.reg

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

Dosya yaratildiktan sonra ustune tiklayin. Bu kadar.