Python ile Stack Yapılarını Gerçekleme

Başlatan sem, 01 Eylül 2011 - 19:34:46

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

sem

http://forum.ubuntu-tr.net/index.php?topic=28891.0

Şurada biraz eksik de olsa (silme koymamıştım sanırım) stack yapıları ile ilgili C örneği paylaşmış ve kodları vermiştim... Şimdi aynı şeyi Python ile denedim... Sonuç biraz şaşıtrıcı oldu... Kod uzunluğu açısından...

Tabii C ile Python arasındaki bu fark yani kod uzunluğu farkı zaten olağan fakat ben Python'da ve bu gibi stack/kuyruk gibi yapılarda da acemi olduğum için algoritma kötü olur ve kod yine uzar diye tahmin ediyordum...

Ki algoritmayı biraz daha yetkin arkadaşlar düzenlese demek ki, kod uzunluğu epey fark edecek =)

stack yapısını düzenlemeye yarayan (her ne kadar bazı özellikleri eksik de olsa) şu modül oluyor, sadece 40 50 satır bir şey olması lazım.

#class to manage stack
class PersonStack:
    def __init__(self, maxCount):
        self.max = maxCount
        self.count = 0
        self.PFI_Container = [] #use as stack
   
    def add_to_stack(self, name, surname, age, job):
        if self.max == self.count:
            return 0
               
        new = self.PersonInfoClass(name, surname, age, job)
        self.count += 1
        self.PFI_Container.append(new)
        return new
       

    def get_count(self):
        return self.count
   
    def get_last(self):
        if self.count == 0:
            return 0
       
        self.count -= 1
        return self.PFI_Container.pop()
#####################################################   
#####################################################
#####################################################   
#class to add infos of a new person     
    class PersonInfoClass:
        def __init__(self, name, surname, age, job):
            self.name = name
            self.surname = surname
            self.age = age
            self.job = job

       
        def copy_person(self):
            new_ex = PersonStack.PersonInfoClass()       
            new_ex.name = self.name
            new_ex.surname = self.surname
            new_ex.age = self.age
            new_ex.job = self.job
            return new_ex


bu modülü şu şekilde kullanabilirsniz;


#!/usr/bin/env python
# -*- coding: utf-8-*-

from PersonInfo import *



myStack = PersonStack(5) #stack size parameter


isim = "İsim"
soyisim = "Soyisim"
meslek = "Meslek"
x = 1

while True:
    ben = myStack.add_to_stack("%s%s" %(isim, x), "%s%s"%(soyisim, x), x, "%s%s"%(meslek, x))
   
    if ben == 0:
        break
    else:
        x += 1   


while True:
    a = myStack.get_last()
    if a == 0:
        break
    else:
        print a.name
        print a.surname
        print a.age
        print a.job
        print "\n"



Buradaki

myStack = PersonStack(5) #stack size parameter

kısmı ile oynayarak istediğiniz uzunlukta bir stack ile çalışabilirsiniz...

10 uzunluğundaki bir yapı için örnek çıktı (verileri sondan yani en son eklenenden itibaren aldığımıza dikkat edin);

Alıntı Yapİsim10
Soyisim10
10
Meslek10


İsim9
Soyisim9
9
Meslek9


İsim8
Soyisim8
8
Meslek8


İsim7
Soyisim7
7
Meslek7


İsim6
Soyisim6
6
Meslek6


İsim5
Soyisim5
5
Meslek5


İsim4
Soyisim4
4
Meslek4


İsim3
Soyisim3
3
Meslek3


İsim2
Soyisim2
2
Meslek2


İsim1
Soyisim1
1
Meslek1








Evet bu işin acemi olarak paylaşım kısmıydı...

Şimdi soruma geçeyim, mutlaka stack, queue yapıları ile ilgili sınıflar vardır Python'da, olmasa şaşardım zaten... Fakat yukarıdaki stack yapısında Python'a diline göre yapmış olduğum bir hata, mantık hatası var mı? Kendimiz gerçekleyerek daha iyi öğrendiğimiz için kendim "manuel" şekilde bir örnek yapmak istedim... Bu nedenle hatalarımı görmek isterim.

Olay şundan ibaret;

list türleri bir aynı liste içerisinde string ya da tam sayı saklayabiliyor... Ayrıca bizim sınıflarımızı da saklayabiliyor... Hali ile yapmış olduğum sınıfı yani kişi bilgilerini tutan sınıfı bir liste içerisinde saklayarak, bu listeye ekleme ve çıkarma işlemi yapıyorum... Aslıdna olay bundan ibaret ama daha iyi bir teknik varsa bildiğiniz öğrenmek isterim...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

utdmr

Stack'ın kullanımını pek anlamama rağmen(bir tek performans sanırım kazancı), bir iki şey söyleyeceğim.

Dediğiniz gibi, Python'un queue modülü ve collections.deque sınıfı var, bu işe yakın olarak gördüğüm(bir de array var ama sadece c tiplerini destekliyor sanırım). Ama bu kodu kullanırsak eğer örneğin;

def copy_person(self):
            new_ex = PersonStack.PersonInfoClass()       
            new_ex.name = self.name
            new_ex.surname = self.surname
            new_ex.age = self.age
            new_ex.job = self.job
            return new_ex


Yerine copy modülünü kullanabiliriz.

def copy_person(self):
            return copy.copy(self)


Ama bu, sadece tek kademe kopyalar, yani sınıfta mutable bir object varsa, onun yine referansı geçer. Eğer copy.deepcopy kullanırsak özyinemeli olarak onlar da kopyalanacaktır. C'de nasıl bilmiyorum ama Python'da genellikle sınıfların bu şekilde bir metodu yazılmaz, isteyen copy'i kullanabilir diye.

Bir de, bildiğiniz gibi C++ veya Java'daki private member olayı yok, her şey public. Ama bunun yerine sadece sınıfı ilgilendiren üye/metod adları _ ile başlatılır, hani onlara erişmekte bir sıkıntı yoktur da, yapmasanız iyi olur gibi :D. Örneğin self._PFI_Container = [] gibi tanımlanabilir. Diğer bir anlamadığım şey de, neden len(self._PFI_Container) yerine count adında bir değişken tuttuğunuz. Sanırım C'dekinden uzaklaşmamak için.

Bir de, stack boyutu aşıldığında 0 return etmek yerine bir Exception raise edebilirsiniz. Python'da diğer dillere nazaran sık kullanılır exceptionlar, hani programın normal kurgusunun bir parçası da olabilir.
Kişisel Blogum: Çoğunlukla Zararsız - cogunluklazararsiz.org
--
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -and a lot of courage- to move in the opposite direction.

sem

#2
Sırayla gideyim ben de =)

Sınıf kopyalamadaki amacım aynı kişi lazım olabilitesi düşünülerek deneme amaçlı yaptım ve denediklerime göre string ve int türlerinde yeni oluşturuyordu =) Gerçi zaten bu sınıfla denemiş oldum biraz da işte =) Gerçi copy kısmı işin deneme kısmı... Çünkü bu sınıf lazım olacak bir sınıf değil, farazi bir sınıf olarak kabul edebiliriz.

C değil de C++'da sınıfları kullanabiliyoruz ama kopyalama methodunu biz yazmazsak derleyici kendisi yazıyordu, Python'da da yorumlayıcı kendi kendine bir kopyalama methodu mu yazıyor... C++'daki = operatörü için yazılan fonksiyondan bahsediyorum...

Aslında bilmiyordum daha doğrusu emin olamadım private, public ayrımı olmadığından... Öğrendiğim/emin olduğum iyi oldu; buradaki count değişkeni için yazılan fonksiyon tam olarak da dediğin gibi tamamen alışkanlık olmakla beraber aslında biraz da okunabilirlik açısından da daha kolaylık sağlıyor bana. Tabii bu kısım biraz öznel...

Aynen istisnai durum fırlatmak çok daha pratik ve prfesyonel bir çözüm... Onları da öğreneyim... Kendim bir exception fırlatıp yakalamayı....

@utdmr önerilerin çok faydalı oluyor gerçekten, teşekkür ederim açıklamalar için, her açıklamada yeni bir şey öğreniyorum... Hepsine ayrı ayrı dikkat ediyorum şimdiki ve önceki tavsiyelerinin...




Stack yapıları ile ilgili not düşeyim... Örneğin C/C++ programlarını düşünelim... Programa ayrılan bellek bölümleri; stack, heap, kod için ayrılan alan vs... Buradaki stack alanı stack sistemi ile çalışıyor. Örneğin bir fonksiyon çağrısı yaptık diyelim; bu fonksiyon parametreleri stack alanında yaratılıyor ve fonksiyon içerisinde kullanılıyor; yani en son yüklenip ilk olarak kullanılmış oluyorlar...

Bu bir örnek, bunun dışında ileri seviye bir çok işlemde kullanıldığını okudum...

Ya da örneğin kuyruk yapısı; queue denilen yapı... Bu yapıyı bağlı listeler ile özellikle çift yönlü bağlı liste ile gerçeklediğimiz zaman, dinamik bellek yönetimi yanı sıra, verilerin bellekte sıralı tutulması, birbirleri arasında geçi gibi bir çok sorunu aynı anda ortadan kaldırmış oluyoruz...

Tabii şimdi Python'da bellek yönetimi bu kadar sıkıntı değil =) Ama C/C++ gibi dillerde bu şekilde sıkıntı olayları bir arada ortadan kaldırabilmek büyük nimet... Hani C++ için de STL'in nimetlerinden yararlanılabilir de C için büyük nimetlermiş bunlar gerçekten... Ben de yeni yeni öğreniyorum işte =)


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 01 Eylül 2011 - 23:14:43

EK: Bazı şeyleri bellekte tutup işlemek yerine önce bir dosyaya yazdırıp sonra dosyadan okuduğumuzu düşünelim... Kısayol Oluşturucu programında böyle yapılıyordu yanılmıyorsam... Hatırlamıyorm şu an problem çözümlerimizi...

Bu gibi bir sistemde geriyi okumak için rewind uygulamak gerekiyor... Ve 4 önceki veriyi okumak da büyük sıkıntı... Okuduğun verilerde \n karakterini ayıklayarak satır sayılarını saymak gerekiyor vs gibi ilginç çözümler... Bunun yerine bir kuyruk yapısı kullansak mesela; tek yapılması gereken 4 önceki indeksi okumak...

böyle böyle faydaları oluyor da şimdi aklıma başka örnek gelmedi bu yapılarla ilgili olarak

Not: hızlı ve dağınık yazdım biraz, imla hataları ve anlam düşüklükleri için kusura bakma.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Yakında benim diyen programlama forumlarını falan geçecek sanırım burası :)
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.