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.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.
string zu no string konvertieren ?
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
-
- User
- Beiträge: 38
- Registriert: Samstag 24. November 2007, 16:50
Würde es die Lage verbessern, wenn ich es zum Beispiel so machem würde?: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.
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)
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?
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.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?
@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.
ist ja nichts anderes als:
Wenn Du die Argumente festlegen, aber die Funktion noch nicht aufrufen willst, kannst Du ``lambda`` verwenden, oder `functools.partial()`.
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))
Code: Alles auswählen
tmp = f(42)
b = X(z=tmp)
-
- User
- Beiträge: 38
- Registriert: Samstag 24. November 2007, 16:50
oh.
Ok, da ich wuerfel.rotating(side) natürlich mit dem Parameter side aufrufen will. Muss ich das Ganze anders lösen.
Das funktioniert zwar. Sieht aber meiner Meinung noch nicht alzu schön aus:
Aber Danke
Ok, da ich wuerfel.rotating(side) natürlich mit dem Parameter side aufrufen will. Muss ich das Ganze anders lösen.
War das so gemeint?BlackJack hat geschrieben:Wenn Du die Argumente festlegen, aber die Funktion noch nicht aufrufen willst, kannst Du ``lambda`` verwenden, oder `functools.partial()`.
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)
-
- 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ü.
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ü.
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.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?
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.
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.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ü.
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.
-
- 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.
Kann eigentlich eh auch english sein.
-
- 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()
Code: Alles auswählen
>>>
white red
black red
yellow green
red green
>>>
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
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.
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.
-
- User
- Beiträge: 38
- Registriert: Samstag 24. November 2007, 16:50
Also, nocheinmal aufgeschrieben:
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 ...
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()
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 ...
Ich habe das hier jetzt nur ultraschnell überflogen, aber gerade am Objektmodell scheint da etwas schief zu liegen.smashed to pieces hat geschrieben:verstehen. Speziell zum Thema objektorientierte Programmierung
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
@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: Ein Schlüssel kann in einem Dictionary nur *einmal* vorkommen. Deine gewünschte Ausgabe ist also so gar nicht möglich.
-
- 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?
Nein, das Modell ist ein abstract layer, keine SimulationBlackJack 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.
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
@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 SpezifikationBlackJack hat geschrieben:@Qubit: Das klingt IMHO alles komplizierter als 6 Seiten jeweils als n*n-Feld von Farbwerten zu speichern.
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 DesignQubit hat geschrieben:Der TO wollte ja etwas über OOD erfahren, oder nicht?