Hallo liebe Leute
Ich habe ein ganz dickes Problem.
seit einiger Zeit programmiere ich in der Schule Python. Aufgabe war ein Conway game of live mit Donout world zu schreiben.
hier ist eine url mit einer Erklärung und einem Testprogramm leider ohne Donout world. Dies ist jedoch nicht weiter schlim. die Donout world sorgt ledentlich dafür das auch am rand auf der gegenüberligenden seite geschaut wird ob es nachbarn gibt.
so viel zur Aufgabe
ich habe nun also eine Klasse geschrieben die einige Methoden verwendet um das Spiel gemäß den Regeln zu realisieren. Dazu habe ich ein Dictionary verwendet. nur leider verändert sich das dictionary nicht. ich kann keine elemente Löschen und auch keins zufügen
Meine Klasse sieht wie folgt aus:
# -*_ coding: cp1252 _*_
from random import *
import copy
class GameOfLive:
# Initialisierung
def __init__(self):
self.__m_yalt = 0
self.__m_xalt = 0
self.__m_x = 0
self.__m_y = 0
self.__m_anz = 0
self.__m_fielddic = {}
self.__m_lastgenerationdic={}
self.__m_eingabe = 0
# setzen der ersten Zellen
def platzieren(self, anz):
self.__m_fielddic[5,3]='C'
self.__m_fielddic[4,4]='C'
self.__m_fielddic[3,5]='C'
self.__m_fielddic[4,6]='C'
self.__m_fielddic[5,7]='C'
self.__m_fielddic[6,6]='C'
self.__m_fielddic[7,5]='C'
self.__m_fielddic[6,4]='C'
# Nachbarn ermitteln
def nachbar(self, x,y):
self.__m_nachbar=[] for z in range (-1,2): for j in range (-1,2): if x!=x+z or y!=y+j: self.__m_nachbar.append([x+z,y+j]) return copy.copy(self.__m_nachbar)
def ersetzen(self, nachbar):
self.__m_nachbar=nachbar
for item in self.__m_nachbar : for z in range (0,2) : if item[z]<0 : item[z] = 9
if item[z] >9 : item [z]=0 return copy.copy(self.__m_nachbar)
# auswerten
def auswerten(self, nachbar):
self.__m_anz=0
for item in nachbar: if self.__m_lastgenerationdic.has_key(tuple(item)):
self.__anz+=1 return self.__m_anz
# wachsen
def wachse(self,anz,x,y):
if anz==3: if self.__m_lastgenerationdic.has_key((x,y))==False:
self.__m_fielddic[(x,y)]='C'
# sterben
def sterbe(self,anz,x,y):
if (anz < 2) or (anz > 3): if self.__m_lastgenerationdic.has_key((x,y)):
del self.__m_fielddic[(x,y)]
# Attribut hole Feld nach Außen geben
def holeFeld(self):
return copy.copy(self.__m_fielddic)
# Letzte gerneration in einem anderen dictionary speichern
def letztegerneration(self):
self.__m_lastgeneration=copy.copy(self.__m_fielddic)
#Testprogramm
if __name__ == '__main__':
gol=GameOfLive()
field={}
nachbar=[]
eingabe=0
anz=0
zahl=0
# platzieren der ersten zellen und bei Fehler abbrechen
gol.platzieren(zahl)
field=gol.holeFeld()
print 'Startkombination'
print
for z in range (0,100):
if z % 10 == 0 :
print
print field.get((z%10, z/10),' '),
print
gol.letztegerneration()
for i in range (0,100):
nachbar=gol.nachbar(i%10,i/10)
nachbar=gol.ersetzen(copy.copy(nachbar))
anz=gol.auswerten(copy.copy(nachbar))
gol.sterbe(anz,i%10,i/10)
gol.wachse(anz,i%10,i/10)
gol.holeFeld()
print 'naechste gerneration'
print
for z in range (0,100):
if z % 10 == 0 :
print
print field.get((z%10, z/10),' '),
print
soo sieht das programm also ungefair aus
in der Methode wachse passiert nichts und bei sterbe eben so wenig, obwohl der interpreter die Klasse und die Methoden ausführt. Auch die If. ich weiß einfach nicht mehr weiter
Kann mir jemand helfen?
Dictionary wird nicht ergenzt bzw verändert
okk erfolgt sogleich muss mich noch etwas zurecht finden
aber danke schon mal für das interesse
Code: Alles auswählen
class GameOfLive:
# Initialisierung
def __init__(self):
self.__m_yalt = 0
self.__m_xalt = 0
self.__m_x = 0
self.__m_y = 0
self.__m_anz = 0
self.__m_fielddic = {}
self.__m_lastgenerationdic={}
self.__m_eingabe = 0
# setzen der ersten Zellen
def platzieren(self, anz):
self.__m_fielddic[5,3]='C'
self.__m_fielddic[4,4]='C'
self.__m_fielddic[3,5]='C'
self.__m_fielddic[4,6]='C'
self.__m_fielddic[5,7]='C'
self.__m_fielddic[6,6]='C'
self.__m_fielddic[7,5]='C'
self.__m_fielddic[6,4]='C'
# Nachbarn ermitteln
def nachbar(self, x,y):
self.__m_nachbar=[]
for z in range (-1,2):
for j in range (-1,2):
if x!=x+z or y!=y+j:
self.__m_nachbar.append([x+z,y+j])
return copy.copy(self.__m_nachbar)
def ersetzen(self, nachbar):
self.__m_nachbar=nachbar
for item in self.__m_nachbar :
for z in range (0,2) :
if item[z]<0 :
item[z] = 9
if item[z] >9 :
item [z]=0
return copy.copy(self.__m_nachbar)
# auswerten
def auswerten(self, nachbar):
self.__m_anz=0
for item in nachbar:
if self.__m_lastgenerationdic.has_key(tuple(item)):
self.__anz+=1
return self.__m_anz
# wachsen
def wachse(self,anz,x,y):
if anz==3:
if self.__m_lastgenerationdic.has_key((x,y))==False:
self.__m_fielddic[(x,y)]='C'
# sterben
def sterbe(self,anz,x,y):
if (anz < 2) or (anz > 3):
if self.__m_lastgenerationdic.has_key((x,y)):
del self.__m_fielddic[(x,y)]
# Attribut hole Feld nach Außen geben
def holeFeld(self):
return copy.copy(self.__m_fielddic)
# Letzte gerneration in einem anderen dictionary speichern
def letztegerneration(self):
self.__m_lastgeneration=copy.copy(self.__m_fielddic)
if __name__ == '__main__':
gol=GameOfLive()
field={}
nachbar=[]
eingabe=0
zelle=0
anz=0
zahl=0
gol.platzieren(zelle
field=gol.holeFeld()
print 'Startkombination'
print
for z in range (0,100):
if z % 10 == 0 :
print
print field.get((z%10, z/10),' '),
print
gol.letztegerneration()
for i in range (0,100):
nachbar=gol.nachbar(i%10,i/10)
nachbar=gol.ersetzen(copy.copy(nachbar))
anz=gol.auswerten(copy.copy(nachbar))
gol.sterbe(anz,i%10,i/10)
gol.wachse(anz,i%10,i/10)
gol.holeFeld()
print 'naechste gerneration'
print
for z in range (0,100):
if z % 10 == 0 :
print
print field.get((z%10, z/10),' '),
print
Theorie und Praxis sind in der Theorie das selbe, doch unterscheiden sie sich meist in der Praxis meilenweit
Ich blicke da nicht so ganz durch. Die Welt wird offensichtlich in einem Dictionary gehalten bzw. zweien um Zugriff auf die letzte Generation zu haben, aus der die jeweils aktuelle berechnet wird. Warum initialisierst Du einige Felder mit einer Zeichenkette ('C')? Ich hätte erwartet, das es sich um Zahlen handelt, die da verwaltet werden. Vergleichen von Zahlen und Zeichenketten geht in Python, bzw. das vergleichen von zwei beliebigen unterschiedlichen Typen, aber es wird nur garantiert, dass bei je zwei Typen immer das gleiche Ergebnis kommt. Also das Zahlen z.B. grundsätzlich "kleiner" sind als Zeichenketten. Das kann bei einem anderen Interpreter oder einer anderen Version andersherum sein.
Ich habe ganz stark das Gefühl Du willst C++ nach Python übertragen. Und das 1:1. Entferne bitte mal alle '__m_' Präfixe von Deinen Attributen. Wozu soll das gut sein?
Dann legst Du in der __init__()-Methode einige Attribute an, die sehr danach aussehen als sollten sie lokale Namen in Methoden sein.
Und im '__main__'-Code steckt Logik, die eigentlich in der Klasse sein sollte. Die sollte eine Methode haben, die ohne Parameter aufgerufen wird und den nächsten Schritt berechnet. So wie es jetzt da steht sind alle möglichen Daten nochmal ausserhalb der Klasse vorhanden. Du kopierst viel zu viel herum. Darum steige ich auch nicht ganz durch was genau passiert.
Noch ein Wort zu Python und der üblichen C++/Java Paranoia: Es ist okay Attribute einfach nach aussen zugänglich zu machen und darauf zu vertrauen, dass sie niemand von aussen "kaputt" macht. Wenn man etwas als privat markieren möchte, dann reicht ein einzelner Unterstrich, also zum Beispiel '_foo' als Name. Da kann zwar jeder rankommen, aber es ist ein eindeutiges Zeichen, das man es von aussen nicht benutzen soll.
Ich habe ganz stark das Gefühl Du willst C++ nach Python übertragen. Und das 1:1. Entferne bitte mal alle '__m_' Präfixe von Deinen Attributen. Wozu soll das gut sein?
Dann legst Du in der __init__()-Methode einige Attribute an, die sehr danach aussehen als sollten sie lokale Namen in Methoden sein.
Und im '__main__'-Code steckt Logik, die eigentlich in der Klasse sein sollte. Die sollte eine Methode haben, die ohne Parameter aufgerufen wird und den nächsten Schritt berechnet. So wie es jetzt da steht sind alle möglichen Daten nochmal ausserhalb der Klasse vorhanden. Du kopierst viel zu viel herum. Darum steige ich auch nicht ganz durch was genau passiert.
Noch ein Wort zu Python und der üblichen C++/Java Paranoia: Es ist okay Attribute einfach nach aussen zugänglich zu machen und darauf zu vertrauen, dass sie niemand von aussen "kaputt" macht. Wenn man etwas als privat markieren möchte, dann reicht ein einzelner Unterstrich, also zum Beispiel '_foo' als Name. Da kann zwar jeder rankommen, aber es ist ein eindeutiges Zeichen, das man es von aussen nicht benutzen soll.
Also, Das mit dem 'C' füllen muss ich laut Aufgabe so machen. ist aber auch eigedlich nicht das Problem.
Mit __ mach ich Variblen doch strong Privat? Laut Erfahrung ist es sicherer es so zu machen.. aber anderes ist auch ok
das m_ steht für member. So bennen ich alle Attribute
Ich Programmiere gerne C++ und ich mag Python noch nicht besonders, deshalb kann es durchaus sein das ich einiges übertrage..
Zur Erklärung
Ich speicher nur die Zellen die schon vorhanden sind mit eine 'C' alle anderen brauch ich nicht speichern.
Dann finde ich mit nachnbar() herraus, welche Koordinaten die benachbarten sind. Für die Donout Welt werden die gegenüberliegenden Ränder 'ersetz' und ich kann mit has.key prüfen ob sich an der Stelle ein Nachbar(Zelle) befindet.
so weit so gut
die Anzahl der Nachbar stimmt auch und wird richtig ausgewertet.
allerdings wird das Dic. nicht um den neune Wert erweiter.
Die Copys dienen dazu nicht die Referenzen zu verändern. Denn wenn die Letzte und die Neue Generation die selben Referenzen benutzen,ist es sinnlos da beide dictionarys verändert werden.
Nachbar kopiere ich nur zur Sichheit weil einemal mehr schadet meiner Meinung bei einer Sprache wie Python nicht da es ja den Gagbage collector gibt.
Ich hoffe das hilft noch ein bischen..
cu PILLE
Mit __ mach ich Variblen doch strong Privat? Laut Erfahrung ist es sicherer es so zu machen.. aber anderes ist auch ok
das m_ steht für member. So bennen ich alle Attribute
Ich Programmiere gerne C++ und ich mag Python noch nicht besonders, deshalb kann es durchaus sein das ich einiges übertrage..
Zur Erklärung
Ich speicher nur die Zellen die schon vorhanden sind mit eine 'C' alle anderen brauch ich nicht speichern.
Dann finde ich mit nachnbar() herraus, welche Koordinaten die benachbarten sind. Für die Donout Welt werden die gegenüberliegenden Ränder 'ersetz' und ich kann mit has.key prüfen ob sich an der Stelle ein Nachbar(Zelle) befindet.
so weit so gut
die Anzahl der Nachbar stimmt auch und wird richtig ausgewertet.
allerdings wird das Dic. nicht um den neune Wert erweiter.
Die Copys dienen dazu nicht die Referenzen zu verändern. Denn wenn die Letzte und die Neue Generation die selben Referenzen benutzen,ist es sinnlos da beide dictionarys verändert werden.
Nachbar kopiere ich nur zur Sichheit weil einemal mehr schadet meiner Meinung bei einer Sprache wie Python nicht da es ja den Gagbage collector gibt.
Ich hoffe das hilft noch ein bischen..
cu PILLE
Theorie und Praxis sind in der Theorie das selbe, doch unterscheiden sie sich meist in der Praxis meilenweit
-
- Python-Forum Veteran
- Beiträge: 1209
- Registriert: Montag 29. September 2003, 17:18
- Wohnort: Purkersdorf (bei Wien [Austria])
Hi!
Die Namenskonventionen sind aber hier nebensächlich.
Wenn mich nicht alles täuscht, kann ersetzen nicht so funktionieren wie Du das willst. Mal ein einfacheres Beispiel:
Gruß, mawe
Naja, irgendwie schon, aber man kann trotzdem von aussen auf sie zugreifen (wenn man weiss wie )PILLE hat geschrieben: Mit __ mach ich Variblen doch strong Privat?
Die Namenskonventionen sind aber hier nebensächlich.
Wenn mich nicht alles täuscht, kann ersetzen nicht so funktionieren wie Du das willst. Mal ein einfacheres Beispiel:
Code: Alles auswählen
nachbar = [1,2,3]
for item in nachbar:
if item == 1:
item = 100
print nachbar # -> [1,2,3] nix verändert
for i in range(len(nachbar)):
if nachbar[i] == 1:
nachbar[i] = 2
print nachbar # -> [2,2,3] jetzt passts
Hi
ob C++ oder Python, manche Dinge betreffen einfach das Design und da solltest Du schon noch ein paar Dinge ändern - weil Du Dir auf Dauer das Leben unnötig schwer machst und dann auch nicht so viel Spaß beim Programmieren hast. Was Du Dir genau zu Herzen nimmst ist natürlich Deine Sache, aber die Anmerkungen von BlackJack zum Thema __main__ haben Hand und Fuß.
Außerdem: Die Funktion platzieren erwartet "anz", damit machst Du aber nichts. Und diese Funktion wird auch nur einmal bei der Erstellung der ersten Instanz aufgerufen. Na? Wie wäre es Du schreibst all dieses in __init__, ggf. kannst Du ja auch mit verschiedenen Paramteren verschiedene Initialisierungen machen, damit das Feld nicht immer gleich aussieht. Und schließlich kannst Du das Füllen der ersten Felder auch mit weniger Codezeilen machen.
In nachbar() deklarierst Du __m_nachbar, was aber in __init__ gar nicht auftaucht. Es ist manchmal geschickter, wenn Du in __init__ alle Attribute deklarierst und deutlich machst, worum es sich handelt - dann kannst Du in einem halben Jahr Dein Programm immer noch lesen. (Was bei einer Hausaufgabe vielleicht nicht so kritisch ist .)
Ähnliches gilt in auswerten(). Muß __anz überhaupt ein Attribut der Klasse sein?
Und jetzt wird es ganz komisch: Wozu soll field gut sein? Warum nicht alles mit Methoden von GameOfLive machen?
Ob die Logik überall stimmt wage ich außerdem zu bezweifeln: Am besten Du konttrollierst Schritt für Schritt was wo herauskommt - stimmt überall die Anzahl der Nachbarn? Wird richtig ersetzt? usw. Und das für jede Generation. Dann wirst Du schon auf die Lösung kommen.
Tut mir leid, wenn das alles jetzt sehr hart klang. Das sollte es nicht sein. Ich sehe auch, daß das keine einfache Hausaufgabe ist. Na, und während ich hier so vor mich hin tippte hat der mawe schon einen Teil der Lösung gegeben - ist doch toll, oder?
Gruß,
Christian
ob C++ oder Python, manche Dinge betreffen einfach das Design und da solltest Du schon noch ein paar Dinge ändern - weil Du Dir auf Dauer das Leben unnötig schwer machst und dann auch nicht so viel Spaß beim Programmieren hast. Was Du Dir genau zu Herzen nimmst ist natürlich Deine Sache, aber die Anmerkungen von BlackJack zum Thema __main__ haben Hand und Fuß.
Außerdem: Die Funktion platzieren erwartet "anz", damit machst Du aber nichts. Und diese Funktion wird auch nur einmal bei der Erstellung der ersten Instanz aufgerufen. Na? Wie wäre es Du schreibst all dieses in __init__, ggf. kannst Du ja auch mit verschiedenen Paramteren verschiedene Initialisierungen machen, damit das Feld nicht immer gleich aussieht. Und schließlich kannst Du das Füllen der ersten Felder auch mit weniger Codezeilen machen.
In nachbar() deklarierst Du __m_nachbar, was aber in __init__ gar nicht auftaucht. Es ist manchmal geschickter, wenn Du in __init__ alle Attribute deklarierst und deutlich machst, worum es sich handelt - dann kannst Du in einem halben Jahr Dein Programm immer noch lesen. (Was bei einer Hausaufgabe vielleicht nicht so kritisch ist .)
Ähnliches gilt in auswerten(). Muß __anz überhaupt ein Attribut der Klasse sein?
Und jetzt wird es ganz komisch: Wozu soll field gut sein? Warum nicht alles mit Methoden von GameOfLive machen?
Ob die Logik überall stimmt wage ich außerdem zu bezweifeln: Am besten Du konttrollierst Schritt für Schritt was wo herauskommt - stimmt überall die Anzahl der Nachbarn? Wird richtig ersetzt? usw. Und das für jede Generation. Dann wirst Du schon auf die Lösung kommen.
Tut mir leid, wenn das alles jetzt sehr hart klang. Das sollte es nicht sein. Ich sehe auch, daß das keine einfache Hausaufgabe ist. Na, und während ich hier so vor mich hin tippte hat der mawe schon einen Teil der Lösung gegeben - ist doch toll, oder?
Gruß,
Christian
PILLE hat geschrieben:Also, Das mit dem 'C' füllen muss ich laut Aufgabe so machen. ist aber auch eigedlich nicht das Problem.
War ein Denkfehler meinerseits. Ich hatte eine Variante im Hinterkopf, wo die Zellen nicht leben oder tot sind, sondern einen Wert haben, wie lebendig sie sind. Da kann man schöne bunte Bilder draus machen.
Kommt auf die Definition von "strong" an. Man kommt da immer noch dran, wenn man will. Das mit der Erfahrung stimmt nur wenn man davon ausgeht, das die Leute einfach Attribute von Klassen verändern, die ihnen nicht "gehören". Das macht man nicht. Dann gibt es auch keine Probleme.Mit __ mach ich Variblen doch strong Privat? Laut Erfahrung ist es sicherer es so zu machen.. aber anderes ist auch ok
Ein Problem mit den '__' ist, dass sie auch für Unterklassen nicht sichtbar sind. Das kann sehr einschränkend sein.
Warum? Bei C++ ist die Begründung, dass man Attribute und lokale Variablennamen besser auseinanderhalten kann. Bei Python müssen Attribute immer mit 'self.' angesprochen werden, das heisst ein zusätzliches 'm_' ist überflüssig. Ausserdem sollten Methoden nicht so lang werden und/oder so viele lokale Namen enthalten, dass man durcheinander kommen könnte.das m_ steht für member. So bennen ich alle Attribute
Die 'nachbar()'-Methode in Deinem Code oben funktioniert so nicht.die Anzahl der Nachbar stimmt auch und wird richtig ausgewertet.
allerdings wird das Dic. nicht um den neune Wert erweiter.
Klar brauchst Du ein eigenes Dictionary für den alten und den neuen Schritt, aber Du kopierts alles mögliche, überall. Und auch für die beiden Dictionaries braucht man kein copy, man kann einfach ein neues, leeres erstellen und die Zellen dann rüberkopieren die noch leben und die hinzufügen die neu sind.Die Copys dienen dazu nicht die Referenzen zu verändern. Denn wenn die Letzte und die Neue Generation die selben Referenzen benutzen,ist es sinnlos da beide dictionarys verändert werden.
Es macht den Code aber schwer durchschaubar. Vor allem wenn sich in Deinem Fall etwas nicht ändert, was sich aber ändern sollte, dann könnte es ja sein, dass Du auf irgendeiner Kopie arbeitest, die dann "verloren geht".Nachbar kopiere ich nur zur Sichheit weil einemal mehr schadet meiner Meinung bei einer Sprache wie Python nicht da es ja den Gagbage collector gibt.
ich sehe ein was mawe sagt, dass ist wohl soo.. aber es funktioniert auch so wie ich das gemacht habe, weil in mein Fall item nur eine Refernez der Liste Nachbar ist, da diese verschachtelt ist und der Interpreter keine Kopie wie bei copy.copy anlegt. Vorrausgeseztz ich hbae alles verstanden was mein Leherer mir vorbrabbelt..
zu Christian.. ich habe die Methoden zum testen vereinfacht. normalerweise lasse ich den Benutzer eingeben, wieviel Zellen er setzten möchte und wieviel Generationen es geben soll. Deshalb die anz in der Methode.
Mein design sehen ich ein kann euch gerne mal die mail addi vn einem "leerer" geben.. dagegen sieht meins gut aus find ich *gg* nein aber spaß am Rand.. hat einer von euch eine Page wo dazu was da steht?
Und das debuggen habe ich auch schon gemacht bis zu den zwei Methoden sterbe und wachse funktioniert alles einwandfrei.. die Werte sind alle richtig bis dahin.. und dann wird das dictionary nicht verändert.. ich verstehe das nicht..
und falls dich das interessiert Das ist die gewöhnkliche platzieren
das Nachbar gar nicht in der init steht ist mir gar nicht aufgefallen.. na ja ich ergänze es da gleich mal..
bin mal gespannt ob es dann besser oder schlechter geht..
Vielleicht amcht dann auch das was mawe gesagt hat Sinn weiß zwar nichtw arum es dann anerder funktionieren sollte aber mal schaun.. man weiß ja nie.. und wennn es nicht geht gebe ich einem von euch die Schuld
eins meiner Problem ist auch das unser Lehere nur die Hälfte der Sachen erklärt die bei Python funktioieren und ich mehr mit Nachschlagen beschäftigt bin als mit Proggen, aber das ist ja nebensache. Er hat ja auch gerade erst angefangen..
okk seh gerade noch einen beitrag.. ich werde das mal ändern und dann die aktuelle varriante auch hier her einstellen wenn es ok ist.. vielelicht finde ich dann den Fehler auch. das mit den Kopien leutet ein .. und als C programmierin bin ich nicht drauf gekommen jedesmal eine neues dict anzulegen.. macht aber auch sinn.. danke schon mal
PILLE
zu Christian.. ich habe die Methoden zum testen vereinfacht. normalerweise lasse ich den Benutzer eingeben, wieviel Zellen er setzten möchte und wieviel Generationen es geben soll. Deshalb die anz in der Methode.
Mein design sehen ich ein kann euch gerne mal die mail addi vn einem "leerer" geben.. dagegen sieht meins gut aus find ich *gg* nein aber spaß am Rand.. hat einer von euch eine Page wo dazu was da steht?
Und das debuggen habe ich auch schon gemacht bis zu den zwei Methoden sterbe und wachse funktioniert alles einwandfrei.. die Werte sind alle richtig bis dahin.. und dann wird das dictionary nicht verändert.. ich verstehe das nicht..
und falls dich das interessiert Das ist die gewöhnkliche platzieren
Code: Alles auswählen
def platzieren(self, anz):
i=0
# erste Zelle plazieren
self.__m_x = randint(0,9)
self.__m_y = randint(0,9)
self.__m_fielddic [self.__x,self.__y] = 'C'
self.__m_xalt=self.__x
self.__m_yalt=self.__y
# weitere Zellen plazieren
if anz-1>0:
for i in anz
self.__m_x = randint(-1,1)
self.__m_y = randint(-1,1)
if self.__m_x == 0 and self.__m_y == 0 :
self.__m_x = 1
if self.__m_yalt == self.__m_y :
self.__m_y = self.__m_y* -1
if self.__m_xalt == self.__m_x :
self.__m_x = self.__m_x*-1
if (((self.__m_xalt+self.__m_x<10) and (self.__m_yalt+self.__m_y<10)) and
((self.__m_xalt+self.__m_x)>=0 and (self.__m_yalt+self.__m_y)>=0)) :
if (((self.__m_xalt+self.__m_x),(self.__m_yalt+self.__m_y)) in self.__m_field) == 0 :
if self.__m_fielddic.has_key(((self.__m_xalt+self.__m_x),(self.__m_yalt+self.__m_y)))==False :
self.__m_fielddic[(self.__xalt+self.__x,self.__yalt+self.__y)] = 'C'
i+=1
else:
return -4
bin mal gespannt ob es dann besser oder schlechter geht..
Vielleicht amcht dann auch das was mawe gesagt hat Sinn weiß zwar nichtw arum es dann anerder funktionieren sollte aber mal schaun.. man weiß ja nie.. und wennn es nicht geht gebe ich einem von euch die Schuld
eins meiner Problem ist auch das unser Lehere nur die Hälfte der Sachen erklärt die bei Python funktioieren und ich mehr mit Nachschlagen beschäftigt bin als mit Proggen, aber das ist ja nebensache. Er hat ja auch gerade erst angefangen..
okk seh gerade noch einen beitrag.. ich werde das mal ändern und dann die aktuelle varriante auch hier her einstellen wenn es ok ist.. vielelicht finde ich dann den Fehler auch. das mit den Kopien leutet ein .. und als C programmierin bin ich nicht drauf gekommen jedesmal eine neues dict anzulegen.. macht aber auch sinn.. danke schon mal
PILLE
Theorie und Praxis sind in der Theorie das selbe, doch unterscheiden sie sich meist in der Praxis meilenweit
soo.. ich habes ich habe es wirklich gelöst
ein Mist das es in dem Sinne keine Sicherheit gibt wenn man einen Variable macht, das der Interpreter da nicht meckert wenn man sie nicht gemacht gemacht hat.
n aja besten dank.. suoper lieb das ihr mir so geholfen habt.. aber schön wäre es wenn irh trtzdem noch mal ausplaudert, wo man eine definition für odendlichen stil in Python findet.. in meinem Buch steht da nicht so viel von..
Noch mal Tausend dank *alle mal knuddel*
heute ist ein erfolgreicher tag
danke danke dank *happy bin*
ein Mist das es in dem Sinne keine Sicherheit gibt wenn man einen Variable macht, das der Interpreter da nicht meckert wenn man sie nicht gemacht gemacht hat.
n aja besten dank.. suoper lieb das ihr mir so geholfen habt.. aber schön wäre es wenn irh trtzdem noch mal ausplaudert, wo man eine definition für odendlichen stil in Python findet.. in meinem Buch steht da nicht so viel von..
Noch mal Tausend dank *alle mal knuddel*
heute ist ein erfolgreicher tag
danke danke dank *happy bin*
Theorie und Praxis sind in der Theorie das selbe, doch unterscheiden sie sich meist in der Praxis meilenweit
Wenn mit Stil hier der Entwurf gemeint war, was in eine Klasse gehört, was Attribut und was lokale Variablen sein sollten, dann ist das keine reine Python-Frage. Das Du in jeder Methode vor so ziemlich alle Variablen 'self.__m_' setzt, wäre auch in C++ und Java sehr fragwürdig. Zum Beispiel Dein `platzieren()` sieht grauenvoll aus. Ist Dir die ganze Tipperei nicht auf die Nerven gegangen!? (Das sieht übrigens alles sehr kryptisch aus)
Ich habe heute auch mal ein kleines GameOfLife gebastelt. Als erstes muss man sich Fragen stellen, was für Daten gehören in so eine Klasse, also was muss über die Welt in jeder Methode bekannt sein. Ich bin auf 4 Sachen gekommen, die Höhe und Breite, ein `Set` für die lebenden Zellen und eine Uhr (`clock`) die die Schritte zählt die schon berechnet wurden. Also nur 4 Namen vor die ein 'self.' kommt.
Dann ist das berechnen des nächsten Schrittes etwas, was in die Klasse gehört, weil man mit Daten arbeitet, die zu dieser Klasse gehören. Wenn man das von aussen macht, also Daten rausholen, bearbeiten und dann wieder in das Objekt zurückschreiben, dann umgeht man den Grund überhaupt eine Klasse zu benutzen. Die sind dazu da, Daten und dazugehörigen Code zu einer Einheit zusammenzufassen.
Das waren jetzt pythonunabhängige Stilfragen. Ob's irgendwo eine gute Zusammenfassung zu Python-Stil gibt weiss ich nicht.
Ich gehe in meinem Code in einem Schritt nicht über alle Felder der Karte, sondern nur die, in denen wirklich etwas passieren kann, also die Zellen die leben und deren Nachbarfelder. Ansonsten ist der Algorithmus ziemlich "straightforward" umgesetzt. Ich habe noch eine ASCII Animation eingebaut, damit man auch was sieht -- die funktioniert aber nur richtig wenn das "Terminal" ANSI Escape-Sequenzen unterstützt. Ich weiss nicht wie das unter Windows aussieht!?
Ich habe heute auch mal ein kleines GameOfLife gebastelt. Als erstes muss man sich Fragen stellen, was für Daten gehören in so eine Klasse, also was muss über die Welt in jeder Methode bekannt sein. Ich bin auf 4 Sachen gekommen, die Höhe und Breite, ein `Set` für die lebenden Zellen und eine Uhr (`clock`) die die Schritte zählt die schon berechnet wurden. Also nur 4 Namen vor die ein 'self.' kommt.
Dann ist das berechnen des nächsten Schrittes etwas, was in die Klasse gehört, weil man mit Daten arbeitet, die zu dieser Klasse gehören. Wenn man das von aussen macht, also Daten rausholen, bearbeiten und dann wieder in das Objekt zurückschreiben, dann umgeht man den Grund überhaupt eine Klasse zu benutzen. Die sind dazu da, Daten und dazugehörigen Code zu einer Einheit zusammenzufassen.
Das waren jetzt pythonunabhängige Stilfragen. Ob's irgendwo eine gute Zusammenfassung zu Python-Stil gibt weiss ich nicht.
Ich gehe in meinem Code in einem Schritt nicht über alle Felder der Karte, sondern nur die, in denen wirklich etwas passieren kann, also die Zellen die leben und deren Nachbarfelder. Ansonsten ist der Algorithmus ziemlich "straightforward" umgesetzt. Ich habe noch eine ASCII Animation eingebaut, damit man auch was sieht -- die funktioniert aber nur richtig wenn das "Terminal" ANSI Escape-Sequenzen unterstützt. Ich weiss nicht wie das unter Windows aussieht!?
Code: Alles auswählen
#!/usr/bin/env python
import time
from sets import Set as set
class GameOfLife:
"""Conway's *Game of Life*"""
neighbour_positions = [(x, y) for x in xrange(-1, 2)
for y in xrange(-1, 2)
if not x == y == 0]
def __init__(self, width, height, cells):
self.width = width
self.height = height
self.cells = set(cells)
self.clock = 0
def __len__(self):
return len(self.cells)
def __str__(self):
worldmap = [['.'] * self.width for dummy in xrange(self.height)]
for x, y in self.cells:
worldmap[y][x] = '#'
return ('Clock: %d\n' % self.clock
+ '\n'.join([''.join(row) for row in worldmap]))
def _is_within_world(self, field):
x, y = field
return 0 <= x < self.width and 0 <= y < self.height
def _neighbour_fields(self, field):
x, y = field
for delta_x, delta_y in GameOfLife.neighbour_positions:
neighbour_field = (x + delta_x, y + delta_y)
if self._is_within_world(neighbour_field):
yield neighbour_field
def _fields_of_interest(self):
fields = set(self.cells)
for cell in self.cells:
fields.update(self._neighbour_fields(cell))
return fields
def step(self):
new_cells = set()
for field in self._fields_of_interest():
alive_neighbours = sum(map(int, [(neighbour_field in self.cells)
for neighbour_field
in self._neighbour_fields(field)]))
if field in self.cells:
# Cell `field` is alive.
if 2 <= alive_neighbours <= 3:
new_cells.add(field)
else:
# Cell `field` is dead.
if alive_neighbours == 3:
new_cells.add(field)
self.cells = new_cells
self.clock += 1
def run(self, callback=None, steps=1000000):
while len(self) and self.clock < steps:
self.step()
if callback is not None:
callback(self)
if __name__ == '__main__':
def display(obj):
print '\033[H%s' % obj # Cursor home and `obj` as string.
time.sleep(0.5)
game = GameOfLife(10, 10, ((5, 3), (4, 4), (3, 5), (4, 6),
(5, 7), (6, 6), (7, 5), (6, 4)))
print '\033[2J' # Clear screen.
try:
game.run(display)
except KeyboardInterrupt:
pass
uii was ist das denn???? wenn ich das so ähnlich mache sagt der wo ich mir das gezogen haben *dumm aus der wäsche schau* was alles bei Python geht*wunder*
Besten dank auf jden fall für diese lehrreichen stunden hier.. ich werde jetzt noch das notwendig protokoll schreiben wenn ich da noch ein bischen verändert habe *einige sachen raussuchen werd*
Besten dank nochmal meine Note ist gerette *alle mal drück die geholfen haben*
Besten dank auf jden fall für diese lehrreichen stunden hier.. ich werde jetzt noch das notwendig protokoll schreiben wenn ich da noch ein bischen verändert habe *einige sachen raussuchen werd*
Besten dank nochmal meine Note ist gerette *alle mal drück die geholfen haben*
Theorie und Praxis sind in der Theorie das selbe, doch unterscheiden sie sich meist in der Praxis meilenweit
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Miserabel, wie so oft (nur readline ist schlimmer). Man braucht sowas wie Wconio (hab mal Binaries für Py2.4 gemacht, das Modul ist recht nett) oder console.BlackJack hat geschrieben:Ich habe noch eine ASCII Animation eingebaut, damit man auch was sieht -- die funktioniert aber nur richtig wenn das "Terminal" ANSI Escape-Sequenzen unterstützt. Ich weiss nicht wie das unter Windows aussieht!?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Geht sowas wirklich nicht in einer normalen "DOS-Eingabeaufforderung"? Unter'm echten MS-DOS gab's dafür einen Treiber, der dabei war (ANSI.SYS). Es geht nicht um eine API wie die, die Du verlinkt hast, sondern nur darum, dass die Escape-Sequenzen vom "Terminal" interpretiert werden. Aber naja, wir reden von Windows...
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ja, Ansi.sys ging ja auch noch bis Dos Me, aber in der NT Serie geht das nicht mehr. Also ich würde deswegen mir Windows 98 nicht wieder antun.BlackJack hat geschrieben:Geht sowas wirklich nicht in einer normalen "DOS-Eingabeaufforderung"? Unter'm echten MS-DOS gab's dafür einen Treiber, der dabei war (ANSI.SYS). Es geht nicht um eine API wie die, die Du verlinkt hast, sondern nur darum, dass die Escape-Sequenzen vom "Terminal" interpretiert werden. Aber naja, wir reden von Windows...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice