From 3dd0969ebc131fedbe94e35d5c9bd9e22ff805c8 Mon Sep 17 00:00:00 2001 From: Michel Schwab <michel.schwab@hu-berlin.de> Date: Tue, 20 Nov 2018 16:35:09 +0100 Subject: [PATCH] Seminar05 modified --- notebooks/seminar05.ipynb | 41 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/notebooks/seminar05.ipynb b/notebooks/seminar05.ipynb index 501ebcd..1a4eb19 100644 --- a/notebooks/seminar05.ipynb +++ b/notebooks/seminar05.ipynb @@ -13,6 +13,11 @@ "source": [ "# Seminar Problemorientierte Programmierung\n", "\n", + "## 5 Verzweigungen und Rekursion\n", + "\n", + "Das erste Thema dieses Kapitels ist die `if`-Anweisung, die unterschiedlichen Code ausführt, je nach Zustand des Programms. Im zweiten Teil lernen Sie die `Rekursion` kennen.\n", + "\n", + "(Buch: http://greenteapress.com/thinkpython2/html/thinkpython2006.html)\n", "## Exkurs: Was mir an Python gefällt\n", "\n", "In dieser Rubrik, die immer am Anfang eines Kapitels steht, möchte ich Ihnen zeigen, wofür ich Python nutze und warum ich es mag. Sie werden vielleicht noch nicht verstehen, was ich genau mache, aber Sie sehen damit schon einmal die Möglichkeiten von Python und können später darauf zurückgreifen. Da dies auch ein Exkurs ist, können Sie diese Rubrik gerne auch erst einmal überspringen.\n", @@ -61,15 +66,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 5 Verzweigungen und Rekursion\n", - "\n", - "Das Thema dieses Kapitels ist die `if`-Anweisung, die unterschiedlichen Code ausführt, je nach Zustand des Programms. Aber schauen wir uns zunächst zwei neue Operatoren an: Ganzzahldivision und Restberechnung.\n", - "\n", "### 5.1 Ganzzahldivision und Restberechnung\n", "\n", "Der Operator `//` für die **Ganzzahldivision** teilt zwei ganze Zahlen und rundet das Ergebnis zu einer ganzen Zahl ab. \n", "\n", - "Angenommen, wir wollen wissen, wie lang ein Film über 105 Minuten in Stunden ist. Bei der üblichen Division erhalten wir eine Gleitkommazahl: " + "Angenommen, wir wollen wissen, wie lang ein Film über 105 Minuten in Stunden dauert. Bei der üblichen Division erhalten wir eine Gleitkommazahl: " ] }, { @@ -245,7 +246,7 @@ "x <= y # x ist kleiner oder gleich y\n", "```\n", "\n", - "Auch wenn Ihnen diese Symbole wahrscheinlich bekannt vorkommen, so sind sie doch anders als ihre mathematischen Äquivalente. Ein üblicher Fehler ist, das einfache Gleichheitszeichen (`=`) statt des doppelten Gleichheitszeichens (`==`) zu verwenden. Wir merken uns: `=` ist der Zuweisungsoperator und `==` ist ein relationaler Operator. Die Operatoren `=<` und `=>` gibt es nicht.\n", + "Auch wenn Ihnen diese Symbole wahrscheinlich bekannt vorkommen, so sind sie doch anders als ihre mathematischen Äquivalente. **Ein üblicher Fehler ist, das einfache Gleichheitszeichen (`=`) statt des doppelten Gleichheitszeichens (`==`) zu verwenden.** Wir merken uns: `=` ist der Zuweisungsoperator und `==` ist ein relationaler Operator. Die Operatoren `=<` und `=>` gibt es nicht.\n", "\n", "\n", "\n", @@ -260,7 +261,7 @@ "\n", "Es gibt drei **logische Operatoren**: `and`, `or` und `not`. Die Semantik (Bedeutung) dieser drei Operatoren ist ähnlich der Bedeutung der englischen Wörter. Beispielsweise ist `x > 0 and x < 10` genau dann wahr, wenn `x` größer als 0 *und* kleiner als 10 ist.\n", "\n", - "`n%2 == 0 or n%3 == 0` ist wahr wenn *eine oder beide* der Bedingungen wahr ist, das heißt wenn die Zahl `n` durch 2 *oder* drei teilbar ist.\n", + "`n%2 == 0 or n%3 == 0` ist wahr, wenn *eine oder beide* der Bedingungen wahr ist, das heißt wenn die Zahl `n` durch 2 *oder* drei teilbar ist.\n", "\n", "Genaugenommen sollten die Operanden der logischen Operatoren Boolesche Ausdrücke sein, aber Python erlaubt uns da mehr Freiheit. Jede Zahl ungleich Null wird als `True` interpretiert:" ] @@ -323,9 +324,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "`if`-Anweisungen haben die gleiche Struktur wie Funktionsdefinitionen: ein (Verzweigungs-)Kopf gefolgt von einem eingerückten (Verzweigungs-)Rumpf. Anweisungen dieser Art werden **Verbundanweisungen** genannt. \n", + "`if`-Anweisungen haben die gleiche Struktur wie Funktionsdefinitionen: ein (Verzweigungs-)Kopf, gefolgt von einem eingerückten (Verzweigungs-)Rumpf. Anweisungen dieser Art werden **Verbundanweisungen** genannt. \n", "\n", - "Die Anzahl an Anweisungen, die im Rumpf stehen können ist nicht begrenzt, aber es muss mindestens eine Anweisung sein. Manchmal ist es nützlich, einen Rumpf ohne Anweisungen zu haben (üblicherweise als Platzhalter für Code, den wir noch schreiben wollen). In diesem Fall können wir die **`pass`**-Anweisung verwenden, die nichts tut:" + "Die Anzahl an Anweisungen, die im Rumpf stehen können, ist nicht begrenzt, aber es muss mindestens eine Anweisung sein. Manchmal ist es nützlich, einen Rumpf ohne Anweisungen zu haben (üblicherweise als Platzhalter für Code, den wir noch schreiben wollen). In diesem Fall können wir die **`pass`**-Anweisung verwenden, die nichts tut:" ] }, { @@ -344,7 +345,7 @@ "source": [ "### 5.5 Alternative Verzweigung\n", "\n", - "Eine zweite Form der `if`-Anweisung ist die \"alternative Verzweigung\", bei der es zwei Möglichkeiten gibt und die Bedingung festglegt, welche davon ausgeführt wird. Die Syntax ist folgendermaßen:" + "Eine zweite Form der `if`-Anweisung ist die \"alternative Verzweigung\", bei der es zwei Möglichkeiten gibt und die Bedingung festlegt, welche davon ausgeführt wird. Die Syntax sieht folgendermaßen aus:" ] }, { @@ -372,7 +373,7 @@ "source": [ "### 5.6 Verkettete Verzweigungen\n", "\n", - "Manchmal gibt es mehr als zwei Möglichkeiten und wir benötigen mehr als zwei Zweige. Eine Möglichkeit eine Berechnung dieser Art auszudrücken sind sogenannte **verkettete Verzweigungen**:" + "Manchmal gibt es mehr als zwei Möglichkeiten und wir benötigen mehr als zwei Zweige. Eine Möglichkeit eine Berechnung dieser Art auszudrücken, sind sogenannte **verkettete Verzweigungen**:" ] }, { @@ -404,7 +405,7 @@ " draw_c()\n", "```\n", "\n", - "Jede Bedingung wird in der vorgegebenen Reihenfolge geprüft. Wenn die erste nicht erfüllt (falsch) ist, wird die nächste geprüft, und so weiter. Sobald eine der Bedingungen erfüllt (wahr) ist, wird der entsprechende Zweig ausgeführt und die `if`-Anweisung wird beendet. Auch wenn mehr als eine Bedingung erfüllt ist, wird nur der erste zutreffende Zweig ausgeführt." + "Jede Bedingung wird in der vorgegebenen Reihenfolge geprüft. Wenn die erste nicht erfüllt (falsch) ist, wird die nächste geprüft, und so weiter. Sobald eine der Bedingungen erfüllt (wahr) ist, wird der entsprechende Zweig ausgeführt und die `if`-Anweisung wird beendet. **Auch wenn mehr als eine Bedingung erfüllt ist, wird nur der erste zutreffende Zweig ausgeführt.**" ] }, { @@ -551,7 +552,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Wenn `n` Null ist oder negativ, gibt die Funktion \"Abheben!\" aus. Ansonsten wird `n` ausgegeben und eine Funktion `countdown` - die Funktion selbst - aufgerufen mit `n-1` als Argument. \n", + "Wenn `n` Null oder negativ ist, gibt die Funktion \"Abheben!\" aus. Ansonsten wird `n` ausgegeben und eine Funktion `countdown` - die Funktion selbst - aufgerufen mit `n-1` als Argument. \n", "\n", "Was passiert wenn wir diese Funktion folgendermaßen aufrufen?" ] @@ -591,7 +592,9 @@ "\n", "Eine Funktion die sich selbst aufruft wird **rekursiv** genannt; der Vorgang wird **Rekursion** genannt.\n", "\n", - "Als weiteres Beispiel schreiben wir eine Funktion die eine Zeichenkette `n` mal ausgibt:" + "**Es ist wichtig, dass Sie dieses Beispiel verstanden haben. Falls das nicht der Fall sein sollte, lassen Sie es sich von Ihrem Partner, Kommilitonen oder Übungsleiter erklären.**\n", + "\n", + "Als weiteres Beispiel schreiben wir eine Funktion, die eine Zeichenkette `n` mal ausgibt:" ] }, { @@ -626,7 +629,7 @@ "\n", "In [Abschnitt 3.9](seminar03.ipynb#3.9-Stapel-Diagramme) haben wir Stapeldiagramme genutzt, um den Zustand eines Programms während eines Funktionsaufrufs zu repräsentieren. Die gleiche Art Diagramm kann uns helfen, eine rekursive Funktion zu interpretieren.\n", "\n", - "Jedes Mal wenn eine Funktion aufgerufen wird, erstellt Python einen Block der die lokalen Variablen und Parameter der Funktion enthält. Für eine rekursive Funktion kann es zur gleichen Zeit mehrere Blöcke auf dem Stapel geben.\n", + "Jedes Mal, wenn eine Funktion aufgerufen wird, erstellt Python einen Block, der die lokalen Variablen und Parameter der Funktion enthält. Für eine rekursive Funktion kann es zur gleichen Zeit mehrere Blöcke auf dem Stapel geben.\n", "\n", "Die folgende Abbildung zeigt ein Stapeldiagramm für den Aufruf von `countdown(3)`:\n", "\n", @@ -726,7 +729,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Bevor man von der Nutzerin eine Eingabe bekommt, ist es eine gute Idee, einen Hinweis auszugeben der der Nutzerin sagt, was Sie eintippen soll. Der Funktion `input` können wir einen solchen Hinweis als Argument übergeben: " + "Bevor man von der Nutzerin eine Eingabe bekommt, ist es eine gute Idee, einen Hinweis auszugeben, der der Nutzerin sagt, was Sie eintippen soll. Der Funktion `input` können wir einen solchen Hinweis als Argument übergeben: " ] }, { @@ -942,8 +945,8 @@ "\\end{equation}\n", "für alle $n$ größer 2 gilt.\n", "\n", - "1. Schreiben Sie eine Funktion `check_fermat` die vier Parameter erwartet - `a`, `b`, `c` und `n` - und prüft, ob Fermats letzter Satz gilt Falls `n` größer als 2 ist und $a^n + b^n = c^n$ gilt, sollte das Programm \"Unglaublich, Fermat lag falsch!\" ausgeben, ansonsten \"Nein, das funktioniert nicht.\"\n", - "2. Schreiben Sie eine Funktion, die den Nutzer bittet, Werte für a, b, c und n einzugeben, diese in ganze Zahlen umwandelt und dann die Funktion `check_fermat` nutzt um zu prüfen, ob sie Fermats letzten Satz erfüllen. " + "1. Schreiben Sie eine Funktion `check_fermat` die vier Parameter erwartet - `a`, `b`, `c` und `n` - und prüft, ob Fermats letzter Satz gilt. Falls `n` größer als 2 ist und $a^n + b^n = c^n$ gilt, sollte das Programm \"Unglaublich, Fermat lag falsch!\" ausgeben, ansonsten \"Nein, das funktioniert nicht.\"\n", + "2. Schreiben Sie eine Funktion, die den Nutzer bittet, Werte für a, b, c und n einzugeben, diese in ganze Zahlen umwandelt und dann die Funktion `check_fermat` nutzt, um zu prüfen, ob sie Fermats letzten Satz erfüllen. " ] }, { @@ -966,7 +969,7 @@ "*Falls eine der drei Längen größer als die Summe der anderen beiden Längen ist, dann lässt sich kein Dreieck formen. (Wenn die Summe der beiden Längen gleich der dritten Länge ist, dann bilden Sie ein sogenanntes \"degeneriertes\" Dreieck.)*\n", "\n", "1. Schreiben Sie eine Funktion `is_triangle` die drei ganze Zahlen als Argumente erwartet und dann entweder \"Ja\" oder \"Nein\" ausgibt, abhängig davon, ob man mit den gegebenen Längen ein Dreieck formen kann oder nicht.\n", - "2. Schreiben Sie eine Funktion die die Nutzerin bittet, drei Längen einzugeben, diese in ganze Zahlen umwandelt und dann `is_triangle` nutzt, um zu prüfen, ob aus Stöcken mit den gegebenen Längen ein Dreieck geformt werden kann oder nicht." + "2. Schreiben Sie eine Funktion, die die Nutzerin bittet, drei Längen einzugeben, diese in ganze Zahlen umwandelt und dann `is_triangle` nutzt, um zu prüfen, ob aus Stöcken mit den gegebenen Längen ein Dreieck geformt werden kann oder nicht." ] }, { -- GitLab