Sudokuprogramm
-
- User
- Beiträge: 53
- Registriert: Sonntag 2. Dezember 2007, 18:25
So... alles überarbeitet, das neue Programm kann jetzt auch schon Testen.
Paste:
http://paste.pocoo.org/show/20280/
@ Leonidas: Bitte beachte einmal nicht den Sternenimport, ich werde jetzt nie wieder Sternenimporte verwenden (soweit es möglich ist) und diesen Import werde ich konkretisieren, wenn ich das Programm fertig hab und genau weiß, was ich alles importieren muss...
Paste:
http://paste.pocoo.org/show/20280/
@ Leonidas: Bitte beachte einmal nicht den Sternenimport, ich werde jetzt nie wieder Sternenimporte verwenden (soweit es möglich ist) und diesen Import werde ich konkretisieren, wenn ich das Programm fertig hab und genau weiß, was ich alles importieren muss...
-
- User
- Beiträge: 128
- Registriert: Freitag 22. Oktober 2004, 09:22
- Wohnort: Salzgitter
- Kontaktdaten:
Da wir ja davon ausgehen müssen, dass der Code ernstgemeint ist, äußere ich mich einmal dazu..
In der Regel erhält master einen Defaultwert (None), da man nicht zwingend das übergeordnete Widget angeben muss.
Die Abfrage sieht hübsch aus, ist aber denkbar unperformant, da bei jedem Aufruf der Methode abfragen() die Liste neu erstellt wird. Wesentlich schneller wäre also, die Liste einmalig als Attribut zu setzen und dann darauf zuzugreifen.
Wenn Null für leer steht, solltest du auch die Zahl und nicht den String übergeben! (vgl. Z. 17)
Zur besseren Lesbarkeit deines Codes solltest du vor und nach dem Gleichheitszeichen ein Leerzeichen einfügen, siehe PEP-0008.
Ich bin mir nicht sicher, was du mit dieser Zeile bezwecken willst, aber es gibt mit Sicherheit einen Weg, weniger kryptologisch und unleserlich zum Ziel zu kommen!
Vergiss' exec! Du wirst es in den nächsten Monaten garantiert nicht brauchen, versprochen! Erstelle doch einfach eine Liste, in der du die einzelnen SudokuFrames speicherst, somit erleichterst du dir selbst den Zugriff und allgemein die Lesbarkeit deines Codes. Was du hier geschrieben hast, ist gelinde gesagt Schwachsinn.
Hier liegt ein klassicher Fall für eine for-Schleife vor, da die Schleife jedes immer exakt neun Mal durchlaufen wird.
Ich verstehe nicht, was du damit bezwecken willst. Wir Programmierer beginnen beim Zählen mit Null, warum erschwerst du dir selbst das Verständnis mit solchen Workarounds?
Siehe oben! Vergiss exec und greife über den schon vorliegenden Index einfach auf die Liste zu:
Die Trennung von GUI und Logik ist dir noch immer nicht geglückt, viel Erfolg damit..
Code: Alles auswählen
class SudokuEntry(Entry):
def __init__(self, master, x=1, y=1):
Entry.__init__(self, master, width=3)
Code: Alles auswählen
if self.get() in ["1","2","3","4","5","6","7","8","9"]
Code: Alles auswählen
return "0" # 0 steht für "leer"
Code: Alles auswählen
i=1
j=1
Code: Alles auswählen
nummer=((j-1)%3)+(9*(((j+2)/3)+3*((i-1)/3)-1))+1+3*((i-1)%3)
Code: Alles auswählen
exec "self.neunerblock"+str(nummer)+\
"=SudokuFrame(self.sudokurahmen, relief=RIDGE, "+\
"borderwidth=3, x="+str(i)+", y="+str(j)+")"
Code: Alles auswählen
i=1
while i<=9:
..
i=i+1
Code: Alles auswählen
Einzelzeile=[0] # Feld 1 der Zeile soll Index 1 haben
Einzelspalte=[0] # Feld 1 der Spalte soll Index 1 haben
Einzelblock=[0] # Feld 1 des Blocks soll Index 1 haben
Code: Alles auswählen
exec "testfeld=self.Zellen["+str(feld)+"][0].abfragen()"
Code: Alles auswählen
testfeld = self.Zellen[feld][0].abfragen()
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
- nkoehring
- User
- Beiträge: 543
- Registriert: Mittwoch 7. Februar 2007, 17:37
- Wohnort: naehe Halle/Saale
- Kontaktdaten:
Hi Vingdoloras!
Bitte sei nicht boese mit Leonidas, Redprince und Co. Wenn man das hier so ließt koennte ich mir vorstellen, dass der ein oder andere denkt, sie machen das aus reiner Schikane!
Aber das tun sie nicht! Sie vergessen nur manchmal neben den Contras auch die Pros hervorzuheben... aber schließlich willst du Hilfe bei der Problemloesung... also ist es ja eigentlich richtig so
Und nochwas:
SternchenImporte sind etwas schreckliches! Glaubst du irgendjemand hat den kompletten Namespace im Kopf, den Tkinter mitbringt?
Und wieviele neue und potenziell nutzbare Namen werden dadurch verbraucht, die man sonst fuer eigene Zwecke nutzen koennte?!
Mein Tipp:
tk.Frame zu schreiben ist ja nun wohl noch vertretbar, oder? Und vorallem weitaus weniger Zeitaufwaendig, als jedem genutzten Import eine eigene import-Zeile zu verpassen!
Beste Gruesse
NKoehring
Bitte sei nicht boese mit Leonidas, Redprince und Co. Wenn man das hier so ließt koennte ich mir vorstellen, dass der ein oder andere denkt, sie machen das aus reiner Schikane!
Aber das tun sie nicht! Sie vergessen nur manchmal neben den Contras auch die Pros hervorzuheben... aber schließlich willst du Hilfe bei der Problemloesung... also ist es ja eigentlich richtig so

Und nochwas:
Vingdoloras hat geschrieben:@ Leonidas: Bitte beachte einmal nicht den Sternenimport, ich werde jetzt nie wieder Sternenimporte verwenden (soweit es möglich ist) und diesen Import werde ich konkretisieren, wenn ich das Programm fertig hab und genau weiß, was ich alles importieren muss...
Mach es doch nicht fuer Leonidas! Mach es fuer DICH und andere, die deinen Quelltext benutzen!Vingdoloras hat geschrieben:@ Leonidas: Hab extra für dich den Sternchenimport weg gemacht Wink
SternchenImporte sind etwas schreckliches! Glaubst du irgendjemand hat den kompletten Namespace im Kopf, den Tkinter mitbringt?
Und wieviele neue und potenziell nutzbare Namen werden dadurch verbraucht, die man sonst fuer eigene Zwecke nutzen koennte?!
Mein Tipp:
Code: Alles auswählen
import Tkinter as tk
Beste Gruesse
NKoehring
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
-
- User
- Beiträge: 53
- Registriert: Sonntag 2. Dezember 2007, 18:25
Änder ich sofort!Redprince hat geschrieben:In der Regel erhält master einen Defaultwert (None), da man nicht zwingend das übergeordnete Widget angeben muss.Code: Alles auswählen
class SudokuEntry(Entry): def __init__(self, master, x=1, y=1): Entry.__init__(self, master, width=3)
Änder ich ebenfalls!Redprince hat geschrieben:Die Abfrage sieht hübsch aus, ist aber denkbar unperformant, da bei jedem Aufruf der Methode abfragen() die Liste neu erstellt wird. Wesentlich schneller wäre also, die Liste einmalig als Attribut zu setzen und dann darauf zuzugreifen.Code: Alles auswählen
if self.get() in ["1","2","3","4","5","6","7","8","9"]
Bei mir hat das Testen nicht funktioniert, weil die Funktion die Zahl zurückgab, der Testmechanismus aber geschaut hat, ob der String zurückgegeben wurde. Ich hab es in der Abfragen-Funktion geändert, aber wenn du willst, mach ich es andersrum.Redprince hat geschrieben:Wenn Null für leer steht, solltest du auch die Zahl und nicht den String übergeben! (vgl. Z. 17)Code: Alles auswählen
return "0" # 0 steht für "leer"
Da ist es wohl mal wieder mit mir durchgegangen, wird auch berichtigt!Redprince hat geschrieben:Zur besseren Lesbarkeit deines Codes solltest du vor und nach dem Gleichheitszeichen ein Leerzeichen einfügen, siehe PEP-0008.Code: Alles auswählen
i=1 j=1
Aus i und j werden jeweils die Feldnummern berechnet, die in einer Zeile/Spalte/einem Block vorkommen. Die Formeln sind von meinem Vater (ich will ihm nicht die Schuld in die Schuhe schieben), aber ich habe selber eine Weile rumprobiert, ob man diese Formel nicht verkürzen könnte, aber glaub mir, Mathematik ist eines meiner Lieblingsfächer in der Schule und ich habe nichts* gefunden.Redprince hat geschrieben:Ich bin mir nicht sicher, was du mit dieser Zeile bezwecken willst, aber es gibt mit Sicherheit einen Weg, weniger kryptologisch und unleserlich zum Ziel zu kommen!Code: Alles auswählen
nummer=((j-1)%3)+(9*(((j+2)/3)+3*((i-1)/3)-1))+1+3*((i-1)%3)
* Ich habe schon etwas gefunden, denn
3*((i-1)/3)
KÖNNTE man ja nach den Regeln der Mathematik extrem vereinfachen, da erst durch drei geteilt wird und dann mit drei multipliziert, aber schau dir das mal genau an... alle Teile der Formel sind Integer, also liefert Python bei Division auch nur Integer zurück, was diese Formel (anscheinend, mein Vater hat sie halt entwickelt, ich kann ihn ja mal fragen, was ihn zu sowas getrieben hat) ausnutzt.
Jedenfalls ließe sich das vielleicht auch mit Python-Code schreiben, aber ich bin mir sicher, dass DAS wirklich zu viele Zeilen wären.
EDIT:Redprince hat geschrieben:Vergiss' exec! Du wirst es in den nächsten Monaten garantiert nicht brauchen, versprochen! Erstelle doch einfach eine Liste, in der du die einzelnen SudokuFrames speicherst, somit erleichterst du dir selbst den Zugriff und allgemein die Lesbarkeit deines Codes. Was du hier geschrieben hast, ist gelinde gesagt Schwachsinn.Code: Alles auswählen
exec "self.neunerblock"+str(nummer)+\ "=SudokuFrame(self.sudokurahmen, relief=RIDGE, "+\ "borderwidth=3, x="+str(i)+", y="+str(j)+")"

Stimmt!Redprince hat geschrieben:Hier liegt ein klassicher Fall für eine for-Schleife vor, da die Schleife jedes immer exakt neun Mal durchlaufen wird.Code: Alles auswählen
i=1 while i<=9: .. i=i+1
Sudoku ist ein reines Zahlenspiel (damit meine ich, dass alles, was der Spieler/der Nutzer des Programms nur Zahlen eingibt und [fast] alle Werte, mit denen das Script arbeitet, Zahlen sind). Daher werden im Lösungsmechanismus ziemlich oft Zahlen vorkkommen. Ziemlich Ziemlich oft. Es werden einmal solche Zahlen vorkommen, die in den Feldern eingetragen sind. Das sind Werte von 1 bis 9. Es werden aber auch Indizes vorkommen, die nnormalerweise bei 0 anfangen. Nun stell dir mal vor, du vergisst in einem Riesencode, der eine Riesenmenge an Zahlen beinhaltet, EIN- oder ZWEIMAL, für Feld x den richtigen Index x-1 zu verwenden und schreibst nur x.Redprince hat geschrieben:Ich verstehe nicht, was du damit bezwecken willst. Wir Programmierer beginnen beim Zählen mit Null, warum erschwerst du dir selbst das Verständnis mit solchen Workarounds?Code: Alles auswählen
Einzelzeile=[0] # Feld 1 der Zeile soll Index 1 haben Einzelspalte=[0] # Feld 1 der Spalte soll Index 1 haben Einzelblock=[0] # Feld 1 des Blocks soll Index 1 haben
Was passiert dann? In vielen Fällen wird das Programm trotzdfem laufen, aber ein falsches Ergebnis liefern, also hast du nichtmal ein Traceback mit Zeilenangabe. Das wird ein Gesuche...
Zusätzlich ist es intuitiver, wenn die erste Zeile
Code: Alles auswählen
sudoku.Zeilen[1]
Das ist wirklich Blindheit gewesenRedprince hat geschrieben:Siehe oben! Vergiss exec und greife über den schon vorliegenden Index einfach auf die Liste zu:Code: Alles auswählen
exec "testfeld=self.Zellen["+str(feld)+"][0].abfragen()"
Code: Alles auswählen
testfeld = self.Zellen[feld][0].abfragen()


-
- User
- Beiträge: 53
- Registriert: Sonntag 2. Dezember 2007, 18:25
Ich habe nie gesagt/gedacht, dass sie mich niedermachen wollen... wenigstens nicht nurnkoehring hat geschrieben:Hi Vingdoloras!
Bitte sei nicht boese mit Leonidas, Redprince und Co. Wenn man das hier so ließt koennte ich mir vorstellen, dass der ein oder andere denkt, sie machen das aus reiner Schikane!
Aber das tun sie nicht! Sie vergessen nur manchmal neben den Contras auch die Pros hervorzuheben... aber schließlich willst du Hilfe bei der Problemloesung... also ist es ja eigentlich richtig so

Ja, ich wollte Leo nur mal ne Freude machennkoehring hat geschrieben:Und nochwas:Vingdoloras hat geschrieben:@ Leonidas: Bitte beachte einmal nicht den Sternenimport, ich werde jetzt nie wieder Sternenimporte verwenden (soweit es möglich ist) und diesen Import werde ich konkretisieren, wenn ich das Programm fertig hab und genau weiß, was ich alles importieren muss...Mach es doch nicht fuer Leonidas! Mach es fuer DICH und andere, die deinen Quelltext benutzen!Vingdoloras hat geschrieben:@ Leonidas: Hab extra für dich den Sternchenimport weg gemacht Wink
SternchenImporte sind etwas schreckliches! Glaubst du irgendjemand hat den kompletten Namespace im Kopf, den Tkinter mitbringt?
Und wieviele neue und potenziell nutzbare Namen werden dadurch verbraucht, die man sonst fuer eigene Zwecke nutzen koennte?!

nkoehring hat geschrieben:Mein Tipp:tk.Frame zu schreiben ist ja nun wohl noch vertretbar, oder? Und vorallem weitaus weniger Zeitaufwaendig, als jedem genutzten Import eine eigene import-Zeile zu verpassen!Code: Alles auswählen
import Tkinter as tk










Das mit den Indizes und dem Start bei 1 ist Unsinn. Starte mal bei 0 und überarbeite dann zum Beispiel die Formel für `nummer`. Die wird dann auf einen Schlag schonmal kürzer, weil die ganzen Indexanpassungen nicht mehr gemacht werden müssen. Es hat einen Grund warum Informatiker bei 0 anfangen ─ weil es einfacher und für Rechner natürlicher ist.
Bei vielen Programmiersprachen fingen Indizes früher bei 1 an, oder der Programmierer konnte sich den Startindex sogar aussuchen. Fast alle neueren Sprachen fangen bei 0 an, weil man aus der Erfahrung mit den ganzen "off by one"-Fehlern gelernt hat, die dadurch entstehen, das der Programmierer ständig bei irgendwelchen Indizes eins dazu zählen oder abziehen musste und es dann doch hier und da vergass oder falsch gemacht hat.
Bei der Formel ist "vereinfachen" vielleicht nicht der richtige Weg sondern eben doch "viele" Zeilen schreiben, die man dafür dann aber versteht. Der kürzeste Quelltext ist nicht immer der verständlichste. Alternativ könnte man die Formel in einem Kommentar verständlich erklären.
Bei vielen Programmiersprachen fingen Indizes früher bei 1 an, oder der Programmierer konnte sich den Startindex sogar aussuchen. Fast alle neueren Sprachen fangen bei 0 an, weil man aus der Erfahrung mit den ganzen "off by one"-Fehlern gelernt hat, die dadurch entstehen, das der Programmierer ständig bei irgendwelchen Indizes eins dazu zählen oder abziehen musste und es dann doch hier und da vergass oder falsch gemacht hat.
Bei der Formel ist "vereinfachen" vielleicht nicht der richtige Weg sondern eben doch "viele" Zeilen schreiben, die man dafür dann aber versteht. Der kürzeste Quelltext ist nicht immer der verständlichste. Alternativ könnte man die Formel in einem Kommentar verständlich erklären.
-
- User
- Beiträge: 53
- Registriert: Sonntag 2. Dezember 2007, 18:25
Die Formel wird dann kürzer? Glaube ich eher nicht...BlackJack hat geschrieben:Das mit den Indizes und dem Start bei 1 ist Unsinn. Starte mal bei 0 und überarbeite dann zum Beispiel die Formel für `nummer`. Die wird dann auf einen Schlag schonmal kürzer, weil die ganzen Indexanpassungen nicht mehr gemacht werden müssen.
- nkoehring
- User
- Beiträge: 543
- Registriert: Mittwoch 7. Februar 2007, 17:37
- Wohnort: naehe Halle/Saale
- Kontaktdaten:
Ich glaub doch:Vingdoloras hat geschrieben:Die Formel wird dann kürzer? Glaube ich eher nicht...BlackJack hat geschrieben:Das mit den Indizes und dem Start bei 1 ist Unsinn. Starte mal bei 0 und überarbeite dann zum Beispiel die Formel für `nummer`. Die wird dann auf einen Schlag schonmal kürzer, weil die ganzen Indexanpassungen nicht mehr gemacht werden müssen.
Code: Alles auswählen
nummer = ((j-1)%3)+(9*(((j+2)/3)+3*((i-1)/3)-1))+1+3*((i-1)%3)
nummer = (j%3)+(9*(((j+1)/3)+3*(i/3)-1))+1+3*(i%3)

[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
-
- User
- Beiträge: 128
- Registriert: Freitag 22. Oktober 2004, 09:22
- Wohnort: Salzgitter
- Kontaktdaten:
Mir ist es vollkommen egal, wie du es machst, allerdings kann es kein guter Stil sein, bewusst einen Integer als String zurückzugeben, weil man selbst irgendwo im eigenen Code einen Fehler eingebaut hat, der das natürliche Verhalten mit einer Fehlermeldung straft!Vingdoloras hat geschrieben:Bei mir hat das Testen nicht funktioniert, weil die Funktion die Zahl zurückgab, der Testmechanismus aber geschaut hat, ob der String zurückgegeben wurde. Ich hab es in der Abfragen-Funktion geändert, aber wenn du willst, mach ich es andersrum.
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
-
- User
- Beiträge: 53
- Registriert: Sonntag 2. Dezember 2007, 18:25
Das Programm ordnet die Felder ganz falsch zu, ich muss was ändern...