Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision | |||
| lehrkraefte:snr:informatik:glf23:python:rekursion [2023/12/09 09:24] – [Einführung am Beispiel] Olaf Schnürer | lehrkraefte:snr:informatik:glf23:python:rekursion [2023/12/10 21:49] (current) – [Link zur Kursseite] Olaf Schnürer | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ~~NOTOC~~ | ||
| + | |||
| + | ====== Rekursion: (Weihnachts-)Bäume und Schneeflocken ====== | ||
| + | |||
| + | ===== Einführung am Beispiel ===== | ||
| + | |||
| + | <WRAP center round todo 100%> | ||
| + | Gemeinsames angeleitetes Programmieren: | ||
| + | |||
| + | <hidden Anweisung für Lehrer:> | ||
| + | Sukzessive die Funktionen '' | ||
| + | |||
| + | Bei konzentrationsschwachen Klassen: Bevor die rekursive Funktion '' | ||
| + | |||
| + | Idee, um das Schreiben " | ||
| + | |||
| + | |||
| + | Alle Funktionen haben die aktuelle Streckenlänge als Parameter '' | ||
| + | |||
| + | Beim Programmieren Hotkeys erläutern: Markieren per Shift+Pfeiltasten, | ||
| + | |||
| + | Einige S schreiben schnell selbst '' | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | Programm-Gerüst: | ||
| + | |||
| + | <code python baum.py> | ||
| + | from turtle import * | ||
| + | |||
| + | STAMMLAENGE = 380 | ||
| + | |||
| + | speed(0) | ||
| + | # hideturtle() | ||
| + | penup() | ||
| + | left(90) | ||
| + | backward(STAMMLAENGE) | ||
| + | pendown() | ||
| + | |||
| + | exitonclick() | ||
| + | |||
| + | # Um die Zeichung schneller erscheinen zu lassen, | ||
| + | # gibt es den folgenden Trick: | ||
| + | # Ersetze die Zeile '' | ||
| + | # und ergänze in der Zeile vor '' | ||
| + | # also nach allen Zeichenbefehlen, | ||
| + | </ | ||
| + | |||
| + | Experimentiere: | ||
| + | * Für welche Verzweigungswinkel kommt eine besonders schöne Figur heraus? (Es gibt zwei " | ||
| + | * Nimm statt 3 Verzweigungen eine andere Zahl von Verzweigungen. | ||
| + | * Zeichne jede der Verzweigungen unterschiedlich lang. | ||
| + | * Variiere die Winkel bei den rekursiven Aufrufen; nett ist es beispielsweise, | ||
| + | * Eventuell kann man auch Verzweigungen in den Stamm einbauen. | ||
| + | * Wer will, kann auch bereits hier eine Schleife über gewisse Verzweigungswinkel laufen lassen (auch wenn das eigentlich erst unten in der Animationsaufgabe vorgeschlagen wird...) | ||
| + | * Sei kreativ! | ||
| + | </ | ||
| + | |||
| + | <WRAP center round info> | ||
| + | Eine Funktion heisst **rekursiv**, | ||
| + | |||
| + | **Rekursion** meint in der Informatik (und ähnlich in der Mathematik) den Einsatz rekursiver Funktionen. | ||
| + | |||
| + | Etymologie: lateinisch // | ||
| + | </ | ||
| + | |||
| + | ===== Aufgabe zur Rekursion: Koch-Kurve und kochsche Schneeflocke ===== | ||
| + | |||
| + | |||
| + | <WRAP center round todo> | ||
| + | Schreibe eine rekursive Funktion '' | ||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | Programm-Gerüst: | ||
| + | <code python koch-kurve.py> | ||
| + | from turtle import * | ||
| + | |||
| + | LEVEL = 3 | ||
| + | SEITENLAENGE = 400 | ||
| + | |||
| + | def kochkurve(level, | ||
| + | # " | ||
| + | # die Schildkröte NICHT zurück zum Ausgansgspunkt geht (wie beim Baum oben). | ||
| + | # Bei allen " | ||
| + | # der Turtle bis zu ihrem Endpunkt genau a Pixel betragen. | ||
| + | print(' | ||
| + | |||
| + | def schneeflocke(level, | ||
| + | # Verwende die Funktion " | ||
| + | print(' | ||
| + | |||
| + | speed(0) | ||
| + | # hideturtle() | ||
| + | penup() | ||
| + | backward(SEITENLAENGE/ | ||
| + | pendown() | ||
| + | linienzug(LEVEL, | ||
| + | # left(60) | ||
| + | # schneeflocke(LEVEL, | ||
| + | exitonclick() | ||
| + | </ | ||
| + | |||
| + | Mit dieser Vorarbeit ist es nun einfach, eine Funktion '' | ||
| + | |||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | ===== Aufgabe zur Rekursion: Pythagoras-Baum ===== | ||
| + | |||
| + | |||
| + | <WRAP center round todo> | ||
| + | Schreibe eine rekursive Funktion '' | ||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | Hinweis: Die Bilder sind mit dem Winkel $\alpha = 35^\circ$ gemalt (übliche Bezeichnungen für rechtwinklige Dreiecke). | ||
| + | Die Kathetenlängen $a$ und $b$ haben in Abhängigkeit von $c$ und $\alpha$ die folgenden Werte: | ||
| + | $$b = \cos(\alpha) \cdot c$$ | ||
| + | $$a = \sin(\alpha) \cdot c$$ | ||
| + | |||
| + | Wenn du Pyhon diese Werte berechnen lassen willst, musst die die Bibliothem '' | ||
| + | <code python> | ||
| + | from math import * | ||
| + | |||
| + | alpha = 35 | ||
| + | |||
| + | b = cos(radians(alpha)) * c | ||
| + | a = sin(radians(alpha)) * c | ||
| + | </ | ||
| + | |||
| + | Du kannst den Pythagoras-Baum auch variieren. Hier einige Ideen: | ||
| + | * Die Äste nicht quadratisch, | ||
| + | * Die inneren Linien weglassen. | ||
| + | * Statt eines rechtwinkligen Dreiecks ein beliebiges anderes Dreieck nehmen (mit $a<c$ und $b<c$, damit der Baum " | ||
| + | |||
| + | $$\frac a{\sin \alpha} = \frac b{\sin \beta} = \frac c{\sin \gamma}$$ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== Aufgabe: Animation der obigen Objekte - " | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | Animiere die Objekte, die wir oben gezeichnet haben: | ||
| + | * Zeichne nacheinander den Baum für verschiedene Verzweigungswinkel, | ||
| + | * Lass die Kochsche Schneeflocke rotieren. | ||
| + | |||
| + | Verstehe dazu eines der unten angegebenen Animations-Beispielprogamme ein bisschen und verändere es, indem du an geeigneter Stelle die Funktion zum Baum-Zeichnen bzw. zum Schneeflocke-Zeichnen aufrufst. | ||
| + | |||
| + | Die wichtigen Befehle in diesen Programmen sind '' | ||
| + | |||
| + | <hidden Animations-Beispielprogramm (einfache Variante)> | ||
| + | <code python animierter-kreis.py> | ||
| + | from turtle import * | ||
| + | from time import * | ||
| + | |||
| + | tracer(n=0) | ||
| + | hideturtle() | ||
| + | |||
| + | for radius in range(-200, 201): | ||
| + | clear() | ||
| + | circle(radius) | ||
| + | update() | ||
| + | sleep(0.01) | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <hidden Animations-Beispielprogramm (kompliziertere Variante, Animation läuft bis zum Abbruch per Mausklick oder Tastendruck)> | ||
| + | <code python animierter-kreis-abbruch-per-click-oder-tastendruck.py> | ||
| + | from turtle import * | ||
| + | from time import * | ||
| + | |||
| + | def abbruch(x=0, | ||
| + | global aktiv | ||
| + | aktiv = False | ||
| + | |||
| + | leinwand = Screen() | ||
| + | tracer(n=0) | ||
| + | hideturtle() | ||
| + | leinwand.onkeypress(abbruch) | ||
| + | leinwand.onclick(abbruch) | ||
| + | listen() | ||
| + | |||
| + | aktiv = True | ||
| + | radius = 20 | ||
| + | veraenderung = 1 | ||
| + | while aktiv: | ||
| + | clear() | ||
| + | circle(radius) | ||
| + | update() | ||
| + | if radius < -200 or radius > 200: | ||
| + | veraenderung = -veraenderung | ||
| + | radius = radius + veraenderung | ||
| + | sleep(0.01) | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== gif-Datei aus Animation erstellen (zumindest unter Linux geht es so...) ===== | ||
| + | |||
| + | to be written down | ||
| + | |||
| + | ===== Weitere Programmierideen ===== | ||
| + | |||
| + | Vielleicht ganz nett, falls jemand Spass am Python-Programmieren bekommen hat: [[https:// | ||
| + | ====== Baum-Programm aus Lektion ====== | ||
| + | |||
| + | <code python baum.py> | ||
| + | from turtle import * | ||
| + | |||
| + | def baum0(a): | ||
| + | forward(a) | ||
| + | backward(a) | ||
| + | |||
| + | def baum1(a): | ||
| + | forward(a) | ||
| + | left(winkel) | ||
| + | baum0(a/2) | ||
| + | right(winkel) | ||
| + | baum0(a/2) | ||
| + | right(winkel) | ||
| + | baum0(a/2) | ||
| + | left(winkel) | ||
| + | backward(a) | ||
| + | |||
| + | def baum2(a): | ||
| + | forward(a) | ||
| + | left(winkel) | ||
| + | baum1(a/2) | ||
| + | right(winkel) | ||
| + | baum1(a/2) | ||
| + | right(winkel) | ||
| + | baum1(a/2) | ||
| + | left(winkel) | ||
| + | backward(a) | ||
| + | |||
| + | |||
| + | def baum(level, a): | ||
| + | if level == 0: | ||
| + | forward(a) | ||
| + | backward(a) | ||
| + | else: | ||
| + | forward(a) | ||
| + | left(winkel) | ||
| + | baum(level - 1, a/2) # Selbstaufruf der Funktion | ||
| + | # rekursive Funktion | ||
| + | # recurrere = zurücklaufen | ||
| + | right(winkel) | ||
| + | baum(level - 1, a/2) | ||
| + | right(winkel) | ||
| + | baum(level - 1, a/2) | ||
| + | left(winkel) | ||
| + | backward(a) | ||
| + | |||
| + | stammlaenge = 250 | ||
| + | winkel = 30 | ||
| + | tracer(0) | ||
| + | # hideturtle() | ||
| + | left(90) | ||
| + | backward(stammlaenge) | ||
| + | # baum2(stammlaenge) | ||
| + | baum(8, stammlaenge) | ||
| + | update() | ||
| + | exitonclick() | ||
| + | </ | ||
| + | |||
| + | <!-- | ||
| + | <code python baum.py> | ||
| + | from turtle import * | ||
| + | |||
| + | STAMMLAENGE = 380 | ||
| + | |||
| + | def baum0(a): | ||
| + | forward(a) | ||
| + | backward(a) | ||
| + | |||
| + | def baum1(a, winkel): | ||
| + | forward(a) | ||
| + | |||
| + | left(winkel) | ||
| + | baum0(a/2) | ||
| + | right(winkel) | ||
| + | baum0(a/2) | ||
| + | right(winkel) | ||
| + | baum0(a/2) | ||
| + | left(winkel) | ||
| + | |||
| + | backward(a) | ||
| + | |||
| + | def baum2(a, winkel): | ||
| + | forward(a) | ||
| + | |||
| + | left(winkel) | ||
| + | baum1(a/2, winkel) | ||
| + | right(winkel) | ||
| + | baum1(a/2, winkel) | ||
| + | right(winkel) | ||
| + | baum1(a/2, winkel) | ||
| + | left(winkel) | ||
| + | |||
| + | backward(a) | ||
| + | |||
| + | def baum(level, a, winkel): | ||
| + | if level == 0: | ||
| + | forward(a) | ||
| + | backward(a) | ||
| + | else: | ||
| + | forward(a) | ||
| + | |||
| + | left(winkel) | ||
| + | baum(level - 1, a/2, winkel) | ||
| + | right(winkel) | ||
| + | baum(level - 1, a/2, winkel) | ||
| + | right(winkel) | ||
| + | baum(level - 1, a/2, winkel) | ||
| + | left(winkel) | ||
| + | |||
| + | backward(a) | ||
| + | |||
| + | speed(0) | ||
| + | # hideturtle() | ||
| + | penup() | ||
| + | left(90) | ||
| + | backward(STAMMLAENGE) | ||
| + | pendown() | ||
| + | baum(6, STAMMLAENGE, | ||
| + | |||
| + | exitonclick() | ||
| + | |||
| + | # Um die Zeichung schneller erscheinen zu lassen, | ||
| + | # gibt es den folgenden Trick: | ||
| + | # Ersetze die Zeile '' | ||
| + | # und ergänze in der Zeile vor '' | ||
| + | # also nach allen Zeichenbefehlen, | ||
| + | </ | ||
| + | --> | ||
| + | |||
| + | ===== Link zur Kursseite ===== | ||
| + | |||
| + | [[lehrkraefte: | ||
| + | |||