Sudokuprogramm

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Hallo Leute!
Ich habe mich auf Anregung meines Vaters an den PC gesetzt, um ein Programm zu schreiben, dass Sudokus löst/prüft.
Ich benutze Python 2.4, also werden die jenigen, die Python ab Version 3 nutzen, es wahrscheinlich nicht nutzen können. Zur erstellung des GUI habe ich Tkinter benutzt, da ich mich mit den anderen nicht auskenne und ich Tkinter für ausreichend halte.
Um es gleich zu sagen: Das Script ist noch nicht fertig. Es enthält jetzt einen vollständig funktionierenden Überprüfungsmechanismus und ich arbeite an einem Lösungsmechanismus.

Der Paste:
http://paste.pocoo.org/show/20280/
Zuletzt geändert von Vingdoloras am Mittwoch 9. Januar 2008, 11:38, insgesamt 5-mal geändert.
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Code: Alles auswählen

# Wer dieses Script weiterverwenden möchte, sollte darauf achten, dass er kein
# from xy import *
# mehr nutzt, damit keine unbeabsichtigten Überschneidungen mit dem Tkinter-Import entstehen können

from Tkinter import *
Solltest du aber auch nicht nutzen.. Warum baust du deine Widgets nicht auf existierenden Tkinter-Widgets auf? Diese zusammenführenden Boxen schreien doch förmlich danach, von Tkinter.Frame zu erben.
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

ERBEN...
es kam mir so oft in den Sinn, aber ich wusste nicht, wie ich es nutzen sollte...
aber ums mal so zu sagen:
Wenn ich das erben lasse, müsste ich alles nochmal überarbeiten und ich weiß auch nicht sehr viel über das Frame-Widget (alles was ich weiß is aus einem Buch oder aus Selbstversuchen, GUIs kommen im Unterricht viiiiiiieeeeeeel später ran...) :oops:
Aber ich freue mich auf jeden Fall, dass jemand geantwortet hat :D
Ich arbeite grad an den anderen beiden Listen

PS: Leonidas, falls du das hier liest: ich verwende wieder exec :twisted: :twisted: :twisted: (sei bitte nich böse, aber wenn du das siehst, wirst du [hoffentlich] verstehen, warum ich das mache :wink: )
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Vingdoloras hat geschrieben:Wenn ich das erben lasse, müsste ich alles nochmal überarbeiten und ich weiß auch nicht sehr viel über das Frame-Widget
Wenn Du wirklich lernen willst, zu Programmieren, wirst du noch sehr oft deinen Code einfach löschen und noch einmal von Vorne anfangen müssen, das gehört dazu. Und besonders umfangreich ist dein Quelltext ja nun wirklich noch nicht..
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Da hast du wirklich Recht(er ist noch nicht sehr umfangreich)...
Zum einfach löschen und neu anfangen: dies ist der fünfte Code, die ersten zwei sind schon endgültig gelöscht, einen der anderen zwei verstehe ich selbst nichtmehr (da hab ich aus einer Laune heraus geschrieben, manchmal führt das zu etwas gutem, aber öfters auch zu etwas anderem^^) und das vierte funktioniert eigentlich gut, nur dass man die Kästchen nicht mit
sudoku.box(1 bis 9).feld(1 bis 9).get()
abrufen kann, sondern mit
sudoku.reihe(1 bis 3).box(1 bis 3).reihe(1 bis 3).feld(1 bis 3)
also noch viel umständlicher.
Aber generell, Coed löschen und neu anfangen, das ist das Try-And-Error-Prinzip :D Ich gehe sehr oft danach vor, auch in der Schule, obwohl mein Lehrer uns mal gesagt hat, dass TryAndError meistens nichts gutes erzeugt. Naja, jedem seine eigene Meinung :roll:

Wunder dich nicht, ich schreibe irgendwie gerne und viel, nur nicht mit Stift auf Papier :wink:

Edit: Es wird sicher noch mehr Code werden, denn das ist ja nur der Rohling. Das Prüfverfahren bzw Lösungsverfahren wird ja viel komplizierter werden.
Nochmal Edit: So. Hab jetzt drei Listen erstellt. Eine Liste "reihen", eine "spalten" und eine "boxen". Jede dieser Listen enthält 9 Unterlisten, die jeweils 9 Objekte enthalten. Mehr habe ich eigentlich nicht geändert, aber die Listen sind ziemlich groß. Ich werde den Code gleich hochladen, dann fange ich mit den Überprüfungsscript an.
Zuletzt geändert von Vingdoloras am Freitag 4. Januar 2008, 15:50, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Vingdoloras hat geschrieben:Aber generell, Coed löschen und neu anfangen, das ist das Try-And-Error-Prinzip :D Ich gehe sehr oft danach vor, auch in der Schule, obwohl mein Lehrer uns mal gesagt hat, dass TryAndError miestens nichts gutes erzeugt. Naja, jedem seine eigene Meinung :roll:
Es gibt einen Unterschied zwischen Trial-and-error und Programming-by-Accident. So ist letzteres einfach nur runterklopfen von Code der dann vielleicht funktioniert (und es meistens nicht tut), ersteres hingegen würde ich als Versuch irgendetwas zu implementieren der dann an irgendetwas gescheitert ist. Wenn ein Konzept scheitert, kann man es noch auf einem anderen Weg versuchen und genau dafür ist es ja auch sinnvoll. Nicht jeder Weg führt sofort zum Ziel.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Leonidas hat geschrieben:Nicht jeder Weg führt sofort zum Ziel.
Habe ich ja auch nie behauptet :wink:
Ich hoffe, der Code gefällt dir diesmal besser als der Terminplaner (in Sachen Sauberkeit und Übersichtlichkeit) :D
BlackJack

@Vingdoloras: IMHO gehst Du das Problem vom falschen Ende an. Schreib doch erst einmal Code zum prüfen/lösen von Sudokus und *dann* erst eine GUI dazu.

So hast Du ja schon das Problem, dass Du Deine GUI danach gestaltest, wie der Algorithmus später auf die Daten zugreifen soll. So etwas hat in einer GUI aber nichts zu suchen. Die sollte man für den Benutzer gestalten und nicht für den Code der darunter irgendwo läuft. Also irgendwie 91 Eingabfelder so darstellen, dass es für den Benutzer möglichst übersichtlich ist und einen "Lösen"-Button. Und wenn man dort drauf drückt, werden die Eingabefelder ausgelesen und an eine Prüf- oder Lösungsfunktion übergeben, deren Ergebnis dann wieder dargestellt wird.
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

@ BlackJack: Es sind 81 Felder :wink: (ich sag auch irgendwie immer 91)
Mein Problem war am Anfang, dass ich nicht wusste, wie die Funktion zum Prüfen/Lösen auf die Felder zugreifen sollte.

Muss erstmal kurz den hochgeladenen Code ändern, ich hab ein paar Kommas vergessen...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Vingdoloras hat geschrieben:Ich hoffe, der Code gefällt dir diesmal besser als der Terminplaner (in Sachen Sauberkeit und Übersichtlichkeit) :D
Ich führe nie Tkinter-Code aus, weil ich es gar nicht installiert habe und schaue mir auch nur ungerne Code an, der Stern-Importe verwendet. Lass das in Zukunft, damit tust du dir auch selbst einen Gefallen.

Was den Code an sich angeht muss ich auch sagen, dass ich nicht sonderlich begeistert bin. Wenn man Variablen anfängt zu nummerieren ist man oft schon dabei das Probelm falsch anzugehen. In Python existieren Listen und for-schleifen, mit denen man beliebige Anzahlen von Widgets erstellen kann. Das würde ich dir eben raten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Leonidas hat geschrieben:Ich führe nie Tkinter-Code aus, weil ich es gar nicht installiert habe
Welche Version von Python nutzt du? Tkinter gehört doch zur Standardbibliothek, oder?


Naja... ich habe irgendein Problem im Programm... Der Lösungsmechanismus funktioniert bei meinem Testsudoku nicht, d.h. er liefert nach einer Weile Widersprüchliche Ergebnisse.

Der Paste:

http://paste.pocoo.org/show/19506/


@ Leonidas: Hab extra für dich den Sternchenimport weg gemacht :wink:

@ Alle: Ich wäre froh, wenn ein paar Leute das mal testen würden. Das Programm beherrscht bis jetzt nur eine simple Abfrage
(dieses Feld kann 1, 2 und 3 sein; das nächste kann nur 5 sein, also wird 5 eingetragen u.s.w.)
an der Negativabfrage
(Feld A kann 1, 2 und 3 sein; kein anderes Feld im Block von Feld A kann 1 sein, also wird 1 in Feld A eingetragen)
arbeite ich noch.

Das Script müsste nun also schon die einfachste sorte von Sudokus lösen können. An alle, die es ausprobieren: Schaut auch auf den Interpreter, wenn das Script gestartet ist. Das Script gibt nach jedem Lösungsdurchlauf an, wie viele Felder es lösen konnte. Wenn es keine weiteren Felder lösen konnte, beendet es die Lösungsschleife.

Wenn es also anzeigt
"0 weitere Felder gefunden!"
dann hat es entweder alle Felder gelöst, oder es ist auf einen Widerspruch gestoßen, also z.B. Feld X kann weder 1, noch 2, noch 3 und so weiter, also Feld X kann GAR NICHTS sein.
Wenn das Script also nichts mehr findet, schaut bitte, ob die Lösung, so weit sie bis jetzt gekommen ist, richtig ist und versucht ggf., das entstandene (halbgelöste oder mit Positivabfragen soweit wie möglich gelöste) Sudoku fertigzulösen, um zu Prüfen, ob es wirklich nicht zu einem Widerspruch kommt.

Wenn es zu einem Widerspruch kommt, postet das Sudoku bitte hier im Thread in der Form

1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18
und so weiter...
73 74 75 76 77 78 79 80 81

Ich werde auch ein paar weitere Sudokus testen.

--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------

@ BlackJack:
BlackJack hat geschrieben:Die sollte man für den Benutzer gestalten und nicht für den Code der darunter irgendwo läuft.
Ich sehe das Programm als ein Puzzlebild. Die zwei (momentan von mir betrachteten) Teile (bitte keine Nerferei von wegen es gibt kein zweiteiliges Puzzle...) sind
--Das Script: es besteht aus zwei voneinander total unabhängigen Teilen
- Testscript
- Lösungsscript
Diese beiden Teile muss man sich so vorstellen, dass an ihrer
Berührungsfläche keine Zähnchen sind, da sie einander nicht benötigen
oder vervollständigen.
--Das GUI: Hier lasse ich mal die Unterteilung in Neunerblöcke beim
Sudoku

Diese zwei Teile sind größtenteils voneinander unabhängig, nur die Zähnchen müssen ineinanderpassen.
Daher sehe ich das so, dass man mit beiden anfangen kann. Ich hatte ja schon eine Idee, nur hatte ich noch nicht die Umsetzung. Schau mal in meinen ersten Post, da habe ich geschrieben, dass es bis da nur der Rohling (damit meinte ich das GUI) ist, ohne jegliche Funktion. Ich habe dieses GUI für den Benutzer geschrieben, nicht für irgendein Script.
DAS war für mich das GUI Puzzleteil ohne Zähnchen.

Dann habe ich Listen hinzugefügt, die der Abfrage der Reihen, Spalten und Blöcke dienen.
DIESE LISTEN waren/sind für mich die Zähnchen!

NUN arbeite ich am Script, dem letzten Puzzleteil. Davon ist das eine Untergeordnete Teil zum Testen von Sudokus schon fertig, aber das ist im Vergleich zu dem, was das Lösungspuzzleteil werden wird, ein Einzeiler.
Wenn du jetzt fragst, wo hat dieses Scriptpuzzleteil die Zähnchen? Das sind die Parameter, die die Listen empfangen.

Mit allem, was ich hier geschrieben habe, möchte ich mit niemandem meckern oder mich beschweren. Ich habe lediglich meine Sicht der Dinge beschrieben und bin für jede Antwort in diesem Thread dankbar.

Edit: WHOA ich glaub ich habe ein wenig viel geschrieben... :oops:
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Vingdoloras hat geschrieben:Mit allem, was ich hier geschrieben habe, möchte ich mit niemandem meckern oder mich beschweren. Ich habe lediglich meine Sicht der Dinge beschrieben und bin für jede Antwort in diesem Thread dankbar.
Die Bereitschaft der Community, dir weitere Antworten zu schreiben, dürfte langsam abnehmen, wenn du gute Vorschläge einfach in den Wind schießt. Leonidas hat doch darauf hingewiesen, dass deine Nummerierung von Variablen schlichtweg sinnfrei ist und durch Listen ersetzt werden müsste. Ergebnis deiner Sturheit sind die Zeilen 83 bis 190, die unter Anwendung von Schleifen auf ein Minimum an Zeilen reduziert werden könnten.
Ferner sprichst du von Puzzleteilen, übersiehst aber, dass deine Puzzleteil aneinander "kleben", da du in in testen() und loesen() bereits GUI und Logik vermischst..
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Redprince hat geschrieben:Leonidas hat doch darauf hingewiesen, dass deine Nummerierung von Variablen schlichtweg sinnfrei ist
Das habe ich vernommen, aber wie soll ich 81 identische Kästchen sonst benennen?
Redprince hat geschrieben:Ergebnis deiner Sturheit sind die Zeilen 83 bis 190, die unter Anwendung von Schleifen auf ein Minimum an Zeilen reduziert werden könnten.
Da war ich wirklich stur... ich werde daran arbeiten, aber wahrscheinlich erst heute abend, da ich in ein paar Minuten weg muss...
Redprince hat geschrieben:Ferner sprichst du von Puzzleteilen, übersiehst aber, dass deine Puzzleteil aneinander "kleben", da du in in testen() und loesen() bereits GUI und Logik vermischst..
Diesen Teil des Scripts muss ich auch nochmals völlig überarbeiten...
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Vingdoloras hat geschrieben:
Redprince hat geschrieben:Leonidas hat doch darauf hingewiesen, dass deine Nummerierung von Variablen schlichtweg sinnfrei ist
Das habe ich vernommen, aber wie soll ich 81 identische Kästchen sonst benennen?
Leonidas hat geschrieben:Wenn man Variablen anfängt zu nummerieren ist man oft schon dabei das Probelm falsch anzugehen. In Python existieren Listen und for-schleifen, mit denen man beliebige Anzahlen von Widgets erstellen kann. Das würde ich dir eben raten.
Immer noch..
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
DER Olf
User
Beiträge: 283
Registriert: Mittwoch 24. Dezember 2003, 19:32

es würde dem Leser deines Codes auch gut tun, englische -kurze- Bezeichnernamen zu lesen.
Leerzeilen innerhalb von Blöcken dienen auch der Übersichtlichkeit, denn so wie er momentan aussieht, werden sich wohl die wenigsten Threadbeobachter ihn durchlesen ;)

Höre doch einmal auf die Ratschläge, die dir bereits von Redprince und Leonidas gegeben wurden und fang nochmal von vorne an - dieses mal mit Flexibler Algorithmus-Implementation und OOP-igerem GUI-Code.
Und wenn du das Frame-Widget (welches eigentlich kein Widget ist, sondern nur ein visueller Container, iirc) nicht kennst, dann wirst du realisieren müssen, dass Programmieren nicht (nur) "from scratch auf die Tasta" hauen, sondern auch Planung, Vorbereitung und Doku-Lesen bedeutet. Ich hätte dir auch zum Tkinter.Frame geraten ... jetzt sind es schon 2 Leute, die dir das empfehlen - also hopp hopp, google.de, Tkinter Frame, es geht natürlich auch help(Tkinter.Frame). Codebeispiele sind natürlich auch nicht zu verachten.

In diesem Sinne noch happy coding ;)

Grüße, olf
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Vingdoloras hat geschrieben:
Leonidas hat geschrieben:Ich führe nie Tkinter-Code aus, weil ich es gar nicht installiert habe
Welche Version von Python nutzt du? Tkinter gehört doch zur Standardbibliothek, oder?
Ich nutze 2.4.x, 2.5.1 und 3.0a2 (wobei 3.0 "nutzt" keiner, ich schaue es mir auch nur an). Aber dankenswerterweise hat der Windows-Installer die Option "[X] Tkinter installieren", wo man das Häkchen wegmachen kann und die meisten Distributionen haben intelligenterweise Tkinter in ein Paket wie ``python-tk`` ausgelagert, das man nicht installieren muss. Das hat auch deswegen Sinn, weil sonst Python Tk reinziehen würde, was wiederrum die X-Libs reinziehen würde, was man auf einem Server nicht braucht und eingentlich auch nicht haben will.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

DER Olf hat geschrieben:dieses mal mit Flexibler Algorithmus-Implementation und OOP-igerem GUI-Code
öhm *hust* ich hab seit einem knappen halben Jahr Informatik in der Schule, so ziemlich alles was ich weiß, habe ich aus zwei Büchern...
DER Olf hat geschrieben:also hopp hopp, google.de, Tkinter Frame
hab ich versucht, Tkinter Frame in Google... kamen berichte über das "neue" Python 1.5 und ein (mehr oder weniger nützlichers) Anwendungsbeispiel, in dem das Frame-Widget vorkam und in dessen erklärung dann im Text einmal Frame und ein paar male Tkinter vorkam, aber keine Erklärung etc. Deswegen hab ich bei Google an "Tkinter Frame" noch "2.4" rangehängt und schwupps kam DIESER Thread hier zum Vorschein :o

help(Tkinter.Frame) liefert nen Error, ich Tipp mich grad Schritt für Schritt durch die Help-Funktionen, erst modules, dann modules Tkinter... das dauert jetzt etwas länger, da mein Virenscanner im Hintergrund läuft...

Redprince hat geschrieben:
Leonidas hat geschrieben:Wenn man Variablen anfängt zu nummerieren ist man oft schon dabei das Probelm falsch anzugehen. In Python existieren Listen und for-schleifen, mit denen man beliebige Anzahlen von Widgets erstellen kann. Das würde ich dir eben raten.
Immer noch..
Ich hab's versucht, aber egal wie ichs drehe und wende, mir fällt nix ein... mir fehlt in solchen Sachen noch etwas die praktische Erfahrung, kann mich da bitte jemand aufklären?
DER Olf
User
Beiträge: 283
Registriert: Mittwoch 24. Dezember 2003, 19:32

Vingdoloras hat geschrieben:
DER Olf hat geschrieben:dieses mal mit Flexibler Algorithmus-Implementation und OOP-igerem GUI-Code
öhm *hust* ich hab seit einem knappen halben Jahr Informatik in der Schule, so ziemlich alles was ich weiß, habe ich aus zwei Büchern...
ach herrje... andere hatten nie Informatik in der Schule. Und Bücher geben generell nur Denkanströße und Beispiele - selber Denken, Ausprobieren, Fehler machen, Erfahrungen sammeln heißen hier die Stichwörter.
help(Tkinter.Frame) liefert nen Error,
Was für einen? -.- Manchmal soll man aus Fehlermeldungen tatsächlich schlau werden...[/quote]
das dauert jetzt etwas länger, da mein Virenscanner im Hintergrund läuft...
dann schalt ihn doch einfach für den Moment aus...
Ich hab's versucht, aber egal wie ichs drehe und wende, mir fällt nix ein... mir fehlt in solchen Sachen noch etwas die praktische Erfahrung, kann mich da bitte jemand aufklären?
kümmer dich mal um Listen (für viele andere sprachen: arrays)
und vorallem um zweidimensionale ;)
dann lässt sich da ganz einfach durch iterieren.

bzgl. Google:
suchwort: Tkinter Frame
2. Treffer: http://effbot.org/tkinterbook/frame.htm

was fehlt dir denn jetzt noch?
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Vingdoloras hat geschrieben:
Redprince hat geschrieben:
Leonidas hat geschrieben:Wenn man Variablen anfängt zu nummerieren ist man oft schon dabei das Probelm falsch anzugehen. In Python existieren Listen und for-schleifen, mit denen man beliebige Anzahlen von Widgets erstellen kann. Das würde ich dir eben raten.
Immer noch..
Ich hab's versucht, aber egal wie ichs drehe und wende, mir fällt nix ein... mir fehlt in solchen Sachen noch etwas die praktische Erfahrung, kann mich da bitte jemand aufklären?
Das [wiki=Tutorial]Tutorial im Wiki[/wiki] kann, speziell der Abschnitt Listen erscheint in diesem Zusammenhang sinnbehaftet. Wälz' dich durch verschiedene für Einsteiger geschriebene Artikel und probiere mit der Phyton-Shell einfach aus, wird schon nichts kaputt gehen.. Letzten Endes bist du nicht der erste, der Programmieren lernt und wirst analog dazu nicht der letzte sein, der über bereits verfasste Texte einen Zugang finden wird.
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hallo,

hier ein Referenz zu Tkinter! Bessers kannst glaube ich nicht finden.
http://docs.huihoo.com/tkinter/tkinter- ... index.html



Gruss
pyStyler
Antworten