Browse Source

Add chapter 05.

master
Jan Paulus 2 years ago
parent
commit
6868734b92

+ 277
- 0
05kapitel/051 Module.ipynb View File

@@ -0,0 +1,277 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 5: Module und Pakete\n",
"\n",
"Die Sichtbarkeit von programmiersprachlichen Objekten wie Funktionen oder globalen Variablen\n",
"ist bei Python auf die jeweilige Programmdatei beschränkt. Eine solche Python-Datei wird auch als\n",
"*Modul* bezeichnet. Sie spannt einen *Namensraum* auf, d.h. innerhalb des Moduls existieren (globale)\n",
"Bezeichner nur einmal; außerhalb der Datei in anderen Modulen können Funktionen etc. gleichen\n",
"Namens existieren, ohne dass es zu Konflikten kommt."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Python bietet jedoch die Möglichkeit, größere Programme auf mehrere Module aufzuteilen und\n",
"so die damit verbundene Komplexität beherrschbar zu gestalten. Typischerweise stützt sich dabei ein\n",
"*Top-Level-Modul* auf weitere nachgeordnete Module, die z.B. Funktionen oder\n",
"Datentypen definieren und bereitstellen.\n",
"\n",
"![Module](../img/module.png \"Module\")\n",
"\n",
"Python selbst liefert bereits eine Reihe von Modulen mit aus, die die Möglichkeiten der Sprache \n",
"erweitern. Die Summe aller mitgelieferten Module wird als *Standard-Bibliothek* bezeichnet.\n",
"\n",
"Die Standard-Bibliothek ist so umfangreich, dass eine vollumfängliche Behandlung bereits im Ansatz\n",
"zum Scheitern verurteilt wäre. Im Folgenden werden lediglich ausgewählte Module als Beispiel\n",
"aufgeführt. Eine vollständige Übersicht bietet die offizielle\n",
"[Dokumentation](https://docs.python.org/3/library/)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 5.1 Import von Modulen\n",
"\n",
"Da die Sichtbarkeit von programmiersprachlichen Objekten normalerweise an der Dateigrenze endet,\n",
"müssen die nachgeordneten Module in das übergeordnete Modul *importiert* werden. Sollen\n",
"Beispielsweise Funktionen des Standard-Moduls <code>math</code> verwendet werden,\n",
"so können diese folgendermaßen zugänglich gemacht werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"import math\n",
"\n",
"zahl = float(input(\"Zahl: \"))\n",
"wurzel = math.sqrt(zahl)\n",
"print(f\"Die Wurzel von {zahl} ist {wurzel}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Um Konflikte bei gleichnamigen Objekten zu vermeiden, muss für den Zugriff in diesem Fall stets der\n",
"komplette Pfad zum importierten Objekt angegeben werden. Alle im Modul definierten Funktionen\n",
"sind so zugänglich. Im Falle von <code>math</code> sind dies die wesentlichen mathematischen Funktionen\n",
"wie z.B.\n",
"\n",
"* Sinus <code>sin</code>\n",
"* Cosinus <code>cos</code>\n",
"* Exponentialfunktion <code>exp</code>\n",
"* Logarithmus <code>log</code>\n",
"* Wurzel <code>sqrt</code>"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"sowie einige mathematische Konstante wie z.B.\n",
"\n",
"* <code>pi</code>\n",
"* <code>e</code>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"import math\n",
"\n",
"print(math.cos(math.pi))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Beim Import kann dem Modul auch ein abweichender Name gegeben werden, um z.B. lange\n",
"Modulnamen abzukürzen. Im nachfolgenden Beispiel das Modul <code>datetime</code> unter dem\n",
"neuen Namen <code>dt</code> importiert und anschließend der im Modul definierte Datentyp\n",
"<code>date</code> verwendet, der die Funktion <code>today</code> bereitstellt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"import datetime as dt\n",
"\n",
"print(dt.date.today())\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 5.2 Einbinden von Modulinhalten\n",
"\n",
"Neben dem Importieren von fremden Modulen können deren Inhalte auch selektiv mittels\n",
"\n",
"<code>from \\< module \\> import \\< Bezeichner \\> </code>\n",
"\n",
"in den eigenen Namensraum eingebunden werden. Die Angabe eines vollständigen Pfads entfällt dann."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"from math import sin, pi\n",
"\n",
"print(sin(pi))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Bei dieser Art der Einbindung können die eingebundenen Objekte umbenannt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"from math import sin as sinus, pi\n",
"\n",
"print(sinus(pi))"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Bei der Einbettung in den eigenen Adressraum kann es zu Konflikten mit im eigenen Modul definierten\n",
"Funktionen o.ä. kommen. Da Python Module beim Importieren ausführt und die darin enthaltenen Definitionen \n",
"verarbeitet, können die so definierten Bezeichner durch eine erneute Definition verändert werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"from math import sin\n",
"\n",
"def sin(x):\n",
" return x\n",
"\n",
"#from math import sin\n",
"\n",
"print(sin(1))"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.9"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 265
- 0
05kapitel/052 Turtle.ipynb View File

@@ -0,0 +1,265 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 5: Module und Pakete\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5.2 Turtle-Grafik\n",
"\n",
"Ein im Standard enthaltenes Modul ist <code>turtle</code>, mit dessen Hilfe sich einfache Grafiken erzeugen lassen.\n",
"Dazu stellt das Modul einen Zeichenstift *Turtle* zur Verfügung, der mit einfachen Befehlen wie <code>forward</code>,\n",
"<code>left</code>, <code>right</code>, ... über den Bildschirm bewegt werden kann."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"In reduzierter Form steht ein solches Modul auch für Jupyter Notebooks zur Verfügung, das nachfolgend\n",
"Verwendung findet. Es heißt <code>ipyturtle</code>."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"from ipyturtle import Turtle\n",
"\n",
"turtle = Turtle(width=400, height=400)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Damit das Grafikfeld im Browser angezeigt wird, muss <code>turtle</code> einmal als Ergebnis einer\n",
"Zelle an das Jupyter Notebook zurückgegeben werden. Im Folienmodus \"hängt\" das Grafikfeld dann leider an der aufrufenden Folien fest."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Anschließend kann der Zeichenstift bewegt werden. Er erzeugt dabei eine Linie."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle.forward(100)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Richtungsänderungen sind mit <code>left</code> und <code>right</code> möglich.\n",
"Die Drehung wird in Grad angegeben."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle.left(90)\n",
"turtle.forward(20)\n",
"turtle.right(45)\n",
"turtle.back(50)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Mit Hilfe von <code>reset</code> kann die Ausgabe gelöscht und der Zeichenstift in die Mitte gesetzt\n",
"werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle.reset()"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Durch das Heben und Senken des Stifts ist es möglich, Bewegungen auszuführen,\n",
"ohne eine Linie zu hinterlassen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"for i in range(10):\n",
" if i%2 == 0:\n",
" turtle.pendown()\n",
" else:\n",
" turtle.penup()\n",
" turtle.forward(10)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Positon und die Ausrichtung des Stifts kann jederzeit abgefragt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle.reset()\n",
"print(turtle.position())\n",
"print(turtle.heading())\n",
"turtle.right(90)\n",
"print(turtle.heading())\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Und schließlich: durch Angabe eines RGB-Wertes kann die Farbe des Stifts gesetzt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle.reset()\n",
"r = 0\n",
"g = 0\n",
"b = 255\n",
"turtle.pencolor(r, g, b)\n",
"turtle.forward(100)"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.9"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 220
- 0
05kapitel/052a Uebung Turtle.ipynb View File

@@ -0,0 +1,220 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 5: Module und Pakete\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 5.3 Beispiel für eine Turtle-Grafik\n",
"\n",
"Unsere Aufgabe ist es, ein Programm zu erstellen, das den \"Baum des Pytagoras\" ausgibt.\n",
"\n",
"![Baum des Pytagoras](../img/BaumPytagoras.png \"Baum des Pytagoras\")\n",
"\n",
"Dazu erzeugen wir uns zunächst ein Ausgabefeld der Größe 400x400 und zeigen es an."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"from ipyturtle import Turtle\n",
"turtle = Turtle(width=400, height=400)\n",
"turtle"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Dann ist es ganz hilfreich, eine Funktion zu definieren, die an der aktuellen Stiftposition\n",
"ein Quadrat vorgegebener Größe zeichnet."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def quadrat(seite):\n",
" for _ in range(4):\n",
" turtle.forward(seite)\n",
" turtle.right(90)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Verästelung des Baums erfolgt ja immer in Form eines rechtwinkligen Dreiecks. Wir bereiten\n",
"eine Funktion vor, mit deren Hilfe sich aus der Größe des Hauptastes die Größe der Teiläste\n",
"berechnen lässt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"import math\n",
"\n",
"def teilast(hauptast):\n",
" return math.sqrt(hauptast * hauptast / 2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Nun können wir eine rekursive Funktion definieren, die den Baum zeichnet."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def baum(seite):\n",
" if seite < 10:\n",
" return\n",
" # Stamm\n",
" quadrat(seite)\n",
" ast = teilast(seite)\n",
" # linker Ast\n",
" turtle.penup()\n",
" turtle.forward(seite)\n",
" turtle.left(45)\n",
" turtle.pendown()\n",
" baum(ast)\n",
" # rechter Ast\n",
" turtle.penup()\n",
" turtle.right(90)\n",
" turtle.forward(ast)\n",
" turtle.pendown()\n",
" baum(ast)\n",
" #zurück zum Ausgangspunkt beim Stamm\n",
" turtle.penup()\n",
" turtle.back(ast)\n",
" turtle.left(45)\n",
" turtle.back(seite)\n",
" turtle.pendown()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Jetzt können wir den Stift an den unteren Rand bewegen und den Baum zeichnen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"turtle.reset()\n",
"turtle.penup()\n",
"turtle.back(180)\n",
"turtle.left(90)\n",
"turtle.forward(50)\n",
"turtle.right(90)\n",
"turtle.pendown()\n",
"baum(70)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"Schön, oder?\n"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.9"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 191
- 0
05kapitel/053 Package.ipynb View File

@@ -0,0 +1,191 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 5: Module und Pakete"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 5.4 Eigene Module\n",
"\n",
"Natürlich ist es auch mögliche, selbst Module zu entwickeln und diese zu importieren. Genau genommen\n",
"ist jede Python-Quellcodedatei ein eigenes Modul. Die darin enthaltenen globalen Objekte\n",
"(insbesondere Funktionen) können mittels <code>import</code> in anderen Quellcodedateien\n",
"zugänglich gemacht werden.\n",
"\n",
"![Import eigener Module](../img/import.png \"Import eigener Module\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Der Name des Moduls beim Import entspricht dem Dateinamen der Python-Quellcodedatei. Gefunden\n",
"werden auf diese Weise Quellcodedateien, die im gleichen Verzeichnis liegen oder in einem der\n",
"beim Python-Interpreter hinterlegten Modulverzeichnisse.\n",
"\n",
"Vorsicht: Sollte das eigene Modul den gleichen Namen beitzen wie ein Standardmodul, so wird\n",
"das Standardmodul gefunden und importiert!\n",
"\n",
"\n",
"Der Name eines Moduls kann im übrigen mit der *Special Variable* <code>\\_\\_name\\_\\_</code> ermittelt\n",
"werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(__name__)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Mit Hilfe der Variable <code>\\_\\_name\\_\\_</code> kann festgestellt werden, ob die Quellcodedatei \n",
"gerade ausgeführt wird, \n",
"\n",
"* weil sie direkt gestartet wurde und das Top-Level-Modul ist - in diesem Fall enthält die\n",
" Variable den String <code>\"\\_\\_main\\_\\_\"</code>\n",
"* weil sie in ein anderes Modul importiert wird - in diesem Fall enthält die Variable \n",
" den Modulnamen, wie er beim Importstatement angegeben ist"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Durch diese Unterscheidung ist es möglich, Module mit Test- oder Beispielcode zu versehen, der\n",
"nicht ausgeführt wird, wenn die Quellcodedatei importiert wird. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"# Definition einer Funktion, die von anderen importiert werden soll\n",
"def f():\n",
" return 17\n",
"\n",
"# Testcode, der nur ausgeführt werden soll, wenn das Modul direkt ausgeführt wird\n",
"if __name__ == \"__main__\":\n",
" if f() != 17:\n",
" print(\"Fehler!\")\n",
" else:\n",
" print(\"Alles ok!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 5.5 Packages\n",
"\n",
"*Packages* dienen dazu, mehrere Module zusammenzufassen und in strukturierter Form\n",
"importieren zu können. Python enthält z.B. bereits im Standard das Package <code>http</code>\n",
"mit den darin enthaltenen Standardmodulen <code>http.client</code>, <code>http.server</code>\n",
"und weiteren. Auf die enthaltenen Teilmodule kann beim Import mit der *Dot-Notation* zugegriffen\n",
"werden kann, z.B.:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"import http.client\n",
"\n",
"connection = http.client.HTTPConnection('www.th-nuernberg.de')\n",
"connection.request(\"GET\", \"/\")\n",
"response = connection.getresponse()\n",
"print(response.status, response.reason)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ein Package ist ein Dateisystem-Verzeichnis mit folgendem Inhalt:\n",
"\n",
"* die Python-Dateien der beinhalteten Module\n",
"* eine optionale Initialisierungsdatei <code>__init__.py</code>,\n",
" die beim Importieren des Packages geladen und ausgeführt wird"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.9"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 22
- 0
05kapitel/rise.css View File

@@ -0,0 +1,22 @@
body.rise-enabled div.inner_cell>div.input_area {
font-size: 150%;
}

body.rise-enabled div.output_subarea.output_text.output_result {
font-size: 150%;
}
body.rise-enabled div.output_subarea.output_text.output_stream.output_stdout {
font-size: 150%;
}

body.rise-enabled div.output_subarea.output_html.rendered_html.output_result {
font-size: 150%;
}

body.rise-enabled td {
font-size: 120%;
}

body.rise-enabled th {
font-size: 120%;
}

Loading…
Cancel
Save