Wenn du die Vektoraufgabe für verschiedene Paare von Vektoren ausführen möchtest, musst du dein Programm im Moment mehrmals starten. Auch wenn der Spieler beim Quiz einen weiteren Versuch möchte, muss er das Programm neu starten. Du wirst oft ähnliche Situationen antreffen, in denen du Code n-mal ausführen möchtest. Die Lösung für solche Situationen sind Schlaufen.
a = 2 while a < 500: print(a) a *= a
Mit while beginnst du einen Code-Block, der solange wiederholt wird, wie die nachfolgende Bedingung True ist. In unserem Beispiel ist die Bedingung, dass a kleiner ist als 500. Solange das gilt, wird a ausgegeben und dann quadriert.
Hinweis: Das Beispiel oben verwendet eine
besondere Syntax um a zu verändern.
Da es häufig vorkommt, dass du eine Variable abhängig von ihrem
aktuellen Wert verändern möchtest, gibt es dafür eine Kurzschreibweise.
a *= a
ist die Kurzform von a = a*a
.
Analog funktionieren +=
, -=
und /=
.
Es ist wichtig, dass du das erste Schlaufen-Beispiel verstehst. Nimm dir deshalb ein Blatt Papier und vervollständige folgende Tabelle für die gesamte Programmausführung.
code | a | Kommentar |
---|---|---|
a = 2 | 2 | |
while a < 500: | 2 | True |
print(a) | 2 | Ausgabe: 2 |
a *= a | 4 | |
while a < 500: | 4 | True |
print(a) | ... |
Wir wollen nun mit while das Mondlandungsquiz erweitern.
Dein Quiz sei in der Funktion frage()
definiert.
Diese Funktion gibt True zurück wenn die Frage richtig
beantwortet wurde, sonst False.
Ist die Antwort falsch, so wollen wir dem Spieler
einen weiteren Versuch anbieten.
def frage(): ans = input("Wann war der erste Mensch \ auf dem Mond? (YYYY-mm-dd) ") return ans == '1969-07-20' again = True while again: result = frage() print(result) if not result: ans = input("Weiterer Versuch? (J,n) ") if (ans.lower() == "n"): again = False else: again = False
In diesem Fall ist die Bedingung die Variable again, die zu Beginn auf True gesetzt wird. Im While-Block wird die Variable dann auf False gesetzt, wenn entweder die Frage richtig beantwortet wurde oder der Spieler aufgibt.
Wenn du dir nicht sicher bist, was bei der Ausführung passiert, erstelle auch hier eine Tabelle mit den ausgeführten Befehlen. Manchmal ist auch ein Fluss-Diagram sehr hilfreich.
Erstelle eine Programm, dass eine Liste mit Namen zusammenstellt. Das Programm soll dich nach einem Namen fragen und diesen zu einer Liste hinzufügen. Du sollst solange Namen eingeben können, wie du nicht einen leeren String eingibst. Überlege dir die Struktur des Programms zuerst auf Papier.
namen = [] neu = "bla" while neu != "": neu = input("neuer Name: ") namen.append(neu) print(namen[0:-1])
Verwende while
und folgende Regeln um den
ggT von zwei Integer-Zahlen a und b zu berechnen:
Hinweise: Du brauchst hier %
.
%
ist der Operator für die Modulo-Division.
a % b
gibt dir also den Rest bei der Division von a durch b.
import sys try: a = int(input("a: ")) b = int(input("b: ")) except ValueError: sys.exit(1) while (b != 0): tmp = a a = b b = tmp % b print("ggT:", a)
Manchmal kommt es vor, dass du eine Schlaufe vorzeitig beenden
möchtest.
Dazu kannst du break
verwenden.
a = 2 while a < 500: print(a) a *= a if (a == 16): break
Vereinfache dein Programm um die Namen einzulesen, in dem
du while True:
verwendest und statt dessen
die Schlaufe mit break
beendest.
Achtung: Wenn du break vergisst, beendet dein Programm nie mehr.
namen = [] while True: neu = input("neuer Name: ") if (neu == ""): break namen.append(neu) print(namen)
Neben der while-Schleife kennt Python auch die for-Schleife. Damit kannst du einen Code-Block für jedes Element einer Liste (oder eines Listen-ähnlichen Objekts) ausführen lassen. Aus
print("Ich esse gerne Birnen") print("Ich esse gerne Orangen") print("Ich esse gerne Pflaumen") print("Ich esse gerne Bananen")
wird damit
liste = ["Birnen", "Orangen", "Pflaumen", "Bananen")] for frucht in liste: print("Ich esse gerne", frucht)
Das besonders nützlich, wenn du diese Früchte später nicht mehr essen möchtest. In dem Fall musst du nur ein Mal nicht einfügen, und nicht vier Mal.
Auch hier ist es sinnvoll, wenn du die Programmausführung mit einer Tabelle oder einem Flussdiagramm veranschaulichst:
code | frucht | Ausgabe |
---|---|---|
liste = [...] | - | |
for frucht [...] | Birnen | |
print([...]) | Birnen | Ich esse gerne Birnen |
for frucht [...] | ... |
Ergänze dein Namen-Programm mit einer for-Schlaufe, die alle eingelesenen Namen begrüsst.
namen = [] while True: neu = input("neuer Name: ") if (neu == ""): break namen.append(neu) print() for name in namen: print("hallo", name)
Wie wir gesehen haben, ist auch ein String ein Listen-artiges Objekt. Du kannst deshalb mit einer for-Schleife auch auf die einzelnen Buchstaben eines Strings zugreifen. Schreibe ein Programm, dass ein Wort einliest und dann Buchstabe für Buchstabe wieder ausgibt.
wort = input("Was soll ich buchstabieren? ") for buchstabe in wort: print(buchstabe)
Oft soll Code auch einfach für eine gewisse Anzahl von Wiederholungen ausgeführt werden.
print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!") print("ROMANI ITE DOMUM!")
Mit einer for-Schleife lässt sich das einfacher erreichen. Dafür brauchen wir eine Liste mit 10 Einträgen, was die Einträge genau sind, ist dabei egal. Wir können zum Beispiel eine Liste mit 10 mal dem Wert 0 verwenden:
for i in [0]*10: print("ROMANI ITE DOMUM!")
Wie du siehst, verwenden wir die Variable i in der Schlaufe nirgends. Das ist völlig ok. Es gibt aber auch immer wieder Fälle in denen du die Zahlen in den Schlaufen verwenden möchtest. So können wir unsere Ausgabe zum Beispiel nummerieren.
for i in [1,2,3,4,5,6,7,8,9,10]: print(i, "ROMANI ITE DOMUM!")
Noch etwas eleganter, wird es wenn du die nötige Liste mit range
erzeugst.
for i in range(1, 11): print(i, "ROMANI ITE DOMUM!")
Beachte, dass wir hier range ohne list verwendet haben. Das funktioniert, weil wir hier die Elemente einzeln und nicht als ganze Liste brauchen.
Verwende for um:
# auf 3 zählen for i in range(1,4): print(i) # von 10 rückwärts zählen for j in range(10, 0, -1): print(" ", j) # 6-er Reihe for i in range(1, 11): print(6*i) # oder for i in range(0, 61, 6): print(i)
Schreibe ein Programm, das folgende Ausgabe erzeugt. Du musst dafür zwei Schlaufen verschachteln.
0 1 1 2 2 1 3 3 2 1
for i in range(4): print(i) for j in range(i, 0, -1): print(" ", j)
Implementiere ein Programm, das n einliest und dann alle ganzen Zahlen von 1 bis n addiert. Dein Programm soll das Ergebnis auf vier Arten lösen:
import sys try: max = int(input("N = ")) except ValueError: sys.exit(1) total_for = 0 total_while = 0 total_sum = 0 total_math = 0 for i in range(max+1): total_for += i n = max while n > 0: total_while += n n -= 1 total_sum = sum(range(max+1)) total_math = max*(max+1)/2 print(total_for, " = ", total_while, " = ", total_sum, " = ", total_math)
Du siehst, oft gibt es mehr als eine Lösung für das gleiche Problem. Meist sind sie unterschiedlich gut geeignet. Es lohnt sich deshalb zuerst zu überlegen und dann zu tippen.
Berechne die Quadrate folgender Zahlen.
[1, 3, 5, 7, 11, 13, 17, 19]
(Ich hoffe du weist noch wie du mit range
die 2. und 3. Liste generieren kannst.)
liste = [] liste.extend([1, 3, 5, 7, 11, 13, 17, 19]) liste.extend(range(2,21,2)) liste.extend(range(-1,-10,-1)) for i in liste: print(i*i)
In der Aufgabe oben haben wir eine for
-Schlaufe verwendet um
auf mehreren Werten mathematische Operationen auszuführen.
Das ist die traditionelle Methode dieses Problem zu lösen.
In Pylab kannst du solche Aufgaben oft eleganter mit Arrays lösen:
from pylab import * liste = array([1, 3, 5, 7, 11, 13, 17, 19]) print(liste**2)
Schau dir das Programm vollkommen.py an. Es sollte keinen Befehl enthalten, den du nicht verstehst. Lasse das Programm laufen und schau dir den Output an. Leider scheint etwas nicht zu funktionieren. Wir müssen uns also auf die Suche nach dem Fehler machen.
Um den Fehler zu finden, sollten wir die Entwicklung von number
,
factor
und total
verfolgen.
Dazu hast du zwei Möglichkeiten.
Du kannst jede dieser Variablen an der interessanten Stelle durch
einen print
-Befehl ausgeben lassen.
Das lohnt sich aber nur, wenn du bloss eine Variable verfolgen möchtest
(z.B.: values
in histogram.py).
Eine elegantere Möglichkeit ist den Python-Debugger
pdb zu verwenden.
Damit kannst du Schritt für Schritt durch dein Programm gehen und
schauen, was wo passiert.
Öffne vollkommen.py in Spyder und lass es im Debugger laufen
(Der Run > Debug oder [ctrl]+[F5]
.)
Der Output in der Console sieht dann etwa so aus:
-> """ (Pdb)
Die Zeile mit dem Pfeil sagt dir wo in der Datei du bist (am Ende des Doc-Strings). (Pdb) ist der Prompt des Debuggers. Im Prompt kannst du nun deine Anweisung eintippen.
Die möglichen Befehle findest du wenn du help
eintippst.
Die wichtigsten drei sind n
, s
und p
.
Schau nach, was diese Befehle bewirken (z.B. mit h n
).
Nützlich sind auch noch c
und b
sowie
display
.
(Du kannst dir auch die Liste auf der Website anschauen.)
Verwende pdb um deine Tabellen von oben (while/for-Einführung) zu kontrollieren. Führt Python die Zeilen in der von dir erwarteten Reihenfolge aus? Haben die Variablen die erwarteten Werte?
Verwende pdb um den Fehler in vollkommen.py zu finden und das Programm zu korrigieren.
break 20 # Ausführung auf Zeile 20 stoppen continue # Ausführen bis zum nächsten Stop (max-Value: 10) display number # Wert von Number ausgehebn wenn er sich ändert continue # zum nächsten Stop ... # bis number = 6 display total # ist noch auf altem Wert (6) display factor # ist noch auf altem Wert (5) next # total wird zurück gesetzt n # factor wird auf 1 gesetzt [enter] # weiter n ausführen ... # bis klar ist weshalb # erwartet: total = 1+2+3 (-> 6) [ctrl]+[d] # Fehler im Skript korrigieren
Hinweis: Es gibt diverse weitere Arten um pdb zu starten.
Wenn du dein Skript mit einer Fehlermerldung abbricht, kannst du es mit
ipython --pdb dein-skript.py
starten.
IPython startet dann den Debugger dort wo der Fehler ausgelöst wird.
Ausserdem kannst du den Debugger an einer beliebigen Stelle eines Skripts starten,
in dem du dort eine Zeile import pdb; pdb.set_trace()
einfügst.
Du kannst die meisten Probleme sowohl mit while wie auch mit for lösen. Allerdings ist oft eine der beiden Arten besser geeignet. Diskutiere mit deinem Nachbar, wann welcher Schlaufentyp sinnvoller ist.
for
while
(Falls ihr noch weitere Situationen gefunden habt, sind wir interessiert diese zu hören.)
Hinweis: Schlaufen sind ein zentrales Hilfsmittel beim Programmieren. Es ist deshalb wichtig, dass du ihre Funktionsweise und Verwendung verstanden hast, bevor du zum nächsten Block wechselst.
Erstelle eine weiteres Quiz, das die Frage solange wiederholt, bis du die richtige Antwort eintippst. Wähle die Frage selbst. Eine Rechnungsaufgabe wäre eine gute Option.
antwort = "0" while (antwort != "42"): antwort = input( """ Was ist der Sinn des Leben, des Universums und des ganzen Rest? """ )
Passe deine Lösung für die Vektorrechnungsaufgabe (Vertiefungsaufgabe im Input-Block) so an, dass du mehrmals Vektoren eintippen kannst.
Löse die Aufgaben Zählen und Zürichsee aus dem Listen-Block mit Hilfe von Schlaufen.
Schreibe ein Programm, dass den Liedtext für Auf der Mauer, Auf der Lauer oder Laurenzia ausgibt.
Collatz-Problem besagt, dass folgende Regel für jeden Startwert zu 1 führt:
a = a/2
a = 3*a + 1
Implementiere ein entsprechendes Programm. Lies einen Startwert ein und schaue wie viele Schritte es braucht um 1 zu erreichen. Lies solange neue Startwerte ein, bis du 0 eingibst.
Hinweise: Um zu bestimmen ob eine Zahl durch eine andere teilbar ist, kannst modulo verwenden.