Browse Source

Initial push.

master
paulusja 2 years ago
parent
commit
5232cc93c7

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
*/.ipynb_checkpoints

+ 132
- 0
01kapitel/011 Interpreter.ipynb View File

@@ -0,0 +1,132 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 1: Einführung \n",
"\n",
"### 1.1 Skriptsprache \n",
"\n",
"Python ist eine Skriptsprache, deren Befehle nicht von einem *Compiler* \n",
"vor der Programmausführung in Maschinencode \n",
"für den jeweiligen Prozessor übersetzt werden, \n",
"sondern die von einem *Interpreter* zur Programmlaufzeit ausgeführt werden.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.1.1 Kommandozeileninterpreter\n",
"\n",
"Ein solcher Interpreter kann z.B. durch einen Kommandozeilenbefehl gestartet werden, \n",
"bei dem der auszuführende Python-Code als Dateiname angegeben wird. Ein solcher \n",
"Kommandozeileninterpreter ist für viele Systeme \n",
"bei __[Python.org](https://www.python.org/downloads/)__ kostenfrei erhältlich.\n",
"\n",
"Unter Linux und MacOS lautet der Kommandozeilenbefehl meist <code>python3</code>, \n",
"unter Windows schlicht <code>python</code>. Die Datei, die die Python-Befehle enthält, \n",
"besitzt i.d.R. die Extension <code>.py</code>.\n",
"\n",
"Beispiel: Der folgende Kommandozeilenbefehl startet einen Python-Interpreter und \n",
"führt die Befehle aus, die in der Datei <code>programm.py</code> enthalten sind:\n",
"\n",
"```\n",
"C:/> python programm.py\n",
"```\n",
"Der Interpreter beendet sich, sobald alle Befehle ausgeführt wurden."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.1.2 Entwicklungsumgebung Visual Studio Code\n",
"\n",
"Das Entwickeln mit einem Kommandozeilen-Interpreter und einem Editor zum Erstellen der \n",
"Programmdateien ist möglich, für einen Anfänger aber recht umständlich. Daher bietet\n",
"es sich an, eine *Entwicklungsumgebung* zu nutzen, die z.B. Python-Befehle auf korrekte \n",
"Syntax überprüft und Fehler frühzeitig anzeigt.\n",
"\n",
"Microsoft *Visual Studio Code* ist eine solche Entwicklungsumgebung, die für alle relevanten\n",
"Betriebssysteme (Windows, Linux, Mac OS) __[hier](https://code.visualstudio.com/)__ heruntergeladen \n",
"werden kann. \n",
"\n",
"Visual Studio Code ist dabei nicht auf eine bestimmte Programmiersprache beschränkt, sondern kann \n",
"durch *Extensions* so erweitert werden, dass z.B. eine Syntaxprüfung für Python durchgeführt wird.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.1.3 Jupyter Notebook\n",
"\n",
"Ein *Jupyter Notebook* ist ein Hilfsmittel zur Erläuterung der Sprache Python. \n",
"Ein solches Notebook kann sowohl erklärenden Text als auch Python-Befehle enthalten.\n",
"\n",
"Für die Anzeige eines Notebooks wird der Browser verwendet, in dem die Python-Befehle \n",
"interaktiv ausgeführt und ggf. auch verändert werden können. Die Unterlagen zur \n",
"Veranstaltung *Software Entwicklung* werden als Notebooks bereitgestellt; dieser Text,\n",
"den Sie gerade lesen, ist bereits Bestandteil eines solchen Notebooks.\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 197
- 0
01kapitel/012 BuildIn.ipynb View File

@@ -0,0 +1,197 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 1: Einführung \n",
"\n",
"### 1.2 Built-In Functions\n",
"\n",
"Jeder Python-Interpreter \"versteht\" eine Reihe von *Built-In Functions*. \n",
"Das sind Bausteine, aus denen dann komplizierte Programme zusammengesetzt werden\n",
"können. Der Aufruf einer Built-In Funktion (und jeder anderen Funktion) liefert \n",
"grundsätzlich einen Rückgabewert. Darüber hinaus kann eine Built-In Funktion\n",
"auch Seiteneffekte ausführen (z.B. eine Datei beschreiben, eine Eingabe \n",
"entgegennehmen etc.).\n",
"\n",
"Im Laufe der Veranstaltung werden wir einige der Built-In Functions kennenlernen. "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.2.1 Ausgabe\n",
"\n",
"Eine ganz elementare Built-In Function ist\n",
"\n",
"```Python\n",
"print()\n",
"```\n",
"Sie wird hauptsächlich wegen ihres Seiteneffekts aufgerufen, den übergeben Parameter \n",
"auf der Konsole auszugeben und danach einen Zeilenwechsel durchzuführen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(17)\n",
"print(\"Hello World!!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Die Funktion <code>print</code> kann jede Art von Parameter entgegennehmen (Zeichenkette, \n",
"Ganzzahl, Gleitkommazahl,...). Natürlich besitzt die Funktion auch einen Rückgabewert, \n",
"der ebenfalls ausgegeben werden kann:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(print(17))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Der Wert <code>None</code> steht in Python für *nichts*. \n",
"Es ist etwas anderes als die Zahl 0 oder ein Leerstring. \n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.2.2 Ausgabe mehrerer Werte\n",
"\n",
"Die Anzahl der Parameter der Funktion <code>print</code> ist nicht beschränkt. \n",
"Wird mehr als ein Parameter angegeben, so erfolgt die Ausgabe nacheinander ohne\n",
"Zeilenumbruch."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(17, 4)\n",
"print()\n",
"print(\"Hello\", \"World\", \"!\", 17, 4)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.2.3 Eingabe\n",
"\n",
"Analog zur Ausgabe gibt es auch eine Funktion zur Eingabe eines Werts: \n",
"\n",
"```Python\n",
"input(\"<prompt>\")\n",
"```\n",
"Der Seiteneffekt dieser Funktion ist zunächst die Ausgabe des Parameters und \n",
"anschließend das Einlesen einer Tastatureingabe bis zum Zeilenwechsel.\n",
"\n",
"Der Rückgabewert der Funktion sind die eingegebenen Zeichen als Zeichenkette."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"scrolled": false
},
"outputs": [],
"source": [
"input(\"Wie ist Ihr Name?\")\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 218
- 0
01kapitel/013 Variable.ipynb View File

@@ -0,0 +1,218 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 1: Einführung \n",
"\n",
"### 1.3 Variable\n",
"\n",
"Wie in jeder anderen Programmiersprache dienen *Variablen* dazu, Werte (z.B. Rückgabewerte von \n",
"Funktionsaufrufen) zu benennen und zu speichern. Die Zuweisung erfolgt mit einem einfachen\n",
"Gleichheitszeichen <code>=</code>. Durch die Vergabe eines Namens kann anschließend gezielt \n",
"auf den Wert zugegriffen werden."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.3.1 Variablennamen\n",
"\n",
"Variablennamen setzen sich aus Buchstaben, Unterstrichen und Ziffern zusammen, wobei Ziffern \n",
"nicht am Amfang des Namens stehen dürfen. Groß- und Kleinschreibung werden vom \n",
"Python-Interpreter unterschieden, d.h. die Bezeichner <code>Abc</code> und <code>abc</code>\n",
"verweisen auf unterschiedliche Werte.\n",
"\n",
"Die *Schlüsselwörter* der Programmiersprache Python, die wir noch kennenlernen werden, sind\n",
"als Variablennamen natürlich nicht zugelassen. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"var = input(\"Wie heißen Sie?\")\n",
"print(var)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.3.2 Konventionen\n",
"\n",
"Nicht alles, was der Python-Interpreter zulässt, ist auch übliche Praxis. Python-Entwickler \n",
"haben sich auf einige Konventionen geeinigt, die das Lesen und Verstehen von fremden \n",
"Programmcode erleichtern:\n",
"\n",
"- Variablennamen sollten keine Großbuchstaben enthalten, also nur Kleinbuchstaben und\n",
" Unterstriche\n",
"- Längere Variablennamen werden durch Unterstriche lesbar gemacht, z.B. \n",
" <code>calculation_result</code>\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.3.3 Vereinbarung\n",
"\n",
"Variablen müssen in Python nicht deklariert werden. Sie entstehen mit der ersten Zuweisung.\n",
"Anschließend kann auch lesend auf die Variable zugegriffen werden.\n",
"\n",
"Der Zugriff auf eine Variable, die (noch) nicht existiert führt zu einer Fehlermeldung und\n",
"dem Abbruch des Programms.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(not_yet_defined)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### 1.3.4 Typisierung\n",
"\n",
"Werte besitzen in Python einen Typ (Ganzzahl, Fließkommazahl, String), Variablen jedoch nicht.\n",
"Somit kann eine Variable im Laufe einer Programmausführung mal einen String, mal eine Zahl\n",
"enthalten, ohne dass der Interpreter sich daran stört.\n",
"\n",
"Der Typ eines in einer Variablen enthaltenen Wertes kann mit der Built-In Function \n",
"\n",
"```Python\n",
"type()\n",
"```\n",
"\n",
"ermittelt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(type(\"Hello\"))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Seit Python 3.6 können Variable mit *Type Annotations* versehen werden, die aber zunächst \n",
"lediglich den menschlichen Leser von Pythoncode in einer standardisierten \n",
"Form darauf hinweisen, dass diese Variable nur Werte eines bestimmten Typs aufnehmen soll.\n",
"Der Python-Interpreter wird den Code auch bei einem Verstoß ohne Widerspruch ausführen. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"ganze_zahl : float\n",
"ganze_zahl = 4\n",
"print(ganze_zahl)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Allerdings existieren Tools zur statischen Codeanalyse, die diese Hinweise auswerten. Für \n",
"*Visual Studio Code* gibt es z.B. die Extension *Pyright*, die eine entsprechende \n",
"Prüfung nachrüstet.\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 1458
- 0
01kapitel/014 Datentypen.ipynb
File diff suppressed because it is too large
View File


+ 22
- 0
01kapitel/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%;
}

+ 318
- 0
02kapitel/021 BedingteAnweisung.ipynb View File

@@ -0,0 +1,318 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 2: Kontrollfluss\n",
"\n",
"Unter dem *Kontrollfluss* eines Programms versteht man die Reihenfolge der Abarbeitung der\n",
"Programmbefehle."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.1 Sequenz \n",
"Die einfachste Form eines Kontrollflusses ist die lineare sequenzielle Ausführung der Befehle\n",
"in der Reihenfolge, wie sie auch im Programmcode stehen. Dies ist das \"normale\"\n",
"Verhalten eines Python-Programms. Ein Zeilenumbruch schließt die Anweisung ab.\n",
"\n",
"![Sequenz](../img/Sequenz.png \"Sequenz\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"print(\"Anweisung 1\")\n",
"print(\"Anweisung 2\")\n",
"print(\"Anweisung 3\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.2 Bedingte Anweisung \n",
"Gelegentlich ist es notwendig, die Abarbeitungsreihenfolge zu variieren. Im einfachsten\n",
"Fall sind eine oder mehrere Anweisungen nur auszuführen, wenn eine *Bedingung* erfüllt ist.\n",
"\n",
"![Bedingte Anweisung](../img/Bedingung.png \"Bedingte Anweisung\") "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Eine bedingte Anweisung wird in Python mit dem Schlüsselwort <code>if</code> eingeleitet. Danach folgt ein\n",
"Ausdruck, der zu einem booleschen Wert evaluiert. Das kann z.B. ein Vergleich sein\n",
"oder auch eine Variable mit einem Boolean-Wert."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"a = 3\n",
"b = 2\n",
"c = (a < b)\n",
"print(\"Anweisung\", c)\n",
"if c:\n",
" print(\"Optionale Anweisung\")\n",
" print(\"Optionale Anweisung\")\n",
"print(\"Anweisung\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die optionale Anweisung folgt nach einem Doppelpunkt. Soll mehr als eine Anweisung optional ausgeführt werden,\n",
"so müssen diese eingrückt ab der nachfolgenden Zeile aufgeführt werden. Leerzeichen haben in Python also eine\n",
"Bedeutung!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 3\n",
"b = 2\n",
"print(\"Anweisung 1\")\n",
"if a <= b:\n",
" print(\"Anweisung 2\")\n",
" if a == b:\n",
" print(\"Anweisung 3\")\n",
" print(\"Anweisung 4\")\n",
"print(\"Anweisung 5\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.3 Verzweigung \n",
"\n",
"Soll nicht nur bei der Erfüllung eine Bedingung optionaler Code ausgeführt werden, sondern auch bei der \n",
"Nichterfüllung, so spricht man von einer *Verzweigung*.\n",
"\n",
"![Verzweigung](../img/Verzweigung.png \"Verzweigung\") "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Alternative, die ausgeführt wird, wenn die Bedingung nicht zutrifft, wird mit dem Schlüsselwort \n",
"<code>else</code> ergänzt. Auch hier folgt ein Doppelpunkt und die auszuführenden Anweisungen\n",
"werden eingerückt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"a = 3\n",
"b = 5\n",
"print(\"Anweisung\")\n",
"if a < b:\n",
" print(\"Optionale Anweisung 1\")\n",
"else:\n",
" print(\"Optionale Anweisung 2\")\n",
"print(\"Anweisung\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.4 Mehrfachverzweigung \n",
"\n",
"Existieren mehr als zwei Alternativen, spricht man von einer *Mehrfachverzweigung*.\n",
"\n",
"![Mehrfachverzweigung](../img/Mehrfach.png \"Mehrfachverzweigung\") "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Sollen mehrere Bedingungen überprüft werden, so können diese mit einer oder mehreren <code>elif</code>-Blöcken \n",
"ergänzt werden. Ein evtl. vorhandener <code>else</code>-Block wird ausgeführt, wenn keine der Alternativen \n",
"zum Zug gekommen ist."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false
}
},
"outputs": [],
"source": [
"a = 5\n",
"b = 2\n",
"print(\"Anweisung\")\n",
"if a < b:\n",
" print(\"Optionale Anweisung 1\")\n",
"elif a > b:\n",
" print(\"Optionale Anweisung 2\")\n",
"else:\n",
" print(\"Optionale Anweisung 3\") \n",
"print(\"Anweisung\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.5 If-Ausdruck\n",
"\n",
"Bei einem *If-Ausdruck* ist das Ergebnis von einer Bedingung abhängig. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 3\n",
"b = 2\n",
"\n",
"min = a if a < b else b\n",
"print(min)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"Die Anweisung unmittelbar vor dem <code>if</code> wird nur ausgeführt, wenn die Bedingung erfüllt ist. Die Anweisung \n",
"nach dem <code>else</code> wird ausgeführt, falls die Bedingung nicht erfüllt ist. Der <code>else</code>-Zweig\n",
"ist bei diesem Konstrukt verpflichtend. Insgesamt entspricht das Ergebnis des Ausdrucks dem Wert der ausgeführten Operation.\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 152
- 0
02kapitel/021a Uebung.ipynb View File

@@ -0,0 +1,152 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 1_\n",
"\n",
"Schreiben Sie ein Python-Programm, das drei Zahlen von der Tastatur einliest und anschließend die\n",
"größte von ihnen ausgibt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"num1 = float(input(\"Erste Zahl:\"))\n",
"num2 = float(input(\"Zweite Zahl:\"))\n",
"num3 = float(input(\"Dritte Zahl:\"))\n",
"\n",
"maximum = num1 if num1 > num2 else num2\n",
"maximum = maximum if maximum > num3 else num3\n",
"print(maximum) \n",
"\n",
"\n",
"if num1 > num2:\n",
" if num1 > num3:\n",
" print(num1)\n",
" else:\n",
" print(num3)\n",
"else:\n",
" if num2 > num3:\n",
" print(num2)\n",
" else:\n",
" print(num3)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 2_\n",
"\n",
"Schreiben Sie ein Python-Programm, das zwei Zahlen von der Tastatur einliest. Anschließend soll\n",
"nachgefragt werden, ob die beiden Zahlen addiert, subtrahiert, mulitpliziert oder dividiert werden sollen. \n",
"Führen Sie die gewünschte Operation aus und geben Sie das Ergebnis aus. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"num1 = float(input(\"Erste Zahl:\"))\n",
"num2 = float(input(\"Zweite Zahl:\"))\n",
"\n",
"op = input(\"Was soll gemacht werden (+,-,*,/):\")\n",
"if op == \"+\":\n",
" erg = num1 + num2\n",
"elif op == \"-\":\n",
" erg = num1 - num2\n",
"elif op == \"*\":\n",
" erg = num1 * num2\n",
"elif op == \"/\":\n",
" erg = num1 / num2\n",
"else:\n",
" erg = None\n",
" \n",
"print(f\"Unbekannter Operator <{op}>.\") if erg is None else print(f\"{num1} {op} {num2} = {erg}\")"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 260
- 0
02kapitel/022 Schleifen.ipynb View File

@@ -0,0 +1,260 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 2: Kontrollfluss"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.6 Schleife \n",
"\n",
"Häufig möchte man eine oder mehrere Anweisungen wiederholen, solange eine *Laufbedingung* erfüllt ist.\n",
"Ein solcher Kontrollfluss wird auch als *Schleife* bezeichnet. Sofern die Bedingung geprüft wird, bevor\n",
"die zu wiederholende Anweisung ausgeführt wird, spricht man von einer *kopfgesteuerten Schleife*.\n",
"Wird erst nach der Ausführung überprüft, ob eine Wiederholung stattfinden soll, so handelt es\n",
"sich um eine *fußgesteuerte Schleife*.\n",
"\n",
"![kopfgesteuerte Schleife](../img/SchleifeKopf.png \"Kopfgesteuerte Schleife\") "
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Mit dem Schlüsselwort <code>while</code> wird in Python eine kopfgesteuerte Schleife begonnen. Die Laufbedingung\n",
"folgt unmittelbar danach abgeschlossen mit einem Doppelpunkt. Die zu wiederholenden Anweisungen werden\n",
"wieder als eingerückter Block angegeben. Diesen Block nennt man auch *Schleifenrumpf*."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 1\n",
"\n",
"while a < 10:\n",
" print(a)\n",
" a = a + 1\n",
" \n",
"print(\"Fertig\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Eine Schleife kann jederzeit abgebrochen werden, wenn im Schleifenrumpf das Schlüsselwort <code>break</code> \n",
"auftaucht. Die Schleife wird dann sofort verlassen und die Ausführung mit dem nächsten Befehl nach dem Schleifenrumpf\n",
"fortgesetzt. Aufgrund der besseren Lesbarkeit sollte <code>break</code> eher sparsam eingesetzt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 1\n",
"\n",
"while a < 10:\n",
" print(a)\n",
" if a == 5:\n",
" break\n",
" a = a + 1\n",
"\n",
"print(\"Fertig\", a)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"In Python gibt es zunächst einmal nur kopfgesteuerte Schleifen, jedoch können fußgesteuerte Schleifen\n",
"recht einfach nachgebaut werden. Auch hier gilt wieder der Verweis auf eine bessere Lesbarkeit durch einen sparsamen Einsatz von <code>break</code>. Endlosschleifen sollten generell vermieden werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 1\n",
"\n",
"while True:\n",
" print(a)\n",
" a = a + 1\n",
" if a >= 6:\n",
" break\n",
"\n",
"print(\"Fertig\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Neben dem vollständigen Schleifenabbruch mit <code>break</code> kann mittels <code>continue</code> auch nur der \n",
"aktuelle Schleifendurchlauf abgebrochen werden. Aufgrund besserer Lesbarkeit sollte man sich aber immer die Frage stellen, ob sich ein <code>continue</code> nicht auch vermeiden lässt, z.B. durch entsprechende bedingte Ausführungen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 0\n",
"\n",
"while a < 10:\n",
" a = a + 1\n",
" if a % 2 != 0:\n",
" continue\n",
" print(a)\n",
"\n",
"print(\"Fertig\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Eine eher selten anzutreffende Variante ist die Verwendung eines optionalen <code>else</code> nach einer \n",
"<code>while</code>-Schleife. Der <code>else</code>-Zweig wird dann ausgeführt, wenn die Laufbedingung \n",
"nicht erfüllt ist *und* die Schleife nicht mit <code>break</code> verlassen wird. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = 5\n",
"\n",
"while a > 0:\n",
" print(a)\n",
" if a < -1:\n",
" break\n",
" a = a - 1\n",
"else:\n",
" print(\"Else!\")\n",
"\n",
"print(\"Fertig\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Python bietet zudem eine <code>for</code>-Schleife an, mit der speziell Listen bzw. iterierbare Konstrukte durchlaufen werden können. Wir werden diese im Zusammenhang mit Listen in einem späteren Kapitel genauer betrachten."
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 146
- 0
02kapitel/022a Uebung.ipynb View File

@@ -0,0 +1,146 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 1_\n",
"\n",
"Schreiben Sie ein Python-Programm, das zunächst eine Zahl von der Tastatur einliest,\n",
"anschließend mittels einer <code>while</code>-Schleife die Binärdarstellung\n",
"der Zahl ermittelt und diese ausgibt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"num = int(input(\"Zahl:\"))\n",
"\n",
"ergebnis = \"\"\n",
"while num > 0:\n",
" ergebnis = str(num % 2) + ergebnis\n",
" num = num // 2\n",
"\n",
"print(ergebnis)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 2_\n",
"\n",
"Schreiben Sie ein Python-Programm, das einen String bestehend aus <code>0</code> und <code>1</code> \n",
"von der Tastatur einliest, diesen als Binärzahl betrachtet und den dezimalen Wert ausgibt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"binaer = input(\"Binärzahl:\")\n",
"\n",
"# Lösung 1\n",
"ergebnis = 0\n",
"index = 0\n",
"while index < len(binaer):\n",
" ergebnis = ergebnis * 2\n",
" if binaer[index] == \"1\":\n",
" ergebnis = ergebnis + 1\n",
" index = index + 1\n",
"\n",
"# Lösung 2 \n",
"index = len(binaer)-1\n",
"ergebnis2 = 0\n",
"while index >=0:\n",
" stellenwert = len(binaer) - 1 - index\n",
" ergebnis2 = ergebnis2 + int(binaer[index])* (2 ** stellenwert ) \n",
" index = index - 1\n",
" \n",
"print(ergebnis)\n",
"print(ergebnis2)"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 195
- 0
02kapitel/023 Berechenbarkeit.ipynb View File

@@ -0,0 +1,195 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 2: Kontrollfluss\n",
"\n",
"### 2.7 Algorithmus\n",
"\n",
"Ein Algorithmus ist\n",
"\n",
"- eine *endliche Folge* von Regeln (*Finitheit*),\n",
"- nach denen sich nach *endlich vielen* (*Terminiertheit*),\n",
"- *eindeutig festgelegten* Schritten (*Determiniertheit*)\n",
"- die Lösung einer *Klasse von Problemen* ergibt (*Allgemeingültigkeit*)."
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Für die Darstellung eines Algorithmus kann können Visualisierungen verwendet werden. Nachfolgend \n",
"ist der Euklid'sche Algorithmus zur Berechnung des größten gemeinsamen Teilers (ggT) zweier Zahlen\n",
"als UML Aktivitätsdiagramm dargestellt: \n",
"\n",
"![Aktivitätsdiagramm GGT](../img/ggtuml.png \"GGT-Berechnung als Aktivitätsdiagramm\") "
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Der gleiche Algorithmus kann aber auch in Form eines Struktogramms visualisiert werden:\n",
"\n",
"![Aktivitätsdiagramm GGT](../img/ggtstruct.png \"GGT-Berechnung als Aktivitätsdiagramm\") "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Sehr gebräuchlich ist mittlerweile die Verwendung von Pseudocode. Es gibt viele Varianten für Pseudocode. Meist einigt man sich innerhalb einer Organisation auf eine einheitliche Syntax. Zudem gibt es in der Literatur viele Syntax-Vorschläge.\n",
"\n",
" Eingabe a, b\n",
" Falls a=0\n",
" Ausgabe a\n",
" Sonst\n",
" Solange b != 0\n",
" Falls a > b\n",
" a := a - b\n",
" Sonst\n",
" b := b - a\n",
" Ausgabe a"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Lösungsidee für ein Problem wird also unabhängig von einer Programmiersprache in\n",
"Form eines Algorithmus entwickelt. Die anschließende Formulierung eines Algorithmus in einer \n",
"Programmiersprache ist dann eine relativ einfache Übertragungsaufgabe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"a = int(input(\"a eingeben:\"))\n",
"b = int(input(\"b eingeben:\"))\n",
"\n",
"if a==0:\n",
" print(b)\n",
"else:\n",
" while b>0:\n",
" if a>b:\n",
" a=a-b\n",
" else:\n",
" b=b-a\n",
" print(a)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 2.8 Berechenbarkeit\n",
"\n",
"In der *theoretischen Informatik* wurden verschiedene \n",
"Modelle für die Beschreibung von Rechenmaschinen entwickelt. Es wurde bewiesen,\n",
"dass viele Modelle gleichwertig zur \n",
"sog. __[Turing-Maschine](https://de.wikipedia.org/wiki/Turingmaschine)__ sind, \n",
"d.h. mit diesen Modellen die gleichen Berechnungen ausgeführt werden können bzw. es keine \n",
"Berechnungsvorschrift gibt, die nur mit einem Modell, nicht aber mit dem anderen ausführbar ist.\n",
"\n",
"Zudem geht man davon aus, dass alle relevanten Algorithmen zur Klasse der von Turing-Maschinen berechenbaren \n",
"Algorithmen gehören (__[Churchsche These](https://de.wikipedia.org/wiki/Church-Turing-These)__).\n",
"\n",
"Mit den Bausteinen *Sequenz*, *Bedingte Anweisung* und *Schleife* sowie *Variablenzuweisung* liefert Python ein Modell, \n",
"von dem bewiesen wurde, dass es äquivalent zur Turing-Maschine ist. Oder anders ausgedrückt: alle weiteren \n",
"Sprachelemente dienen lediglich der besseren Verständlichkeit und leichteren Wartbarkeit von Python-Code,\n",
"erweitern aber nicht die Möglichkeiten der Berechenbarkeit.\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 22
- 0
02kapitel/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%;
}

+ 607
- 0
03kapitel/031 Listen.ipynb View File

@@ -0,0 +1,607 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 3: Listen und Tupel\n",
"\n",
"Die bisher betrachteten Datentypen umfassen stets genau einen Wert. Möchte man mehrere Werte \n",
"mit den bekannten Datentypen verwalten, müsste für jeden Wert eine Variable verwendet werden.\n",
"Man erkennt schnell, dass dies nicht praktikabel ist, da oft sehr viele Werte verarbeitet werden\n",
"müssen und gelegentlich die genaue Anzahl vorab nicht bekannt ist."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.1 Liste \n",
"Python bietet mit *Listen* einen Datentyp, der\n",
"* mehrere Werte\n",
"* auch unterschiedlichen Typs\n",
"* in einer festen Reihenfolge\n",
"\n",
"beinhalten kann. Listen können zudem entstehen, dynamisch wachsen, schrumpfen und aufgelöst werden, \n",
"ohne dass explizit Speicherplatz angefordert oder freigegeben werden müsste. Die Speicherverwaltung übernimmt \n",
"vollständig der Python-Interpreter. Listen-Literale werden in Python mit eckigen Klammern begrenzt\n",
"und die Elemente mit Kommas getrennt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"[3, \"Hallo\", True, None]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Natürlich können Listen - wie jeder andere Datentyp - auch Variablen zugewiesen und Funktionen\n",
"übergeben werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = [4, 5, 6]\n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Listen-Literale werden im Code häufig erweitert, verkürzt oder hinsichtlich der Reihenfolge verändert. Um dies \n",
"möglichst einfach zu gestalten, können die Listeneinträge über mehrere Zeilen verteilt werden. \n",
"Ein Komma <code>,</code> nach dem letzten Eintrag ist optional erlaubt, so dass bei Anpassung nicht Syntaxfehler\n",
"durch fehlende oder überzählige Kommata entstehen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = [ \"Erster Eintrag\",\n",
" \"Zweiter Eintrag\",\n",
" # \"Letzter (?) Eintrag\",\n",
" # \"Noch einer\",\n",
" ]\n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.2 Operationen \n",
"\n",
"Auf die einzelnen Elemente einer Liste kann mithilfe eines Index zugegriffen werden. Dabei \n",
"besitzt das erste Element der Liste den Index <code>0</code>."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2, 3]\n",
"print(liste[2])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Der Zugriff funktioniert nicht nur lesend, sondern auch schreibend."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2, 3]\n",
"liste[1] = 5\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Erwartungsgemäß führt der Zugriff mit einem zu großen Index zu einem Laufzeitfehler."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2, 3]\n",
"print(liste[10])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Negative Zahlen werden als Zugriffsindex vom Ende der Liste interpretiert, d.h. <code>-1</code> greift auf \n",
"das letzte Listenelement zu, <code>-2</code> auf das vorletzte usw."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2, 3]\n",
"print(liste[-1])\n",
"print(liste[-2])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Für das Aneinanderhängen zweier Listen kann die Infix-Operator <code>+</code> verwendet werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"[1, 2] + [3, 4]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Dabei werden vorhandene Elemente nicht abgeglichen, d.h. ggf. sind gleiche Elemente mehrfach enthalten."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"[1, 2] + [2]\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Für das Anhängen einzelner *Elemente* an eine Liste steht die <code>append</code> in Dot-Notation zur Verfügung."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2]\n",
"liste.append(\"Wert\")\n",
"print(liste)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Mittels <code>remove</code> kann ein Element auch wieder aus einer Liste entfernt werden.\n",
"Die nachfolgenden Elemente rücken auf, d.h. es verbleibt keine Lücke in der Liste."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, \"Zwei\", 3, \"Zwei\"]\n",
"liste.remove(\"Zwei\")\n",
"print(liste)\n",
"liste.remove(\"Zwei\")\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ist das zu löschende Element mehrfach enthalten, wird nur das erste Auftreten entfernt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2, 3, 2, 4]\n",
"liste.remove(2)\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Möchte man ein Element an einer bestimmten Stelle einer Liste einfügen, so leistet dies <code>insert</code>. \n",
"Der erste Parameter ist dabei der Index, an dem das Element eingefügt werden soll, der zweite Parameter\n",
"das einzufügende Element."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'C']\n",
"liste.insert(1, 'B')\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Anzahl des Auftretens eines bestimmten Elements kann mittels <code>count</code> ermittelt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'C', 'A', 'B']\n",
"liste.count('Z')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Die Position eines Elements in einer Liste liefert <code>index</code>."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'C', 'A', 'B']\n",
"liste.index('B')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ob ein Element überhaupt in einer Liste enthalten ist, kann mit dem Infix-Operator <code>in</code>\n",
"festgestellt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'C', 'A', 'B']\n",
"'P' in liste"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.3 Built-In-Funktionen und Listen\n",
"\n",
"Wird der Built-In-Funktion <code>len</code> eine Liste als Parameter übergeben, so ist das \n",
"Ergebnis die Anzahl der in der Liste enthaltenen Elemente."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'B', 'C']\n",
"len(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Built-In-Funktionen <code>min</code> und <code>max</code> ergeben das Minimum bzw. das Maximum der Liste."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['AA', 'B', 'a']\n",
"print(min(liste))\n",
"print(max(liste))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Natürlich müssen dazu die Elemente der Liste vergleichbar sein, d.h. eine Ordnungsrelation definiert sein."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 2, 'C']\n",
"print(min(liste))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Und schließlich: mit der Built-In Funktion <code>del</code> können Elemente einer Liste \n",
"mit Angabe ihrer Position gelöscht werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 2, 'C', 2]\n",
"del(liste[1], liste[2])\n",
"print(liste)\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 289
- 0
03kapitel/032 Traversieren.ipynb View File

@@ -0,0 +1,289 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 3: Listen und Tupel"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.4 Traversieren \n",
"\n",
"Häufig müssen Listen von vorne bis hinten durchlaufen werden, um mit den Elementen der Liste Berechnungen \n",
"durchzuführen oder Aktionen auszuführen. Dieses Traversieren der Liste kann bereits mit den bekannten \n",
"Sprachmitteln erledigt werden:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [3, 7, 4, 9]\n",
"index = 0\n",
"while index < len(liste):\n",
" print(liste[index])\n",
" index = index + 1"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Allerdings bietet Python eine eigene Schleifenkonstruktion für das Traversieren einer Sequenz (wie z.B. einer Liste).\n",
"Dabei ist nach dem Schlüsselwort <code>for</code> eine Variable anzugeben (hier <code>element</code> genannt),\n",
"die sukzessive alle Werte annimmt, die in der Liste enthalten sind. Eine Variable für den Index ist nicht mehr nötig.\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [3, 7, 4, 9]\n",
"for element in liste:\n",
" print(element)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Neben Listen können z.B. auch Strings mit Hilfe von <code>for</code> durchlaufen werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"s = \"Hello!\"\n",
"for char in s:\n",
" print(char)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die bekannten Schlüsselworte <code>break</code> und <code>continue</code> können auch bei einer \n",
"<code>for</code>-Schleife verwendet werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"text = input(\"Text:\")\n",
"vokale = ['A', 'E', 'O', 'U', 'I', 'a', 'e', 'o', 'u', 'i']\n",
"ergebnis = \"\"\n",
"\n",
"for char in text:\n",
" if char in vokale:\n",
" continue\n",
" ergebnis = ergebnis + char\n",
"\n",
"print(ergebnis)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.5 Range\n",
"\n",
"Möchte man mit einer <code>for</code>-Schleife über einen Zahlenbereich iterieren,\n",
"so kann mit Hilfe der Built-In-Funktion <code>range</code> eine passende Sequenz \n",
"erzeugt werden. Der Zahlenbereich startet - sofern nichts anderes angegeben wurde - bei 0\n",
"und endet so, dass die übergebene Grenze gerade nicht erreicht wird."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"bereich = range(1000)\n",
"print(bereich)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ein *Range* ist keine Liste, da man sich den Speicherplatz für viele einzelne \n",
"Elemente sparen kann, wenn man die Unter- und Obergrenze kennt. Möchte man eine\n",
"Sequenz wie *Range* doch in eine Liste umwandeln, so kann die Built-In-Funktion \n",
"<code>list</code> verwendet werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"bereich = range(50)\n",
"print(list(bereich))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ein *Range* kann auch mit Angabe der Untergrenze, der Obergrenze und der Sprungweite angelegt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"unten = 10\n",
"oben = 20\n",
"sprung = 2\n",
"bereich = range(unten, oben, sprung)\n",
"print(list(bereich))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ein *Range* kann von einer <code>for</code>-Schleife durchlaufen werden, ohne dass er zuvor in eine \n",
"Liste umgewandelt wird."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"for index in range(5):\n",
" print(index)"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 304
- 0
03kapitel/033 Tupel.ipynb View File

@@ -0,0 +1,304 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 3: Listen und Tupel"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.6 Tupel\n",
"\n",
"*Tupel* sind wie Listen ein Datentyp, mit dem *mehrere Werte* verwaltet werden können. Aber anders als Listen\n",
"kann ein einmal erzeugtes Tupel nicht verändert werden, d.h.\n",
"\n",
"* es können keine weiteren Werte hinzugefügt werden\n",
"* es können keine Werte aus dem Tupel entfernt werden\n",
"* es kann kein Wert innerhalb des Tupels verändert werden\n",
"\n",
"Aufgrund dieser Einschränkungen werden Tupel i.d.R. schneller verarbeitet als Listen.\n",
"\n",
"Tupel werden durch runde Klammern begrenzt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"tupel = (3, 7, 4, 9)\n",
"print(len(tupel))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Lesender Zugriff ist wiederum mit einem Index möglich."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"tupel = (3, 7, 4, 9)\n",
"print(tupel[2])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Schreibender Zugriff wird aufgrund des Read-Only-Charakters von Tupeln verwehrt. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"tupel = (3, 7, 4, 9)\n",
"tupel[2] = 3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Elemente eines Tupels können mit einem einzigen Befehl separaten Variablen zugewiesen werden. Die Anzahl der\n",
"aufnehmenden Variablen muss aber exakt der Länge des Tupels entsprechen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"tupel = (3, 7, 4, 9)\n",
"e1, e2, e3, e4 = tupel\n",
"print(e4)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Wie die Liste ist auch ein Tupel eine Sequenz, die mit Hilfe der <code>for</code>-Schleife\n",
"durchlaufen werden kann."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"for zahl in (3, 7, 4, 9):\n",
" print(zahl)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Listen und Tupel können verschachtelt werden, d.h. eine Liste kann wiederum Listen und/oder Tupel enthalten bzw. \n",
"die Elemenente eines Tupels können auch Listen oder Tupel sein."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"tupel = ((3, 7), (4, 9))\n",
"print(len(tupel))\n",
"print(tupel[1][0])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"ergebnis = []\n",
"for zeilennummer in range(1, 6):\n",
" neue_zeile = []\n",
" for index in range(zeilennummer):\n",
" neue_zeile.append(zeilennummer)\n",
" ergebnis.append(neue_zeile)\n",
"print(ergebnis)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Gelegentlich möchte man eine Liste \"durchnummerieren\", d.h. neben den eigentlichen Listenelementen\n",
"auch den Index des Listenelements ausweisen:\n",
"\n",
"<code>['A', 'B', 'C']</code> -> <code>[(0, 'A'), (1, 'B'), (2, 'C')]</code>\n",
"\n",
"Genau dieses leistet die Built-In-Funktion <code>enumerate</code>, die aus einer Liste eine Sequenz \n",
"von derartigen Tupeln generiert. Und wie bei <code>range</code> muss das Ergebnis erst noch in eine Liste\n",
"umgewandelt werden, um wirklich das obige Verhalten nachzubilden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(list(enumerate(['A', 'B', 'C'])))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Ein häufiger Anwendungsfall einer <code>enumerate</code>-Sequenz ist die Verwendung in einer \n",
"<code>for</code>-Schleife. Die entstehenden Tupel können unmittelbar in zwei einzelne Variablen \n",
"übernommen werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [3, 7, 4, 9]\n",
"for index, zahl in enumerate(liste):\n",
" print(f\"{index+1}. Zahl ist {zahl}\")"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 360
- 0
03kapitel/034 Comprehensions.ipynb View File

@@ -0,0 +1,360 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 3: Listen und Tupel\n",
"\n",
"### 3.7 List Comprehensions\n",
"\n",
"Mit Hilfe von *List Comprehensions* können Listen basierend auf bestehenden Listen oder Sequenzen erzeugt werden. \n",
"Dazu wird die bestehende Sequenz mit einer <code>for</code>-Schleife durchlaufen und die einzelnen Elemente zu einer\n",
"neuen Liste zusammengefasst. Die Syntax dazu sieht so aus:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"alte_liste = [1, 2, 3]\n",
"neue_liste = [x for x in alte_liste]\n",
"print(neue_liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Natürlich sind auch Funktionsaufrufe möglich."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"alte_liste = ['Hello', 'World!']\n",
"neue_liste = [len(word) for word in alte_liste]\n",
"print(neue_liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Durch das Ergänzen eines <code>if</code> können Elemente der ursprünglichen Liste bzw. Sequenz \n",
"ausgelassen werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"neue_liste = [x for x in range(20) if x%2 == 0 ]\n",
"print(neue_liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.8 Listen und Strings\n",
"\n",
"Gelegentlich möchte man einen String in einzelne Wörter zerlegen und diese als\n",
"Liste zurückgeliefert bekommen. Hierzu dient die Operation <code>split</code>, die \n",
"in Dot-Notation im Datentyp String enthalten ist."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"text =\"Software Entwicklung macht Spaß\"\n",
"liste = text.split()\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Normalerweise verwendet <code>split</code> ein *Whitespace*-Zeichen (d.h. Leerzeichen, Tabulator, neue Zeile,...)\n",
"als Trennzeichen für die Zerlegung. Es kann jedoch auch eine andere Zeichenkette festgelegt werden. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"text = \"der, die, das, wieso, weshalb, warum\"\n",
"liste = text.split(\", \")\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Hinweis: Mehrere unterschiedliche Trennzeichen sind mit der Standard-<code>split</code>-Funktion nicht realisierbar. \n",
"Dazu benötigt man *reguläre Ausdrücke*, die zu einem späteren Zeitpunkt eingeführt werden."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Soll umgekehrt aus einer Liste von einzelnen Wörtern ein String zusammengesetzt werden, kann die \n",
"Funktion <code>join</code> genutzt werden. Sie wird in der Dot-Notation mit einem String verwendet,\n",
"der die einzufügenden Trennzeichen enthält."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [\"das\", \"ist\", \"das\", \"Haus\", \"vom\", \"Nikolaus\"]\n",
"text = \"\".join(liste)\n",
"print(text)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 3.9 Slicing\n",
"\n",
"Viele Sequenztypen in Python (bisher bekannt: Listen, Tupel, Strings, Ranges) können mittels *Slicing* \n",
"zurechtgeschnitten werden. Dazu werden der Index des ersten zu berücksichtigenden Elements und der\n",
"Index des ersten nicht mehr zu berücksichtigenden Elements getrennt durch einen Doppelpunkt angegeben."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'B', 'C', 'D', 'E']\n",
"middle = liste[1:4]\n",
"print(middle)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Wird einer der Indexwerte weggelassen, so bedeutet dies, dass der Ausschnitt am Anfang beginnt bzw. bis\n",
"zum Ende reicht."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'B', 'C', 'D', 'E']\n",
"anfang = liste[:3]\n",
"print(anfang)\n",
"ende = liste[2:]\n",
"print(ende)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Natürlich funktionieren auch negative Indizes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = ['A', 'B', 'C', 'D', 'E']\n",
"middle = liste[1:-1]\n",
"print(middle)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Und schließlich kann durch Angabe eines dritten Parameters eine Schrittweite vorgegeben werden. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"sequenz = range(20)\n",
"gerade = sequenz[0::2]\n",
"print(list(gerade))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Auch negative Schrittweiten sind zulässig. Die Sequenz wird dann von hinten durchlaufen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"text = \"TH Nürnberg\"\n",
"print(text[::-1])\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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 152
- 0
03kapitel/034a Uebung.ipynb View File

@@ -0,0 +1,152 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 1_\n",
"\n",
"Schreiben Sie ein Python-Programm, das einen Text von der Tastatur einliest und anschließend\n",
"die Anfangsbuchstaben aller Wörter im Text ausgibt. Dabei soll jeder Buchstabe nur einmal vorkommen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"text = input(\"Text:\")\n",
"\n",
"worte = text.split()\n",
"startchars = [wort[0] for wort in worte ]\n",
"\n",
"for index, current in enumerate(startchars):\n",
" if current not in startchars[:index]:\n",
" print(current)"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 2_\n",
"\n",
"Gegeben sind zwei Listen gleicher Länge mit Artikeln und zugehörgen Preisen, z.B.:\n",
"\n",
"<code>artikel = [ \"Klopapier\", \"Maske\", \"Desinfektionsmittel\" ]</code>\n",
"\n",
"<code>preis = [ 3.5, 2.25, 7.4 ]</code>\n",
"\n",
"Schreiben Sie ein Python-Programm, das eine Ergebnisliste berechnet, in der Artikel und Preis zu Tupeln \n",
"zusammengefasst sind:\n",
"\n",
"<code>ergebnis = [('Klopapier', 3.5), ('Maske', 2.25), ('Desinfektionsmittel', 7.4)] </code>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"artikel = [ \"Klopapier\", \"Maske\", \"Desinfektionsmittel\" ]\n",
"preis = [ 3.50, 2.25, 7.4 ]\n",
"\n",
"ergebnis = [(a, preis[index]) for index, a in enumerate(artikel)]\n",
"print(ergebnis)\n",
"\n",
"########\n",
"ergebnis2 = list(zip(artikel, preis))\n",
"print(ergebnis2)\n",
"\n",
"########\n",
"index = 0\n",
"ergebnis3 = []\n",
"while index < len(artikel):\n",
" ergebnis3.append((artikel[index], preis[index]))\n",
" index = index + 1\n",
"print(ergebnis3)"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 22
- 0
03kapitel/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%;
}

+ 419
- 0
04kapitel/041 Funktionen.ipynb View File

@@ -0,0 +1,419 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 4: Funktionen\n",
"\n",
"Bislang wurden lediglich Operationen verwendet, die bereits im Sprachumfang von Python enthalten sind, wie \n",
"z.B. Built-In Funktionen, Infix-Operatoren oder Funktionen eines gegebenen Datentyps in Dot-Notation. \n",
"In diesem Kapitel wird vorgestellt, wie eigene Funktionen definiert und genutzt werden können."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.1 Funktionsdefinition und -aufruf\n",
"Die Definition einer Funktion wird eingeleitet durch das Schlüsselwort <code>def</code> gefolgt vom \n",
"Namen der Funktion, einer Parameterliste und einem Doppelpunkt. Danach werden die Befehle der Funktion, \n",
"auch *Funktionsrumpf* genannt, eingerückt angegeben."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def name_der_funktion():\n",
" print(1)\n",
" print(2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Allein durch die Definition der Funktion wird noch kein Code aus dem Funktionsrumpf ausgeführt. Dies geschieht \n",
"erst, indem die Funktion aufgerufen wird. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(name_der_funktion())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Man sieht in diesem Beispiel auch, dass die Zellen eines Jupyter-Notebooks nicht voneinander unabhängig sind,\n",
"sondern sich einen Namensraum teilen. Die in der ersten Zelle definierte Funktion ist nach ihrer Ausführung \n",
"anschließend in der zweiten Zelle bekannt. Das gilt für alle Vereinbarungen wie z.B. auch Variablen."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.2 Rückgabewerte\n",
"\n",
"Wie schon früher einmal ausgeführt liefert jede Operation in Python einen Wert zurück. Bei der oben defnierten\n",
"Funktion ist dies <code>None</code>, weil keine anderen Anweisungen gegeben wurden. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"print(name_der_funktion())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Soll die Funktion einen Rückgabewert besitzen, so ist dieser mit dem Schlüsselwort <code>return</code> \n",
"anzugeben."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def immer_drei():\n",
" return 3\n",
"\n",
"print(immer_drei())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Ausführung des Funktionsrumpfs wird mit einer <code>return</code>-Anweisung beendet. Sollte der Rumpf\n",
"danach weitere Anweisungen beitzen, werden diese nicht ausgeführt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def immer_drei():\n",
" if 3 < 4:\n",
" return 3\n",
" if 4 < 3:\n",
" return \"Hallo\"\n",
" print(\"Noch in der Funktion\")\n",
"\n",
"print(immer_drei())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Anders als in anderen Programmiersprachen ist der Datentyp des Rückgabewertes in Python nicht \n",
"festgelegt. Es kann also durchaus vorkommen, dass ein Kontrollflusszweig im Methodenrumpf einen\n",
"*String* zurückgibt, ein anderer einen *Integer*-Wert und wieder ein anderer nichts bzw. <code>None</code>."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Natürlich sind auch komplexere Rückgabetypen wie Listen oder Tupel zulässig. Tupel sind eine verbreitete\n",
"Möglichkeit, mehr als einen Wert zurückzugeben, was in anderen Programmiersprachen oft schwieriger \n",
"zu realisieren ist."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def immer_drei_ohne_fehler():\n",
" return (3, False)\n",
" \n",
" \n",
"ergebnis, fehler = immer_drei_ohne_fehler()\n",
"print(ergebnis)\n",
"print(fehler)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.3 Gültigkeitsbereich von Variablen\n",
"\n",
"Variablen \"entstehen\" in Python durch die Zuweisung eines Wertes. Findet diese Zuweisung \n",
"in einer Funktion statt, so entsteht eine *lokale Variable*, die nur in dieser Funktion bekannt ist.\n",
"Erfolgt die Zuweisung außerhalb einer Funktion, so ist es eine *globale Variable*, die in \n",
"allen Funktionen der jeweiligen Programmdatei bekannt ist. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"def test_variablen():\n",
" lokale_varibale = 1\n",
" print(lokale_varibale)\n",
" print(globale_variable)\n",
"\n",
"globale_variable = 2\n",
"test_variablen()\n",
"print(globale_variable)\n",
"print(lokale_varibale)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Wird in einer Funktion einer Variablen ein Wert zugewiesen, die bereits als globale Variable \n",
"initialisiert ist, so entsteht eine zusätzliche lokale Variable, die die globale Variable verdeckt. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def verdeckte_variablen():\n",
" a = 2\n",
" print(a)\n",
"\n",
"a = 1\n",
"verdeckte_variablen()\n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Eine Variable kann nicht \"verzögert\" zu einer lokalen Variable werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def keine_verzoegerte_lokale_variablen():\n",
" print(b)\n",
" b = 2\n",
" print(b)\n",
"\n",
"b = 1\n",
"keine_verzoegerte_lokale_variablen()\n",
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Soll das Verdecken einer globalen Variable verhindert werden, d.h. die Zuweisung eines\n",
"Wertes an eine globale Variable erlaubt werden, so muss diese Variable mit dem \n",
"Schlüsselwort <code>global</code> ausgewiesen werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def keine_verdeckte_variable():\n",
" global c\n",
" c = 2\n",
" print(c)\n",
"\n",
"c = 1\n",
"keine_verdeckte_variable()\n",
"print(c)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Sollte die mit <code>global</code> ausgewiesene Variable erstmals in der Funktion mit\n",
"einem Wert versorgt werden, so wird sie als *globale Variable* angelegt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def keine_verdeckte_variable():\n",
" global d\n",
" d = 2\n",
" print(d)\n",
"\n",
"keine_verdeckte_variable()\n",
"print(d)"
]
}
],
"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
}

+ 696
- 0
04kapitel/042 Parameter.ipynb View File

@@ -0,0 +1,696 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 4: Funktionen\n",
"\n",
"### 4.4 Funktionsparameter \n",
"\n",
"Globale Variablen sind keine gute Idee, um Werte in Funktionen verfügbar zu machen, da schnell der\n",
"Überblick verloren geht, welche Variable in welcher Funktion gelesen oder sogar geändert wird.\n",
"Auch würde ein solches Vorgehen erfordern, dass man funktionsübergreifend Variablennamen im \n",
"Blick behält, was ebenfalls bei komplexeren Aufgaben ein schwieriges Unterfangen ist."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Daher verwendet man besser *Funktionsparameter*, um Werte von der aufrufenden Programmstelle \n",
"in eine Funktion zu übergeben. Die erwarteten Parameter werden bei der Funktionsdefinition\n",
"und beim Funktionsaufruf zwischen den runden Klammern aufgeführt. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def drucke_addition(a, b):\n",
" print(a+b)\n",
"\n",
"drucke_addition(4, 7)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Natürlich können auch Werte aus Variablen beim Funktionsaufruf übergeben werden. \n",
"Dabei sind die Variablen- und Parameternamen völlig unabhängig. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def drucke_addition(a, b):\n",
" print(a+b)\n",
"\n",
"x=1\n",
"y=2\n",
"drucke_addition(x, y)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Um berechnete Werte aus einer Funktion an die Außenwelt unter Vermeidung von\n",
"globalen Variablen zurückzugeben, sollten Rückgabewerte benutzt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def tausche(a, b):\n",
" return (b, a)\n",
"\n",
"x=\"Erster\"\n",
"y=\"Zweiter\"\n",
"x, y = tausche(x, y) \n",
"print(x, y)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.5 Identität vs. Gleichheit\n",
"\n",
"In der Informatik wird zwischen *Identität* und *Gleichheit* unterschieden. Zwei \n",
"Variablen sind gleich, wenn sie den gleichen Wert enthalten. Dies wird typischerweise\n",
"durch das Doppel-Gleichheitszeichen <code>==</code> überprüft."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"x=5\n",
"y=5\n",
"if x == y:\n",
" print(\"Gleich!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Die Identität von zwei Variablen ist dann gegeben, wenn sie auf das gleiche Objekt im\n",
"Speicher verweisen. Überprüft wird dies in Python durch den Infix-Operator <code>is</code>. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"x=5\n",
"y=5\n",
"if x is y:\n",
" print(\"Identisch!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Außerdem kann mit der Built-In Funktion <code>id</code> eine Art *Speicheradresse* eines Werts \n",
"ermittelt werden, der bei identischen Werten gleich ist. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"x=\"Hello\"\n",
"y=\"Hello\"\n",
"\n",
"print(id(x))\n",
"print(id(y))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Bei Datentypen, deren Werte unveränderlich sind, können Identität und Gleichheit synonym verwendet werden. \n",
"In Python sind dies\n",
"\n",
"* Zahlen\n",
"* Strings\n",
"* <code>True</code> und <code>False</code>\n",
"* Tupel"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Variablen, die diese Art von Datentypen enthalten, ändern somit automatisch ihre Identität, wenn\n",
"sich ihr Wert ändert."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"x=17\n",
"print(id(x))\n",
"x = x + 1\n",
"print(id(x))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Bei veränderlichen Datentypen wie Listen ist es aber möglich, dass \n",
"sich ihr Wert ändert, ohne dass sie ihre Identität verlieren. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste = [1, 2, 3]\n",
"print(id(liste))\n",
"liste.append(4)\n",
"print(id(liste))\n",
"print(liste)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Werden Variablen an eine Funktion übergeben, so behalten sie im aufrufenden Kontext \n",
"in jedem Fall ihre Identität, auch wenn in der Funktion der Wert des zugeordneten Parameters\n",
"geändert wird.\n",
"\n",
"Bei unveränderlichen Datentypen, bei denen eine Wertänderung unweigerlich auch zu einer\n",
"neuen Identität führt, sind diese Parameter somit wie lokale Variable zu betrachten,\n",
"die vollständig vom aufrufenden Code entkoppelt sind."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"def tue_was(a):\n",
" print(f\"ID von a vor Änderung: {id(a)}\")\n",
" a = a + 1\n",
" print(a)\n",
" print(f\"ID von a nach Änderung: {id(a)}\")\n",
"\n",
"x=1\n",
"print(f\"ID von x vor Aufruf: {id(x)}\")\n",
"tue_was(x)\n",
"print(x)\n",
"print(f\"ID von x nach Aufruf: {id(x)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Bei veränderlichen Datentypen wie Listen können \n",
"Wertänderungen nach außen durchschlagen, weil \n",
"die Identität durch die Wertänderung nicht verändert wird."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def tue_was_mit_liste(a):\n",
" print(f\"ID von a vor Änderung: {id(a)}\")\n",
" a.append(3)\n",
" print(a)\n",
" print(f\"ID von a nach Änderung: {id(a)}\")\n",
"\n",
"x=[1, 2]\n",
"print(f\"ID von x vor Aufruf: {id(x)}\")\n",
"tue_was_mit_liste(x)\n",
"print(x)\n",
"print(f\"ID von x nach Aufruf: {id(x)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Daher liefern die Operatoren <code>==</code> und <code>is</code> bei Listen \n",
"ggf. auch abweichende Ergebnisse."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste1 = [1, 2, 3]\n",
"liste2 = [1, 2, 3]\n",
"\n",
"if liste1 == liste2:\n",
" print(\"Gleich!\")\n",
" \n",
"if liste1 is liste2:\n",
" print(\"Identisch!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"**Aber:** Zuweisungen und Parameterübergaben erhalten bei allen Datentypen (auch bei Listen) die Identität."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste1 = ['A', 'B', 'C']\n",
"liste2 = liste1\n",
"\n",
"print(id(liste1))\n",
"print(id(liste2))\n",
"\n",
"if liste1 == liste2:\n",
" print(\"Gleich!\")\n",
" \n",
"if liste1 is liste2:\n",
" print(\"Identisch!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Soll bei einer Zuweisung oder Parameterübergabe einer Liste die empfangende Seite eine eigene \n",
"Identität erhalten, so muss eine Kopie der Liste verwendet werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"liste1 = ['A', 'B', 'C']\n",
"liste2 = liste1.copy()\n",
"\n",
"print(id(liste1))\n",
"print(id(liste2))\n",
"\n",
"if liste1 == liste2:\n",
" print(\"Gleich!\")\n",
"\n",
"if liste1 is liste2:\n",
" print(\"Identisch!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.6 Benannte Parameter\n",
"\n",
"Normalerweise erfolgt das Mapping der Parameter beim Aufruf einer Funktion \n",
"aufgrund der Reihenfolge der Parameter. Die Variablennamen bzw. Parameternamen \n",
"haben keinen Einfluss."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = \"1\"\n",
"b = \"2\"\n",
"\n",
"def ausgabe(a, b):\n",
" print(a)\n",
" print(b)\n",
" \n",
"ausgabe(b, a) # Reihenfolge vertauscht"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Möchte man beim Aufruf die Reihenfolge der Parameter ändern, so können auch die\n",
"Parameternamen explizit aufgeführt werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = \"1\"\n",
"b = \"2\"\n",
"\n",
"def ausgabe(parm1, parm2):\n",
" print(parm1)\n",
" print(parm2)\n",
" \n",
"ausgabe(parm2=b, parm1=a) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Bei einem Funktionsaufruf können benannte und unbenannte Parameter gemischt werden,\n",
"jedoch dürfen nach einem benannten Parameter keine unbenannten mehr folgen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def viele_parameter(a, b, c, d, e, f):\n",
" print(a, b, c, d, e, f)\n",
"\n",
"viele_parameter(1, 2, 3, f=7, e=3, d=5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.7 Funktionen mit variabler Parameterzahl\n",
"\n",
"Normalerweise müssen bei einem Funktionsaufruf alle Parameter angegeben werden. \n",
"Werden bei der Funktionsdefinition Parameter jedoch mit *Default-Werten* versehen,\n",
"so können diese beim Aufruf ausgelassen werden. In der Funktion steht dann \n",
"der Default-Wert zur Verfügung."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def default_parameter(a, b=1, c=True):\n",
" return a+b if c else a*b\n",
"\n",
"print(default_parameter(5))\n",
"print(default_parameter(5, c=False))\n",
"print(default_parameter(5, 2))\n",
"print(default_parameter(4, 4, False))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Noch flexibler ist die Verwendung eines <code>*</code> vor den Parameternamen. Dadurch werden \n",
"beliebig viele Parameter als Tupel an die Funktion übergeben. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def ausgabe_tupel(*args):\n",
" for parm in args:\n",
" print(parm)\n",
" \n",
"ausgabe_tupel(1, 'A', 3.14) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Dieser besondere Parameter kann mit weiteren Parametern kombiniert werden, muss aber als \n",
"letzter (unbenannter) Parameter in der Liste stehen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def ausgabe_parms_und_tupel(a, b, *args):\n",
" if a > b:\n",
" print(\"Größer!\")\n",
" for parm in args:\n",
" print(parm)\n",
" \n",
"ausgabe_parms_und_tupel(4, 3, 1, 'A', 3.14) "
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 153
- 0
04kapitel/042a Uebung.ipynb View File

@@ -0,0 +1,153 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"pycharm": {
"name": "#%% md\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 1_\n",
"\n",
"Schreiben Sie eine Funktion <code>schnittmenge</code>, die zwei Listen als Parameter erwartet\n",
"und eine Liste zurückgibt, die nur die Elemente beinhaltet, die in beiden übergebenen Listen enthalten waren."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Todo: Hier die Funktion anlegen\n",
"print(schnittmenge([1, 2, 3, 10], [3, 4, 1]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
},
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"def schnittmenge(liste1, liste2):\n",
" ergebnis = []\n",
" for element in liste2:\n",
" if element in liste1:\n",
" ergebnis.append(element)\n",
" return ergebnis\n",
"\n",
"print(schnittmenge([1, 2, 3, 10], [3, 4, 1]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"_Aufgabe 2_\n",
"\n",
"Schreiben Sie eine Funktion <code>pascal</code>, der eine Liste <code>z</code> von Integer-Zahlen \n",
"übergeben wird. Sei <code>n</code> die Länge dieser Liste. \n",
"Das Ergebnis soll eine neue Liste sein mit folgenden Einträgen\n",
"\n",
"Falls <code>n == 0</code>:\n",
"\n",
"&nbsp;<code>[ 1 ]</code>\n",
"\n",
"Falls <code>n == 1</code>:\n",
"\n",
"&nbsp;<code>[ 1 , 1 ]</code>\n",
"\n",
"Sonst:\n",
"\n",
"&nbsp;<code>[ 1 , z[0]+z[1] , z[1]+z[2] , ... , z[n-2]+z[n-1] , 1 ]</code>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"# Todo: Hier die Funktion anlegen\n",
"\n",
"print(pascal([]))\n",
"print(pascal([5]))\n",
"print(pascal([5, 2, 7, 3]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"def pascal(z):\n",
" erg = [1]\n",
" erg.extend([a+b for a, b in zip(z[:-1], z[1:])])\n",
" if len(z) > 0:\n",
" erg.append(1)\n",
" return erg\n",
"\n",
"print(pascal([]))\n",
"print(pascal([5]))\n",
"print(pascal([5, 2, 7, 3]))"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 217
- 0
04kapitel/043 Lambda.ipynb View File

@@ -0,0 +1,217 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Software Entwicklung \n",
"\n",
"## Kapitel 4: Funktionen"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.8 Funktionen als Datentyp \n",
"\n",
"In Python werden Funktionen als *first class object* behandelt, d.h. sie sind ein\n",
"vollwertiger Datentyp, dessen Werte Variablen zugewiesen oder als Parameter übergeben\n",
"werden können. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def quadrat(x):\n",
" return x*x\n",
"\n",
"variable = quadrat\n",
"print(type(variable))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Mit einer Variablen, die als Wert eine Funktion enthält, verfügt man quasi über einen\n",
"zweiten Alias-Namen für die Funktion. Der Aufruf der Funktion ist auch mittels dieses Alias möglich."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def quadrat(x):\n",
" return x*x\n",
"\n",
"zweiter_name = quadrat\n",
"print(zweiter_name(5))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Eine interessante Anwendung ist die Übergabe von Funktionen als Parameter an andere Funktionen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def drucke_1():\n",
" print(\"1\")\n",
"\n",
"def drucke_2():\n",
" print(\"2\")\n",
"\n",
"def tue_das_eine_und_x_mal_das_andere(f1, x, f2):\n",
" f1()\n",
" for _ in range(x):\n",
" f2()\n",
" \n",
"tue_das_eine_und_x_mal_das_andere(drucke_1, 4, drucke_2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### 4.9 Lambda-Funktionen\n",
"\n",
"Kurze Funktionen können als sog. *Lambda-Funktionen* ohne Funktionsnamen\n",
"definiert werden. *Lambda-Funktionen* bestehen nur aus einer einzigen Operation, deren Ergebnis ohne\n",
"<code>return</code> zurückgegeben wird. Die Parameterliste wird nicht eingeklammert; der aus\n",
"nur einem Befehl bestehende Funktionsrumpf folgt unmittelbar nach einem Doppelpunkt.\n",
"\n",
"<code>lambda < Parameterliste > : < Befehl > </code>\n",
"\n",
"anstelle von\n",
"\n",
"<code>def < Funktionsname > ( < Parameterliste > ) : <br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp; return < Befehl > </code>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
},
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"quadrat = lambda x : x*x\n",
"\n",
"print(quadrat(3))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Diese kompakte Form der Funktionsdefinition ist insbesondere bei der Übergabe der\n",
"Funktion als Parameter beliebt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"is_executing": false,
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def foreach(f, *args):\n",
" result = []\n",
" for element in args:\n",
" result.append(f(element))\n",
" return result\n",
"\n",
"foreach(lambda x: x*x+1, 1, 2, 3)"
]
}
],
"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"
},
"pycharm": {
"stem_cell": {
"cell_type": "raw",
"metadata": {
"collapsed": false
},
"source": []
}
}
},
"nbformat": 4,
"nbformat_minor": 1
}

+ 22
- 0
04kapitel/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%;
}

+ 6
- 0
code/annotations.py View File

@@ -0,0 +1,6 @@


ganze_zahl : int
ganze_zahl = "z"

print("Hello World")

+ 57
- 0
code/awsd.py View File

@@ -0,0 +1,57 @@
import sys
import socket
import os

def read_char():
import sys, termios, tty
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch


def read_view(f):
view = f.readline()
if not view:
return
for x in range(2, len(view)):
line = f.readline()
if not line:
return
view += line
return view


def main(host='localhost', port=62688):
s = socket.socket()
s.connect((host, port))
f = s.makefile()

commands = {'w':'^', 'a':'<', 's':'v', 'd':'>', 'W':'^', 'A':'<', 'S':'v', 'D':'>' }


while True:
try:
view = read_view(f)
if not view:
break
os.system('clear')
sys.stdout.write(view)
cmd = read_char()
if cmd == 'q':
break
cmd = commands[cmd]
s.send(cmd if sys.version_info[0] < 3 else str.encode(cmd))
except Exception as e:
print(e)
break
s.close()



if __name__ == '__main__':
main( * sys.argv[1:])

+ 120
- 0
code/botserver.py View File

@@ -0,0 +1,120 @@
import docker
import os
import getpass
import logging

_image = "dokoliho/botserver"
_uid = os.getuid()
_username = getpass.getuser()
_containername = "botserver_" + _username
_port = 62187 + _uid
_logger = logging.getLogger(__name__)
_from_env=False
_verbose=False

def _client():
if _from_env:
client = docker.from_env()
else:
client = docker.DockerClient(base_url='tcp://172.17.0.1:2375')
return client

def _get_running_container():
client = _client()
try:
return client.containers.get(_containername)
except:
msg = f"Container {_containername} not found."
if _verbose: print(msg)
_logger.info(msg)
return None

def connect_remote_daemon(flag):
global _from_env
_from_env = not flag

def stop_container():
container = _get_running_container()
if container is not None:
container.stop()
container.remove()
msg = f"Container {_containername} stopped."
if _verbose: print(msg)
_logger.info(msg)

def start_container(verbose=False):
global _verbose
_verbose = verbose
stop_container()
client = _client()
try:
client.containers.run(_image,
command=["sleep", "inf"],
detach=True,
name=_containername,
ports={63187: _port})
msg = f"Container {_containername} started with port {_port}"
if _verbose: print(msg)
_logger.info(msg)
return _port
except Exception as e:
if _verbose: print(str(e))
_logger.warning(str(e))
return None

def exec_in_container(command):
container = _get_running_container()
if container == None:
msg = f"Container {_containername} not running."
_logger.warning(msg)
raise Exception(msg)
try:
msg = f"Executing {command}"
if _verbose: print(msg)
_logger.info(msg)
result = container.exec_run(command, stream=True)
except Exception as e:
print(str(e))
_logger.warning(str(e))
return
for line in result.output:
print(line.decode("utf-8"))
msg = f"Execution of {command} finished."
if _verbose: print(msg)
_logger.info(msg)

def exec_synced_in_container(command):
container = _get_running_container()
if container == None:
msg = f"Container {_containername} not running."
_logger.warning(msg)
raise Exception(msg)
try:
msg = f"Executing (sync) {command}"
if _verbose: print(msg)
_logger.info(msg)
exit_code, output = container.exec_run(command)
except Exception as e:
print(str(e))
return
print(output.decode("utf-8") )
msg = f"Execution of {command} finished."
if _verbose: print(msg)
_logger.info(msg)

def print_logs():
container = _get_running_container()
if container == None:
msg = f"Container {_containername} not running."
_logger.warning(msg)
raise Exception(msg)
print(container.logs().decode("utf-8"))


if __name__ == "__main__":
connect_remote_daemon(False)
start_container(verbose=True)
# exec_in_container("echo 'hello world'")
exec_in_container("/bots/server/bots training")
stop_container()


+ 38
- 0
code/client.py View File

@@ -0,0 +1,38 @@
import socket

def read_view(f):
view = f.readline()
if not view:
return
for x in range(2, len(view)):
line = f.readline()
if not line:
return
view += line
return view

def main(host, port):
s = socket.socket()
s.connect((host, port))
f = s.makefile()

commands = {'w': '^', 'a': '<', 's': 'v', 'd': '>', 'W': '^', 'A': '<', 'S': 'v', 'D': '>'}

while True:
try:
view = read_view(f)
if not view:
break
print(view)
cmd = input("[WASD]:")
cmd = commands[cmd]
if cmd is None:
break
s.send(str.encode(cmd))
except Exception as e:
print(e)
break
s.close()

port = 63188
main("141.75.33.7", port)

+ 42
- 0
code/func arguments.py View File

@@ -0,0 +1,42 @@
import datetime
import os


def get_current_date():
return datetime.datetime.now()


def file_exists(filename):
os.path.exists(filename)


def add(x, y):
return x + y


def assert_equals(message, expected, actual):
if expected != actual: print(message)


def open_window(parent, top, bottom, left, right, modal):
do_something_with(parent, top, bottom, left, right, modal)

class Parent():
def open_modal_window(self, d):
pass

parent = Parent()

top = bottom = left = right = modal = None

open_window(parent, top, bottom, left, right, modal)


dimensions = (top, bottom, left, right)
parent.open_modal_window(dimensions)



def do_something_with(*args):
pass


+ 3
- 0
code/testdir/test.py View File

@@ -0,0 +1,3 @@
def f1():
return 17


BIN
img/BaumPytagoras.png View File


BIN
img/Bedingung.png View File


BIN
img/IEEE754.png View File


BIN
img/JHTree.png View File


BIN
img/JNClear.png View File


BIN
img/Mehrfach.png View File


BIN
img/Primitive.png View File


BIN
img/SchleifeKopf.png View File


BIN
img/Sequenz.png View File


BIN
img/Verzweigung.png View File


BIN
img/ggtstruct.png View File


BIN
img/ggtuml.png View File


BIN
img/import.png View File


BIN
img/module.png View File


BIN
img/object.png View File


Loading…
Cancel
Save