string zu no string konvertieren ?

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

str1442 hat geschrieben:Also mir fiele nur das Decorator Pattern ein, das direkt in Python möglich wäre, auch, wenn Klassen Dekoratoren erst ab 2.6 möglich sind.
Spontan fällt mir das Factory Pattern ein und das Visitor Pattern würde man so in Python auch nicht machen. Aber ich habe das Buch gerade nicht da, also kann jetzt nicht reinschauen und sagen was man da noch anders machen würde.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

BlackJack hat geschrieben:Und der Code unter der ``if __name__``-Abfrage sollte noch in einer `main()`-Funktion verschwinden. Dann sieht man auch gleich, das Exemplare von `Root` auf ein "globales" `cube`-Objekt zugreifen, was so nicht sein sollte.
Würde es die Lage verbessern, wenn ich es zum Beispiel so machem würde?:

Code: Alles auswählen

class Root(object):
    def __init__(self, Wuerfel):
        self.Wuerfel = Wuerfel

                

def main():
    if __name__ == "__main__":
        Wuerfel = Cube()
        Fenster = Root(Wuerfel)

main()

Hab gerade auch meinen Fehler im richtigem Code gefunden.
Bei der definition von einem Button wird bei mir das command sofort ausgeführt.

Code: Alles auswählen

        for side in ('back', 'bottom', 'front', 'left', 'right', 'top'):
            self.rotationButtonDict[side] = 'Button'
            self.rotationButtonDict[side] = tk.Button(self.container5, text=(str(side)+'.'), width=16,
                                                      command=wuerfel.rotating(side)) 
            self.rotationButtonDict[side].pack(side='left', padx=2, pady=6)
Deswegen ist der Cube immer schon verdreht, ich die Felder abgebildet werden.
Ich habe Recht, wenn ich annehme, dass rotationButtonDict kein geeigneter name ist?

Ist mir neu, dass bei der Definition von Buttons die command-Anweisung ausgeführt wird. Gehört sich das so?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

smashed to pieces hat geschrieben:Ist mir neu, dass bei der Definition von Buttons die command-Anweisung ausgeführt wird. Gehört sich das so?
Das liegt an dir. Wenn du nicht willst, dass der Command-Handler ausgeführt wird (was man eben meistens nicht will), dann darfst du ihn nicht AUFRUFEN sondern musst den Handler als Objekt übergeben. Oder in Kurzform: Die Klammern müssen weg.
BlackJack

@smashed to pieces: Üblicherweise ruft man die `main()` innerhalb der ``if``-Abfrage auf Modulebene auf, aber so geht's natürlich auch.

Und das die Methoden aufgerufen werden "gehört sich so" denn schliesslich rufst *Du* sie ja auch auf. Und zwar bevor der Button überhaupt erstellt wird.

Code: Alles auswählen

b = X(z=f(42))
ist ja nichts anderes als:

Code: Alles auswählen

tmp = f(42)
b = X(z=tmp)
Wenn Du die Argumente festlegen, aber die Funktion noch nicht aufrufen willst, kannst Du ``lambda`` verwenden, oder `functools.partial()`.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

oh. :oops:

Ok, da ich wuerfel.rotating(side) natürlich mit dem Parameter side aufrufen will. Muss ich das Ganze anders lösen.
BlackJack hat geschrieben:Wenn Du die Argumente festlegen, aber die Funktion noch nicht aufrufen willst, kannst Du ``lambda`` verwenden, oder `functools.partial()`.
War das so gemeint?
Das funktioniert zwar. Sieht aber meiner Meinung noch nicht alzu schön aus:

Code: Alles auswählen

for side in ('back', 'bottom', 'front', 'left', 'right', 'top'):
    self.rotationButtonDict[side] = 'Button'
    self.rotationButtonDict[side] = tk.Button(self.container5, text=(str(side)+'.'), width=16,
                                              command=lambda side=side: self.Wuerfel.rotating(side))
    self.rotationButtonDict[side].pack(side='left', padx=2, pady=6)
Aber Danke :)
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Nochmal hallo,

ich bin noch immer auf der Suche noch einem Buch um Python besser zu verstehen. Speziell zum Thema objektorientierte Programmierung, da ich den Informationsaustausch zwischen Klassen noch relativ wenig verstehe. In dem Buch sollte nach Möglichkeit aber auch immer die übliche Verwenung von Dingen erleutert werden. Wichtig ist natürlich auch, dass es kein Buch für komplette Anfänger ist, da ich das grundlegende Wissen für Python im groben schon besitze.

Dazu meine Frage:
Ist das Buch Objektorientierte Programmierung mit Python von Michael Weigend für diesen Zweck geeignet, bzw. würdet ihr es als gutes Buch weiterempfelen?


Meine zweite Frage ist, ob man für die Oberfläche etwas größerer Programmes üblicherweise mehrere Klassen verwendet. Also zum Beispiel, eine Klasse für das Fenster im allgemeinem und eine weitere allein für das Menü.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

smashed to pieces hat geschrieben:Ist das Buch Objektorientierte Programmierung mit Python von Michael Weigend für diesen Zweck geeignet, bzw. würdet ihr es als gutes Buch weiterempfelen?
Ich halte das Buch für Programmieranfänger für gut geeignet, weil sehr sanft und anständig in die Programmierung eingeführt wird. Sogar so fundamentale Sachen wie "EVA"-Prinzip werden explizit behandelt.

Geeignet ist es auch, wenn man ein deutschsprachiges Buch sucht, in dem Tkinter auf mehr als 3 Seiten behandelt wird (es sind rund 100 Seiten in diesem Buch) oder einen ersten Einblick braucht, wie man Python und CGI zusammenbringt.

Speziell was die Objektorientierung angeht, so fand ich das Buch nicht so überragend, weil mir die Beispiele nicht so gefallen haben und mir da irgendwie der Tiefgang gefehlt hat.
smashed to pieces hat geschrieben:Meine zweite Frage ist, ob man für die Oberfläche etwas größerer Programmes üblicherweise mehrere Klassen verwendet. Also zum Beispiel, eine Klasse für das Fenster im allgemeinem und eine weitere allein für das Menü.
IMHO gibt es hier kein "üblicherweise", es hat eher etwas mit persönlichen Vorlieben zu tun. Und auch mit der Definition von "etwas größer". Es bietet sich zumindest an, den ersten Aufbau der GUI, wenn er nicht ganz simpel ist, aus der __init_-()-Methode auszulagern in eine eigene Methode, die man dann aus __init__() heraus aufruft.
BlackJack

Zur GUI: Ich denke schon das man üblicherweise etwas komplexere GUIs auf Klassen aufteilt. Es würde sich zum Beispiel anbieten ein `CubeWidget` zu implementieren, also eine GUI-Komponente für den Würfel.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Gibt es ein anderes Buch, welches du mir empfehlen kann?
Kann eigentlich eh auch english sein.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Code: Alles auswählen

class Cube(object):
    def __init__(self, width=3, colors=['black','white','red','yellow','blue','green'], sides=['top','bottom','front','back','left','right']):
        self.width = width
        self.colors = colors
        self.sides = sides
        self.reset()
        self.borderDict = {self.cubeDict['top'][1]:self.cubeDict['back'][7], self.cubeDict['top'][3]:self.cubeDict['left'][5], 
                          self.cubeDict['top'][5]:self.cubeDict['right'][3], self.cubeDict['top'][7]:self.cubeDict['front'][1],
                          self.cubeDict['bottom'][1]:self.cubeDict['back'][1], self.cubeDict['bottom'][3]:self.cubeDict['right'][5], 
                          self.cubeDict['bottom'][5]:self.cubeDict['left'][3], self.cubeDict['bottom'][7]:self.cubeDict['front'][7],
                          self.cubeDict['front'][3]:self.cubeDict['left'][7], self.cubeDict['front'][5]:self.cubeDict['right'][7],
                          self.cubeDict['back'][3]:self.cubeDict['left'][1], self.cubeDict['back'][5]:self.cubeDict['right'][1]}
        self.cornerDict = {}
    
    def create_side(self, color):
        return [color for dummy in xrange(self.width*self.width)]
    
    def create_cube(self):
        return dict((side, self.create_side(color))
                    for side, color in zip(self.sides, self.colors))

    def main(self):
        return self.create_cube()

    def reset(self):
        self.cubeDict = self.main()

    def prob(self):
        for side in self.borderDict:
            print side, self.borderDict[side]

def main():
    cube = Cube()
    cube.prob()
main()
Ausgabe:

Code: Alles auswählen

>>> 
white red
black red
yellow green
red green
>>> 
Die Ausgabe versteh ich überhaupt nicht.
Self.borderDict besteht aus 10 Parren und nicht aus 4. Trotzdem werden nur 4 Paare ausgegeben.
Es sieht eher so aus als würden nur die letzten Paare einer Seite ausgegeben werden, das heißt als ob sich die Werte überschreiben?! Aber wie sollte soetwas in einer for-Schleife funktionieren?
Hab auch schon self.borderDict.iterkeys() ausprobiert, was allerdings das gleiche bewirkt, und auch solltet oder?

mfg
smashed
BlackJack

Das ist alles so durch die Brust ins Auge. Diese Aufrufkette `__init__()` -> `reset()` -> `main()` -> `create_cube()` macht den Quelltext schwerer zu lesen als er sein müsste. Eine `reset()`-Methode würde ich weglassen. Wenn jemand einen neuen Würfel haben will, kann er auch ein neues Exemplar erstellen, statt einen vorhandenen zu "resetten". `main()` ist ein komischer Name für eine Methode. Und die hier tut noch nicht mal wirklich etwas. Bei `create_cube()` als öffentlicher Methode würde ich einen `Cube` als Rückgabewert erwarten und kein Dictionary mit irgendwelchen Interna eines `Cube`.

Schreib doch einfach erst einmal eine möglichst einfache `__init__()`, die ein komplett initialisiertes `Cube`-Exemplar hinterlässt.

`self.boderDict` enthält 4 Einträge und nicht 10. Sonst würden ja auch 10 ausgegeben werden.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Also, nocheinmal aufgeschrieben:

Code: Alles auswählen

class Cube(object):
    def __init__(self):
        self.cubeDict = self.create_cubeDict()
        
        self.borderDict = {self.cubeDict['top'][1]:self.cubeDict['back'][7],self.cubeDict['top'][3]:self.cubeDict['left'][5],
                           self.cubeDict['top'][5]:self.cubeDict['right'][3],self.cubeDict['top'][7]:self.cubeDict['front'][1],
                           self.cubeDict['bottom'][1]:self.cubeDict['back'][1],self.cubeDict['bottom'][3]:self.cubeDict['right'][5],
                           self.cubeDict['bottom'][5]:self.cubeDict['left'][3],self.cubeDict['bottom'][7]:self.cubeDict['front'][7],
                           self.cubeDict['front'][3]:self.cubeDict['left'][7],self.cubeDict['front'][5]:self.cubeDict['right'][7],
                           self.cubeDict['back'][3]:self.cubeDict['left'][1],self.cubeDict['back'][5]:self.cubeDict['right'][1]}
        
        self.cornerDict = {self.cubeDict['top'][0]:(self.cubeDict['left'][3],self.cubeDict['back'][6]),
                           self.cubeDict['top'][2]:(self.cubeDict['back'][8],self.cubeDict['right'][0]),
                           self.cubeDict['top'][6]:(self.cubeDict['front'][0],self.cubeDict['left'][8]),
                           self.cubeDict['top'][8]:(self.cubeDict['right'][6],self.cubeDict['front'][2]),
                           self.cubeDict['bottom'][0]:(self.cubeDict['right'][2],self.cubeDict['back'][2]),
                           self.cubeDict['bottom'][2]:(self.cubeDict['back'][0],self.cubeDict['left'][0]),
                           self.cubeDict['bottom'][6]:(self.cubeDict['front'][8],self.cubeDict['right'][8]),
                           self.cubeDict['bottom'][8]:(self.cubeDict['left'][6],self.cubeDict['front'][6]),}
    
    
    def create_cubeDict(self):
        colors = ['black','white','red','yellow','blue','green']
        sides = ['top','bottom','front','back','left','right']
        def create_side(color):
            return [color for dummy in xrange(9)]
        return dict((side, create_side(color))
                    for side, color in zip(sides, colors))
        
    def dissolving(self):
        for side in self.cornerDict:
            print side
        print
        for side in self.borderDict:
            print side
            
cube = Cube()
cube.dissolving()
Ausgabe:
white
black

white
black
yellow
red


Dazu ist zu sagen das in borderDict alsauch in cornerDict doch eindeutig mehr als 10 Paare definiert sind, bzw. warum sind sie es nicht, sollte meines Erachtens eigentlich passen. Aber anscheinend ist eben dieses falsch, funktioniert ja nicht wie gewollt.

Die Ausgabe die ich wollte :
white
white
white
white
black
black
black
black

white
white
white
white
black
black
black
black
yellow
yellow
red
red


So das jeder Schlüssel einmal abgebildet wird.
Aber irgendwie ... :(
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

smashed to pieces hat geschrieben:verstehen. Speziell zum Thema objektorientierte Programmierung
Ich habe das hier jetzt nur ultraschnell überflogen, aber gerade am Objektmodell scheint da etwas schief zu liegen.
Imho besteht der Zauberwürfel" eben nicht nur aus "Seiten" und "Farben", er hat (mal kurz überschlagen) 26 Teile:

8 Ecken mit 3 Seiten und 3 Farben
12 Teile mit 2 Seiten und 2 Farben
6 Teile mit 1 Seite und 1 Farbe
(+ 1 Teil in der Mitte)

Diese Objekte haben somit Attribute. Desweiten sollte dann das Objekt Würfel mit diesen (Teil) Objekten modelliert werden. Diese sind gleichsam der innere Zustand des Würfels, der durch jene Lagerungen als Attribut des Würfels bestimmt ist.
Der Würfel bietet darüber hinaus Methoden an, "Moves", die dessen inneren Zustand ändern, so dass diese Zuständänderungen mit den möglichen Lagerungen der Teilobjekte verträglich ist.
Bevor du hier nicht eine vernünftige Objektmodellierung hast, würde ich kein Zeichen Code schreiben ;-)
BlackJack

@Qubit: Wobei man es mit dem Realismus auch nicht übertreiben muss. Es reicht durchaus Seiten mit Farben zu verwalten, es muss kein "physikalisch" korrektes Modell sein.

@smashed to pieces: Ein Schlüssel kann in einem Dictionary nur *einmal* vorkommen. Deine gewünschte Ausgabe ist also so gar nicht möglich.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Heißt das folglich auch, dass die dictionaries unverwendbar sind, weil der Python-Interpret Ausdrücke wie self.cubeDict['top'][1] sofort in die aktuelle Farbe umwandelt?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

smashed to pieces hat geschrieben:Heißt das folglich auch, dass die dictionaries unverwendbar sind[...]
Nein, dass heisst nur das du nicht in der Lage bist dictionaries richtig zu verwenden.
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

BlackJack hat geschrieben:@Qubit: Wobei man es mit dem Realismus auch nicht übertreiben muss. Es reicht durchaus Seiten mit Farben zu verwalten, es muss kein "physikalisch" korrektes Modell sein.
Nein, das Modell ist ein abstract layer, keine Simulation ;-)
So interessieren hier zB nicht die Drehungen um 90 Grad und das "gequietsche" des Würfels. Es interessieren diesbezüglich (endliche) Zustände, daher würde ich auch von "Transitions" und nicht von "Drehungen" in den Methoden sprechen.
Der Vorteil ist, dass man nicht alle Zustände der Teilsysteme in den Methoden als Interface des Würfels implementieren und somit kennen muss; das ergibt sich dann aus dem Objektmodell von selbst :-)
Wenn man einen Zustandsraum mitmodelliert, dann legen die 6 zentrierten Objekte (plus das oBdA im Mittelpunkt fixierte Objekt) ein "Bezugssystem" fest. Da "Transitions" zwei Richtungen haben, legen jeweils zwei der 6 Objekte auch eine Rictung + "Drehsinn" fest, sozusagen ein "Farbbezugssystem".
Ich würde nun die Zustände in den Objekten selbst speichern. Transitions modifizieren also direkt die Attribute der Objekte. Wenn ich also ein "Zweifarbenobjekt" hätte (blau,gruen), dann wäre eine Transition zB ein Übergang von [blau,gruen] -> [rot,gelb], der Zustand somit eine Eigenschaft des Objekts selbst (zusätzlich zur intrinsischen Eigenschaft (blau,gruen)). Natürlich müssen alle Transitions wohlüberlegt modelliert werden; notfalls händisch, besser mit einer "Würfelalgebra". Aber das würde dann vielleicht doch etwas über das Ziel hinausgehen ;-)
BlackJack

@Qubit: Das klingt IMHO alles komplizierter als 6 Seiten jeweils als n*n-Feld von Farbwerten zu speichern.
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

BlackJack hat geschrieben:@Qubit: Das klingt IMHO alles komplizierter als 6 Seiten jeweils als n*n-Feld von Farbwerten zu speichern.
Naja, klar, die Spezifikationen sind umfänglicher als eine anschliessende Implementierung in Python oder Ruby.. nur in Java wäre die Implementierung umfänglicher als die Spezifikation ;-)
Der TO wollte ja etwas über OOD erfahren, oder nicht?
lunar

Qubit hat geschrieben:Der TO wollte ja etwas über OOD erfahren, oder nicht?
Gemessen an dem, was der OP erreichen möchte, waren deine Ausführung aber schon näher am Overengineering als am Design ;)
Antworten