Kellerspeicher und umgekehrte Polnische Notation

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
xdhwde
User
Beiträge: 3
Registriert: Mittwoch 14. November 2007, 10:04

he, liebe pythonfreunde! ich hab mal wider nen problem.

ich hab mir nen stack gebastelt zur simulation eines kellerspeichers der hat folgende funktionen leer, voll, raus, rein,..so alles schick und gut...jeden falls will ich jetzt zum beispiel mit der eingabe 4,5,3,8,+,-,*,+2 was auch immer, die sachen in einen stack packen und nach einander ausrechnen..und da hapers ich pack die sachen zwar in so wie sie da stehn in stack aber bekomme sie net mehr abgearbeitet...

ich bräuchte hilfe bei den stack methoden oben (das letzte element auslesen, bzw das erste), zeigen(die reihe nach die elemente anzeigen) und wie gesagt eine methode die eine eingabe wie oben beschrieben in den stack packt die elemente entnimmt und ausrechnet..eine art polnische notation

quellcode vom stack

Code: Alles auswählen

01 class stack : 
02  	

03 def __init__(self) : 
04                  self.liste = [] 
05

06 def empty (self)   : 
06                  return len (self.liste) == 0 
07  

08 def push (self)    : 
09                  self.liste.insert (0,wert) 
10  

11 def pop (self)     : 
12                  if self.liste == [] : return 
13                  else                :
14                      wert = self.liste [0]  
15                      del self.liste [0]
16                      return wert 
17                       
18 def top (self)    : 

19                  return self.liste [0] 
vll. könnt ihr mir ja weiter helfen?
Zuletzt geändert von xdhwde am Sonntag 23. November 2008, 01:37, insgesamt 1-mal geändert.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Äh... *WAS* willst du nochmal machen?
Bahnhof, Bahnhof, Bahnhöfe
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Code: Alles auswählen

def foo(operator, *args):
    return eval(' {0} '.format(operator).join(str(arg) for arg in args))
BlackJack

@xdhwde: Erst einmal sieht das verdammt danach aus, als wenn wir Deine Hausaufgaben für Dich lösen sollen.

Dann ist das *sehr* merkwürdig formatierter Python-Quelltext, der ausserdem noch nicht einmal kompiliert, wegen der Zeilennummern.

Der `Stack` -- den Klassennamen solltest Du mit einem Grossbuchstaben beginnen -- ist ziemlich ineffizient implementiert, weil Du immer an Index 0 Elemente einfügst und entfernst, was letztendlich bedeutet, dass alle anderen Elemente im Speicher verschoben werden müssen. Schreib das mal so um, dass das Ende verwendet wird.

Du darfst die Daten nicht erst alle auf den Stapel packen und sie danach ausrechnen. Du musst die Daten der Reihe nach verarbeiten und bei jedem Datum entscheiden was damit passieren soll. Zeig mal was Du bisher hast. Und bitte so, dass man das a) auch ausführen kann und es b) ordentlich formatiert ist, soll heissen wie Python-Quelltext und nicht wie Haskell oder so.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

BlackJack hat geschrieben:Der `Stack` -- den Klassennamen solltest Du mit einem Grossbuchstaben beginnen -- ist ziemlich ineffizient implementiert, weil Du immer an Index 0 Elemente einfügst und entfernst, was letztendlich bedeutet, dass alle anderen Elemente im Speicher verschoben werden müssen. Schreib das mal so um, dass das Ende verwendet wird.
Oder ``collections.deque`` verwenden.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

xdhwde, dein Code ist umständlich, erfüllt aber so weit doch deine eigenen Anforderungen. Dein "zeigen" wäre doch einfach ein `print self.liste`. Dat schafft du schon noch selbst.

Ausrechnen kann man das ganze so, entspricht jedoch bestimmt nicht der Aufgabenstellung, da es den Vorteil der UPN ad absurdum führt, da mein Algorithmus rekursiv ist. Genau das lässt sich vermeiden, wenn man es anders macht:

Code: Alles auswählen

def pop_and_eval(stack):
	val = stack.pop()
	if callable(val):
		b, a = pop_and_eval(stack), pop_and_eval(stack)
		return val(a, b)
	return val

add = int.__add__

mul = int.__mul__

stack = [1, 2, add, 3, mul]

print pop_and_eval(stack)
Stefan
xdhwde
User
Beiträge: 3
Registriert: Mittwoch 14. November 2007, 10:04

he..danke euch erstmal für die vielen antworten ..werd mir das erstmal intensiv durchlesen und nachher meine Quelltexte reinposten! mit kommentierung und ordnerlicher formatierung, gestern arben war schon spät^^
xdhwde
User
Beiträge: 3
Registriert: Mittwoch 14. November 2007, 10:04

hier erstmal der fast fertige quelltext:

Code: Alles auswählen

class stack:

      def __init__(self):
          
          self.liste = []

      def empty(self):
      #Vor.: der Stapel ist initialisiert
      #Erg.: geliert ist True, falls der Stapel kein Element enthält, sonst False

            return len (self.liste) == 0
            return True

      def push(self, wert):
      #Vor.: der Stapel ist initialisiert und nicht voll, wert ist vom Typ Elemtnttyp.
      #Erg.: geliefert ist True, falls der Stapel kein Element enthält, sonst False

            self.liste.insert (0, wert)

      def pop(self):
      #Vor.: der Stapel ist initialisiert
      #Erg.: das Element, das als letztes aufgelegt wurde, ist vom Stapel entfernt

            wert = self.liste [0]
            del self.liste [0]

      def top(self):
      #Vor.: der Stapel ist initialisiert
      #Erg.: geliefert ist das Element, das als letztes aufgelegt wurde

            return self.liste [0]

      def show(self):
      #Vor.: der Stapel ist initialisiert
      #Erg.: die Elemente, die auf dem Stapel liegen, sind der Reihe nach angezeigt

            return self.liste



def pop_and_eval(stack):
    val = stack.pop()
    if callable(val):
        b, a = pop_and_eval(stack), pop_and_eval(stack)
        return val(a, b)
    return val

add = int.__add__

mul = int.__mul__



stack = [1, 2, add, 3, mul]

print pop_and_eval(stack)


theoretisch müsst ich ja nur noch ne raw_input methode machen für die werte und dann die methode pop and eval aufrufen oder? habt ihr noch verbesserungs vorschläge!
BlackJack

@xdhwde: Du willst echt das jemand Deine Hausaufgaben für Dich macht, oder?

Theoretisch müsstest Du nur noch eine Lösung für die Aufgabe programmieren, statt Quelltext zu kopieren, der den Stack überhaupt nicht verwendet, und damit an der Aufgabenstellung vorbei geht.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

xdhwde hat geschrieben:habt ihr noch verbesserungs vorschläge!
Ja habe ich?

Ich würde den Stack nach hinten wachsen lassen, statt nach vorne wie du es machst, weil es so wesentlich effizienter ist. Python ist kein Lisp indem man Elemente via ``cons`` vorne anhängt. Außrdem solltest du den Stack vielleicht auch nutzen, den du da definiert hast, statt sma seine Lösung zu kopieren und deine Stackklasse oben drüber zu setzen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Eine kleine Anmerkung: Eine Python Liste stellt eigentlich schon einen Stack dar, wenn man [].pop(-1) benutzt.

Code: Alles auswählen

In [7]: a = [1, 2, 3]

In [8]: a.pop(-1)
Out[8]: 3

In [9]: a
Out[9]: [1, 2]
farid
User
Beiträge: 95
Registriert: Mittwoch 8. Oktober 2008, 15:37

Dauerbaustelle hat geschrieben:Äh... *WAS* willst du nochmal machen?
Bahnhof, Bahnhof, Bahnhöfe
Er moechte vielleicht einen alten HP Taschenrechner nachbilden. RPN war eine lange Zeit sehr en vogue:

http://en.wikipedia.org/wiki/Reverse_Polish_notation
BlackJack

Was heisst alt und wieso "war"? Ich mag meinen HP jedenfalls und mein C64 ist deutlich älter (und den mag ich auch). :-)
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Hi,
hab mal kurz was gebastelt.
Hoffe es ist nicht zu schlecht.

Code: Alles auswählen

## Kellerspeicher.py

class Kellerspeicher (object):
    
    def __init__ (self, alphabet=[]):
        self.kspeicher = []
        self.kalphabet = alphabet

    def __push__ (self, item):
        self.item = item
        if (self.item in self.kalphabet) == True:
            self.kspeicher.append(self.item)
            print item,"dem Kellerspeicher hinzugefuegt."
        else:
            print item,"ist nicht im Kelleralphabet."

    def __pop__ (self):
        try:
            return self.kspeicher.pop(-1)
        except IndexError:
            print "Nichts im Kellerspeicher."
MfG Jonas
PS: Schönes Restwochenende.

EDIT: Polnische Umgekehrte Notation kann der Threadsteller schön
selbst basteln... Wir machen hier schließlich wie schon von vielen
meiner Vorposter erwähnt nicht die Hausaufgaben.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Was soll das soll das ``k`` vor den Namen? Es ist ja nicht so, als ob Python keine Namespaces hätte. Die Klasse bietet dir einen solchen und ``alphabet`` ist einfacher zu lesen, verstehen und zu tippen als ``kalphabet``, Außerdem ist das ``== True`` ebenfalls überflüssig, wenn if prüft schon auf True, da muss man nicht noch extra sichergehen, dass ``True == True``. Die Klammern sind dann auch überflüssig.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Leonidas hat geschrieben:Was soll das soll das ``k`` vor den Namen?
Vielleicht hast du gerade einen KDE-Entwickler enttarnt :D
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

hi,
@Leonidas:
Das `k` vor den Namen steht für "Keller-"
Ich wäre dir verbunden wenn du den Hinweis auf
die Namespaces nochmal in diesem Zusammenhang
erläutern könntest, kapier ich nämlich nicht :?:
Wenn man den Kellerspeicher benutzt benutzt man
doch nur "alphabet":

Code: Alles auswählen

IMkeller = Kellerspeicher(alphabet=[1,2,3,4])
MfG Jonas :D
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@jonas Die Aufgabenstellung löst dass wohl nicht so ganz und die Underscores bei push und pop gehören da nicht hin. Wenn überhaupt verwendet man zwei vor dem Namen aber hier will man ja von außen darauf zugreifen.
Zu den namespaces kellerspeicher.kalphabet vs. kellerspeicher.alphabet was erscheint dir sinnvoller?

Sinnvoller ist es hier von list zu erben und append(, pop) zu überschreiben.
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Hi,
@DasIch:
Danke für die hilfreichen Anregungen zum Code.
Wann benutzt man den genau "Underscores"?
Erben von z.B. list werd ich mir nochmal ansehen.
:D

MfG Jonas
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jonas hat geschrieben:Das `k` vor den Namen steht für "Keller-"
Ich wäre dir verbunden wenn du den Hinweis auf
die Namespaces nochmal in diesem Zusammenhang
erläutern könntest, kapier ich nämlich nicht :?:
Ja, aber welchen Sinn haben die ``k``? Es ist schon klar, dass ``alphabet`` zu ``Kellerspeicher`` gehört, es ist ja ein Attribut der Klasse.

Du stimmst mir sicher zu, dass

Code: Alles auswählen

kellerspeicher = Kellerspeicher(['a'])
print kellerspeicher.kalphabet
irgendwie seltsam ist wenn ``kellerspeicher.alphabet`` genauso möglich wäre.

Außerdem hast du da ein Mutables Objekt in der Signatur, das solltest du lassen, denn damit kannst du dir erstaunlich abstruse Fehler einfangen. So wird die Liste nur einmal erstellt und behält ihre Inhalte (statt immer auf [] gesetzt zu werden) - sowas willst du mit hoher Sicherheit nicht haben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten