"Beschreiben Sie in 2-3 Stichpunkten kurz was Sie im Seminar heute lernen wollen. Klicken Sie dazu doppelt auf diesen Text und bearbeiten Sie dann den Text:\n",
"\n",
"- \n",
"- \n",
"- \n",
"\n",
"\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",
"\n",
"Man kann schnell und einfach ein Programm aufschreiben und testen. Man muss es weder kompilieren, noch viel \"unnötige\" Syntax kennen:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def factorial(n):\n",
" if n < 2:\n",
" return 1\n",
" else:\n",
" return n * factorial(n - 1)\n",
"\n",
"print(factorial(5))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4: Fallstudie: Schnittstellenentwurf\n",
"\n",
"In diesem Kapitel lernen wir anhand einer Fallstudie, wie wir Funktionen entwerfen können, die gut zusammenarbeiten.\n",
"\n",
"Wir lernen außerdem das `turtle`-Modul kennen, mit dessen Hilfe wir Graphiken erzeugen können. \n",
"\n",
"### 4.1 Das `turtle`-Modul\n",
"\n",
"Führen Sie den folgenden Code aus, um zu testen, ob das `turtle`-Modul installiert ist:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import turtle\n",
"bob = turtle.Turtle()\n",
"turtle.mainloop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Es sollte sich ein Fenster öffnen, in dem ein kleiner Pfeil zu sehen ist - dieser repräsentiert die Schildkröte (\"turtle\"). Schließen Sie das Fenster.\n",
"\n",
"*(Hinweis: In Jupyter gibt es manchmal Probleme mit dem `turtle`-Modul. Dann hilft es, das Turtle-Fenster zu schließen und den Code nochmal auszuführen. Wenn es gar nicht klappt, dann nutzen Sie für die Turtle-Programmierung bitte nicht Jupyter-Notebooks, sondern Python-Dateien und führen diese direkt mit Python aus.)*\n",
"\n",
"Probieren Sie nun folgendes (am besten in einem eigenen Jupyter-Notebook, einer eigenen Python-Datei, oder im folgenden Block, den Sie dann schrittweise ergänzen):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import turtle\n",
"bob = turtle.Turtle()\n",
"print(bob)\n",
"turtle.mainloop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das `turtle`-Modul (mit kleinem `t`) stellt eine Funktion `Turtle` (mit großem `T`) bereit, die ein Turtle-Objekt erzeugt - dieses weisen wir einer Variable mit dem Namen `bob` zu. Wenn wir `bob` mit `print` ausgeben, erhalten wir eine Ausgabe ähnlich\n",
"\n",
"```\n",
"<turtle.Turtle object at 0xb7bfbf4c>\n",
"```\n",
"\n",
"Das bedeutet, dass `bob` auf ein Objekt vom Typ `Turtle` verweist, wie es im `turtle`-Modul definiert wurde.\n",
"\n",
"Der Aufruf von `mainloop` weist das Fenster an, auf Nutzeraktivität zu warten. In diesem Fall kann man als Nutzerin allerdings kaum mehr tun, als das Fenster zu schließen.\n",
"\n",
"Sobald wir eine Schildkröte erzeugt haben, können wir eine **Methode** aufrufen, um die Schildkröte über das Fenster zu bewegen. Eine Methode ist wie eine Funktion, aber die Syntax ist etwas anders. Z.B. können wir die Schildkröte mit dem Aufruf von \n",
"\n",
"```python\n",
"bob.fd(100)\n",
"```\n",
"\n",
"nach vorne bewegen. Die Methode `fd` gehört zu dem Turtle-Objekt welches wir `bob` nennen. Wenn wir die Methode aufrufen, bitten wir `bob` nach vorne zu gehen (**f**orwar**d**).\n",
"\n",
"Das Argument von `fd` ist eine Strecke in Pixeln (den Bildpunkten auf dem Monitor), daher hängt die Entfernung, die `bob` geht, von unserer Monitorauflösung ab.\n",
"\n",
"Andere Methode, die wir auf einer Schildkröte aufrufen können sind `bk` für eine Rückwärtsbewegung (**b**ac**k**ward), `lt` für eine Linksdrehung (**l**eft **t**urn) und `rt` für eine Rechtsdrehung (**r**ight **t**urn). Das Argument für `lt` und `rt` ist ein Winkel in Grad.\n",
"\n",
"Jede Schildkröte hat außerdem einen Stift, der entweder oben oder unten ist. Wenn der Stift unten ist, hinterlässt die Schildkröte eine Spur, wenn sie sich bewegt. Die Methoden `pu` und `pd` stehen für \"Stift hoch\" (**p**en **u**p) und \"Stift herunter\" (**p**en **d**own).\n",
"\n",
"Fügen Sie die folgenden Zeilen zu Ihrem Programm hinzu, um einen rechten Winkel zu zeichnen (nachdem Sie `bob` erzeugt haben und bevor Sie `mainloop` aufrufen):\n",
"\n",
"```python\n",
"bob.fd(100)\n",
"bob.lt(90)\n",
"bob.fd(100)\n",
"```\n",
"\n",
"Wenn Sie dieses Programm ausführen, sollte sich `bob` zunächst nach Osten und dann nach Norden bewegen und dabei zwei Strecken zeichnen.\n",
"\n",
"Verändern Sie ihr Programm jetzt, so dass `bob` ein Quadrat zeichnet. Fahren Sie erst mit dem Kurs fort, wenn es funktioniert.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.2 Einfache Wiederholung\n",
"\n",
"Vielleicht haben Sie folgendes geschrieben:\n",
"\n",
"```python\n",
"bob.fd(100)\n",
"bob.lt(90)\n",
"\n",
"bob.fd(100)\n",
"bob.lt(90)\n",
"\n",
"bob.fd(100)\n",
"bob.lt(90)\n",
"\n",
"bob.fd(100)\n",
"```\n",
"\n",
"Wir können das gleiche deutlich knapper mit einer `for`-Schleife formulieren. Testen Sie folgendes: "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(4):\n",
" print('Hello!')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sie sollten folgende Ausgabe sehen:\n",
"\n",
"```\n",
"Hello!\n",
"Hello!\n",
"Hello!\n",
"Hello!\n",
"```\n",
"\n",
"Das ist die einfachste Art und Weise, eine `for`-Schleife zu verwenden. Wir werden uns das später ausführlicher anschauen, aber das sollte reichen, damit Sie ihr Programm zum Zeichnen eines Quadrats vereinfachen können. Bitte fahren Sie erst fort, wenn Sie ihr Programm mit Hilfe der `for`-Schleife vereinfacht haben.\n",
"Folgende `for`-Schleife zeichnet ein Quadrat:\n",
"\n",
"```python\n",
"for i in range(4):\n",
" bob.fd(100)\n",
" bob.lt(90)\n",
"```\n",
"\n",
"Die Syntax für die `for`-Schleife ist ähnlich einer Funktionsdefinition: Es gibt einen (Schleifen-)Kopf, der mit einem Doppelpunkt endet und einen eingerückten (Schleifen-)Rumpf. Im Rumpf können beliebig viele Anweisungen stehen.\n",
"\n",
"Man nennt dies eine Schleife, denn der Rumpf wird abgearbeitet und dann beginnt der Kontrollfluss wieder von vorn. In unserem Beispiel wird der Rumpf viermal durchlaufen.\n",
"\n",
"Dieser Code ist etwas anders als der vorherige Code zum Zeichnen eines Quadrats, denn nachdem die letzte Seite des Quadrats gezeichnet wurde wird noch eine weitere Drehung durchgeführt. Diese zusätzliche Drehung kostet etwas Zeit, aber der Code ist etwas einfacher, wenn in jedem Schleifendurchlauf immer die gleiche Folge von Anweisungen ausgeführt wird. Ein Nebeneffekt ist, dsss die Schildkröte am Ende wieder in der Ausgangsposition ist mit Blickrichtung zur Ausgangsrichtung.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.3 Übungen\n",
"\n",
"Es folgen einige Übungen zur \"Schildkrötenwelt\". Sie sollen Ihnen Spaß bereiten, aber die Übungen haben auch eine Bedeutung. Überlegen Sie, was das sein könnte, während Sie daran arbeiten.\n",
"\n",
"1. Schreiben Sie eine Funktion `square`, die einen Parameter namens `t` erwartet, welcher eine Schildkröte ist. Die Funktion soll die Schildkröte nutzen, um ein Quadrat zu zeichnen.\n",
"2. Schreiben Sie einen Funktionsaufruf, der `bob` als Argument an `square` übergibt und rufen Sie ihr Programm wieder auf.\n",
"3. Ergänzen Sie die Funktion `square` um einen weiteren parameter namens `length`. Ändern Sie den Rumpf der Funktion, so dass dass die Seitenlänge des gezeichneten Quadrats `length` entspricht. Passen Sie dann den Funktionsaufruf an, so dass ein weiteres Argument als Länge übergeben wird. Starten Sie ihr Programm noch einmal und testen Sie es mit verschiedenen Werten für die Länge.\n",
"4. Kopieren Sie die Definition der Funktion `square` und benennen Sie die Kopie in `polygon` um. Fügen Sie einen weiteren Parameter namens `n` hinzu und ändern Sie den Funktionsrumpf, so dass ein n-seitiges [reguläres Vieleck](https://de.wikipedia.org/wiki/Regelm%C3%A4%C3%9Figes_Polygon) (Polygon) gezeichnet wird. *Tipp: Die Außenwinkel eines n-seitigen Vielecks betragen n/360 Grad.* \n",
"5. Schreiben Sie eine Funktion `circle` die eine Schildkröte `t` und einen Radius `r` als Parameter erwartet und annähernd einen Kreis zeichnet, indem die Funktion `polygon` mit einer geeigneten Seitenlänge und Anzahl von Seiten aufruft. Testen Sie ihre Funktion mit verschiedenen Werten für `r`.\n",
"\n",
" *Tipp: Finden Sie den Umfang des Kreises heraus und stellen Sie sicher, dass `length * n` gleich dem Umfang ist.*\n",
" \n",
"6. Schreiben Sie eine verallgemeinerte Funktion `circle`, so dass sie ein weiteres Argument `angle` erwartet, welches angibt, welcher Teil eines Kreises gezeichnet werden soll. Der Wert von `angle` ist dabei in Grad, so dass für `angle=360` ein vollständiger Kreis gezeichnet werden sollte."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Speichern Sie dieses Notebook, so dass Ihre Änderungen nicht verlorengehen (nicht auf einem Pool-Rechner). Klicken Sie dazu oben links auf das Disketten-Icon und nutzen Sie beispielsweise einen USB-Stick, E-Mail, Google Drive, Dropbox oder Ihre [HU-Box](https://box.hu-berlin.de/). "
"Herzlichen Glückwunsch! Sie haben das 3. Kapitel geschafft. Weiter geht es in [5: Bedingungen und Rekursion](seminar05.ipynb)."
]
}
],
"metadata": {
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
%% Cell type:markdown id: tags:
# Seminar Problemorientierte Programmierung
## Ihre Lernziele
Beschreiben Sie in 2-3 Stichpunkten kurz was Sie im Seminar heute lernen wollen. Klicken Sie dazu doppelt auf diesen Text und bearbeiten Sie dann den Text:
-
-
-
## Exkurs: Was mir an Python gefällt
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.
Man kann schnell und einfach ein Programm aufschreiben und testen. Man muss es weder kompilieren, noch viel "unnötige" Syntax kennen:
%% Cell type:code id: tags:
```
def factorial(n):
if n < 2:
return 1
else:
return n * factorial(n - 1)
print(factorial(5))
```
%% Cell type:markdown id: tags:
## 4: Fallstudie: Schnittstellenentwurf
In diesem Kapitel lernen wir anhand einer Fallstudie, wie wir Funktionen entwerfen können, die gut zusammenarbeiten.
Wir lernen außerdem das `turtle`-Modul kennen, mit dessen Hilfe wir Graphiken erzeugen können.
### 4.1 Das `turtle`-Modul
Führen Sie den folgenden Code aus, um zu testen, ob das `turtle`-Modul installiert ist:
%% Cell type:code id: tags:
```
import turtle
bob = turtle.Turtle()
turtle.mainloop()
```
%% Cell type:markdown id: tags:
Es sollte sich ein Fenster öffnen, in dem ein kleiner Pfeil zu sehen ist - dieser repräsentiert die Schildkröte ("turtle"). Schließen Sie das Fenster.
*(Hinweis: In Jupyter gibt es manchmal Probleme mit dem `turtle`-Modul. Dann hilft es, das Turtle-Fenster zu schließen und den Code nochmal auszuführen. Wenn es gar nicht klappt, dann nutzen Sie für die Turtle-Programmierung bitte nicht Jupyter-Notebooks, sondern Python-Dateien und führen diese direkt mit Python aus.)*
Probieren Sie nun folgendes (am besten in einem eigenen Jupyter-Notebook, einer eigenen Python-Datei, oder im folgenden Block, den Sie dann schrittweise ergänzen):
%% Cell type:code id: tags:
```
import turtle
bob = turtle.Turtle()
print(bob)
turtle.mainloop()
```
%% Cell type:markdown id: tags:
Das `turtle`-Modul (mit kleinem `t`) stellt eine Funktion `Turtle` (mit großem `T`) bereit, die ein Turtle-Objekt erzeugt - dieses weisen wir einer Variable mit dem Namen `bob` zu. Wenn wir `bob` mit `print` ausgeben, erhalten wir eine Ausgabe ähnlich
```
<turtle.Turtle object at 0xb7bfbf4c>
```
Das bedeutet, dass `bob` auf ein Objekt vom Typ `Turtle` verweist, wie es im `turtle`-Modul definiert wurde.
Der Aufruf von `mainloop` weist das Fenster an, auf Nutzeraktivität zu warten. In diesem Fall kann man als Nutzerin allerdings kaum mehr tun, als das Fenster zu schließen.
Sobald wir eine Schildkröte erzeugt haben, können wir eine **Methode** aufrufen, um die Schildkröte über das Fenster zu bewegen. Eine Methode ist wie eine Funktion, aber die Syntax ist etwas anders. Z.B. können wir die Schildkröte mit dem Aufruf von
```python
bob.fd(100)
```
nach vorne bewegen. Die Methode `fd` gehört zu dem Turtle-Objekt welches wir `bob` nennen. Wenn wir die Methode aufrufen, bitten wir `bob` nach vorne zu gehen (**f**orwar**d**).
Das Argument von `fd` ist eine Strecke in Pixeln (den Bildpunkten auf dem Monitor), daher hängt die Entfernung, die `bob` geht, von unserer Monitorauflösung ab.
Andere Methode, die wir auf einer Schildkröte aufrufen können sind `bk` für eine Rückwärtsbewegung (**b**ac**k**ward), `lt` für eine Linksdrehung (**l**eft **t**urn) und `rt` für eine Rechtsdrehung (**r**ight **t**urn). Das Argument für `lt` und `rt` ist ein Winkel in Grad.
Jede Schildkröte hat außerdem einen Stift, der entweder oben oder unten ist. Wenn der Stift unten ist, hinterlässt die Schildkröte eine Spur, wenn sie sich bewegt. Die Methoden `pu` und `pd` stehen für "Stift hoch" (**p**en **u**p) und "Stift herunter" (**p**en **d**own).
Fügen Sie die folgenden Zeilen zu Ihrem Programm hinzu, um einen rechten Winkel zu zeichnen (nachdem Sie `bob` erzeugt haben und bevor Sie `mainloop` aufrufen):
```python
bob.fd(100)
bob.lt(90)
bob.fd(100)
```
Wenn Sie dieses Programm ausführen, sollte sich `bob` zunächst nach Osten und dann nach Norden bewegen und dabei zwei Strecken zeichnen.
Verändern Sie ihr Programm jetzt, so dass `bob` ein Quadrat zeichnet. Fahren Sie erst mit dem Kurs fort, wenn es funktioniert.
%% Cell type:markdown id: tags:
### 4.2 Einfache Wiederholung
Vielleicht haben Sie folgendes geschrieben:
```python
bob.fd(100)
bob.lt(90)
bob.fd(100)
bob.lt(90)
bob.fd(100)
bob.lt(90)
bob.fd(100)
```
Wir können das gleiche deutlich knapper mit einer `for`-Schleife formulieren. Testen Sie folgendes:
%% Cell type:code id: tags:
```
for i in range(4):
print('Hello!')
```
%% Cell type:markdown id: tags:
Sie sollten folgende Ausgabe sehen:
```
Hello!
Hello!
Hello!
Hello!
```
Das ist die einfachste Art und Weise, eine `for`-Schleife zu verwenden. Wir werden uns das später ausführlicher anschauen, aber das sollte reichen, damit Sie ihr Programm zum Zeichnen eines Quadrats vereinfachen können. Bitte fahren Sie erst fort, wenn Sie ihr Programm mit Hilfe der `for`-Schleife vereinfacht haben.
Die Syntax für die `for`-Schleife ist ähnlich einer Funktionsdefinition: Es gibt einen (Schleifen-)Kopf, der mit einem Doppelpunkt endet und einen eingerückten (Schleifen-)Rumpf. Im Rumpf können beliebig viele Anweisungen stehen.
Man nennt dies eine Schleife, denn der Rumpf wird abgearbeitet und dann beginnt der Kontrollfluss wieder von vorn. In unserem Beispiel wird der Rumpf viermal durchlaufen.
Dieser Code ist etwas anders als der vorherige Code zum Zeichnen eines Quadrats, denn nachdem die letzte Seite des Quadrats gezeichnet wurde wird noch eine weitere Drehung durchgeführt. Diese zusätzliche Drehung kostet etwas Zeit, aber der Code ist etwas einfacher, wenn in jedem Schleifendurchlauf immer die gleiche Folge von Anweisungen ausgeführt wird. Ein Nebeneffekt ist, dsss die Schildkröte am Ende wieder in der Ausgangsposition ist mit Blickrichtung zur Ausgangsrichtung.
%% Cell type:markdown id: tags:
### 4.3 Übungen
Es folgen einige Übungen zur "Schildkrötenwelt". Sie sollen Ihnen Spaß bereiten, aber die Übungen haben auch eine Bedeutung. Überlegen Sie, was das sein könnte, während Sie daran arbeiten.
1. Schreiben Sie eine Funktion `square`, die einen Parameter namens `t` erwartet, welcher eine Schildkröte ist. Die Funktion soll die Schildkröte nutzen, um ein Quadrat zu zeichnen.
2. Schreiben Sie einen Funktionsaufruf, der `bob` als Argument an `square` übergibt und rufen Sie ihr Programm wieder auf.
3. Ergänzen Sie die Funktion `square` um einen weiteren parameter namens `length`. Ändern Sie den Rumpf der Funktion, so dass dass die Seitenlänge des gezeichneten Quadrats `length` entspricht. Passen Sie dann den Funktionsaufruf an, so dass ein weiteres Argument als Länge übergeben wird. Starten Sie ihr Programm noch einmal und testen Sie es mit verschiedenen Werten für die Länge.
4. Kopieren Sie die Definition der Funktion `square` und benennen Sie die Kopie in `polygon` um. Fügen Sie einen weiteren Parameter namens `n` hinzu und ändern Sie den Funktionsrumpf, so dass ein n-seitiges [reguläres Vieleck](https://de.wikipedia.org/wiki/Regelm%C3%A4%C3%9Figes_Polygon)(Polygon) gezeichnet wird. *Tipp: Die Außenwinkel eines n-seitigen Vielecks betragen n/360 Grad.*
5. Schreiben Sie eine Funktion `circle` die eine Schildkröte `t` und einen Radius `r` als Parameter erwartet und annähernd einen Kreis zeichnet, indem die Funktion `polygon` mit einer geeigneten Seitenlänge und Anzahl von Seiten aufruft. Testen Sie ihre Funktion mit verschiedenen Werten für `r`.
*Tipp: Finden Sie den Umfang des Kreises heraus und stellen Sie sicher, dass `length * n` gleich dem Umfang ist.*
6. Schreiben Sie eine verallgemeinerte Funktion `circle`, so dass sie ein weiteres Argument `angle` erwartet, welches angibt, welcher Teil eines Kreises gezeichnet werden soll. Der Wert von `angle` ist dabei in Grad, so dass für `angle=360` ein vollständiger Kreis gezeichnet werden sollte.
%% Cell type:markdown id: tags:
 Speichern Sie dieses Notebook, so dass Ihre Änderungen nicht verlorengehen (nicht auf einem Pool-Rechner). Klicken Sie dazu oben links auf das Disketten-Icon und nutzen Sie beispielsweise einen USB-Stick, E-Mail, Google Drive, Dropbox oder Ihre [HU-Box](https://box.hu-berlin.de/).