Kapitel VI - Verzweigungen
Nachdem wir nun bereits die Kontrollstruktur "Schleife" erfolgreich zur Wiederholung von (einzelnen) Anweisungen oder ganzen Anweisungsblöcken eingesetzt haben, wollen wir im Rahmen dieses Kapitels die zweite Struktur zum Kontrollieren des Ablaufes eines Programmes kennenlernen. Dabei handelt es sich um sogenannte Verzweigungen.
Für Verzweigungen finden wir viele Beispiele in unserem täglichen Leben: Abhängig davon, was passiert oder welche sonstigen äußeren Umstände vorliegen, handeln wir. An einem Werktag gehen wir normalerweise zur Schule. An einem Tag während des Wochenendes schlafen wir aus und gehen nicht zur Schule. Wenn wir Hausaufgaben aufbekommen haben, so erledigen wir diese. Andernfalls gehen wir anderen Beschäftigungen nach.
Nach erfolgreicher Bearbeitung des sechsten Kapitels kannst du
- den Unterschied zwischen bedingten Anweisungen und Verzweigungen aufzeigen.
- die Funktionsweise einer bedingten Anweisung und damit auch einer Verzweigung erläutern.
- logische Ausdrücke konstruieren und auswerten.
- den Unterschied zwischen dem Zuweisungsoperator und dem logischen Vergleich wiedergeben.
- bedingte Anweisungen und Verzweigungen in deinen Programmen einsetzen.
- die Syntax von bedingten Anweisungen und Verzweigungen darstellen und erläutern.
Schreibe mit Hilfe der drei Funktionen
ein Programm, das die folgende Ausgabe liefert:def dreieck():""" zeichnet ein Dreieck """n=3for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def quadrat():""" zeichnet ein Quadrat """n=4for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def abstandshalter():""" zeichnet den Platzhalter zwischen zwei Figuren """myTurtle.penup()myTurtle.forward(2*abmessung)myTurtle.pendown()
Achte darauf, dass du in dem restlichen Programm die gleichen Variablen verwendest, wie in den bereits programmierten Funktionen.# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Reihe aus Dreiecken und Quadratenfrom turtle import TurtlemyTurtle = Turtle("turtle")abmessung = 10def dreieck():""" zeichnet ein Dreieck """n=3for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def quadrat():""" zeichnet ein Quadrat """n=4for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def abstandshalter():""" zeichnet den Platzhalter zwischen zwei Figuren """myTurtle.penup()myTurtle.forward(2*abmessung)myTurtle.pendown()# Programmfor i in range(5):dreieck()abstandshalter()quadrat()abstandshalter()# Fenster geoeffnet lassen - fuer LinuxmyTurtle.screen._root.mainloop()
In dem obigen Programm werden die folgenden Anweisungen in dieser Reihenfolge wiederholt:
- Zeichne ein Dreieck
- Zeichne einen Abstandshalter
- Zeichne ein Quadrat
- Zeichne einen Abstandshalter
Wir werden das Programm nun so umstrukturieren, dass die folgenden Anweisungen wiederholt werden:
- Zeichne ein Dreieck oder ein Quadrat - je nachdem, welche Figur an der Reihe ist
- Zeichne einen Abstandshalter
Dazu werden wir die Kontrollstruktur Verzweigung verwenden, die uns helfen wird, zu entscheiden, ob wir (oder besser das Programm) ein Dreieck oder ein Quadrat zeichnen soll.
Bedingte Anweisungen
Bevor wir uns mit Verzweigungen beschäftigen, setzen wir uns mit den sogenannten bedingten Anweisungen auseinander. Diese kann man als eine Vorstufe der Verzweigungen auffassen. Doch was genau versteht man unter einer bedingten Anweisung? Bei bedingten Anweisungen handelt es sich um Anweisungen (für den Computer), die nur ausgeführt werden, wenn eine bestimmte Bedingung erfüllt ist.
Ähnlich wie Schleifen und Funktionen bestehen auch bedingte Anweisungen aus zwei "Teilen":
-
Kopf der bedingten Anweisung
Der Kopf der bedingten Anweisung besteht wiederum aus zwei Teilen: Einmal dem Schlüsselwort if (engl. für "wenn", "sofern" oder "falls") und einer Bedingung, einem sogenannten logischen Ausdruck. Dieser logische Ausdruck (bzw. die Bedingung) kann entweder falsch (False) oder richtig (True) sein. True und False sind dabei einerseits selber wieder logische Ausdrücke, andererseits reservierte Wörter. Wenn der logische Ausdruck wahr ist, so wird der Körper der bedingten Anweisung ausgeführt - und nur dann. Ist der logische Ausdruck also falsch, so wird keine Anweisung des Blockes ausgeführt. -
Körper der bedingten Anweisung
Im Körper der bedingten Anweisung befinden sich alle Anweisungen, die unter einer erfüllten Bedingung ausgeführt werden sollen. Oft werden diese - wie gehabt - auch als Anweisungsblöcke bezeichnet. Diese müssen eingerückt werden, damit Python sie richtig zuordnen kann.
Hinsichtlich des syntaktischen Aufbaus finden wir auch eine starke Ähnlichkeit zu der Definition einer Funktion oder Schleife vor. Der Kopf beginnt mit dem reservierten Wort if. Auf dieses folgt ein logischer Ausdruck. Wie logische Ausdrücke aussehen, werden wir später noch vertiefen. Für unsere ersten beiden Beispiele sollen die beiden logischen Ausdrücke True und False genügen. Abgeschlossen wird der Kopf - wie bekannt - mit einem Doppelpunkt. Es folgt nun der Körper. Hier gilt ebenfalls: Alle zum Körper gehörenden Anweisungen müssen eine Stufe eingerückt werden und bilden einen Block.
Muster:
# Kopf der bedingten Anweisungif (Bedingung):# Beginn Körper# ...# Letzte Zeile des Körpers# Diese Zeile gehört nicht mehr zur bedingten Anweisung
Beispiel:
# Kopf der bedingten Anweisungif True:print("bedingte Anweisung")print("normale Anweisung")
Probiere das obige Beispiel aus.
Kannst du den Kopf der Anweisung so verändern, dass die Bedingung falsch ist und der Körper nicht ausgeführt wird?
Bei Ausführung erhält man folgende Ausgabe:
Da wir bisher nur zwei logische Ausdrücke kennen (True und False) und True ein wahrer logischer Ausdruck ist, müssen wir True durch False ersetzen. Dieser logische Ausdruck ist nicht wahr. Folglich werden die Anweisungen im Körper nicht ausgeführt.bedingte Anweisungnormale Anweisung
Folglich sieht die Ausgabe nun wie folgt aus:# Kopf der bedingten Anweisungif False:print("bedingte Anweisung")print("normale Anweisung")
normale Anweisung
Wenn der Python-Interpreter bei der Ausführung unseres Programmes eine bedingte Anweisung als nächste Anweisung vorfindet, so wertet er als erstes die Bedingung aus. Wenn die Auswertung einen wahren Wert, also True ergibt, dann werden die Anweisungen im Körper ausgeführt. Ergibt die Auswertung hingegen den Wert False, so geht es weiter mit der nächsten Anweisung nach dem Körper.
Entsprechend sind auch die obigen beiden Programme zu erklären. Allerdings ist hier anzumerken, dass im eigentlichen Sinne keine Auswertung der Bedingung stattgefunden hat, da es sich direkt um einen wahren bzw. falschen Wert gehandelt hat.
True und False nennt man auch Wahrheitswerte. Dabei handelt es sich ebenfalls wie Zahlen und Zeichenketten um sogenannte (primitive) Datentypen.
Logische Ausdrücke
Bisher kennen wir bereits zwei logische Ausdrücke: True und False. Mittels logischer Ausdrücke wird es möglich, bestimmte Anweisungen nur unter ganz bestimmten Bedingungen auszuführen. Diese Bedingungen werden durch logische Ausdrücke in die bedingten Anweisungen integriert.
Der vermutlich am häufigsten benutzte logische Ausdruck ist der Vergleich zweier Objekte (Zeichenketten, Zahlen, Turtle-Objekte etc.) In Python vergleicht man zwei Objekte mittels einem doppelten Gleichheitszeichen ==. Vor dem ersten bzw. nach dem zweiten Gleichheitszeichen steht das erste bzw. das zweite Objekt, das verglichen werden soll. Beispiel:
objekt1 == objekt2
Wir erinnern uns an den Zuweisungsoperator =. Ein häufiger Fehler, der passiert, ist, dass man statt des doppelten Gleichheitszeichenes für den Vergleich innerhalb eines logischen Ausdruckes (aus Unachtsamkeit) den Zuweisungsoperator verwendet. Python würde in diesem Fall einen Syntaxfehler melden und uns dadurch auf den Fehler hinweisen. Das ist nicht in allen Programmiersprachen so. Dort führt eine Verwechselung zu ungewünschten Nebeneffekten und schlimmstenfalls zu einem vollständigen Datenverlust.
Probieren wir es aus:
"a" == "b"
liefert
FalseKlar, denn offensichtlich ist die Zeichenkette "a" nicht gleich der Zeichenkette "b". Die Auswertung ergibt also den Wahrheitswert False.
Ferner können wir die in der Mathematik gebräuchlichen anderen Vergleichszeichen ohne Probleme nutzen:
- >
- <
- <=
- >=
Beachte dabei, dass das Gleichheitszeichen nicht zuerst stehen darf, da Python sonst vergeblich nach einer Wertzuweisung sucht.
Liefern wir der Shell hingegen die Eingabe:
"a" == "a"
Erhalten wir als Rückgabe
TrueKlar, denn offensichtlich sind die Zeichenketten "a" und "a" identisch. Die Auswertung ergibt also den Wahrheitswert True. Ein gleiches Ergebnis erhalten wir bei der Eingabe
17 == 17
Wir können nicht nur zwei Werte vergleichen lassen, sondern auch "kompliziertere" logische Ausdrücke konstruieren. So wäre es denkbar, dass wir vor dem Vergleich noch Werte (Objekte) berechnen lassen, wie in den vorliegenden Beispielen:
16+1 == 17-1 oder
16+1 == 18-1
Eine Auswertung ergibt False bzw. True.
Gib an, welchen Wahrheitswert die folgenden logischen Ausdrücke ergeben.
-
16+1 == 18-1 -
"a" == "A" -
12+2 == 28/2 -
11 == 12-1 -
"2" == 2 -
"a"+"bc" == "abc" -
1 == 11 % 2 -
8 == 2*(2**2) -
True == False -
True == "True" -
True == 1
Kontrolliere deine Vermutungen mit der Python-Shell. Dort wird dir das Ergebnis angezeigt. Kannst du dieses auch begründen? Wenn nicht, frage einen Mitschüler oder den Lehrer.
Hinweis zum letzten logischen Ausdruck: Oft wird der Wahrheitswert True auch durch die Zahl 1 dargestellt. Hast du eine Vermutung, welche Zahl mit dem Wahrheitswert False in Verbindung steht?
Bisher haben wir nur Zeichenketten oder Zahlen bzw. verknüpfte Zeichenketten und arithmetische Ausdrücke in unsere Vergleiche einbezogen. Selbstverständlich können wir auch Variablen in unsere Vergleiche einbeziehen. Beispiel:
Die Eingabe
a=1a==1True
ergibt - a hat den Wert 1 - True. Ferner können wir Rechnungen mitsamt Variablen kombinieren:
a=1a+1==3-1True
ergibt ebenfalls den Wert True. Auch Variablen auf beiden Seiten sind möglich:
zahlA=1zahlB=1zahlA==zahlBTrue
Achtung: Die versehentliche Eingabe von
zahlA=zahlB liefert keine Ausgabe, sondern weißt der Variablen zahlA den in zahlB gespeicherten Wert zu. Danach ergibt eine Abfrage von
zahlA==zahlB in jedem Fall den Wert True.
Python ist in diesem Fall nicht in der Lage den Syntax bzw. den Semantikfehler zu erkennen. Diese Möglichkeit besteht nur, wenn wir die Wertzuweisung versehentlich in einer Bedingung verwenden. Wäre die Wertzuweisung in dem obigen Beispiel nicht gewollt, hätten wir nun den in zahlA gespeicherten Wert bzw. das Objekt verloren.
Bedingte Anweisungen im Einsatz
Das Programm
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Ausgabe aller maximal zweistelligen Zahlenfor zahl in range(100):print(zahl)
gibt alle maximal zweistelligen Zahlen aus.
Wir wollen das Programm jetzt so umbauen, dass nur die geraden, maximal zweistelligen Zahlen ausgegeben werden. Auf den ersten Blick könnte man auf die Idee kommen, das Tupel range(100) zu verändern, beispielsweise zu (0,2,4,6,8,10,12 .. 98). Diese Lösung ist aber nicht praktikabel, da wir alle Zahlen aufschreiben müssten.
Der Trick ist, dass wir die print()-Funktion zur Ausgabe einer Zahl nur dann ausführen lassen, wenn die Zahl wirklich gerade ist. Wir müssen also einen logischen Ausdruck konstruieren, der genau dann wahr ist, wenn die aktuelle Zahl gerade ist. Wenn dann die print()-Funktion im Körper der zugehörigen bedingten Anweisung steht, erhalten wir nur eine Ausgabe, wenn die Zahl gerade ist. Insgesamt wäre damit der gewünschte Umbau das Programmes realisiert.
Wir müssen uns also genauer überlegen, wann eine Zahl gerade ist. Ein Zahl ist gerade, wenn sie ohne Rest durch 2 teilbar ist. Die Bestimmung eines Divisionsrestes haben wir in den vorhergehenden Kapiteln bereits kennengelernt. Dazu dient in Python das Zeichen %. So gibt beispielsweise
15 % 2 den Rest der Division von 15 durch 2, also 1, an. Entsprechend ergibt die Eingabe
16 % 2 die Ausgabe 0, da 16 eine gerade Zahl ist. Entsprechend prüft der logische Ausdruck zahl % 2 == 0, ob in der Variablen zahl eine gerade Zahl gespeichert ist. Zuerst wird hier der Wert berechnet und anschließend mit dem vorgegebenen Wert verglichen.
Gib an, wie der logische Ausdruck lautet, um zu überprüfen, ob der in der Variablen zahl gespeicherte Wert eine ungerade Zahl ist.
Der logische Ausdruck zahl % 2 == 1 gibt, an, ob die Zahl ungerade ist oder nicht.
Zur Erklärung: Eine Zahl ist ungerade, wenn bei der Division durch 2 der Rest 1 bleibt. Der entsprechende Ausdruck vergleicht den entstehenden Rest mit dem Wert 1. Stimmen diese überein, ergibt der logische Ausdruck bei der Auswertung den Wert True.
Wie im Vorfeld dargestellt, können wir nun - nach Konstruktion des logischen Ausdruckes - diesen in die bedingte Anweisung integrieren und damit die Ausgabe der Zahlen wie gewünscht einschränken.
- Formuliere die bedingte Anweisung in der Programmiersprache Python.
- Integriere diesen in das obige Programm und teste dieses.
-
if zahl % 2 == 0:print(zahl)Die entsprechende Zahl wird nur ausgegeben, wenn die Bedingung erfüllt ist. Die Bedingung ist genau dann erfüllt, wenn die Zahl gerade ist. Entsprechend erhalten wir nur in diesem Fall eine Ausgabe.
-
Achte auf die doppelte Einrückung der print()-Funktion!# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Ausgabe aller maximal zweistelligen und geraden Zahlenfor zahl in range(100):if zahl % 2 == 0:print(zahl)Wir durchlaufen nun in einer Schleife alle Zahlen und prüfen für jede, ob diese gerade ist oder nicht.
Nun sollen alle maximal dreistelligen Zahlen, die ungerade sind, ausgegeben werden.
Es müssen an zwei Stellen Veränderungen vorgenommen werden:# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Ausgabe aller maximal dreistelligen und ungeraden Zahlenfor zahl in range(1000):if zahl % 2 == 1:print(zahl)
- Veränderung des Tupels range(100)
- Veränderung des logischen Ausdruckes
Verzweigungen
Bei bedingten Anweisungen werden die Anweisungen im Körper ausgeführt, sofern die Bedingung wahr ist. Ist die Bedingung nicht erfüllt, so werden keine Anweisungen ausgeführt.
Überlege dir ein Programm, dass die folgende Ausgabe für alle maximal zweistelligen Zahlen liefert:
Eine umgangssprachliche Formulierung deiner Ideen zur Umsetzung reicht vorerst aus.0 - die Zahl ist gerade1 - die Zahl ist ungerade2 - die Zahl ist gerade
Klar ist, dass wir eine Schleife benötigen, die über die ersten 100 Zahlen, also von 0 bis 99 läuft. Für jede Zahl muss entschieden werden, ob die Zahl gerade oder ungerade ist. Entsprechend der erfüllten Bedingung muss eine passende Ausgabe erfolgen. Dazu benötigen wir zwei bedingte Anweisungen, bei denen jeweils die Bedingung ist, ob die Zahl gerade oder ungerade ist.
Setze deine bisher nur umgangssprachlich formulierten Ideen in ein lauffähiges Python-Programm um. Teste dein Programm.
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Ausgabe aller maximal zweistelligen Zahlen mit# # Zusatzinformation, ob die Zahl gerade oder ungerade istfor zahl in range(100):if zahl % 2 == 0:print(zahl,"- die Zahl ist gerade")if zahl % 2 == 1:print(zahl,"- die Zahl ist ungerade")
Achte auf die entsprechenden Einrückungen. Die folgenden Einrückungen sind falsch und führen zu einer anderen Ausgabe. Kannst du erklären warum?
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Ausgabe aller maximal zweistelligen Zahlen mit# # Zusatzinformation, ob die Zahl gerade oder ungerade istfor zahl in range(100):if zahl % 2 == 0:print(zahl,"- die Zahl ist gerade")if zahl % 2 == 1:print(zahl,"- die Zahl ist ungerade")
In dem obigen Programmbeispiel ist immer eine der beiden Bedingungen erfüllt, denn eine Zahl ist entweder gerade oder ungerade. Ist die erste Bedingung nicht erfüllt, so ist die zweite definitiv erfüllt - und umgekehrt. Genau hier kommen Verzweigungen ins Spiel.
Eine Verzweigung beinhaltet - genau wie eine bedingte Anweisung - eine Bedingung. Allerdings gibt es hier nicht nur einen Körper, sondern zwei verschiedene Körper. Ist die Bedingung wahr, so werden die Anweisungen im ersten Körper ausgeführt. Ist die Bedingung hingegen falsch, kommen die Anweisungen im zweiten Körper zum Zuge. Wir haben hier also zwei Anweisungsblöcke vorliegen.
Wir wählen als Bedingung für die Verzweigung zahl % 2 == 0 aus. Überlege, welche Anweisung im ersten und welche Anweisung im zweiten Körper stehen muss, um das obige Programm zu realisieren.
erster Körper
print(zahl,"- die Zahl ist gerade")
zweiter Körper
print(zahl,"- die Zahl ist ungerade")
Begründung: In den ersten Körper gehört die Anweisung, die ausgeführt werden muss, wenn die Zahl gerade ist. In diesem Fall ist die formulierte Bedingung erfüllt. Entsprechend gehört in den zweiten Körper die Anweisung für den Fall, dass die Zahl nicht gerade, also ungerade ist.
Nochmal zur Erinnerung: Es ist offensichtlich, dass, wenn der erste Vergleich unserer Bedingung zahl % 2 == 0 True ergibt, dann muss der zweite Vergleich, den wir bislang in unserem Programm haben, also zahl % 2 == 1, auf jeden Fall False ergeben. Im Falle, dass die Bedingung zahl % 2 == 0 falsch ist, also False ergibt, verhält es sich mit der zweiten Bedingung genau umgekehrt.
Um den in den beiden Fällen unterschiedlichen Ausgaben gerecht zu werden, haben wir bisher zwei bedingte Anweisungen benutzt. Da aber immer nur eine der beiden gegensätzlichen Bedingungen erfüllt ist, können wir auch mit einer Verzweigung arbeiten und die beiden bedingten Anweisungen darin kombinieren.
Eine Verzweigung ist von der Syntax her ähnlich aufgebaut wie eine bedingte Anweisung. Am Ende des (ersten) Körpers folgt das reservierte Wort else (engl. für andernfalls oder sonst). Dieses wird nicht wie die Anweisungen des Körpers eingerückt, sondern steht auf gleicher Höhe wie das reservierte Wort if, dass die Verzweigung bzw. die bedingte Anweisung einleitet. Es gehört nicht mehr zum Anweisungsblock für den Fall, dass die Bedingung erfüllt ist. Auf das reservierte Wort else folgt - wie immer vor Anweisungen, die eingerückt werden müssen - ein Doppelpunkt. Anschließend folgen die Anweisungen des zweiten Körpers, die wieder um eine Stufe, also auf Höhe des ersten Körpers, eingerückt werden. Wir merken uns: Der zu else gehörenden Block deckt die gegenteilige Bedingung ab.
Muster:
if (Bedingung):# Anweisungen, die ausgeführt# werden, wenn die Bedingung wahr istelse:# Anweisungen, die ausgeführt# werden, wenn die Bedingung falsch ist# Ende der Verzweigung
Entsprechend ergibt das für unser Beispiel:
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Ausgabe aller maximal zweistelligen Zahlen mit# # Zusatzinformation, ob die Zahl gerade oder ungerade istfor zahl in range(100):if zahl % 2 == 0:print(zahl,"- die Zahl ist gerade")else:print(zahl,"- die Zahl ist ungerade")
Zurück zu unserer ursprünglichen Aufgabe
Wir wollten das Programm zur obigen Zeichnung so umstrukturieren, dass die folgenden Anweisungen wiederholt werden:
- Zeichne ein Dreieck oder ein Quadrat - je nachdem, welche Figur an der Reihe ist
- Zeichne einen Abstandshalter
Wir verwenden dazu weiterhin eine Zählschleife, um die Anweisungen zu 1. und 2. zu wiederholen. Im ersten Schritt müssen wir allerdings unterscheiden, ob ein Dreieck oder ein Quadrat an der Reihe ist. Es ist offensichtlich, dass die entsprechende Entscheidung von der Nummer der Figur in der Reihe abhängt. Folglich hängt die Entscheidung von dem Wert der Variablen in der Zählschleife ab. Ein Dreieck muss gezeichnet werden in der 0., 2., 4. ... Ausführung der Schleife. Sonst muss ein Quadrat gezeichnet werden. Wir können im Prinzip die Bedingung des Programmes aus dem letzten Abschnitt übernehmen.
Integriere die bisherigen Überlegungen hinsichtlich der Verzweigung in das Programm vom Anfang des Kapitels. Achte darauf, die Variable in der Bedingung an die in der Zählschleife verwendete Variable anzupassen.
Beschreibe, was dir bei der Ausführung auffällt.
Bei der Ausführung fällt auf, dass nur die Hälfte der Figuren gezeichnet wurden.# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Reihe aus Dreiecken und Quadratenfrom turtle import TurtlemyTurtle = Turtle("turtle")abmessung = 10def dreieck():""" zeichnet ein Dreieck """n=3for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def quadrat():""" zeichnet ein Quadrat """n=4for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def abstandshalter():""" zeichnet den Platzhalter zwischen zwei Figuren """myTurtle.penup()myTurtle.forward(2*abmessung)myTurtle.pendown()# Programmfor i in range(5):if i % 2 == 0:dreieck()else:quadrat()abstandshalter()# Fenster geoeffnet lassen - fuer LinuxmyTurtle.screen._root.mainloop()
Die Erklärung ist leicht nachzuvollziehen: Beide Schleifen werden jeweils 5 mal wiederholt. In der Schleife des anfänglichen Programmes werden jeweils zwei Figuren gezeichnet, also insgesamt 2*5=10 Figuren. In der neuen Schleife wird jeweils nur eine Figur gezeichnet, abhängig davon, welche Figur an der Reihe ist. Um die gleiche Figur zu zeichnen, muss man in der zweiten Schleife ein Tupel mit 10 Elementen in den Schleifenkopf integrieren.
Weitere Übungsaufgaben
Kann man die Ausgabe auch mit einer Verzweigung realisieren?
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Reihe aus Dreiecken (gefüllt und ungefüllt)from turtle import TurtlemyTurtle = Turtle("turtle")abmessung = 10def dreieck():""" zeichnet ein Dreieck """n=3for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def abstandshalter():""" zeichnet den Platzhalter zwischen zwei Figuren """myTurtle.penup()myTurtle.forward(2*abmessung)myTurtle.pendown()# Programmfor i in range(5):if i % 2 == 0:myTurtle.begin_fill()dreieck()if i % 2 == 0:myTurtle.end_fill()abstandshalter()# Fenster geoeffnet lassen - fuer LinuxmyTurtle.screen._root.mainloop()
Eine entsprechende Realisierung mittels einer Verzweigung sieht wie folgt aus. Dabei unterscheidet man zwischen dem Zeichnen eines normalen Dreieckes und eines gefüllten Dreieckes.
# Programmfor i in range(5):if i % 2 == 0:myTurtle.begin_fill()dreieck()myTurtle.end_fill()else:dreieck()abstandshalter()
In der vorliegenden Aufgabe geht es um das Schreiben eines Programmes mit der folgenden Ausgabe:
- Schreibe eine Funktion jump(), die die Turtle um eine festgelegte Distanz vorwärts bewegt, ohne dabei einen Strich zu zeichnen.
- Kombiniere eine normale Vorwärtsbewegung und den Aufruf der jump()-Funktion innerhalb einer Schleife, um die gewünschte Ausgabe zu erzeugen. Nutze bei der Kombination eine Verzweigung.
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: zeichnen einer gestrichelten Liniefrom turtle import TurtlemyTurtle = Turtle("turtle")abmessung = 10def jump():""" das Turtle-Objekt springt """myTurtle.penup()myTurtle.forward(abmessung)myTurtle.pendown()# Programmfor i in range(50):if i % 2 == 0:jump()else:myTurtle.forward(abmessung)# Fenster geoeffnet lassen - fuer LinuxmyTurtle.screen._root.mainloop()
Zur Realisation der unten dargestellten Ausgabe müssen zwei Entscheidungen getroffen werden:
- Welche Figur muss gezeichnet werden? Ein Dreieck oder ein Quadrat?
-
Muss die Figur ausgefüllt werden?
Hinweis: Jede dritte Figur muss ausgefüllt werden. Bei jeder dritten Figur gibt die Division durch 3 den Rest 0.
- Prüfe, ob die Methode begin_fill() aufgerufen werden muss.
- Zeichne die entsprechende Figur.
- Prüfe, ob mittels der Methode end_fill() das Ausfüllen beendet werden muss.
- Zeichne einen entsprechenden Abstandshalter.
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Reihe aus Dreiecken und Quadraten# gefuellt und ungefuelltfrom turtle import TurtlemyTurtle = Turtle("turtle")abmessung = 10def dreieck():""" zeichnet ein Dreieck """n=3for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def quadrat():""" zeichnet ein Quadrat """n=4for i in range(n):myTurtle.left(360/n)myTurtle.forward(abmessung)def abstandshalter():""" zeichnet den Platzhalter zwischen zwei Figuren """myTurtle.penup()myTurtle.forward(2*abmessung)myTurtle.pendown()# Programmfor i in range(15):if i % 3 == 0:myTurtle.begin_fill()if i % 2 == 0:dreieck()else:quadrat()if i % 3 == 0:myTurtle.end_fill()abstandshalter()# Fenster geoeffnet lassen - fuer LinuxmyTurtle.screen._root.mainloop()
Für die vorliegende Aufgabe bilden die folgenden drei Funktionen die Grundlage:
def dreieckspitze():""" ??? """n=3for i in range(n):if i == n-1:myTurtle.penup()myTurtle.left(360/n)myTurtle.forward(abmessung)myTurtle.pendown()def quadratspitze():""" ??? """n=4for i in range(n):if i == n-1:myTurtle.penup()myTurtle.left(360/n)myTurtle.forward(abmessung)myTurtle.pendown()def jump():""" ??? """myTurtle.penup()myTurtle.forward(abmessung)myTurtle.pendown()
- Gib an, welche "Vorbereitungen" getroffen werden müssen, damit die drei Funktionen ausgeführt werden können.
- Zeichne bzw. erläutere die Ausgabe der einzelnen drei Funktionen. Markiere jeweils die Position der Turtle vorher und nachher.
- Formuliere kurze, aber prägnante Docstrings zu den Funktionen.
- Es muss das Turtle-Modul geladen und ein Objekt erzeugt bzw. gespeichert werden. Ferner müssen die in dem Programm verwendeten Variablen mit Werten belegt worden sein. In diesem Fall betrifft das nur die Variable abmessung.
- Vergleiche dazu die Ausgabe der nächsten Aufgabe. Ein Funktionsaufruf der oberen beiden Funktionen zeichnet ein entsprechendes Dreieck bzw. Quadrat ohne die Grundseite einzuzeichnen. Die letzte Methode bewegt das Objekt der Klasse Turtle vorwärts, ohne einen Strich zu hinterlassen.
-
""" zeichnet die Spitze eines Dreieckes """
""" zeichnet die Spitze eines Quadrates """
""" Turtle-Objekt springt """
Man stellt fest, dass jede vierte Teilfigur ein Dreieck ist. Dementsprechend muss ein Dreieck gezeichnet werden, wenn die Division durch 4 den Rest 0 ergibt.
# Autor: Christian Graf# Datum: 26.03.2011# Beschreibung: Reihe aus Dreiecken und Quadratenfrom turtle import TurtlemyTurtle = Turtle("turtle")abmessung = 25def dreieckspitze():""" zeichnet die Spitze eines Dreieckes """n=3for i in range(n):if i == n-1:myTurtle.penup()myTurtle.left(360/n)myTurtle.forward(abmessung)myTurtle.pendown()def quadratspitze():""" zeichnet die Spitze eines Quadrates """n=4for i in range(n):if i == n-1:myTurtle.penup()myTurtle.left(360/n)myTurtle.forward(abmessung)myTurtle.pendown()def jump():""" Zeichnet einen unsichtbaren Abstandhalter """myTurtle.penup()myTurtle.forward(abmessung)myTurtle.pendown()# Programmfor i in range(2):if i % 4 == 0:dreieckspitze()else:quadratspitze()jump()# Fenster geoeffnet lassen - fuer LinuxmyTurtle.screen._root.mainloop()
Weiter geht's mit der Lernfortschrittskontrolle zu Kapitel VI.