Elemente in Matrix verändern

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
Python24
User
Beiträge: 20
Registriert: Mittwoch 14. Oktober 2015, 21:35

Hallo Leute,

gleich einmal Danke, an alle, die mir meine Frage beantworten können, es geht hier nämlich um ein kleines Problem in einer großen Aufgabe.

Code: Alles auswählen

m=1
while m<n**2:
    m=int(input("Zahl von 1 bis n**2"))
    s=int(input("Nummer der Spalte"))
    z=int(input("Nummer der Zeile"))
    if True:
print(M)
Eine kurze Erklärung hierzu: n ist die Länge meiner Quadratischen Matrix, also n**2 die Anzahl der Elemente darin.
M ist diese Matrix, in der jede Zeile durch eine Liste N dargestellt wird und vor der Schleife sind alle n**2 Elemente 0.
Die Schleife soll es nun ermöglichen alle Elemente in der Matrix beliebig zu ersetzen, also muss die Schleife n**2 Mal durchlaufen werden.
Nun die Fragen: Ist die Bedingung der while-Schleife richtig? Die Schleife muss n**2 Mal laufen, bis keine 0 mehr in M steht
Was muss bei if True stehen, damit in der Matrix auch nur die richtige Spalte und Zeile ersetzt wird?
Ich vermute etwas wie if True: M[z] = m and N[s] = m. Ich bitte um Hilfe, da ich in meinen Unterlagen nichts dazu finde.

Schöne Grüße
Python 24
Zuletzt geändert von Anonymous am Donnerstag 2. Juni 2016, 13:52, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@Python24: wenn Du etwas genau n**2-mal machen willst, dann nimm eine for-Schleife. So wie es jetzt dasteht hängt es ja davon ab, was Du als m eingibst, wie oft die Schleife durchlaufen wird. Die if-Abfrage verstehe ich nicht, was soll da geprüft werden? Ein Element setzt Du per »M[z][s] = m«.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du möchtest dass die Nutzerin für jedes Element in der Matrix ein Wert eingibt und fragst dann trotzdem nochmal nach der Zeile und Spalte?

Geh doch einfach durch die Matrix Zeile für Zeile und Spalte für Spalte, sag wo du grad bist und frag nach dem passenden Wert. Wenn du weisst wieviele Iterationen die machen willst ist eine while Schleife übrigens nie die richtige Wahl.
Python24
User
Beiträge: 20
Registriert: Mittwoch 14. Oktober 2015, 21:35

Danke, ich werde es schnellstmöglich als for-Schleife umschreiben versuchen, bisher hat das bei mir nicht geklappt, da ich nicht sich bin, wie ich dem Programm sage, dass die Schleife n**2 Mal gebraucht wird. Ich kenne leider nur Abhängigkeiten wie größer/kleiner n**2, wenn n global ist.
Klar wäre es sinnvoll die Zeilen und Spalten der Reihenfolge nach zu füllen, aber leider will die Aufgabenstellung, dass der Nutzer die Zeile und Spalte immer frei wählen kann, was aber auch mehr als n**2 Durchläufe zulassen müsste, wenn das gleiche Element mehrmals verändert wird.
Aufgrund des eben von mir geschilderten Problems, muss ich doch mal für alle Fälle fragen, wie kann ich die Matrix der Reihe nach durchlaufen?
Was das if angeht, ich muss in der fertigen Matrix ein paar Dinge prüfen, in meiner Schleife hätte man damit anfangen können, in der for eher nicht.
Python24
User
Beiträge: 20
Registriert: Mittwoch 14. Oktober 2015, 21:35

Ich brauche nur noch die korrekte Bedingung für die for-Schleife, denn meine Schleife hört immer noch auf, wenn ich ein m > n**2 eingebe und nicht nach n**2 Durchläufen, oder wenn in M keine 0 mehr ist, ist beides in Ordnung. Der Rest klappt aber schon gut, allerdings mit M[z-1][s-1] = m, danke.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

For Schleifen haben keine Bedingungen, insofern kannst du da weder eine angeben noch kann es eine passende geben. Wie groß die Matrix ist, ob sie rechteckig oder quadratisch ist spielt übrigens überhaupt keine Rolle. Iterier mit der For Schleife einfach direkt über die Matrix.
Zuletzt geändert von DasIch am Donnerstag 2. Juni 2016, 17:56, insgesamt 1-mal geändert.
BlackJack

@Python24: ``for``-Schleifen haben keine Bedingung deshalb ist mir die Frage nicht so ganz klar‽

Allerdings hast Du ja nach eigenen Aussagen doch nicht n² Durchläufe sondern so viele Durchläufe bis die Matrix komplett bestückt ist, und eventuell auch noch zusätzliche Bedingungen erfüllt. In dem Fall brauchst Du dann doch wieder eine ``while``-Schleife und zum Beispiel eine Funktion die eine Matrix bekommt und `True` zurück gibt falls die ”fertig” ist und `False` falls nicht. Die kann dann in der Bedingung verwendet werden.

Das ``… - 1`` brauchst Du nur wenn der Benutzer Zeilen- und Spaltennummern eingeben soll die bei 1 anfangen und nicht bei 0 wie es bei den meisten Programmiersprachen üblich ist.

Die Abfrage einer ganzen Zahl in einem vorgegebenen Bereich solltest Du in eine Funktion auslagern die solange fragt bis ein passender Wert eingegeben wurde. Also die Frage wiederholt bis der Benutzer a) tatsächlich eine Zahl eingegeben hat, und b) diese im geforderten Bereich liegt. Sonst nervt das Benutzer schnell wenn sie fast die gesamte Matrix ausgefüllt haben und ihnen *dann* ein Fehler in der Eingabe passiert und sie von komplett vorne anfangen müssen.

Weil Du von einem globalen `n` gesprochen hast: Gewöhn Dir am besten gleich an alles sinnvoll auf Funktionen zu verteilen. Keine globalen Variablen. Auf Modulebene gehören nur Definitionen von Konstanten, Funktionen, und Klassen. Sonst wird es schnell unübersichtlich und man kann die einzelnen Teile des Programms nicht isoliert testen, zum Beispiel um Fehler zu suchen, oder automatisierte Tests zu schreiben.
Python24
User
Beiträge: 20
Registriert: Mittwoch 14. Oktober 2015, 21:35

Wie schon eben angeklungen, bin ich jetzt doch bei der while-Schleife geblieben, habe nur als zweite Bedingung m>0 hinzugefügt. Vielleicht wäre es wirklich sinnvoll für den Fall, dass m wiederholt wird vom Nutzer zu fragen, ob er sich da sicher ist etc. Dass übrigens nur die Zahlen zwischen 0 und n**2, also von 1 bis n**2 in die Matrix dürfen ist gewollt, da dies Elemente einer anderen Liste L sind und nur diese in die Matrix dürfen. Mein Problem dabei, der Nutzer muss immer mit n**2 aufhören, was er vielleicht nicht will. Zweites Problem, wenn ich nun stattdessen n**2+1 nehme, dann wird >=n**2+1 auch in die Matrix eingegeben, was auch für die <=0 gilt, meine Liste L ist aber range(1, n**2+1), was bedeutet, dass diese Matrix dann am ende immer falsch sein würde. Was muss das Programm wissen, um mit diesen Zahlen die Schleife aufzuhören, sie aber aus der Matrix zu lassen?
BlackJack

@Python24: Welchen Wert `m` hat ist schlicht die falsche Bedingung. Der Benutzer muss dann nicht nur mit 2**n aufhören sondern er kann damit auch aufhören ohne alle Werte einzutragen. Deine Abbruchbedingung hat nichts mit `m` zu tun, sondern muss, wie schon gesagt, eine Prüfung der Matrix sein, ob die alle Bedingungen erfüllt um vollständig zu sein. Wenn die vollständig gefüllt sein soll und alle Werte von 1 bis 2**n enthalten muss, dann ist genau *das* was Du prüfen musst.
Python24
User
Beiträge: 20
Registriert: Mittwoch 14. Oktober 2015, 21:35

Code: Alles auswählen

m=1
while m > 0 and m < n**2+1:
    m=int(input("Zahl aus der Liste"))
    z=int(input("Nummer der Zeile"))
    s=int(input("Nummer der Spalte"))
    M[z-1][s-1] = m
print(M)
Dies ist also richtig außer die Bedingung, ich war überzeugt, wenn ich es erreiche, dass keine falsche Zahl in der Matrix steht, dann passt alles.
Nun aber zu deiner Idee, da ich später sowieso noch prüfen muss, ob in der Matrix nur die Zahlen von 1 bis n**2 vorkommen und diese Zahlen alle genau einmal, hätte ich gerne einen Tipp, da ich schon Bedingungen wie range(1, n**2+1) in M probiert habe, aber diese schlicht falsch waren.
Außerdem danke nochmal für die Hilfe, denn ich habe leider noch nicht so viel mit Matrizen programmiert, dies ist aber für Mathe wichtig.
BlackJack

@Python24: Das ist keine simple Bedingung. Wild rumprobieren klappt da nicht. Damit kommt man allgemein nicht weit beim Programmieren. Du musst Dir überlegen welche Eigenschaften die Matrix haben muss und dann Code schreiben der die alle prüft. Wie gesagt am besten als Funktion. Eventuell sogar als Funktion die weitere Funktionen benutzt um Teilaspekte einer kompletten Matrix zu prüfen.

Wenn ich es richtig verstanden habe darf kein Feld leer sein (wie auch immer Du leere Felder modelliert hast), es müssen 2**n verschiedene Werte sein (hier kann der `set()`-Datentyp ein Teil der Lösung zum prüfen sein), und alle Werte müssen im Bereich 1 bis 2**n liegen. Beim ersten und letzten Punkt kann man die `all()`-Funktion und einen Generatorausdruck verwenden und `itertools.chain.from_iterables()` um die Prüfung der beiden Punkte möglichst kompakt in *einem* Ausdruck zu formulieren. Man kann aber natürlich auch umfangreichere Funktion aus mehreren Anweisungen mit einer Schleife schreiben.

Wie schon gesagt solltest in Sinne der Benutzer auf jeden Fall die Eingaben so absichern das falsche Eingaben keinen Programmabruch zur Folge haben und der Benutzer von vorne Anfangen muss. Ausserdem dürfte es den meisten schwer Fallen sich im Kopf zu merken welche Felder sie schon mit welchen Werten belegt haben. Also sollte man vor jeder Eingabe für eine Feldbelegung das bisherige Feld ausgeben. Ab besten mit Zeilen und Spaltennummern.
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@Python24: um es nochmal deutlich zu sagen, vor dem Losprogrammieren brauchst Du eine klare Problembeschreibung mit allen Nebenbedingungen.

1. Es soll eine nxn-Matrix mit den Zahlen 1 bis n² gefüllt werden, wobei jede Zahl genau einmal vorkommen soll.
2. Der Benutzer soll Zeile, Spalte und Wert eingeben.

Daraus läßt sich schonmal ein Umgangssprachenprogramm schreiben. Solange die Bedingung von 1. nicht erfüllt ist, sollen die Zeile, Spalte und Wert vom Benutzer abgefragt werden und in die Matrix eingetragen werden. Oder in Python:

Code: Alles auswählen

n = 3
matrix = create_empty_matrix(n, n)
while not is_valid_matrix(matrix):
    fill_matrix_with_userinput(matrix)
Ich habe einfach mal drei Funktionen genommen, um anhand deren Namen deutlich zu machen, was die Funktionen machen sollen. Deine Aufgabe wäre es jetzt, diese drei Teilprobleme so lange in weitere Teile zu zerlegen, bis die Implementierung trivial ist. Also, z.B. is_valid_matrix muß prüfen, daß kein Feld leer ist, dass keine Zahl <1 oder >n² vorkommt und dass jede Zahl genau einmal vorkommt. Das ist entweder ein Einzeiler oder aber mehrere verschachtelte for-Schleifen, je nachdem, wie Du diese Funktion implementierst. Genauso verfährst Du mit fill_matrix_with_userinput. Die kannst Du entweder so schreiben, dass der Benutzer von vorne anfangen muß, falls er sich vertippt, oder dem Benutzer Rückmeldung geben, falls etwas nicht stimmt und ihn korrigieren lassen.
Python24
User
Beiträge: 20
Registriert: Mittwoch 14. Oktober 2015, 21:35

Danke für die Ideen, klingt zwar etwas doof, aber ich werde die nicht ganz korrekte Schleife vorerst lassen, da später in der Matrix noch so Manches berechnet werden muss. Ich werde erst ml schauen, dass die Rechnungen alle passen und dann nochmal an die Schleife gehen.
Sollte ich dazu nochmal fragen haben, werde ich sie stellen (vielleicht unter anderem Betreff), aber eigentlich kenne ich Rechnungen wie Spur (also Summe aller Mjj) oder Determinante oder Zeilenprodukt und Zeilensumme aus der Mathematik schon, darum will ich da erst mal selbst versuchen.
Antworten