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.