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.

7 yorum:

  1. Ellerinize sağlık ve hoş geldiniz :)

    YanıtlaSil
  2. Teşekkür Ederim. :)

    YanıtlaSil
  3. Ya windows kullanıyorum ama bendeki pythonda tkinder mödülü yok nerden indirebilirim???

    YanıtlaSil
  4. @Adsız:
    Hangi Python sürümünü kullanıyorsunuz? Eğer kurduğunuz sürümde idle çalışıyorsa, Tkinter modülü de var demektir. Zira Idle Tkinter ile yapıldı. Kurduğunuz Python paketinin içinde Idle olup olmadığını kontrol edin.

    YanıtlaSil
  5. python 3 ü kurdum şimdi import ediyorum tkinderi ama hata veriyo yardım edin lütfen

    YanıtlaSil
  6. Bunun cevabını vermiştim size, Tkinder olarak değil, Tkinter olarak deneyin.

    YanıtlaSil
  7. python 3 kısmını atlamışım, python 3'e geçişte tkinter olarak değişiklik yapılmıştı.

    _tkinter modülünü ise kullanmanız tavsiye edilmez, tkinter'dan farklı olarak özellikler içerir, farklı amaçlar için kullanılan bir modüldür o.

    YanıtlaSil