Ausgeben einer matrix

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.
Antworten
Benutzeravatar
JustHechi
User
Beiträge: 12
Registriert: Samstag 26. Oktober 2013, 20:14

Hallo!

Jaa ich hab eine frage aber noch kein code dazu. Also meine Aufgabe ist es ein Sudoku zu programmieren und es fägnt schon damit an das ich nicht weiß wie es es ausgeben soll...... und zwar gar nicht das einzige was ich machen wollte ist eine liste mit 81 variablen und dann mit print zu arbeiten aber das hab ich aus probiert und hab natürlich nicht das erhoffte ergebnis bekommen.

Also damit ich aber auch eine klare frage hier stehen hab. Wie gebe ich ein 9x9 Matrix aus aber alle werte müssen bearbeitet werden können?

danke für alle antworten!

grüße hechi~~!!
BlackJack

@JustHechi: Wenn Du eine Liste mit 81 Elementen verwendest, dann musst Du Dir halt Code schreiben der das als Matrix ausgibt. Die Fragen die sich da stellen sind doch ganz einfach: Nach wie vielen ausgegebenen Elementen muss man jeweils eine neue Zeile in der Ausgabe anfangen.

Etwas „natürlicher” bei einer zweidimensionalen Tabelle wäre es vielleicht eine Liste mit Listen für die Zeilen anzulegen, die dann jeweils wieder neun Elemente enthalten. *Das* wäre dann auch relativ einfach auszugeben.
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

Kennst du das Solving Every Sudoku Puzzle by Peter Norvigl? Finde ich ganz spannend in dem Zusammenhang. Die Frage ist aus meiner Sicht, ob du ein gegebenes Sudoku im Rechner repräsentieren und ausgeben musst oder selbst ein Sudoku erzeugen musst. Ich würde ebenfalls eine Liste verwenden.
Benutzeravatar
JustHechi
User
Beiträge: 12
Registriert: Samstag 26. Oktober 2013, 20:14

Ich schau mir den link an danke und ich arbeite mit listen von listen wie ihrs mir geraten habt es funktionier auch im grunde und ich hab eine die auch am laufen bloß hat es nicht die richtige "struktur" es ist einfach eine ganz lange liste und nicht 9 x 9 wie ich es eingentlich brauche habt ihr vllt ein tipp für mich

@pixewakb: ich muss selber ein suduoku erzeugen das vom benutzer dann zu lösen ist in der konsole...

Code: Alles auswählen

A = ["A", "B", "C" ,"D" ,"E", "F", "G", "H", "I"]
B = [1, 2, 3, 4, 5, 6, 7, 8, 9]

def cross(lst1, lst2):
    global matrix
    matrix = []
    
    for a in range(9):
        row = []
        for b in range(3):
            row.append(str(A[a]) + str(B[b]))
        matrix.append(row)
        row = []
        for b in range(3,6):
           row.append(str(A[a]) + str(B[b]))
        matrix.append(row)
        row = []
        for b in range(6,9):
            row.append(str(A[a]) + str(B[b]))
        matrix.append(row)
        row= []         
    #print(matrix)
cross(A, B)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hast du mal ein Tutorial vollständig durchgearbeitet? Dein jetziger Code sieht sehr stark danach aus, als ob du Grundlagen nicht verstanden hast und versuchst dein Programm irgendwie zu raten. Ständige Wiederholungen, unnötige Anweisungen ohne Effekt und ohne Struktur. Programmieren funktioniert so nicht, schon gar nicht bei etwas komplexeren Problemen. Du musst erst die Grudlagen lernen, dann schaust du dir das Problem an, überlegst wie du es umsetzen kannst und erst dann schreibst du es. Du scheinst momentan eher wild zu probieren.
Das Leben ist wie ein Tennisball.
BlackJack

@JustHechi: Vergiss ``global``. Werte sollten Funktionen als Argumente betreten und als Rückgabewerte verlassen. Nur so ist eine Funktion eine „black box” in die man an einem Ende etwas herein steckt und am anderen Ende etwas heraus kommt. Wenn man ``global`` verwendet, schafft man schwer durchschaubare Abhängigkeiten und schlecht testbare oder wiederverwendbare Funktionen.

Mir ist auch nicht ganz klar was für eine Struktur Du da versuchst aufzubauen und wofür? Ein Sudoku besteht aus 9×9 Feldern in denen entweder eine Zahl oder „nichts” steht. Warum versuchst Du da Zeichenketten mit Koordinaten hinein zu stecken? Es würde sich eine verschachtelte Liste mit Zahlen von 0 bis 9 und `None` für „nichts” anbieten.

Die *drei* inneren Schleifen verstehe ich auch nicht. Für eine zweidimensionale Struktur braucht man insgesamt nur *zwei* — eine äussere und eine innere Schleife.

Alternativ könnte man ein eine flache Liste mit 91 Werten verwenden. Letztendlich sollte man die Datenstruktur sowieso kapseln und sich Funktionen für den Zugriff schreiben. Das führt eigentlich ziemlich direkt zu einer eigenen Klasse für diesen Datentyp. Ob man eine flache oder eine verschachtelte Liste verwendet wirkt sich dann nur noch darauf aus wie die Funktionen konkret aussehen mit denen auf die Elemente zugegriffen wird. Die sollte man so strukturieren dass möglichst wenige die Struktur kennen müssen.

Die beiden Varianten beim Erzeugen:

Code: Alles auswählen

def create_sudoku(size=9):
    return [[None] * size for _ in xrange(size)]

def create_sudoku(size=9):
    return [None] * (size * size)
Wenn man die Grösse abfragen will:

Code: Alles auswählen

def get_size(sudoku):
    return len(sudoku)

def get_size(sudoku):
    return int(len(sudoku)**0.5)
Iterieren über die Zeilen:

Code: Alles auswählen

def iter_sudoku_rows(sudoku):
    return iter(sudoku)

def iter_sudoku_rows(sudoku):
    size = get_size(sudoku):
    for i in xrange(size):
        yield sudoku[i * size:(i + 1) * size]
Und um das Sudoku in eine Zeichenkette umzuwandeln braucht man dann schon gar nicht mehr zu wissen wie die Struktur aussieht:

Code: Alles auswählen

def sudoku_to_string(sudoku):
    return '\n'.join(
        ' '.join('-' if x is None else str(x) for x in row)
        for row in iter_sudoku_rows(sudoku)
    )
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

BlackJack hat geschrieben:Alternativ könnte man ein eine flache Liste mit 91 Werten verwenden.
81. Ich wollte dich einfach nur mal korrigieren :mrgreen:
Das Leben ist wie ein Tennisball.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

EyDu hat geschrieben:
BlackJack hat geschrieben:Alternativ könnte man ein eine flache Liste mit 91 Werten verwenden.
81. Ich wollte dich einfach nur mal korrigieren :mrgreen:
Das ist ein Puffer wie bei SSDs falls mal ein Listeneintrag kaputt geht. :mrgreen:
BlackJack

Grmpf. :oops: Das '8' und '9' aber auch auf der Tastatur so eng nebeneinander liegen müssen. Ich baue am besten gleich mal die Tastatur um. 8)
Benutzeravatar
JustHechi
User
Beiträge: 12
Registriert: Samstag 26. Oktober 2013, 20:14

Code: Alles auswählen

def create_sudoku(size=9):
    return [[None] * size for _ in xrange(size)]
 
def create_sudoku(size=9):
    return [None] * (size * size)
Ich versteh hier den Code nicht wirklich ich brauch ja am Ende nicht einen Rückgabewert von der Funktion sondern eine 9 x 9 Matrix die ich bearbeiten kann z.b. mit kommando [] []
und eine Liste mit 81 Elementen kann ich nicht benutzen da es nicht die richtige Struktur für ein Sudoku hat wenn die Liste ausgegeben wird ist es eine lange Liste ich hab brauch 9 Zahlen und dann erst in der nächsten Zeile wieder 9 Zahlen und das 9x deswegen die Matrix ich versteh aber was ihr meint mit der Zeichenkette und den Koordinaten meint aber das hab ich so gemacht weil der Benutzer ja das Sudoku bearbeiten muss und das wollte ich mit kommando [spalte] [zeile] dafür hab ich den Spalten Buchstaben gegeben und den Zeilen Zahlen

ich hab mein code mittlerweile überarbeitet

Code: Alles auswählen

A = ["A", "B", "C" ,"D" ,"E", "F", "G", "H", "I"]
B = [1, 2, 3, 4, 5, 6, 7, 8, 9]

def cross(lst1, lst2):
    global matrix
    matrix = []
    
    for a in range(9):
        row = []
        for b in range(9):
            row.append(str(A[a]) + str(B[b]))
        matrix.append(row)
              
    #print(matrix)
cross(A, B)

def print_():
    el = 0
    t = ""
    l = 1
    for i in matrix:
        for num in i:
            if (el % 3) == 0:
                t += "  "+ chr(9162) + num + chr(9162)
            else:
                t += chr(9134) + num
                el += 1
        print(t)
        if l % 3 == 0:
            print(" ")
        """if l == 0:
            print()"""
        l+=1
        t=""

BlackJack

@JustHechi: Doch den Rückgabewert brauchst Du. Das ist ja genau die verschachtelte Liste beziehungsweise eine flache Liste.

Du solltest nicht mit dem Indexoperator auf die Sudoku-Datenstruktur zugreifen, sondern mit einer Funktion, beziehungsweise zwei Funktionen. Eine um einen Wert von einer gegebenen Koordinate abzufragen und eine um einen Wert an einer gegebenen Koordinate zu setzen. Trenne die (interne) Organisation von der von aussen verwendeten Schnittstelle. Dann kannst Du den inneren Aufbau einfacher ändern.

Vergiss bitte ``global``. Wenn Du das benutzt dann machst Du mit 100%iger Sicherheit etwas falsch. Normalerweise würde ich sagen mit 99,9%tiger Sicherheit, aber Du bist ganz offensichtlich noch nicht weit genug um die 0,1% Ausnahmefälle zu erkennen, also lass es bitte. Lerne wie Funktionen funktionieren.

Wenn Du die „list comprehension”-Syntax nicht kennst, dann lerne sie. Die sollte in jedem vernünftigen Python-Tutorial erklärt werden.

Und könntest Du bitte mal *Satzzeichen* benutzen? Das ist furchtbar schwer zu lesen was Du da ohne Punkt und Komma runterschreibst.

Natürlich kannst Du auch eine Liste mit 81 Elementen benutzen. *Die* richtige Struktur bei der alle erforderlichen Zugriffe der Anordnung der Daten im Speicher entspricht gibt es sowieso nicht. Für die Ausgabe musst Du zeilenweise auf die Daten zugreifen, da ist eine Liste mit Zeilen-Listen einfacher — das sieht man ja auch an meinen Beispiel-Funktionen. Aber im Laufe der weiteren Entwicklung wirst Du auf Spalten und 3×3-Ausschnitte zugreifen müssen, und das gibt keine der beiden Strukturen *direkt* her. Man muss also in jedem Fall Quelltext schreiben der mit Koordinaten Berechnungen anstellt. Eine weitere Möglichkeit wäre ein Wörterbuch zu verwenden welches Tupel mit Koordinaten auf Kästchen abbildet. Die passende Datenstruktur muss nicht das sein was für die Anzeige oder Umwandlung in eine Zeichenkette das praktischste oder direkteste ist, sondern eine die *alle* Operationen berücksichtigt, und gut für die ausgelegt ist, die am häufigsten ausgeführt werden.

Du hast nicht den Spalten und Zeilen Zahlen und Buchstaben gegeben, sondern das hast Du als *Werte* benutzt. Das sind aber nicht die Werte mit denen man bei Sudoku zu tun hat. Die möglichen Werte für ein Kästchen sind „leer” und die Ziffern 0 bis 9, wobei man „leer” wie schon gesagt sinnvoll mit `None` abbilden kann. Etwas wie ``A2`` ist kein gültiger Wert für ein Kästchen. Das kann man als Koordinatenangabe verwenden, aber die Koordinaten speichert man nicht in einer Listenstruktur. Dort sind dir Koordinaten implizit in der Datenstruktur enthalten. Wenn man das Sudoku als Wörterbuch mit Koordinaten als Schlüssel speichert, *dann* speichert man auch die Koordinaten in der Datenstruktur.

Der Sinn der `cross()`-Funktion erschliesst sich mir deshalb immer noch nicht. Zumal die auch fehlerhaft und „unpythonisch” geschrieben ist.

Die Argumente `lst1` und `lst2` hbn ncht nr schlcht Nmn (so Scheisse liest sich das wenn man anfängt Vokale wegzulassen), sondern werden innerhalb der Funktion gar nicht verwendet. Die Argumente wegzulassen wäre übrigens die falsche Lösung an der Stelle.

Man iteriert in Python nicht über Indexzahlen um damit dann nur auf Sequenzen zuzugreifen. Man kann *direkt* über die Elemente der Sequenzen iterieren. Mit „list comprehension(s)” ist das ganze ein Zweizeiler:

Code: Alles auswählen

def cross(sequence_a, sequence_b):
    return [['{0}{1}'.format(a, b) for b in sequence_b] for a in sequence_a]
Bei `print_()` fehlt das Argument `matrix` weil Werte Funktionen als Argumente betreten sollten und nicht einfach so magisch aus dem Modulnamensraum kommen sollten.

Die einbuchstabigen Namen sind schlecht, weil nichtssagend. Für alles was kein Index ist oder nur in einem sehr beschränkten Gültigkeitsbereich („comprehensions”, Generatorausdrücke, ``lambda``-Ausdrücke) verwendet wird, sind einbuchstabige Namen nicht aussagekräftig genug.

Wenn man zusätzlich zu den Elementen eines iterierbaren Objekts auch noch einen Laufindex braucht, sollte man den nicht manuell verwalten, sondern die `enumerate()`-Funktion verwenden.

`t` wird an *zwei* ungünstigen Stellen an die leere Zeichenkette gebunden statt nur an *einer* günstigeren Stelle.
Antworten