|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Castellano ChineseGB Deutsch Francais Italiano Portugues Turkce |
Hilaire Fernandes <hilaire(at)ofset.org> Yazar hakk�nda: Hilaire Fernandes Gnome masa�st� i�in "�cretsiz" e�itsel yaz�l�mlar geli�tiren OFSET adl� organizasyonun ikinci ba�kan�d�r. Ayn� zamanda bir dinamik geometri program� olan Dr.Geo'yu yazd�. Halen Gnome i�in bir ba�ka e�itim program� olan Dr.Genius �zerinde �al��maktad�r. T�rk�e'ye �eviri: Esen Fahri AKIN <eseaki(at)be.itu.edu.tr> ��erik:
|
Python kullanarak Gnome i�in Uygulama Geli�tirme(B�l�m 3)�zet:
Bu makale serisi �zellikle Gnome ve GNU/Linux kullanan amat�r programc�lar i�in yaz�lmi�t�r. Geli�tirme i�in se�ilen dil, Python, C gibi derlenmi� dillerin al��ageldi�imiz genel hatlar�n� kullanmaz. Bu makaleyi anlaman�z ic cin temel Python programlama bilgisine sahip olman�z gerekir. Python ve Gnome hakk�nda ayr�nt�l� bilgiyi http://www.python.org ve http://www.gnome.org. adreslerinden edinebilirsiniz.Serideki di�er makaleler : |
Bu makalede tan�t�lan program� �al��t�rmak i�in gereken yaz�l�mlar i�in bu serinin 1.b�l�m�ne bak�n�z.
Di�er gereksinimler:
Python-Gnome ve LibGlade kurulumu ve kullan�m� i�in B�l�m 1'e bak�n�z.
�nceki makalede (B�l�m 2), ileride tan�mlanacak al��t�rmalar�n kodlamas� i�in bir �er�eve olan -- Drill -- adl� kullan�c� aray�z�n� olu�turduk. �u a�amada, Drill'e yararl�k kazand�rmak a��s�ndan Python kullanarak nesne y�nelimli geli�tirmeyi daha yak�ndan incelemeliyiz. Bu �al��mada, Gnome'da Python geli�tirmeyi bir kenara b�rakaca��z.
O halde b�rakt���m�z yerden devam edelim, okuyucu i�in bir al��t�rma olmas� bak�m�ndan Drill i�ine bir renk oyununun eklenmesine bakal�m. Bunu konumuzu g�rselle�tirmek, ayn� zamanda da bu al��t�rma i�in bir ��z�m sunmak i�in yapaca��z.
K�saca, ayr�nt�l� bir ��z�mleme yapmaks�z�n, nesne y�nelimli geli�tirmenin olaylar�n ger�ekte olup olmad���n� Bu budur ili�kileri ile tan�mlamaya �al��t���n� s�yleyebiliriz. Bu ilgilendi�imiz problemdeki nesneleri �zetlemek olarak da g�r�lebilir.De�i�ik alanlarda kar��l�klar bulabiliriz, Aristoteles'in kategorileri, taksonomiler, ontolojiler gibi. Bunlar�n hepsinde, ki�i karma��k bir durumu �zetleme yoluyla anlamak durumundad�r. Bu t�r bir geli�tirme pekala kategori y�nelimli geli�tirme olarak adland�r�labilir.
Bu geli�tirme modelinde, program taraf�ndan de�i�tirilen yada program� olu�turan nesneler s�n�flar bu �zet nesnelerin temsilcileri de �rnekler olarak an�l�r. S�n�flar nitelikler (de�erler i�eren) ve y�ntemler (fonksiyonlar) ile tan�mlan�rlar. Asl�nda �ocuk s�n�f�n �zelliklerini ebeveyn s�n�ftan ald���bir ebeveyn-�ocuk ili�kisinden s�z ediyoruz. S�n�flar bu budurili�kisiyle organize olmu�lard�r ve bir �ocuk hem bir aile tipidir hem de bir �ocuk. S�n�flar tamamen tan�mlanamayabilirler, b�yle bir durumda �zet s�n�flar olarak adland�r�l�rlar. Bir y�ntem ifade edilmi� fakat tan�mlanmam��sa (fonksiyonun g�vdesi bo�sa) buna da sanal y�ntem denir. Bir �zet s�n�f bu tan�mlanmam�� y�ntemlerden bir veya birden fazla i�erir ve bu nedenle �rneklenemez. �zet s�n�flar t�retilmi� s�n�flar�n - saf sanal y�ntemlerin tan�mlanaca�� �ocuk s�n�flar - ald�klar� formlar� tan�mlamaya izin verir.
�e�itli dillerin nesne tan�mlamadaki zariflikleri farkl�d�r fakat ortak paydan�n �unlar oldu�unu s�yleyebiliriz:
Python i�in bu se�ilen en k���k ortak paydad�r. Bu metodolojinin i�inde kaybolmadan nesne y�nelimli geli�tirme ��renmeye olanak sa�lar.
Python'da, bir nesnenin y�ntemleri her zaman sanal y�ntemlerdir. Bu her zaman bir �ocuk s�n�f taraf�ndan ge�ersiz k�l�nabilece�i anlam�na gelir - ki nesne y�nelimli gel��tirmede biz bunu istiyoruz - ve s�z dizimini biraz basitle�tirir. Fakat bir y�ntemin ge�ersiz k�l�n�p k�l�nmad���n�n ay�rd�na varmak kolay de�ildir. Bunun da �tesinde, bir nesneyi donuk k�lmak, bunun sonucunda da nesne d���ndan niteliklerine ve y�ntemlerine eri�imi reddetmek olanaks�zd�r. Sonu� olarak, bir Python nesnesinin nitelikleri d��ar�dan okunabilir ve yaz�labilirdir.
�rne�imizde, (templateExercice.py dosyas�na bak�n), exercice tipinde nesneler tan�mlamak istiyoruz. exercice tipi nesneyi tan�mlayarak daha sonra olu�turaca��m�z exercice'ler i�in bir �zet temel s�n�f olu�turmu� olduk. exemple nesnesi olu�turulacak t�m di�er tip nesnelerin ebeveyn s�n�f�d�r. Bu t�retilmi� tipler en az�ndan exercice ile ayn� nitelik ve y�ntemlere sahiptirler. Bu bize her t�rden nesneye, nereden t�retildi�ine bakmaks�z�n, m�dahale etme imkan� verecektir.
exercice s�n�f�na �rnek olarak �unu yazabiliriz:
from templateExercice import exercice monExercice = exercice () monExercice.activate (ceWidget) |
Asl�nda exercice s�n�f�na �rnek olu�turmak gereksizdir ��nk� zaten di�er s�n�flar�n t�retildi�i bir kal�pt�r.
Nitelikler
E�er al��t�rman�n ba�ka y�nleriyle de ilgileniyorsak, edinilen skoru yada ka� kez �al��t�r�ld���n� belirten nitelikler ekleyebiliriz.
Y�ntemler
Bu Python kodunda bize �u sonucu verir :
class exercice: "A template exercice" exerciceWidget = None exerciceName = "No Name" def __init__ (self): "Create the exericice widget" def activate (self, area): "Set the exercice on the area container" area.add (self.exerciceWidget) def unactivate (self, area): "Remove the exercice fromt the container" area.remove (self.exerciceWidget) def reset (self): "Reset the exercice" |
Bu kodu kendi dosyas� olan templateFichier.py i�ermektedir, bu da bizim her nesnenin kendine �zg� g�revlerini ay�rt etmemizi sa�lar. Y�ntemler, asl�nda fonksiyonlar demek daha do�ru olur, exercice s�n�f�n�n i�inde ifade edilmi�tir.
area arg�man�n�n LibGlade taraf�ndan olu�turulan GTK+ widget'�na referans oldu�unu g�rece�iz.
Bu y�ntemde __init__ ve reset bo�tur ve gerekti�inde �ocuk s�n�flar taraf�ndan ge�ersiz k�l�nacakt�r.
Bu neredeyse bo� bir al��t�rma. Yaln�zca bir tek �ey yap�yor, o da Drill'in al��t�rma b�lgesine al��t�rman�n ad�n� koymak. Hen�z olu�turmad���m�z ama Drill'in sol taraf�n� dolduracak olan al��t�rmalar i�in bir ba�lat�c� g�revi g�r�yor.
exercice'da oldu�u gibi, labelExercice da kendi dosyas� olan labelExercice.py'a konuyor. Bundan sonra nesne exercice'in �ocu�u i�in ebeveyninin nas�l tan�mland���n� anlatmam�z gerek. Bu basit�e import'la yap�l�yor :
from templateExercice import exercice |
Bunun anlam�, exercice s�n�f�n�n templateExercice.py dosyas�ndaki tan�m� bu koda getirtiliyor(import).
�imdi en �nemli noktaya geldik, labelExercice s�n�f�n�n exercice'in �ocu�u olarak ifade edilmesi.
labelExercice a�a��daki �ekilde ifade edilir :
class labelExercice(exercice): |
��te, bu labelExercice'in exercice.
'in t�m nitelik ve y�ntemlerini almas� i�in yeterli.Tabii ki, hala yapacak i�imiz var, al��t�rman�n widget'�n� ba�latmam�z(initialize) gerekiyor. Bunu __init__ y�ntemini ge�ersiz sayarak yap�yoruz. Bu widget'a exerciceWidget niteli�inde de at�fta bulunulmal�d�r ki activate ve unactivate y�ntemlerini ge�ersiz k�lmam�z gerekmesin.
def __init__ (self, name): self.exerciceName = "Un exercice vide" (�evirmenin notu: bo� bir al��t�rma) self.exerciceWidget = GtkLabel (name) self.exerciceWidget.show () |
Bu ge�ersiz k�ld���m�z tek y�ntem. labelExercice �rne�ini olu�turmak i�in yapmamiz gereken:
monExercice = labelExercice ("Un exercice qui ne fait rien") (�evirmenin Notu: "Un exercice qui ne fait rien" "Hi�bir �ey yapmayan al�st�rma" demektir) |
Niteliklerine ve y�ntemlerine eri�mek i�in:
# Le nom de l'exercice (�evirmenin notu: al��t�rman�n ad�) print monExercice.exerciceName # Placer le widget de l'exercice dans le container "area" # (�evirmenin notu: Al��t�rman�n widget'�n� konteyner alan�na yerle�tir) monExerice.activate (area) |
Burada ilk makalede g�r�len renk oyununu ad� colorExercice.py olan exercice tipi bir s�n�fa d�n��t�rmeye ba�l�yoruz. Kendi dosyas� olan colorExercice.py'ye koyuyoruz(kaynak kodu bu belgeye eklidir).
Ba�taki kaynak kodda yap�lmas� gereken de�i�iklikler �o�unlukla fonksiyonlar�n ve de�i�kenlerin colorExercice s�n�f�ndaki y�ntem ve niteliklere yeniden da��t�m�n� i�erir.
K�resel de�i�kenler s�n�f�n ba��nda ifade edilerek niteliklere d�n��t�r�l�r:
class colorExercice(exercice): width, itemToSelect = 200, 8 selectedItem = rootGroup = None # to keep trace of the canvas item colorShape = [] |
labelExercice s�n�f�nda oldu�u gibi, __init__ y�ntemi al��t�rman�n widget'lar�n�n olu�turulmas� i�in ge�ersiz say�lm��t�r:
def __init__ (self): self.exerciceName = "Le jeu de couleur" # �evirmenin Notu: Renk Oyunu self.exerciceWidget = GnomeCanvas () self.rootGroup = self.exerciceWidget.root () self.buildGameArea () self.exerciceWidget.set_usize (self.width,self.width) self.exerciceWidget.set_scroll_region (0, 0, self.width, self.width) self.exerciceWidget.show () |
exerciceWidget'de at�fta bulunulan yaln�z GnomeCanvas ise ba�lang�� koduna k�yasla yeni bir �ey yok.
Ge�ersiz say�lan y�ntem reset'dir. Oyunu s�f�ra e�itledi�i i�in renk oyununa uyarlanmas� gerekir:
def reset (self): for item in self.colorShape: item.destroy () del self.colorShape[0:] self.buildGameArea () |
Di�er y�ntemler, eklenen de�i�ken self d���nda orjinal fonksiyonun do�rudan kopyas�d�r. Yaln�z buildStar ve buildShape y�ntemlerinde istisnalar vard�r, ondal�k parametre k bir tam say� ile de�i�tirilmi�tir. colorExercice.py d�k�man�nda garip bir davran��� fark ettim. Kaynak kod taraf�ndan al�nan ondal�k say�lar kesiliyordu(truncation). Sorun gnome.ui mod�l�nden Frans�z notasyonundan kaynaklan�yor gibi g�r�n�yor(ondal�k k�s m� nokta yerine virg�lle ay�r�rlar).Bir sonraki makaleye kadar sorunun kayna��n� bulma �zerine �al��aca��m.
�imdi iki tip al��t�rmam�z var -- labelExercice ve colorExercice. drill1.py kodunda addXXXXExercice fonksiyonlar� ile �rnekler olu�turabiliriz. exerciceList s�zl���nde bu �rneklere at�fta bulunuluyor. Bu s�zl�kte anahtarlar ayn� zamanda soldaki a�a�taki her al��t�rman�n sayfalar�n�n arg�manlar�:
def addExercice (category, title, id): item = GtkTreeItem (title) item.set_data ("id", id) category.append (item) item.show () item.connect ("select", selectTreeItem) item.connect ("deselect", deselectTreeItem) [...] def addGameExercice (): global exerciceList subtree = addSubtree ("Jeux") addExercice (subtree, "Couleur", "Games/Color") exerciceList ["Games/Color"] = colorExercice () |
addGameExercice fonksiyonu addExercice fonksiyonunu �a��rarak a�a�ta niteli�i id="Games/Color" olan bir yaprak olu�turur. Bu nitelik colorExercice() taraf�ndan exerciceList s�zl���nde olu�turulan renk oyunu �rne�inde anahtar olarak kullan�l�r.
Polimorflu�un nesne y�nelimli geli�tirmedeki s�kl��� dolay�s�yla al��t�rmalar�her nesne i�in farkl� davran�� g�steren ayn� fonksiyonlarla y�r�tebiliriz. Y�ntemleri yaln�zca �zet temel s�n�fta exercice'da �a��r�yoruz ve onlar colorExercice s�n�f�nda ve labelExercice s�n�f�nda farkl� �eyler yap�yorlar. Programc� t�m al��t�rmalara ayn� �eyi "s�yl�yor", her al��t�rman�n "yan�t�" biraz farkl� olsa da. Bunu yapmak i�in a�ac�n yapraklar�n�n id niteli�i ile exerciceList s�zl���n�n yada exoSelected de�i�keninin kullan�m�n� birle�tiriyoruz. B�t�n al��t�rmalar�n exercice'�n �ocu�u oldu�u bilgisini kullanarak, onun y�ntemlerini her t�rl� al��t�rmay� kontrol etmek i�in kullan�yoruz.
def on_new_activate (obj): global exoSelected if exoSelected != None: exoSelected.reset () def selectTreeItem (item): global exoArea, exoSelected, exerciceList exoSelected = exerciceList [item.get_data ("id")] exoSelected.activate (exoArea) def deselectTreeItem (item): global exoArea, exerciceList exerciceList [item.get_data ("id")].unactivate (exoArea) |
Makalemiz burada bitiyor. Python'da nesne y�nelimli geli�tirmenin �ekicili�ini grafik kullan�c� aray�z� ortam�nda ke�fettik. �lerideki makalelerde Drill'e ekleyece�imiz yeni al��t�rmalar kodlayarak Gnome widget'lar�n� ke�fetmeye devam edece�iz.
drill1.py
#!/usr/bin/python # Drill - Teo Serie # Copyright Hilaire Fernandes 2002 # Release under the terms of the GPL licence # You can get a copy of the license at http://www.gnu.org from gnome.ui import * from libglade import * # Import the exercice class from colorExercice import * from labelExercice import * exerciceTree = currentExercice = None # The exercice holder exoArea = None exoSelected = None exerciceList = {} def on_about_activate(obj): "display the about dialog" about = GladeXML ("drill.glade", "about").get_widget ("about") about.show () def on_new_activate (obj): global exoSelected if exoSelected != None: exoSelected.reset () def selectTreeItem (item): global exoArea, exoSelected, exerciceList exoSelected = exerciceList [item.get_data ("id")] exoSelected.activate (exoArea) def deselectTreeItem (item): global exoArea, exerciceList exerciceList [item.get_data ("id")].unactivate (exoArea) def addSubtree (name): global exerciceTree subTree = GtkTree () item = GtkTreeItem (name) exerciceTree.append (item) item.set_subtree (subTree) item.show () return subTree def addExercice (category, title, id): item = GtkTreeItem (title) item.set_data ("id", id) category.append (item) item.show () item.connect ("select", selectTreeItem) item.connect ("deselect", deselectTreeItem) def addMathExercice (): global exerciceList subtree = addSubtree ("Mathématiques") addExercice (subtree, "Exercice 1", "Math/Ex1") exerciceList ["Math/Ex1"] = labelExercice ("Exercice 1") addExercice (subtree, "Exercice 2", "Math. Ex2") exerciceList ["Math/Ex2"] = labelExercice ("Exercice 2") def addFrenchExercice (): global exerciceList subtree = addSubtree ("Français") addExercice (subtree, "Exercice 1", "French/Ex1") exerciceList ["French/Ex1"] = labelExercice ("Exercice 1") addExercice (subtree, "Exercice 2", "French/Ex2") exerciceList ["French/Ex2"] = labelExercice ("Exercice 2") def addHistoryExercice (): global exerciceList subtree = addSubtree ("Histoire") addExercice (subtree, "Exercice 1", "Histoiry/Ex1") exerciceList ["History/Ex1"] = labelExercice ("Exercice 1") addExercice (subtree, "Exercice 2", "Histoiry/Ex2") exerciceList ["History/Ex2"] = labelExercice ("Exercice 2") def addGeographyExercice (): global exerciceList subtree = addSubtree ("Géographie") addExercice (subtree, "Exercice 1", "Geography/Ex1") exerciceList ["Geography/Ex1"] = labelExercice ("Exercice 1") addExercice (subtree, "Exercice 2", "Geography/Ex2") exerciceList ["Geography/Ex2"] = labelExercice ("Exercice 2") def addGameExercice (): global exerciceList subtree = addSubtree ("Jeux") addExercice (subtree, "Couleur", "Games/Color") exerciceList ["Games/Color"] = colorExercice () def initDrill (): global exerciceTree, label, exoArea wTree = GladeXML ("drill.glade", "drillApp") dic = {"on_about_activate": on_about_activate, "on_exit_activate": mainquit, "on_new_activate": on_new_activate} wTree.signal_autoconnect (dic) exerciceTree = wTree.get_widget ("exerciceTree") # Temporary until we implement real exercice exoArea = wTree.get_widget ("exoArea") # Free the GladeXML tree wTree.destroy () # Add the exercice addMathExercice () addFrenchExercice () addHistoryExercice () addGeographyExercice () addGameExercice () initDrill () mainloop () |
templateExercice.py
# Exercice pure virtual class # exercice class methods should be override # when exercice class is derived class exercice: "A template exercice" exerciceWidget = None exerciceName = "No Name" def __init__ (self): "Create the exericice widget" def activate (self, area): "Set the exercice on the area container" area.add (self.exerciceWidget) def unactivate (self, area): "Remove the exercice fromt the container" area.remove (self.exerciceWidget) def reset (self): "Reset the exercice" |
labelExercice.py
# Dummy Exercice - Teo Serie # Copyright Hilaire Fernandes 2001 # Release under the terms of the GPL licence # You can get a copy of the license at http://www.gnu.org from gtk import * from templateExercice import exercice class labelExercice(exercice): "A dummy exercie, it just prints a label in the exercice area" def __init__ (self, name): self.exerciceName = "Un exercice vide" self.exerciceWidget = GtkLabel (name) self.exerciceWidget.show () |
colorExercice.py
# Color Exercice - Teo Serie # Copyright Hilaire Fernandes 2001 # Release under the terms of the GPL licence # You can get a copy of the license at http://www.gnu.org from math import cos, sin, pi from whrandom import randint from GDK import * from gnome.ui import * from templateExercice import exercice # Exercice 1 : color game class colorExercice(exercice): width, itemToSelect = 200, 8 selectedItem = rootGroup = None # to keep trace of the canvas item colorShape = [] def __init__ (self): self.exerciceName = "Le jeu de couleur" self.exerciceWidget = GnomeCanvas () self.rootGroup = self.exerciceWidget.root () self.buildGameArea () self.exerciceWidget.set_usize (self.width,self.width) self.exerciceWidget.set_scroll_region (0, 0, self.width, self.width) self.exerciceWidget.show () def reset (self): for item in self.colorShape: item.destroy () del self.colorShape[0:] self.buildGameArea () def shapeEvent (self, item, event): if event.type == ENTER_NOTIFY and self.selectedItem != item: item.set(outline_color = 'white') #highligh outline elif event.type == LEAVE_NOTIFY and self.selectedItem != item: item.set(outline_color = 'black') #unlight outline elif event.type == BUTTON_PRESS: if not self.selectedItem: item.set (outline_color = 'white') self.selectedItem = item elif item['fill_color_gdk'] == self.selectedItem['fill_color_gdk'] \ and item != self.selectedItem: item.destroy () self.selectedItem.destroy () self.colorShape.remove (item) self.colorShape.remove (self.selectedItem) self.selectedItem, self.itemToSelect = None, \ self.itemToSelect - 1 if self.itemToSelect == 0: self.buildGameArea () return 1 def buildShape (self,group, number, type, color): "build a shape of 'type' and 'color'" w = self.width / 4 x, y, r = (number % 4) * w + w / 2, (number / 4) * w + w / 2, w / 2 - 2 if type == 'circle': item = self.buildCircle (group, x, y, r, color) elif type == 'squarre': item = self.buildSquare (group, x, y, r, color) elif type == 'star': item = self.buildStar (group, x, y, r, 2, randint (3, 15), color) elif type == 'star2': item = self.buildStar (group, x, y, r, 3, randint (3, 15), color) item.connect ('event', self.shapeEvent) self.colorShape.append (item) def buildCircle (self,group, x, y, r, color): item = group.add ("ellipse", x1 = x - r, y1 = y - r, x2 = x + r, y2 = y + r, fill_color = color, outline_color = "black", width_units = 2.5) return item def buildSquare (self,group, x, y, a, color): item = group.add ("rect", x1 = x - a, y1 = y - a, x2 = x + a, y2 = y + a, fill_color = color, outline_color = "black", width_units = 2.5) return item def buildStar (self,group, x, y, r, k, n, color): "k: factor to get the internal radius" "n: number of branch" angleCenter = 2 * pi / n pts = [] for i in range (n): pts.append (x + r * cos (i * angleCenter)) pts.append (y + r * sin (i * angleCenter)) pts.append (x + r / k * cos (i * angleCenter + angleCenter / 2)) pts.append (y + r / k * sin (i * angleCenter + angleCenter / 2)) pts.append (pts[0]) pts.append (pts[1]) item = group.add ("polygon", points = pts, fill_color = color, outline_color = "black", width_units = 2.5) return item def getEmptyCell (self,l, n): "get the n-th non null element of l" length, i = len (l), 0 while i < length: if l[i] == 0: n = n - 1 if n < 0: return i i = i + 1 return i def buildGameArea (self): itemColor = ['red', 'yellow', 'green', 'brown', 'blue', 'magenta', 'darkgreen', 'bisque1'] itemShape = ['circle', 'squarre', 'star', 'star2'] emptyCell = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] self.itemToSelect, i, self.selectedItem = 8, 15, None for color in itemColor: # two items of same color n = 2 while n > 0: cellRandom = randint (0, i) cellNumber = self.getEmptyCell (emptyCell, cellRandom) emptyCell[cellNumber] = 1 self.buildShape (self.rootGroup, cellNumber, \ itemShape[randint (0, 3)], color) i, n = i - 1, n - 1 |
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Hilaire Fernandes "some rights reserved" see linuxfocus.org/license/ http://www.LinuxFocus.org |
�eviri bilgisi:
|
2004-11-23, generated by lfparser version 2.50