5 Kasım 2009 Perşembe

Appengine'de Mail Api'nin Kullanılışı

Web sayfanızda iletişim bölümünde hazırladığınız bir form olsun ve sonuçlarını mail adresine gelmesini istiyorsunuz o zaman bu yazı size faydalı olabilir. Sıralama şu şekilde, 1.Formunuzu oluşturun, 2.Veritabanı için modelinizi yazın, 3.Formdan geleni işleyin. Öncelikle dosya yapımız;

|----- app.yaml
|----- iletisim.py
|----- model.py
|----- templates
|----------iletisim.html

Şeklindedir. Sıra sıra gitmek istiyorum. Html formumuzu oluşturalım(template/iletisim.html);



*

*



İsim ve soyisim girişi yapıldığında ve "Yolla" tıklandığında bilgilerin mail adresinize gelmesi için bir kaç adım var. Öncelikle modelimizi oluşturan python kodumuzu yazalım ("model.py")


from google.appengine.ext import webapp,db

class Basvuru_(db.Model):
"""
Basvuru yapilacagi zaman kullanilacak olan model
"""
ad = db.StringProperty(verbose_name="ad",required=True)
soyad = db.StringProperty(verbose_name="soyad",required=True)

##Otamatik Form Olusturmasi icin Kullanabilirsiniz
class Basvuru_form(djangoforms.ModelForm):
#Kullanisi
class Meta:
model = Basvuru_
fields = ('ad','soyad')


Modelimizi de olusturduktan sonra formdan gelen veriyi islemeye geldi. Bunun icin iletisim.py python dosyamızı oluşturup işlemlerimizi yapıyoruz.


from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users,mail
from django.shortcuts import render_to_response
import os,sys

class Iletisim(webapp.RequestHandler):
def get(self):

template_values={}
path = os.path.join(os.path.dirname(__file__), 'templates/iletisim.html')
self.response.out.write(template.render(path, template_values))

def post(self):
veri = Basvuru_form() #Bos girilip girilmedigini kontrol eder
if not veri.is_valid():
ad = up(unicode(self.request.POST["ad"]).encode("utf-8"))
soyad = up(unicode(self.request.POST["soyad"]).encode("utf-8"))
#TURKCE YAP
if ad and soyad: # isim ve soyisim girilmemisse formu kaydetmez
kayit = Basvuru_(ad=ad,soyad=soyad)
kayit.put()

if not mail.is_email_valid(ad): #eger isim yazmamissa size mail atmaz
pass
else:
sender_address = "yetis.m@gmail.com"
yollanan_adres="yetis.m@gmail.com,bilgi@spssanaliz.net"
subject = "Birisi Formu Doldurdu"
body ="\nAd Soyad : "+ad+" "+soyad+"formunuzu doldurdu."
mail.send_mail(sender_address,yollanan_adres, subject, body)
self.redirect("/ulasildi")#Burada form yollama basarili oldugunu gösteren bir mesaj verdirebilirsiniz.
else:
self.response.out.write("Bilgileri eksik girdiniz lütfen tekrar deneyiniz!!!iletisim")
else:
self.redirect("/hata")
application = webapp.WSGIApplication(
[
('/iletisim',Iletisim),
], debug=True)


Bunlara ek olarak dikkatinizi çekmiştir. "up" fonksiyonu kullanılmış, Türkçe karakter sorununu kaldırmak üzere bir arkadaşımdan bulduğum fonksiyonu kullanabilirsiniz. İşinizi oldukça göreceğini düşünüyorum ki sadece python'da değil, hangi dilde olursa olsun bu mantık ile Türkçe karakter problemlerini ortadan kaldırabilirsiniz. Eğer Türkçe karakter (ı,ğ,ü,ş,İ,ö,ç vb..)girilmiş ise büyük harfe çevip bu karakterlerden arındırıyor. Fonksiyonumuz;


def up(text):
"""Girilen TR karakterleri EN karakterlere cevirir"""
groupone = ["a", "b", "c", "\xc3\xa7", "\xc3\x87", "d", "e", "f", "g", \
"\xc4\x9f", "\xc4\x9e", "h", "\xc4\xb1", "i", "\xc4\xb0", \
"j", "k", "l", "m", "n", "o", "\xc3\xb6", "\xc3\x96", "p", \
"q", "r", "s", "\xc5\x9f", "\xc5\x9e", "t", "u", "\xc3\xbc", \
"\xc3\x9c", "v", "w", "x", "y", "z",\
"\xfe","\xde","\xfd","\xdd","\xf0","\xd0","\xfc","\xdc","\xf6","\xd6","\xe7","\xc7",\
"\u015f"]

grouptwo = ["A", "B", "C", "C", "C", "D", "E", "F", "G", "G", "G", "H", \
"I", "I", "I", "J", "K", "L", "M", "N", "O", "O", "O", "P", \
"Q", "R", "S", "S", "S", "T", "U", "U", "U", "V", "W", "X", \
"Y", "Z",\
"S","S","I","I","G","G","U","U","O","O","C","C",\
"S"]
for counter in range(len(groupone)):
text = text.replace(groupone[counter], grouptwo[counter])
return text


Uzun zamandır blogumuzda yazı göremiyorum. Eskiden zevkle okuyordum. Bu yazı benim 20 dakikamı aldı. Özellikle uzak sunucu işlemleri için yazıları çok merak ediyorum ve jquery,ajax,python üclüsünü kullanacak örneklerde sizlerden beklemekteyim.

3 Eylül 2009 Perşembe

Django'da iki sunucuda birden çalışmak ve settings.py

Şu sıralar uğraştığım bir Django uygulaması var geliştirirken karşılaştığım bir sorunu ve çözümünü paylaşayım dedim.

Geliştirdiğim uygulamayı sunucuya yükledikten sonra lokalde geliştirirken oluşturduğum bir çok seçeneğin sunucudayken değişmesi gerektiğini farkettim. Bu ayarları değiştirmek kolaydı fakat sıkıntı çektiğim nokta uygulamanın hem sunucuda hemde kendi laptopumda tek bir settings.py ile sorunsuzca çalışması gerekiyordu. Bende şöyle bir çözüm buldum :

settings.py :

from os import uname, getcwd
from os.path import join
MACHINE_NAME = uname()[1]
if MACHINE_NAME == "web77.webfaction.com":
DOCUMENT_ROOT = "/path/to/document/"
DATABASE_ENGINE = ...
DATABASE_NAME = ...
DATABASE_USER = ...
DATABASE_PASSWORD = ...
DATABASE_HOST = ...
DATABASE_PORT = ...
else:
DOCUMENT_ROOT = getcwd()
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = join(DOCUMENT_ROOT,'sqlite3.db')
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

7 Ağustos 2009 Cuma

Yeni bir tat...

Python gezegenine bir girdi düştü... Richard Jones adlı arkadaş hafif ve basit bir gui sistemi üzerinde çalışıyormuş. Anlaşılan en güzel tarafı araç kitinin tam pythonic bir yazıma sahip olması

import withgui
gui = withgui.Window()
gui.image('http://www.python.org/images/python-logo.gif')
gui.run()


sonuç :

output

Ne yalan söyleyeyim beni meraklandırmayı başardı :)

16 Haziran 2009 Salı

PyS60 ile Dosya Tarayıcısı

Merhabalar,

Birkaç gündür Symbian Python'u inceliyorum çok yakında bu konuda ayrıntılı dökümanlar yazacağım...
Bu yazıda Symbian telefonlar için çok çok basit bir dosya tarayıcısı yazacaz...

Lafı fazla uzatmadan anlatmaya geçelim,

Modülümüzü import ediyoruz ve uygulamanın başlığını ayarlıyoruz...

import os
from appuifw import *

app.title = u"Dosya Tarayicisi"



while True:
liste = [u"x Cikis", u"< Geri"]
for i in os.listdir(os.getcwd()): liste.append(unicode(i))

Bu kısımda dizin içeriğini alıyoruz ve tüm içeriği unicode şeklinde listeye ekliyoruz (telefonda utf-8 kullanılması gerektiği için)

döngüye devam ediyoruz...

i = selection_list(liste, 1)
if liste[i] == u"x Cikis": break;
elif liste[i] == u"< Geri":
os.chdir("/".join(os.getcwd()[:-2].split("/")[:-1]) + "//")
continue;
else: os.chdir("%s%s" % (os.getcwd(), liste[i]))

Bu kısımda selection_list ile dizini listeliyoruz bu fonksiyon seçilen elamanın listedeki indexini verir...
(örneğin; ilk eleman seçildiyse 0 döndürür)
ayrıca selection_list raw_input gibidir uygulamayı bekletir bir eleman seçildiğinde değerini döndürür ve kod aşağıya doğru devam eder...

daha sonraki işlemler ise seçilen elemanlar neyse ona göre işlem yapılıyor, Geri işlemi ise bulunulan dizinin son kısmı silinerek yapılıyor...

ve eğer "geri" veya "cikis" seçilmediyse bulunulan_dizin + secilen_dizin e giriliyor, ve tekrar listeleme yapılıyor bu şekilde döngü devam ediyor...

Ve son olarak kodun tamamı,

# -*- coding: utf-8 -*-
# s60 dosya tarayıcısı denemesi
# coded by rohanrhu

import os
from appuifw import *

app.title = u"Dosya Tarayicisi"

while True:
liste = [u"x Cikis", u"< Geri"]
for i in os.listdir(os.getcwd()): liste.append(unicode(i))

i = selection_list(liste, 1)
if liste[i] == u"x Cikis": break;
elif liste[i] == u"< Geri":
os.chdir("/".join(os.getcwd()[:-2].split("/")[:-1]) + "//")
continue;
else: os.chdir("%s%s" % (os.getcwd(), liste[i]))

9 Mayıs 2009 Cumartesi

Google App Engine İçin Özel Şablon Yardımcıları

GAE ile bir uygulama geliştirirken şablon kısmında ekrana yazılan değeri biçimlendirmem gerekti. Bu konuyla alakalı daha önce Django için bir yazı yazmıştım. Google App Engine de ise durum Django dan biraz farklıymış. Özel şablon yardımcıları oluşturmak için ilk olarak ana dizinde ya da herhangi bir dizinde bir dosya oluşturuyoruz. Örneğin ana dizinde customfilters.py adında bir dosya oluşturalım:

Dosyaya öncelikle webapp modülünü dahil ediyoruz:

#-*- coding: utf-8 -*-
from google.appengine.ext import webapp


Ardından fonksiyonlarımızı şablon içinde kullanabilmemizi sağlayan kaydediciyi oluşturuyoruz.

register = webapp.template.create_template_register()


Sonrada fonksiyonumuzu yazıyoruz. Fonksiyon gelen bağlantıdaki boşlukları - karakteri ile değiştirip geriye sonucu döndürüyor.

def escape_url(url):
return url.replace(' ','-')


Son olarakta oluşturduğumuz fonksiyonu kaydediyoruz.

register.filter(escape_url)


Şimdi customfilters.py dosyamızı projemize tanıtmamız gerekiyor. Bunun içinde main fonksiyonunun içine aşağıdaki kodları ekliyoruz:

def main():
webapp.template.register_template_library('customfilters')
run_wsgi_app(application)

if __name__ == "__main__":
main()


Bu sayede customfilters.py dosyamızı projemize tanıtmış oluyoruz. Bu tanıtım işlemi ile birlikte artık escape_url yardımcısını şablon içerisinde kullanabilirsiniz:

<a href="/book/{{ data.name|escape_url }}/{{ data.key }}">{{ data.name }}</a>


register.filter ile fonksiyonumuzu yardımcı bir filtre olarak tanımladık. Eğer fonksiyonu bir etiket ile kullanmak istersek aşağıdaki yöntem işimizi görecektir. Bu yöntem için farklı bir fonksiyon geliştirelim. Mesela gelen parametreleri kullanıp geriye img kodunu göndersin:

def create_image(image,alt):
return '<img src="/media/images/%s" alt="%s" />' %(image,alt)

register.simple_tag(create_image)


register.simple_tag ile kaydettiğimiz fonksiyonumuzun şablon dosyasındaki kullanımı ise şöyle olmalı:

{% create_image "sample.png" "Örnek Açıklama" %}

24 Nisan 2009 Cuma

Python’da Karakter Dizisi İşlemleri

(http://www.gokmengorgen.net adresinden alıntıdır.)

Geçenlerde bir arkadaşım, Python 3′te gettext modülünün nasıl kullanılacağını sormuştu, ben de henüz 3.* sürümünü denemediğim için bir cevap verememiştim. Hala da verebilecek aşamada değilim; ama bu konu üzerinde biraz araştırma yaparken, ilginç bir internet sayfasıyla[1] karşılaştım. Aşağıda paylaşacağım kodların ve bilgilerin Python 2.* serisinde çalışmaması söz konusu olabilir.

Python’da karakter dizilerini iki biçimde çağırabiliyoruz:

  • Karakter dizileri için % işleyicisi[2].

  • string.Template modülü[3]



% işleyicisiyle kullanım örneği, Python belgelerinde verilmiş:


>>> print('%(language)s has %(#)03d quot types.' % {'language': "Python", "#": 2})
#Python has 002 quot types.


Bu kodda değişkenler bir sözlük içinde eşleştirilmekte ve print çıktısında tanımlanmış değerleriyle ekrana yazılmaktadır. Bunun aynısı şu şekilde de yapabilirdik:


>>> print('%s has %03d quot types.' % ("Python", 2))
#Python has 002 quot types.


Birincisine göre daha basit olsa da, birinci kodda şöyle bir avantaj söz konusudur:

>>> print('The %(first)s variable, and the %(second)s variable.' % {'second': "New", 'first': "Old"})
#The Old variable, and the New variable.


Bu şekilde kullandığımız zaman, ikinci işleyiciyi ilk olarak tanımlayıp, ikinci işleyiciyi ise sonra tanımlayabilme fırsatımız olabiliyor. Nerelerde kullanılabileceği ayrı bir merak konusu. Bu merakı gidermeden önce bir de şu şekilde kullanıma bir bakalım:


>>> print('The {1} variable, and the {0} variable.'.format("New", "Old"))
#The Old variable, and the New variable.


İlginç, değil mi? Aslında bu kadar çeşitlilik olması garibime gidiyor; ama bu son yöntemin yüksek seviye programlama diline daha yakın bir tarz olduğunu düşünmeden edemiyorum. Yanılmıyorsam bu tip kullanım, C# ve Java’da da var. Şimdi son olarak aşağıdaki kodu inceleyelim:


import sys

class Main:
def __init__(self):
print("Python version is, {0}.".format(sys.version[:5])) # print'lerin yazimina dikkat..

digits_list = self.digits()

print("{1} is bigger than {0} as digit.".format(digits_list[0], digits_list[1]))

def digits(self):
try:
first_digit = int(input("Please write a digit: ")) # raw_input yerine input kullaniliyor.
second_digit = int(input("And second digit: "))

except ValueError:
print("\nSorry, you must enter a digit.")
exit()

return self.sort(first_digit, second_digit)

def sort(self, x, y):
return sorted([x,y])

if __name__ == "__main__":
Main()


Kodun yaptığı şey basit: Sizden iki sayı girmeniz isteniyor ve sayıları, büyüklüklerine göre {0} ve {1} ile eşleştirip, “X, Y’den sayıca büyüktür.” gibisinden bir cümle döndürüyor. Kod basit olduğu için bu tip karakter dizisi işleyicilerin faydası pek belli olmuyor; ama mutlaka bir yerde faydası vardır =). Son kodun çıktısı şu şekilde:


[gkmngrgn@gacer ~]$ python3 rank.py
Python version is, 3.0.1.
Please write a digit: 3
And second digit: 1
3 is bigger than 1 as digit.
[gkmngrgn@gacer ~]$


[1]: http://www.python.org/dev/peps/pep-3101/
[2]: http://docs.python.org/library/stdtypes.html#string-formatting-operations
[3]: http://docs.python.org/library/string.html#string.Template

27 Mart 2009 Cuma

Opencv Modülü İle Kamera Görüntüsü Alma

Bu yazımızda python, opencv modülü ve qt ile kamera görüntüsü alıp göstereceğiz, hatta resim de çekeceğiz.


# -*- coding: utf-8 -*-

from PyQt4 import QtGui, QtCore

import Image
import ImageQt
import opencv
from opencv import highgui

# kamera yakalayıcı...
camera = highgui.cvCreateCameraCapture(0)

# kamera işlemimiz sürekli olarak ekrana görüntüyü basıyor...
class camThread(QtCore.QThread):
def run(self):
while True:
# görüntüleri basarken her aralıkda 60ms bekliyoruz, buda 60fps demek...
# eğer sizde görüntü yavaş olursa yani fps yi düşürün...
self.msleep(60)
# görüntüyü alıyoruz...
self.image = highgui.cvQueryFrame(camera)

# resim sinyalini yayıyoruz ve gidecek fonksiyona self.image değişkenini,
# gönderiyoruz...
self.emit(QtCore.SIGNAL("image"), (self.image))

class camoruxWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)

self.resize(650, 450)

self.camThread = camThread()

self.showLabel = QtGui.QLabel(self)
self.showLabel.resize(640, 480)

# camThread den gelen sinyali alıyoruz ve self.showImage ye bağlıyoruz...
self.connect(self.camThread, QtCore.SIGNAL("image"), self.showImage)
self.camThread.start()

self.button = QtGui.QPushButton(self)
self.button.setText(u"Resim çek")
self.connect(self.button, QtCore.SIGNAL("clicked(bool)"), self.cek)

def cek(self):
# flash
self.flash = QtGui.QWidget()
self.flash.setStyleSheet("background-color: rgb(255, 255, 255);")
self.flash.showFullScreen()

# resim çekiliyor...
i = highgui.cvQueryFrame(camera)
opencv.adaptors.Ipl2PIL(i).save("deneme.png")

# flash kapanıyor
self.flash.close()

def showImage(self, image):
# burada: gelen resmi ImageQt ile QLabel in istediği şekile dönüştürüyoruz...
self.image = ImageQt.ImageQt(opencv.adaptors.Ipl2PIL(image).transpose(Image.FLIP_LEFT_RIGHT))
# ve gösteriyoruz...
self.showLabel.setPixmap(QtGui.QPixmap.fromImage(self.image))

app = QtGui.QApplication([])
mw = camoruxWindow()
mw.show()
app.exec_()

Dikkat etmeniz gereken nokta şu:
camThread görüntüyü gösterirken 60ms bekliyor yani 60fps ile görüntü gösteriliyor, sizde eğer görüntü yavaş olursa fps yi düşürmeniz gerekiyor demektir. 30-40 fps arası deneyin…

19 Mart 2009 Perşembe

PyGame İle İlerleme Çubuğu (ProgressBar) Yapalım

Bugün pygame ile basit bir ilerleme çubuğu yapacağız. Uzun zaman alan işlemlerde kullanıcı sıkılmasın diye ekranda sürekli ilerleyen bir çubuk görmeye alışkınsanız bunu neden biz de yapamayalım diyor olabilirsiniz. Öyleyse bu yazı size göre.

İlerleme çubuğu sınıfımız ProgressBar olacak. Bu sınıf görsel hazırlıklarını, miras aldığı ProgressImage'a yaptıracak. Kullanım için biraz ilkel olsa da başlangıç olarak basit bir yöntem seçtim. Ama bu yazının amacı sizlere pygame'i anlatmak. Kullanmanızı ve neden ben de yapmayayım demenizi sağlamak. Bu yüzden kullanılabilirlik konusunda yeterinden öte ayrıntıya girmedim.

Örneğin uzun zaman alan bir döngünüz var:

for i in range(kere):
oturanboga.konus()



Bu döngüde ProgressBar sınıfından bir nesneyi şu şekilde kullanacaksınız:

bariscubugu = ProgressBar(kere, adim, cubukboyutu, ilkrenk, sonrenk)
while not bariscubugu.isEnd():
oturanboga.konus()
bariscubugu.makestep()


Bu kadarı bile sizleri harekete geçirmiştir sanırım. Şimdi yapıma geçelim :)

Önce meşhur modülümüzü import edelim ve bakalım internetten indirmiş misiniz ya da pisi paket yöneticinizden yüklemiş misiniz:


import sys
try:
import pygame
except ImportError:
print '''
This Program Needs Pygame module to be installed.
For windows you can download it from this adress:
http://pygame.org/ftp/pygame-1.8.1release.win32-py2.5.msi
For linux this adress will be helpful:
http://pygame.org/ftp/pygame-1.8.1release.tar.gz
'''
sys.exit(0)


Burada try bloğu içinde yer alan ifade("import pygame") test edilir; hata varsa except bloğunda verilen hataya bakılır. Hatalar uyuşuyorsa except bloğu çalıştırılır; traceback ile başlayan soğuk cümleler yerine bizim programımızda yer alan kullanıcı dostu arkadaş cümleler kullanılabilir ve kullanıcının yüreği ferah tutulmuş olur.

Kök sınıfımız(miras veren sınıf) ProgressImage'ı yazmaya başlayalım:


class ProgressImage:
def __init__(self, size, initcolor, barcolor):
pygame.display.init() #1.
self.screen = pygame.display.set_mode(size) #2.
self.bar = pygame.Surface((size[0]-10,size[1]-10)) #3.
self.bar.fill(initcolor) #4.
pygame.display.update(self.screen.blit(self.bar, (5,5))) #5.

def quit(self):
pygame.display.quit()



  1. Bu sınıfı iyi inceleyelim. Pygame bilenler ne yapıldığını aşağı yukarı anlayacaklardır ama bilmeyen ya da az bilenler için açıklayalım:
    pygame.display.init() satırı display modülünü başlangıçlandırır. Değer döndürmez. Bu metod kullanılmadan önce pygame.display.SDL_VIDEODRIVER ortam değişkeninin -eğer isteniyorsa- değiştirilmesi mümkündür. Böylece kullanılacak video sürücüsü seçilebilir. (Ayrıntı için bakınız)

  2. pygame.display.set_mode() metodu görüntüyü ayarlar ve 3 argüman alır. Bize sadece iki tanesi hatta biri gerekecek. İlk argüman genişlik ve yükseklik değerlerini içeren bir sabit listedir.(tuple) Burada (genislik, yukseklik) şeklinde geçecektir. İkinci argüman flags parametresidir. Bu da görüntü modunu seçmeye yarar. Kodumuzda size parametresiyle yetinilmiştir. Bu metod geriye bir Surface nesnesi döndürür.

    • Surface görüntüleri pixeller halinde saklayan bir nesnedir.
    • Yeni bir nesne oluştururken tual = pygame.Surface((100,100)) şeklinde kullanılabilir. Bu tual isminde bir yüzey nesnesi oluşturacaktır.
    • Örneğimizde self.screen = pygame.display.set_mode(size) kodu screen isminde bir Surface nesnesini display modülünün ilk kez oluşturduğu ana ekrandan almaktadır.
    • screen artık ana ekrana referans etmektedir.


  3. self.bar = pygame.Surface((size[0]-10,size[1]-10))
    satırında da az önce gördüğümüz gibi bir Surface nesnesi yaratılmaktadır. Bu nesneyi screen ana ekranının üzerine çizeceğiz; çünkü bu nesne göstergemizin görüneceği nesne olacak(siz buna katman(layer) da diyebilirsiniz). Göstergenin boyutu screen nesnesinin boyutuna göre 5 piksel içerde görünecek.

  4. self.bar.fill(initcolor) satırında elde ettiğimiz bar isimli yüzey nesnesini initcolor rengiyle dolduruyoruz. Burada color hakkında şunu söylemeliyim: Kırmızı(red), Yeşil(green), Mavi(blue) değerlerini 0-255 değerleri arasında içeren bir üçlü sabit listedir color. (0,0,255) gibi(mavi)

  5. pygame.display.update(self.screen.blit(self.bar, (5,5))) satırında önce pygame.display.update() metoduna verilen parametreye bakalım.

    • self.screen.blit(self.bar, (5,5)) komutu bar nesnesini screen nesnesinin üzerine çizer. Ama bunu ekrana yansıtmaz. Dikkat: nesneleri üstüste bindirir ancak görüntünün oluşması için update() metodu çalışmaldır.
    • Bu metod yani blit() metodu Rect döndürür. Bu bar nesnesinin kapladığı dikdörtgen alanın koordinatlarını içeren başka bir nesnedir ki tahmin edeceğiniz gibi pygame.display.update() metodu Rect alır.
    • Sonuç olarak yaptığımız ana ekran nesnesi olan screen'in üzerine bar nesnesini yanlızca kapladığı alan içinde bindirmektir. Bu bütün ekranı güncellemekten daha hızlı bir metoddur.



Bu kadarı pygame için yeterli sanırım şimdi programı huzurlarınıza sunuyorum. Sizde programı dilediğiniz gibi kopyalayıp kendi başınıza birşeyler deneyebilirsiniz.


import sys
try:
import pygame
except ImportError:
print '''
This Program Needs Pygame module to be installed.
For windows you can download it from this adress:
http://pygame.org/ftp/pygame-1.8.1release.win32-py2.5.msi
For linux this adress will be helpful:
http://pygame.org/ftp/pygame-1.8.1release.tar.gz
'''
sys.exit(0)

class ProgressImage:
def __init__(self, size, initcolor, barcolor):
pygame.display.init()
self.screen = pygame.display.set_mode(size)
self.bar = pygame.Surface((size[0]-10,size[1]-10))
self.bar.fill(initcolor)
pygame.display.update(self.screen.blit(self.bar, (5,5)))

class ProgressBar(ProgressImage):
def __init__(self, whole, step, size, initcolor, barcolor):
ProgressImage.__init__(self, size, initcolor, barcolor)
self.size = size
self.initcolor = initcolor
self.barcolor = barcolor
self.whole = whole
self.step = step
if whole < step:
print "Error: ProgressBar length can't be smaller than step"
sys.exit(1)
self.slice = float(step)/float(whole)
self.percent = 0.0

def showprogress(self):
self.screen.fill(self.initcolor)
barwidth = (self.size[0]-10)*self.percent
barheight = self.size[1]-10
self.bar = pygame.Surface((barwidth,barheight))
self.bar.fill(self.barcolor)
pygame.display.update(self.screen.blit(self.bar, (5,5)))

def reset(self):
self.percent = 0.0
self.showprogress()

def makestep(self):
if self.percent < 1.0:
self.percent += self.slice
self.showprogress()

def quit(self):
pygame.display.quit()

def isEnd(self):
if self.percent<=1.0:
return False
else:
return True

if __name__ == "__main__":
pb = ProgressBar(1000, 10, (100,40), (255,255,255), (0,0,255))
i, j, k = 0, 0, 0
while not pb.isEnd():
temp = "running.."
for j in range(5):
for k in range(5):
print temp
pb.makestep()
pb.quit()


progressbar.png
Hepinize kolay gelsin :)

22 Şubat 2009 Pazar

Listenin kopyasını almak

Python da her eşitlik referans gösterir. Bu iddalı lafın anlamını şöyle ifade edeyim.
Örneğin şekildeki gibi bir liste = başka bir liste şeklinde kopya almaya çalıştığınızda şöyle bir gariplik (aslında güzellik) ile karşılaşırsınız.

>>> a = ["a","b","c"]
>>> b = a
>>> b.append("d")
>>> print a, b
['a', 'b', 'c', 'd'] ['a', 'b', 'c', 'd']


Nesnelere gelince yine aynı mantık, nesne = başkabirnesne dediğinizde referans göstermiş oluyorsrunuz :


>>> class obj:
... def __init__(self):
... self.counter = 0
... def inc(self):
... self.counter += 1
...
>>> a = obj()
>>> b = a
>>> a.inc()
>>> print a.counter
1
>>> print b.counter
1


Bir nesnenin ya da değişkenin kopyasını almak istediğinizde çeşitli yöntemler var, sanırım verilerin (list, tuple, dict vs) kopyasını alırken karşılaştığım en yakışıklı yöntem şu :

>>> a = ["a","b","c"]
>>> b = list(a)
>>> print a , b
['a', 'b', 'c'] ['a', 'b', 'c']
>>> a.append("d")
>>> print a, b
['a', 'b', 'c', 'd'] ['a', 'b', 'c']


Peki bir nesnenin kopyasını almak istiyorsak? bunun için copy adında bir modül yapmışlar :

>>> class obj:
... def __init__(self):
... self.counter = 0
... def inc(self):
... self.counter += 1
...
>>> a = obj()
>>> from copy import copy
>>> b = copy(a)
>>> a.inc()
>>> b.inc()
>>> b.inc()
>>> b.inc()
>>> print a.counter, b.counter
1 3
Eğer copy modülünden deepcopy fonksionunu import eder kullanırsak, nesneyi özyinelemeli olarak kopyalıyormuş. Herkese iyi hafta sonları

17 Şubat 2009 Salı

Django'da ImageField'ı kayıt esnasında yeniden adlandırmak.

Elimde şu şekilde bir model var :

products/models.py
class Product(models.Model):
    type = models.PositiveSmallIntegerField(choices = PRODUCT_TYPES,)
    category = models.ForeignKey(Category)
    name = models.CharField(max_length=50)
    slug = models.SlugField()

    image = models.ImageField(upload_to = "product_images")
    def __unicode__(self):
        return self.name


Yapmak istediğim ise şu : yönetici panelinde bu modeli kaydederken verilen dosyanın soyadı değişmeden isminin slugfield olarak değiştirilip kaydedilmesi.

Örnek vermek gerekirse adı "Vestel Cep Televizyonu" olan bir ürünü image alanı img13.jpg dosyası ile kaydettiğimi düşünelim. Bu durumda image, "product_images/vestel-cep-televizyonu.jpg" olarak kaydedilmeli (soyadı olan jpg aynı kalıyor, dosyanın adı slug ile eşitleniyor)

Bunu yapabilmek için düşünmeye başladığımda admin site'sinin, save_model fonksiyonunu override edebildiğimizi öğrendim ve şöyle bir şey yazdım :

from os.path import dirname, join, splitext
from shutil import move as rename

class ProductAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("name",)}
    def save_model(self, request, obj, form, change):
        extension = splitext(obj.image.path)
        new_image_path = join(dirname(obj.image.path), obj.slug + extension)
        rename(obj.image.path, new_image_path)
        obj.image.path = new_image_path
        obj.save()


Fakat bu şöyle bir hataya yol açıyordu :

File "/home/horselogy/django/mobil8/../mobil8/products/admin.py" in save_model
36. obj.image.path = new_image_path

Exception Type: AttributeError at /admin/products/product/2/
Exception Value: can't set attribute


Saatlerce path değişkenini set edemiyorum diye saç baş yolduktan sonra fark ettim ki tek yapmam gereken obj.image = "uploaded/path" şeklinde yolu göstermem. Çünkü name ve path değerleri bu şekilde otomatik olarak set ediliyor. Neyse son hali ile şu şekilde olayı gerçekleştirdim

products/admin.py
class ProductAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("name",)}
    def save_model(self, request, obj, form, change):
        extension = splitext(obj.image.path)[-1]
        new_image_name = obj.slug + extension
        new_path = join(dirname(obj.image.path), new_image_name)
        rename(obj.image.path,new_path)
        obj.image = join("product_images", new_image_name)
        obj.save()


Bir dili anlarken çok zor bir dönem geçer, en aptal şey için bile saatlerinizi harcarsınız. Sonrası çorap söküğü gibi gelir her şey kolaylaşır. Sanırım bende Django konusunda bu dönemden geçiyorum. Sizin dönemlerinizin sancısız olmasını diliyor yazıyı burada bitiriyorum :).

31 Ocak 2009 Cumartesi

Django Kullanıcı Profilleri

Django ile uygulama geliştirirken kullandığımız User modelinde username, first_name, last_name, email, password, is_staff, is_active, is_superuser, last_login, date_joined alanları bulunmakta. Çoğu proje için bu alanlar bize yetsede, ek alanlara büyük ölçüde ihtiyaç duyabiliyoruz. Böyle durumlarda yine User modeli içindeki get_profile() methodu işimizi kolaylaştırmaktadır.


Bu methodu kullanabilmek için öncelikle settings.py dosyamıza aşağıdaki eklemeyi yapmamız gerekmekte:



[...]
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'projectname.users'
)

AUTH_PROFILE_MODULE = 'users.UserProfile'


users uygulama adı, UserProfile ise bu uygulama içinde tanımlanan bir veritabanı modeli adını belirtmektedir. Şimdi bu modelimizi yazalım ve ardından syncdb ile değişiklikleri veritabanımıza yansıtalım:



from django.contrib.auth.models import User

class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
telefon = models.CharField(max_length=15)


Bu modeli kullanıcı kaydı sırasında aşağıdaki şekilde kullanabilir ve oluşan kullanıcı için bir profil oluşmasını sağlayabilirsiniz:



from projectname.users.models import UserProfile

[...]
user = User.objects.create_user(username,'',password)
user.is_staff = True
user.is_active = True
user.save()
[...]

profile = UserProfile(user=user,telefon=telefon)
profile.save()


Kullanıcı bilgilerinin düzenlenmesi işleminde ise aşağıda kod profildeki bilgilerin güncellenmesini sağlayacaktır:



profile = request.user.get_profile()
profile.telefon = telefon
profile.save()

18 Ocak 2009 Pazar

Erime efekti.

Malum sınav zamanı yazacak hiç vaktim yok fekat şu spor olsun diye yaptığım çalışmayı yayınlamadan edemedim. Kod çok kısa ve çok açık. Sıkı bir inceleme ile ne yaptığı anlaşılabilir. Hatta bu bulmacamsı bir yazı olsun, siz çözün nasıl çalıştığını :)


reverse melting effect made with python and pygame - 2 from Mirat Can Bayrak on Vimeo.

from pygame import surfarray, display, image
from random import choice
from os.path import join
class Screen:
def __init__(self,name,resolution):
display.set_mode(resolution,0,24)
display.set_caption(name)
self.surface = display.get_surface()
self.width, self.height = resolution

def blurize(surfarray):
for y in range(2,len(surfarray)-2):
for x in range(2,len(surfarray[y])-2):
surfarray[x][y] = surfarray[x + choice((-1,0,+1))][y + choice((-1,0,+1))]
res = (440,440) # it must be same as image size
screen = Screen('Rendering...',res) # i want a screen
img = image.load("melt.jpg") # load image
screen.surface.blit(img,(0,0))
array = surfarray.pixels3d(screen.surface) # create array from it
display.update() # update my view
frames = 400 # num of frames to render
for frame in range(frames):
image.save(surfarray.make_surface(array), join("output/" ,str(frames-frame) + ".png"))
if frame > 25 :
# do not blurize on first 25 frames
blurize(array)
display.update()
print frame ,"th frame rendered"

5 Ocak 2009 Pazartesi

Tkinter ile Bir Deneme: Sözcükleri Çoğul Yapma

Merhaba Arkadaşlar;
Bugün küçük bir form penceresi oluşturacağız. Penceremizde iki metin girdisi(Entry), iki etiket(Label), bir adet düğme(Button) olacak. Programımız form aracılığı ile birinci metin girdisinden alacağı türkçe kelime girdisini ikinci metin girdisinde çoğul olarak gösterecek. Ve üstelik bunların hepsini Python ile ve komut satırından çıkmadan yapacağız.

Önce program çekirdeğini oluşturacak "plurize(word)"(cogulyap(kelime)) metodunu yazalım. Bu metod word katarını(string) alır ve çoğul olan kelimeyi( : word + postfix) döndürür. Bunun için türkçedeki kurallara bir bakalım:
Türkçede son hecesi ince(e,i,ö,ü) sesli(vowel) olan kelimelere 'ler' eki(postfix) eklenir.
Son hecesi kalın(a,ı,o,u) sesli(vowel) olan kelimelere 'lar' eki(postfix) eklenir.
Türkçede heceler dört harfli ise sesli harf(vowel) baştan ikinci harftir.
Türkçede üç sessiz harf yanyana gelmez.

Şimdi bu kurallara göre bir fonksiyon oluşturalım. Daha sonra kullanıcı arayüzünü(user interface) oluşturmaya geçeceğiz.

Bunun için önerdiğim çözüm şöyle başlıyor:


vowelMatrix = {
'back': {'vowels' : (a, ı, o, u), 'postfix': 'lar'}
'front': {'vowels' : (e, i, ö, ü), 'postfix': 'ler'}
}


Bu sözlük yapısı bize arama ve karşılaştırma yaparken lazım olacak. Burada;
vowelMatrix['back'] = {'vowels' : (a, ı, o, u), 'postfix': 'lar'}
vowelMatrix['front'] = {'vowels' : (e, i, ö, ü), 'postfix': 'ler'}
vowelMatrix[0][vowels][3] = u

Fonksiyonumuzu yazalım:


def plurize(self, word):
'''Dört ya da daha fazla harften oluşan kelimelerde geçerlik sınaması yapar.
wordü çoğul yapar ve döndürür'''
isValid = None
letters = list(word) #harfler
backVowels = self.vowelMatrix['back']['vowels']
frontVowels = self.vowelMatrix['front']['vowels']
triad = letters[:3] #üçlü harf listesi
if len(letters) > 4:
#Dört sesten uzun kelimeler için
for letter in letters: # geçerli bir sözcük mü
if letter == ' ': # içinde boşluk içeriyorsa
return None # Hata.
for l in triad: # Üç sessiz harf ardarda geliyor mu
if (l in backVowels) or (l in frontVowels):
#üçlüdekilerden biri bile sesli ise geçerli.
isValid = True
break #tamam kelime geçerli
else:
#yoksa geçersizdir
isValid = False
if isValid:
#kelimede sesli harf varsa
tetrad = []*4 #geçici dörtlü
tetrad[:3] = triad #ilk üç sesi üçlüden
tetrad.append(letter) #dördüncü sesi sıradaki sesten aldık
triad = tetrad[1:] #son üç sesi üçlüye yükledik
else:
#üç sessiz ardarda gelmiş.
return None #Hata.
#Kelime geçerli.
#Şimdi çoğul yapma algoritması:
if (letters[-1] in backVowels) or (letters[-2] in backVowels):
#Sondan birinci harf ya da ikincisi kalın ise..
#kelimeye uygun eki(postfix) yani 'lar' ekini ekle ve döndür
return word + self.vowelMatrix['back']['postfix']
elif (letters[-1] in frontVowels) or (letters[-2] in frontVowels):
#Sondan birinci harf ya da ikincisi ince ise..
#kelimeye uygun eki(postfix) yani 'ler' ekini ekle ve döndür
return word + self.vowelMatrix['front']['postfix']
elif len(letters) == 4:
# 4 harfli ise 2. harfi sesli olabilir; 2. 4. sesi sesli olabilir;
# 2. 3. sesi 'a' olabilir:
if ((letters[0] not in backVowels) or (letters[0] not in frontVowels)) \
and ((letters[2] not in backVowels) or (letters[2] not in frontVowels)) \
and ((letters[3] not in backVowels) or (letters[3] not in frontVowels)) \
and ((letters[1] in backVowels) or (letters[1] in frontVowels)):
#1.3.4. sesler sessiz; 2. ses sesli ise(kask, türk gibi)
return letters[1] in backVowels \
and word + self.vowelMatrix['back']['postfix'] \
or word + self.vowelMatrix['front']['postfix']
elif (letters[1] == 'a') and (letters[2] == 'a'):
#2. ve 3. ses 'a' ise(saat, maaş gibi)
#kelimeye uygun eki(postfix) yani 'ler' ekini ekle ve döndür
return word + self.vowelMatrix['front']['postfix']
elif ((letters[1] in backVowels) or (letters[1] in frontVowels)) \
and ((letters[3] in backVowels) or (letters[3] in frontVowels)):
#2. 4. sesler sesli ise(pepe, lapa gibi)
return letters[1] in backVowels \
and word + self.vowelMatrix['back']['postfix'] \
or word + self.vowelMatrix['front']['postfix']
elif letters[3] in frontVowels:
#4. sesli ince ise
#kelimeye uygun eki(postfix) yani 'ler' ekini ekle ve döndür
return word + self.vowelMatrix['front']['postfix']
else:
#kelime geçersizse
return None #Hata.
elif len(letters) == 3:
#3 harfli ise salt 2. harfi sesli olabilir;
#ya da salt 1. ve 3. sesler sesli olabilir:
if (letters[1] in backVowels) or (letters[1] in frontVowels) <>\
~( (letters[0] in backVowels or letters[0] in frontVowels) \
and (letters[2] in backVowels or letters[2] in frontVowels) ):
#1. ve 3. ses sessiz, 2. ses sesli ise ya da tersi
if (letters[1] in backVowels) or (letters[1] in frontVowels):
#2. ses sesli ise
#kelimeye uygun eki(postfix) ve döndür
return letters[1] in backVowels \
and word + self.vowelMatrix['back']['postfix'] \
or word + self.vowelMatrix['front']['postfix']
else:
#2. ses sessiz ise
#kelimeye uygun eki(postfix) ve döndür
return letters[2] in backVowels \
and word + self.vowelMatrix['back']['postfix'] \
or word + self.vowelMatrix['front']['postfix']
else:
#kelime geçersizse
return None #Hata.
elif len(letters) == 2:
#2 harfli ise ya birinci harf sesli ikincisi sessizdir ya da tersi
if not ( ((letters[0] in backVowels) or (letters[0] in frontVowels)) <> \
((letters[1] in backVowels) or (letters[1] in frontVowels)) ):
#iki ses de sesli ya da iki ses de sessiz ise hata. (aa, kk)
return None
elif ( (letters[0] in backVowels or letters[0] in frontVowels) <> \
~(letters[1] in backVowels or letters[1] in frontVowels) ):
#ya birinci harf sesli ikincisi sessizdir ya da tersi(ka, ak)
return (letters[0] in backVowels or letters[1] in backVowels) \
and word + self.vowelMatrix['back']['postfix'] \
or word + self.vowelMatrix['front']['postfix']
else:
#Başka olasılık kalmadı; ama denemeye değer:
return None
elif len(letters) == 1 or word == None:
return None


Burada yapılan işlem yukarıda sıraladığım kuralları program mantığına uyarlamak. Sırasıyla 4 sesten büyük, 4 sesli, 3 sesli, 2 sesli ve 1 sesli durumları sınandı.

Dialog Sınıfını yazarken bu fonksiyonu(işlevi) def plurize(self, word)
şeklinde ekleyeceğiz. Tkinter ile kullanıcı arayüzü(user interface) içeren uygulamalar yazmak için öncelikle kodumuza uygun modülleri "import" etmeliyiz:

# -*- coding: utf-8 -*-
#!usr/bin/python
from Tkinter import *


Bu kod ile Tkinter modülünden bütün sınıfları içerdik(import, include). Artık örneğin Label sınıfını kullanırken "Tkinter.Label" şeklinde açımlamak zorunda kalmayacağız. Doğrudan "Label" şeklinde açımlama(decleration) yapabileceğiz.
Şimdi sınıf mantığı ile Tkinter nasıl birleştirilir onu görelim. Bir etiket yapmak o kadar kolay değil; belki de çok kolay ;)

class PlurizeDialog:
def __init__(self, master):
pass


Burada PlurizeDialog isimli bir sınıf tanımladık. Bu bizim UI(user interface : kullanıcı arayüzü) sınıfımız. Bu sınıfın yapıcısı(constructor) __init__() işlevi. Bu işleve dikkat:

def __init__(self, master):

Bu kod içinde yer alan master parametresi root = Tk() ile yaratacağımız ana pencerenin referansını alacak. Yani
root = Tk()
pl = PlurizeDialog(root)

diyebilmek için master parametresini kullanıyoruz.
Geri kalan işlemler basit:

Label(master, text='Enter Turkish:').pack()
self.e1 = Entry(master)
self.e1.pack(padx=18)
Label(master, text='Plural:').pack(pady=3)
self.e2 = Entry(master)
self.e2.pack(pady=3, padx=18)
b = Button(master, text='Plurize', command=self.show_plurize)
b.pack(pady=9)

kodu ile __init__() bitiyor. Burada yaptığımız Label ile iki tane etiket oluşturmak. Entry ile iki metin girdisi oluşturmak, Button ile bir düğme eklemek. Burada command=show_plurize atamasına dikkat. Düğmeye tıklandığında çalışacak olan show_plurize() şimdi geliyor:

def show_plurize(self):
word = self.e1.get()
newWord = self.plurize(word)
if newWord != None:
self.e2.insert(0, newWord)
else:
self.e2.insert(0, "Invalid Word!")


Burada b düğmesine tıklandığında çalışacak işlev görülüyor. plurize() işlevini kullanan bu işlev sayesinde kod kısmı ile ui kısmını ayırmış olduk.

İşte Dialog Sınıfı ve programın son hali:


# -*- coding: utf-8 -*-

from Tkinter import *

class PlurizeDialog:
def __init__(self, master):
Label(master, text='Enter Turkish:').pack()
self.e1 = Entry(master)
self.e1.pack(padx=18)
Label(master, text='Plural:').pack(pady=3)
self.e2 = Entry(master)
self.e2.pack(pady=3, padx=18)
b = Button(master, text='Plurize', command=self.show_plurize)
b.pack(pady=9)
vowelMatrix = { \
'back': {'vowels' : ('a', 'ı', 'o', 'u'), 'postfix': 'lar'}, \
'front': {'vowels' : ('e', 'i', 'ö', 'ü'), 'postfix': 'ler'} \
}
def show_plurize(self):
word = self.e1.get()
newWord = self.plurize(word)
if newWord != None:
self.e2.insert(0, newWord)
else:
self.e2.insert(0, "Invalid Word!")
def plurize(self, word):
pass #yukarıda verildi.

if __name__ == '__main__':
root = Tk()
pd = PlurizeDialog(root)
root.mainloop()


İyi Çalışmalar.
Özgür Sönmez.