{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Einführung zu Python \n", "\n", " Alexander Heidelbach, April 2020\n", "\n", "In diesem kurzen _jupyter_ -Notebook können Sie die grundlegenden Funktionen von _python_ (3) kennenlernen und direkt selbst ausprobieren. Der hier gezeigte Bruchteil der Programmiersprache zeigt Ihnen jedoch nur die Spitze des Eisberges. Nehmen Sie die Inhalte und Beispiele mit für die Erkundung des tatsächlichen Eisberges und entdecken Sie die schier unendlichen Möglichkeiten, die _python_ Ihnen bietet. Das Notebook bietet Ihnen die Grundlage zu dem Kurs \"Computergestützte Datenanalyse\", zur Anwendung in den physikalischen Praktika und weit darüber hinaus. Auch Wissenschaftler nutzen die Sprache *python*, die mächtige Methoden zur Visualisierung, Auswertung und Interpretation von Daten aller Art bereit stellt. \n", "Auch bei Ihren eignen wissenschaftlichen Abschlussarbeiten bis hin zur Promotion werden Ihnen *python*-Kenntnise sehr nützlich sein. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "---\n", "# Inhalt \n", "## 1. [Grundlegendes](#Sec:basics)\n", "### 1.1 [Was ist das Ganze hier?](#SubSec:jupy)\n", "### 1.2 [Was ist *python*?](#SubSec:python)\n", "### 1.3 [Wer hilft mir bei *python* Problemen?](#SubSec:doku)\n", "## 2. [Sprachsyntax](#Sec:syntax)\n", "### 2.1 [Kommentare und Einrückungen](#SubSec:comments)\n", "### 2.2 [Operatoren](#SubSec:operators)\n", "### 2.3 [Variablen](#SubSec:variables)\n", "### 2.4 [Datentypen](#Subsec:datatype)\n", "### 2.5 [Umwandlung](#SubSec:transform)\n", "## 3. [Kontrollstrukturen](#Sec:controllstructure)\n", "### 3.1 [Bedingte Anweisungen, Verzweigungen](#SubSec:statements)\n", "### 3.2 [Schleifen](#SubSec:loops)\n", "### 3.3 [Funktionen](#SubSec:functions)\n", "## 4. [Ein- und Ausgabe](#Sec:inoutput)\n", "## 5. [Module](#Sec:modules)\n", "### 5.1 [_numpy_](#SubSec:numpy)\n", "### 5.2 [_matplotlib_](#SubSec:matplotlib)\n", "## 6. [Bonusmaterial](#Sec:bonus)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "---\n", "# 1. Grundlegendes [^](#Inhalt)\n", "---\n", "\n", "Die folgenden Kapitel sind dazu gedacht Ihnen Anstöße zum Erlernen einiger Grundlagen der Skript-Sprache *python* zu geben. Um den Lerneffekt zu erhöhen und die Einstiegshürde geringer zu halten, werden die Themen nicht in ihrem gesamten Ausmaß diskutiert. Nichtsdestotrotz ist das Anwenden der ersten textuellen Sprache zur Formulierung von Anweisungen an einen Computer keine leichte Aufgabe und erfordert, neben Disziplin, eine gewisse Probierlust und Geduld, wenn erste Ansätze einmal scheitern sollten. Leben Sie \n", "Ihre Neugierde beim Programmierenlernen aus, wie keine Vorlesung das sonst bieten kann. \n", "\n", "Ein Skript in der Sprache *python*, auch \"*python*-Programm\" genannt, ist im Prinzip nichts weiter als \n", "eine Liste von Anweisungen. Eine solche Liste könnte auch aus einer einer Folge von Mausklicks in einer grafischen Oberfläche bestehen - das wäre aber sehr umständlich ! Versuchen Sie doch einmal, die einzelnen Schritte zum Öffnen einer Textdatei, das Ersetzen eines bestimmten Worts durch ein anders und zum Abspeichern auf der Festplatte genau aufzuschreiben - sie werden sehen, wie umständlich das ist und werden es zu schätzen lernen, wie einfach diese Schritte in einer textuellen Sprache formuliert werden können.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 1.1 Was ist das Ganze hier? \n", "---\n", "\n", "Die Umgebung, in der Sie hier arbeiten, wird als *jupyter* notebook bezeichnet. *jupyter notebooks*\n", "sind Dateien vom Typ *.ipynb*, die sowohl erklärenden Text als auch Anweisungen für den Computer\n", "enthält. *jupyter* bietet eine Browser-Schnittstelle mit einer (einfachen) Entwicklungsumgebung für \n", "Anweisungen in der Sprache *python* und erklärende Texte im intuitiven *markdown*-Format. Die \n", "Eingabe von Formeln im *LaTeX*-Format zur komfortablen und grafisch ansprechenden Gestaltung von \n", "Formeln wird ebenfalls unterstützt. \n", "\n", "Die *jupyter*-Oberfläche lässt sich zwar komplett mit der Maus bedienen, viel effizienter ist\n", "es allerdings, nach einiger Eingewöhnung die Tastatur zu benuzten. Eine kleine Liste an \n", "Tastenkürzeln (genannt \"*jupyter*-Shortcuts\") ist hier - als Tabelle im *markdown*-Format:\n", "\n", " Modus | Befehl | Aktion |\n", ":-----------------|:------------------|:--------------------------------------------|\n", "**A**llgemein | `esc` | verlässt Editiermodus |\n", " A | `enter` | geht in Editiermodus | \n", "**E**ditiermodus | `shift` + `enter` | führt Zelle aus und geht zur nächsten |\n", " E | `ctrl` + `enter` | führt Zelle aus |\n", "**K**ommandomodus | `d,d` | löscht aktuelle Zelle |\n", " K | `z` | macht Zellenlöschung rückgängig |\n", " K | `a` | fügt neue Zelle überhalb der aktuellen ein |\n", " K | `b` | fügt neue Zelle unterhalb der aktuellen ein |\n", " K | `m` | ändert zu Markdown |\n", " K | `y` | ändert zu Code |\n", "\n", "\n", "Durch Doppelklick in diese Zelle sehen sie den eingegebenen Text, wenn Sie `shift` + `enter`\n", "eingeben, wird die Zelle formatiert und sie sehen eine schön gesetzte Tabelle. \n", "\n", "**Bitte ausprobieren !**\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mit den obigen Kommandos kann man leicht eine neue leere Zelle einfügen. \n", "Scheuen Sie sich nicht, an jeder beliebigen Stelle eine Zelle wie diese hier einzufügen \n", "und Codeschnipsel auszuprobieren, die Sie im Kopf haben. \n", "Dadurch beschleunigt sich der Lernprozess sogar ganz sicher.\n", "\n", "Und daran denken: mit 'd d' werden Sie die Testzelle auch ganz einfach wieder los. \n", "Wenn Sie zu voreilig beim Löschen waren, kommt die gelöschte Zelle über den Menüeintrag \n", "\"Edit / undo cell operation\" auch wieder zurück! " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 1.2 Was ist *python*? \n", "---\n", "\n", "> Python $[...]$ ist eine universelle, üblicherweise interpretierte, höhere Programmiersprache.\n", "[Wikipedia](https://de.wikipedia.org/wiki/Python_(Programmiersprache))\n", "\n", "Für diejenigen, die bereits eine Programmiersprache kennen, ist dieser Ausdruck beinahe ausreichend zur Erklärung. Schön wäre noch zu wissen, dass *python* auf allen gängigen Betriebssystemen kostenlos verfügbar ist und dass *python* erst durch den Einsatz der großen Zahl verfügbarer Module mit einem enormen Funktionsumfang wirklich mächtig wird. Das reicht bis zum Einsatz in Bereich \"Data Science\" und\n", "\"Deep Learning\" (für diejenigen, die Buzzwords mögen ...), oder wissenschaftlicher ausgedrückt: im\n", "Bereich der multivariaten Datenauswertung. \n", "\n", "Wer noch keinen Kontakt mit einer textuellen Programmiersprache hatte: Zerbrechen Sie sich nicht den Kopf! Wenn *python* eins ist, dann ist es **einsteigerfreundlich**. Sie lernen im Verlauf dieser\n", "Einführung Stück für Stück die sehr intuitive Arbeitsweise von *python* kennen. Sie können\n", "ohne Furcht **learning by doing** praktizieren! " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 1.3 Wer hilft mir bei *python* Problemen? \n", "---\n", "\n", "**Suchmaschinen**\n", "\n", "Eine Programmiersprache lernen Sie nicht durch einfaches Durchlesen, sondern durch Probieren und Austesten von Gedanken. Sie werden im Laufe des Lernprozesses auf falsche Ausgaben oder Fehlermeldungen treffen. Denken Sie kurz über Ihren Code nach und wenn das nicht hilft, dann kopieren Sie einfach Ihre Fehlermeldung in das Suchfeld, weil sicherlich irgendjemand genau das auch schon versucht hat. Klicken Sie sich dabei nicht nur durch Dokumentationen, sondern auch durch diverse Foren. Die Erklärungen darin sind zu Beginn vielleicht etwas hilfreicher, auch wenn die Beispiele manchmal nicht im besten Stil sind. Eine typische Situation beim Lernen von Programmiersprachen: In einem Fenster hat man den Editor (z.B. *jupyter*), im anderen ein *python* Nachschlagewerk.\n", "\n", "Zur Vollständigkeit hier trotzdem einige Tutorien:\n", "* [*python* 3 Kurs](https://www.python-kurs.eu/python3_kurs.php)\n", "* [PEP 8](https://www.python.org/dev/peps/pep-0008/) - Style Guide for Python Code\n", "* [*numpy* quickstart](https://docs.scipy.org/doc/numpy/user/quickstart.html)\n", "* [Intro to pyplot](https://matplotlib.org/tutorials/introductory/pyplot.html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "# 2. Sprachsyntax [^](#Inhalt)\n", "---\n", "\n", "Analog zum Lernen einer natürlichen Sprache beginnen wir mit den grundlegenden Bausteinen und lernen zunächst die Grundlagen der Sprachsyntax kennen. Der folgende Abschnitt ist dazu da, einen Großteil des Alphabetes in Form von Operatoren, Variablen und Datentypen und die Grammatik kennen zu lernen.
\n", "Doch zunächst beginnen wir mit dem klassischen $\\texttt{Hello World!}$, das am Anfang einer jeden Programmiersprache gezeigt wird." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"Hello World!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Diejenigen, die bereits andere Programmiersprachen kennen, dürfen gerne erstaunt sein, wie kurz das $\\texttt{Hello World!}$ ausfällt. Der einzige Aspekt, der beachtet werden muss, sind seit *python* 3 die Klammern nach dem `print()` Ausdruck, da *print* eine globale [Funktion](#SubSec:functions) ist." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 2.1 Kommentare und Einrückungen \n", "---\n", "\n", "Schon bald werden Sie ihre eigenen *python*-Programme schreiben und vielleicht wollen Sie diese auch unter Ihren Kollegen/Kolleginnen teilen. Vor allem für sich selbst aber auch für andere LeserInnen Ihrer Programme wollen Sie sicherstellen, dass die Programme verstanden werden. Um das zu ermöglichen, verwenden Sie **Kommentare** in ihrem Code. Kommentare machen einen Code leserlich und auch über lange Zeit verwendbar. Sie werden nicht mit ausgegeben, sondern sind nur im reinen Quelltext zu sehen.
\n", "In der *python*-Syntax wird in einer einzelne Zeile kommentiert, sobald ein `#` in der Zeile auftaucht. Der Text hinter dem `#` Zeichen wird zum Kommentar.\n", "\n", "Als erstes Beispiel betrachten wir das obige $\\texttt{Hello World!}$ und schmücken dies mit einem Kommentar aus." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"Hello World!\") # Gebe Hello World! aus" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Anders, als dieses Beispiel zeigt, sollten die Kommentare möglichst sinnvoll und in englischer Sprache sein. Das Prinzip haben wir damit aber kennengelernt. Sollten Sie mehrere offensichtliche Schritte hintereinander ausführen, beispielsweise das Umrechnen von Messdaten, können Sie auch Blockkommentare bilden." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Convert current into voltage according to U = R * I\n", "#\n", "# Print out the result\n", "\n", "I = 10\n", "R = 2\n", "\n", "U = R * I\n", "\n", "print(\"Angelegte Spannung U=\" + str(U) + \"V\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Zu Beginn erscheint es Ihnen möglicherweise als unnötig und zeitraubend die Kommentare zu verwenden, doch wenn Sie nach der Semesterpause im Praktikum die Auswertung durchführen und nochmal in Ihren Code aus CgDa zur Hilfe nehmen, werden Sie merken, wie wertvoll sinnvolle Kommentare sind. Spätestens wenn Sie während einer Abschlussarbeit fremden Code vorgelegt bekommen, der nicht kommentiert ist, werden sie den/die SchreiberIn verfluchen, weil sie wochenlang damit beschäftigt sind, den Code zu verstehen. Beugen Sie solchen Situationen vor und nutzen Sie von Begin an sinnvolle Kommentare!\n", "\n", "Eine strukturierte Programmiersprache, wie *python*, ermöglicht den Einsatz von Blöcken. Ein Block ist eine Gruppe von Anweisungen und kann selbst Blöcke beinhalten. Ein Beispiel in *C* wäre dafür:\n", "\n", "```c\n", "if (x==42) {\n", " printf(\"The Answer to the Ultimate Question of Life, the Universe, and Everything\\n\");\n", "} else {\n", " printf(\"Just a number!\\n\");\n", "}\n", "```\n", "\n", "Wohlgemerkt sind die **Einrückungen** hier nicht notwendig. Dem Compiler reicht\n", "\n", "```c\n", "if (x==42) {printf(\"The Answer to the Ultimate Question of Life, the Universe, and Everything\\n\");} else {printf(\"Just a number!\\n\");}\n", "```\n", "\n", "vollständig aus. Die Einrückungen dienen der besseren Lesbarkeit für AnwenderInnen und sind in fast jeder Programmiersprache *empfohlen*. *python* 'zwingt' jedoch die NutzerInnen den Code direkt übersichtlich zu gestalten und Einrückungen zu verwenden.\n", "Blöcke werden hier nicht durch Klammern, sondern die gleiche Einrückung definiert.\n", "So wird automatisch auch ein übersichtlicher Code produziert.\n", "\n", "Ein häufiges Beispiel für einen Block sind Anweisungen, wie *while*- oder *for*-Schleifen, die aus einem Anweisungskopf und einem Anweisungskörper zusammensetzen.\n", "\n", "```\n", "Anweisungskopf:\n", " Anweisung\n", " \n", " Anweisung\n", "```\n", "\n", "Besonders wichtig für solche Anweisungen sind die Doppelpunkte am Ende des Kopfes und die gleichmäßige Einrückung der Anweisungen. [PEP 8](https://www.python.org/dev/peps/pep-0008/) empfiehlt die Verwendung von **vier Leerzeichen** pro Einrückungsebene. Mehr zu den Strukturen befindet sich im [dritten Kapitel](#Sec:controllstructure)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 2.2 Operatoren \n", "---\n", "\n", "Sie haben nun die Struktur von *python*-Code kennengelernt. Es wird an der Zeit, dass Sie nun auch eigenen schreiben können. Beginnen wir hierfür mit der einfachsten Anwedung von *python* - **python als Taschenrechner**. Ähnlich zu einem physischen Taschenrechner können Sie Zahlen miteinander verrechnen. Oder wie man auch sagen könnte: einen Operator auf ein oder mehrere Ziele anwenden. Die folgende Aufteilung der Operatoren müssen Sie sich nicht merken, nur ihre Anwendung sollten Sie im Kopf behalten." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Arithmetische Operatoren \n", "\n", "Die arithmetischen Operatoren führen ihre intuitiven Aufgaben durch.\n", "\n", "* Addition `+`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 + 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Subtraktion `-`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 - 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Multiplikation `*`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 * 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Division `/`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 / 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Exponentiation `**` (Vorsicht: `^` führt etwas vollkommen [Anderes](#SubSubSec:bitwiseoperator) aus!)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3**4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Rest einer Division (Modulo-Funktion) `%`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "11 % 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Ganzzahldivision `//`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "11 // 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vergleichsoperatoren \n", "\n", "Die Vergleichsoperatoren führen ebenfalls genau das aus, was man von ihnen erwartet. Jedoch ist das Ergebnis keine Zahl, sondern ein [*bool*scher Wert](#SubSubSec:bool). Kurz gesagt, ist das Ergebnis entweder **wahr** (*True* bzw. 1) oder **falsch** (*False* bzw. 0). Wir verwenden Vergleichsoperatoren häufig bei den [Kontrollstrukturen](#Sec:controllstructre), um Bedingungen zu formulieren.\n", "\n", "* Kleiner `<`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 < 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Größer `>`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 > 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Kleiner gleich `<=`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "4 <= 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Größer gleich `>=`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "4 >= 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Gleich `==` (Vorsicht: `=` ist nicht gleichbedeutend mit dem Vergleich! `=` ist ein [Zuweisungsoperator](#SubSubSec:assignmentoperator))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 == 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Ungleich `!=`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 != 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Logische Operatoren \n", "\n", "Logische Operatoren stellen meistens eine Verbindung zwischen zwei boolschen Werten her und gibt genau einen boolschen Wert aus. Im Prinzip funktionieren sie genauso wie arithmetische Operatoren. Wir nehmen zwei Zahlen, wollen sie addieren (die Operation `+` anwenden) und erhalten eine Zahl (3+4=7). Die logischen Operatoren haben nur 'ihre eigene Algebra'. Wir verwenden die logischen Operatoren häufig bei den [Kontrollstrukturen](#Sec:controllstructre), um Bedingungen zu verknüpfen.\n", "\n", "* Das `and` gibt genau dann *wahr* aus, wenn beide Optionen *wahr* sind.\n", "\n", "| a | b | `and` |\n", "|:-------:|:-------:|:-------:|\n", "| True | True | True |\n", "| True | False | False |\n", "| False | True | False |\n", "| False | False | False |" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "True and True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "True and False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "7 <= 6 and 2 > 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "7 > 9 and 3 == 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Das `or` gibt genau dann *wahr* aus, wenn eine der beide Optionen *wahr* ist.\n", "\n", "| a | b | `and` |\n", "|:-------:|:-------:|:-------:|\n", "| True | True | True |\n", "| True | False | True |\n", "| False | True | True |\n", "| False | False | False |" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "True or True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "True or False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "7 <= 6 or 2 > 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "7 > 9 or 3 == 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Das `not()` invertiert den logischen Wert" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "not (True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "not (False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "not (3 >= 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Zuweisungsoperatoren \n", "\n", "Zuweisungsoperatoren weisen einer oder mehreren [Variablen](#SubSec:variables) einen Wert zu. Da [Variablen](#SubSec:variables) erst im nächsten Kapitel besprochen werden, verwenden wir hier ganz simpel nur $a$ und $b$. Es gibt insgesamt acht Zuweisungsoperatoren - eine normale Zuweisung und sieben verknüpft mit den arithmetischen Operatoren.\n", "\n", "* Zuweisung `=`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 7\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sie können auch mehrere Variablen gleichzeitig zuweisen" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = b = 6\n", "print(\"a=\", a)\n", "print(\"b=\", b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Plus Gleich `+=` und Minus Gleich `-=`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a += 6\n", "b -= 4\n", "print(\"a=\", a)\n", "print(\"b=\", b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Analog funktionieren die restlichen arithmetischen Operationen mit Zuweisung: `*=,/=,**=,%=,//=`\n", "\n", "Mehr Operatoren finden Sie beim [Bonusmaterial](#SubSec:opsplus)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 2.3 Variablen \n", "---\n", "\n", "Variablen werden mithilfe der Zuweisung definiert, insofern die Zuweisung denn gültig ist. In *python* spielt der [Datentyp](#SubSec:datatype) der Variable keine gesonderte Rolle bei der Zuweisung und muss nicht, wie in anderen Programmiersprachen üblich, der Variable zugewiesen werden. Bevor wir uns jedoch den Datentypen zuwenden, betrachten wir zunächst die erlaubten und üblichen Namen.
\n", "Gültige Variablennamen können folgende Zeichen besitzen.\n", "\n", "* Großbuchstaben von A bis Z\n", "* Kleinbuchstaben von a bis z\n", "* Unterstrich\n", "* Die Zahlen 0 bis 9 (nicht an erster Stelle)\n", "* Unicode-Zeichen\n", "\n", "Die Läng der Variablennamen ist nicht begrenzt. Es ist aber auf Groß- und Kleinschreibung zu achten. Beispiele hierfür sehen Sie in der folgenden Zelle." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "height = 10\n", "maximum_height = 100\n", "\n", "υψος = 10\n", "μεγιστη_υψος = 100\n", "\n", "MinimumHeight = 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Es ist sinnvoll Variablen so zu benennen, dass ihr Sinn ohne weitere Erklärung klar wird, um die Leserlichkeit des Codes zu gewährleisten. Dadurch kann es vorkommen, dass eine Variable aus mehreren Wörtern besteht. Da das Leerzeichen nicht erlaubt ist in der Variablenbezeichnung, gibt es zwei verbreitete Arten die Variablen zu bennen. Sie sehen die beiden Arten an den Beispielen `maximum_height` und `MinimumHeight`. [PEP 8](https://www.python.org/dev/peps/pep-0008/) empfiehlt die Variante mit dem Unterstrich als Trennung zwischen zwei Wörtern.
\n", "Neben den oben genannten Regeln gibt es *python*-Schlüsselwörter, die nicht als Variablenname benutzt werden dürfen. Diese lauten: `and, as, assert, break, class, continue, def, del, elif, else, except, False, finally, for, from, lobal, if, import, in, is, lambda, None, nonlocal, not, or, pass, raise, return, True, try, while, with, yield`. **Sie müssen sich natürlich nicht alle merken.** Die meisten Editoren mit Farbhervorhebung ändern die Farbe, wenn Sie diese Wörter verwenden. Außerdem wird bei der Ausführung eines *python* ein Fehler angezeigt." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 2.4 Datentypen \n", "---\n", "\n", "Wie Sie bereits erfahren haben, spielt es bei der normalen Zuweisung keine Rolle, welchen Datentyp ein Wert hat, wenn er einer Variablen zugewiesen wird. Da Sie bei der Auswertung von Daten jedoch vermutlich viele Variablen mit einander verrechnen oder darstellen wollen, sollten Sie wissen welche es gibt und wie sie sich verhalten. Besonders wichtig sind an dieser Stelle die sequentiellen Datentypen und [später](#SubSec:numpy) lernen Sie auch die außerordentlich praktischen *numpy arrays* kennen.
\n", "Im Folgenden verwenden wir die in *python* integrierte Funktion `type()`, um den Datentypen einer Variable zu sehen.\n", "\n", "### Zahlen \n", "\n", "*python* kennt insgesamt sechs verschiede Datentypen für Zahlen. Die drei wichtigsten Typen an Zahlen sehen Sie in den folgenden Beispielen.\n", "\n", "* Ganze Zahlen (Integer)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 1\n", "type(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Fließkommazahlen (float)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = 1.2\n", "type(b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c = 4e09\n", "c" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Komplexe Zahlen (complex)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d = 1 + 2j\n", "type(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sequentielle Datentypen \n", "\n", "Ein sequentieller Datentyp beinhaltet eine Folge von gleichartigen oder verschiedenen Elementen. Die Elemente eines sequentiellen Datentyps haben eine definierte Reihenfolge und dadurch kann mithilfe von Indizes auf sie zugegriffen werden. \n", "\n", "* Zeichenkette (**String**)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "zeichenkette = \"Hello World!\"\n", "type(zeichenkette)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* **Liste** `[]` - In einer Liste kann eine Folge beliebiger Objekte gespeichert werden, also zum Beispiel Zahlen, Strings, Listen und Tupel." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "liste1 = [1, 2, 4, 5, 7, 8, 9, 4, 0]\n", "type(liste1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "liste2 = [42, [\"Hallo\", 1], [7, [\"test\"]]]\n", "type(liste2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* **Tupel** `()` - In einem Tupel können wie in einer Liste eine Folge beliebiger Objekte gespeichert werden, aber ein Tupel kann dann während des weiter Programmverlaufs nicht mehr geändert werden." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tupel1 = (\"tupel\", \"sind\", \"unveränderlich\", 11)\n", "type(tupel1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* **Dictionary** `{}` - Bei dicts handelt es sich um assoziative Felder. Dicts bestehen aus Schlüssel-Objekt-Paaren. Zu einem bestimmten Schlüssel gehört immer ein Objekt." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "city_population = {\"New York City\": 8550405, \"Los Angeles\": 3971883, \"Toronto\": 2731571}\n", "type(city_population)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sie haben so eben die gängigsten Arten an sequentiellen Datentypen kennengelernt. Alleine mit diesem Wissen können Sie schon vielleicht die eine oder andere alltägliche Aufgabe lösen. Wir sollten aber noch einen Blick darauf werfen, wie Sie auf einzelne Elemente der sequentiellen Datentypen zugreifen und wie Sie sie manipulieren können.
\n", "\n", "#### Indizierung/Adressierung\n", "\n", "Die Strings-, Listen- und Tupelelemente erreichen Sie über den entsprechenden Index. **Achtung: Zählen ab 0!** Betrachten wir kurz an unserem Beispiel $\\texttt{Hello World!}$ die Indizierung. Das Minus deutet das Zählen von hinten ab -1 an.\n", "\n", "| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |\n", "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", "| H | e | l | l | o | | W | o | r | l | d | ! |\n", "| -12 | -11 | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(zeichenkette)\n", "print(\"0: \", zeichenkette[0])\n", "print(\"8: \", zeichenkette[8])\n", "print(\"-8: \", zeichenkette[-8])\n", "print(\"-1: \", zeichenkette[-1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(liste1)\n", "print(\"0: \", liste1[0])\n", "print(\"-4: \", liste1[-4])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(liste2)\n", "print(\"0: \", liste2[0])\n", "print(\"-1: \", liste2[-1])\n", "print(\"1,0: \", liste2[1][0])\n", "print(\"2,1:\", liste2[2][1])\n", "print(\"2,1,0:\", liste2[2][1][0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bei Dictonaries greifen Sie nicht mit dem Index auf ein Element zu, sondern mit dem entsprechenden Schlüssel." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(city_population)\n", "print(city_population[\"New York City\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Ausschneiden/Slicing\n", "\n", "Sie können ebenfalls auf Teile eines sequentiellen Datentyps zugreifen. Im Falle eines Strings erhalten Sie einen Teilstring oder bei Listen wieder eine Liste. Dabei entspricht der Zugriff dem folgenden Schema: `[Start:Stop:Step]`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(liste1)\n", "print(\"4 bis 8: \", liste1[4:8])\n", "print(\"4 bis 8 in 2er Schritten: \", liste1[4:8:2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Weglassen des Steps, was meistens gewollt ist, führt die Schritte einzeln aus. Weglassen des Start bzw. Stops führt das Ausschneiden vom 0ten bzw. bis zum letzten Element durch." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(zeichenkette)\n", "print(\"bis 4: \", zeichenkette[:4])\n", "print(\"bis 5: \", zeichenkette[:5])\n", "print(\"ab 5: \", zeichenkette[5:]) # Nicht das Leerzeichen vergessen!\n", "print(\"ab 6: \", zeichenkette[6:])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Das folgende Beispiel zeigt die Umkehrung der Listen." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "stadt = \"Hamburg\"\n", "print(stadt[::-1])\n", "print(stadt[::-2])\n", "print(liste1[::-1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Operatoren\n", "\n", "Einige Operatoren funktionieren auch sequentiellen Datentypen. Betrachten wir kurz die wichtigsten davon.\n", "\n", "* Länge `len()`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(zeichenkette)\n", "len(zeichenkette)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Verkettung `+`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "liste1 + liste2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Wiederholung `*`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 * \"Hallo\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Boolsche Werte \n", "\n", "Wie Sie bereits bei den [Vergleichsoperatoren](#SubSubSec:relationoperators) gesehen haben, gibt es noch einen Datentyp, der genau zwei Werte annehmen kann: `True` oder `False`. Manchmal kommt es vor, dass Sie in Programmen aber nicht unbedingt genau die zwei Werte erhalten können durch Vergleiche, sondern Zahlen, Strings oder sequentielle Datentypen verarbeiten. Dazu müssen Sie jedoch auch ihren boolschen Wert kennen.\n", "\n", "* `False` sind:\n", " * `None`\n", " * Leere sequentielle Datentypen: `[],(),{},\"\"`\n", " * 0\n", "* `True` sind die restlichen Werte." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 2.5 Umwandlung \n", "---\n", "\n", "Sie können begrenzt auch die Datentypen in andere Datentypen umwandeln. Dazu stehen Ihnen die entsprechenden Funktionen `int(), float(), complex(), str(), tuple(), list(), bool()` zur Verfügung. Sie können jedoch nicht beliebig den Datentyp wechseln. Sie können zum Beispiel nicht aus einer Liste einen float machen. Sie können auf der anderen Seite einen String in eine Zahl umwandeln, wenn die Zahl dem Datentyp entspricht. Durch etwas rumprobieren lernen Sie schnell, was geht und was nicht geht, wenn Sie es benötigen. Betrachten wir kurz zwei Beispiele.\n", "\n", "Sie erhalten eine Fließkommazahl (float), brauchen aber nur den Wert vor dem Komma und achten nicht auf korrekte Rundung." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 4.7\n", "int(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eine Variable kann nicht mehrere Datentypen haben. Wenn Sie also zum Beispiel den Satz \"{Ergebnis} ist eine Zahl\" ausgeben möchten (und noch nicht mit der format-Funktion vertraut sind), dann müssen Sie das Ergebnis vorher in einen String umwandeln." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 300 + 700\n", "print(str(x) + \" ist eine Zahl\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "# 3. Kontrollstrukturen [^](#Inhalt)\n", "---\n", "\n", "Sie haben sich bisher mit der Sprachsyntax von *python* beschäftigt und die wichtigsten Grundzüge kennengelernt. Doch bisher verwendeten wir *python* bestenfalls als etwas besseren Taschenrechner. Alle Eingaben, die wir bis hierhin machen können, sind strikt linear. Mithilfe der Kontrollstrukturen können wir jetzt häufige lineare Anwendungen wiederholen lassen oder auch ganz allgemein mit Schleifen Strukturen aufbauen. Außerdem lernen wir im Folgenden, wie wir Bedingungen einbauen und somit unsere Arbeitsprozesse vielleicht auch vereinfachen können. Denken Sie beim Lesen der nächsten Unterkapitel an die [Einrückungen](#SubSec:comments) für Blockstrukturen." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 3.1 Bedingte Anweisungen, Verzweigungen \n", "---\n", "\n", "Die meisten Programme enthalten **Verzweigungen**. Die Verzweigungen (oder auch **bedingt Anweisungen**) legen fest, welcher von zwei oder mehr Programmteilen in Abhängigkeit von von einer oder mehreren Bedingungen ausgeführt wird. *python* gibt Ihnen drei Strukturbausteine vor, die Sie verwenden können für das Bauen von Verzweigungen: `if, elif, else`. Die Struktur würde im Prinzip ungefähr so aussehen:\n", "\n", "```python\n", "\n", "if :\n", " \n", "elif :\n", " \n", "else:\n", " \n", "```\n", "\n", "Maniupulieren Sie das folgende Beispiel, um alle drei Ergebnisse zu erhalten." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 0\n", "\n", "if i == 0:\n", " print(\"Hallo\")\n", "elif i == 1:\n", " print(\"Hello\")\n", "else:\n", " print(\"Tschüss\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Oder rechnen Sie das Menschenalter Ihres Hundes aus." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "age = int(input(\"Age of the dog: \"))\n", "print()\n", "if age < 0:\n", " print(\"This cannot be true!\")\n", "elif age == 0:\n", " print(\"This corresponds to 0 human years!\")\n", "elif age == 1:\n", " print(\"Roughly 14 years!\")\n", "elif age == 2:\n", " print(\"Approximately 22 years!\")\n", "else:\n", " human = 22 + (age - 2) * 5\n", " print(\"Corresponds to \" + str(human) + \" human years!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 3.2 Schleifen \n", "---\n", "\n", "Sie werden Schleifen dann benötigen, wenn Sie einen Codeblock (Schleifenkörper) wiederholt ausführen möchten. dabei ist das Grundprinzip der Schleifen simpel.
\n", "Sie formulieren eine Bedingung. Wenn diese erfüllt ist, also `True`, dann führt die Schleife Ihre Anweisungen durch und geht wieder an den Anfang. Solange die Bedingung `True` bleibt, wiederholt sich der Vorgang. Sollte die Bedingung `False` sein, dann läuft das Programm weiter und erfüllt andere Anweisungen.
\n", "\n", "### while-Schleife \n", "\n", "Die while Schleife arbeitet ganz strikt mit den Bedingungen, die Sie ihr formulieren. Der prinzipielle Aufbau würde so aussehen:\n", "\n", "```python\n", "\n", "while :\n", " \n", "```\n", "\n", "Denken Sie bei der Formulierung der Bedingung an die gelernten [Vergleichsoperatoren](#SubSubsec:relationoperators) und die [logischen Operatoren](#SubSubSec:logicoperators). So können Sie bspw. bereits eine ganz einfache while-Schleife schreiben." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 0\n", "\n", "while i <= 5:\n", " print(i)\n", " i += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Beachten Sie hierbei, dass Sie die Laufvariable `i` vorher definieren mussten, das übernimmt nicht *python* für sie. Außerdem denken Sie daran ihre Variable auch anzupassen innerhalb der Schleife, sonst erzeugen Sie eine Endlosschleife.
\n", "Sie können auch den while-Schleifen ein genaues Verhalten für ihr Ende vorgeben mithilfe vom bereits kennengelernten `else`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 0\n", "\n", "while i <= 5:\n", " print(i)\n", " i += 1\n", "else:\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mit `break` oder `continue` können Sie while-Schleifen vorzeitig abbrechen oder an den Anfang wieder schicken. `break` ignoriert dann auch nach die `else` Anweisunen. `continue` ignoriert alles, was nach der Anweisung kommt." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 0\n", "\n", "while i <= 10:\n", " print(i)\n", " if i > 4:\n", " i += 1\n", " continue\n", " i += 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 0\n", "\n", "while i <= 1e20:\n", " print(i)\n", " if i == 5:\n", " break\n", " i += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### for-Schleife \n", "\n", "Die Bedingung bei for-Schleifen ist etwas versteckt im `in` Operator und für das Verständnis davon auch nicht relevant. Die for-Schleife arbeitet anhand einer Variable eine Liste ab. Die Variable definieren Sie bei jedem Durchlauf der mit dem nächsten Element in der Liste. Betrachten wir kurz die Syntax der for-Schleife und anschließend basteln wir das erste Beispiel der while-Schleifen mit einer for-Schleife nach.\n", "\n", "```python\n", "for in :\n", " \n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for i in [1, 2, 3, 4, 5]:\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An diesem Beispiel wird der Unterschied noch nicht ganz deutlich. Betrachten wir jedoch mal ein anderes Beispiel:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "languages = [\"C\", \"C++\", \"Perl\", \"Python\"]\n", "\n", "for language in languages:\n", " print(language)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Meisten wollen Sie jedoch keine Liste an Strings abarbeiten, sondern Datensätze bearbeiten oder ausgeben. Sie müssen beispielsweise etwas so oft machen, wie lang ein Datensatz ist, und wollen aber nicht vorher überprüfen, wie lange der Datensatz ist. Dazu gibt es die ganz praktische Funktion `range()`. Sie bildet eine Liste vom *Start* bis zum *Stop* in *Schritten*: `range(Start, Stop, Schritte)`. Auch hier können Sie den Startwert weglassen. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(range(4, 8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(range(10, 21))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Beachten Sie, dass der letzte Werte nicht gleich dem Stopwert ist. Das ist praktisch, wenn Sie die Länge einer Liste angeben als Stopwert und die Variable als Index verwenden." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list3 = [3, 5, 3, 436, 457, 32, 1, 436, 324, 123, 52]\n", "\n", "for i in range(len(list3)):\n", " print(list3[i])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 3.3 Funktionen \n", "---\n", "\n", "Funktionen sind in modernen Programmiersprachen unabdingbar. Sie sind dazu da, um häufig auftretende Anweisungen zu gruppieren und somit wiederholbar zu machen. Zwar könnten Sie den Code immer wieder kopieren und die entsprechenden Stellen ändern, jedoch würden Sie bei mehreren Wiederholungen schnell bemerken, wie aufwändig und fehleranfällig der Prozess ist. Außerdem würde sich dadurch Ihr Programmcode deutlich verlängern. Spätere Änderungen (zum Beispiel ein Fehler bei der Auswertung von Daten im Praktikum) müssten Sie an jeder Stelle durchführen. Mit Funktionen nur an der Funktionsdefinition.
\n", "Alle Vielfalten bei der Definition einer Funktion und ihrer Verwendung sprengt den Rahmen des [Bonusmaterials](#Sec:bonus) und ist eher ein Thema für das Selbststudium. Wir betrachten hier kurz die einfachsten Aspekte, damit Sie wiederholende Aufgaben in Funktionen verwirklichen können. Die Syntax zur Funktionsdefinition sieht aus wie folgt:\n", "\n", "```python\n", "\n", "def funktion_name():\n", " \n", " return \n", "```\n", "\n", "Das `return` gehört nicht prinzipiell in den Funktionskörper hinein, jedoch wollen wir hier uns auf die Fälle beschrenken, die eine Umrechnung durchführen. Betrachten wir für das Prinzip das Quadrieren einer Zahl." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def square(x):\n", " return x**2\n", "\n", "\n", "x = 5\n", "square(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Der Funktionenkörper kann auch andere bekannte Kontrollstrukturen enthalten. Als Beispiel wollen wir jeden Eintrag in einer Liste mit einem von uns gewählten Faktor multiplizieren. Später sehen wir bei den [numpy-arrays](#SubSec:numpy) wie viel einfacher Sie jedes Element in einer Liste mulitplizieren können." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "def multiplikation_for_lists(lis, fak):\n", " for i in range(len(lis)):\n", " lis[i] *= fak\n", " return lis\n", "\n", "\n", "liste4 = [4, 5, 12, 45, 67, 2, 6, 32, 0]\n", "\n", "multiplikation_for_lists(liste4, 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "# 4. Ein- und Ausgabe [^](#Inhalt)\n", "---\n", "\n", "Damit Sie Daten bei zukünftigen Auswertung überhaupt bearbeiten können, müsse diese erst einmal Ihrem Programm mitgeteilt werden. Bisher haben wir immer kurze Listen selbst geschrieben und diese dann bearbeitet. Ihre Messdaten liegen jedoch meist in bestimmten Datentabellen vor und je nach Größe wäre es sehr unpraktische diese alle von Hand einzutippen. Deshalb betrachten wir kurz die Ein- und Ausgabe Methoden, die *python* von Grund aus zur Verfügung stellt.\n", "\n", "### input() und print()\n", "\n", "Wie Sie bereits gesehen haben, verwendeten wir in den vorherigen Kapiteln die zwei Funktionen `input()` und `print()` für die Darstellung oder das Einlesen von Werten. In manchen Situationen, für Fingerübungen oder kleinere Test wollen Sie, dass Ihr Programm eine ganz bestimmt Eingabe benutzt. Möglicherweise wollen Sie diese selbst über Ihre Tastatur tätigen. Bei den [Verzweigungen](#SubSec:statements) sehen Sie das Beispiel mit der Umrechnung von Hundejahren in Menschenjahre, dass die `input()` nicht alleine bei der Zuweisung zu einer Variable steht. Die Inputfunktion wird noch zusätzlich interpretiert durch `int()`. Das liegt daran, dass `input()` die gesamte Eingabe als String abspeichert. Auch wenn Sie eine Zahl eingeben, kann nur mit `input()` mit der Zahl nicht weiter gerechnet werden, weil sie sich nicht wie eine verhält. \n", "Denken sie kurz an die Operatoren bei den sequentiellen Datentypen an den `*`-Operator und machen sich den Unterschied am folgenden Beispiel bewusst." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "number1 = input(\"Geben Sie eine Zahl ein\\n\")\n", "print(3 * number1)\n", "print(type(number1))\n", "number2 = float(input(\"Geben Sie eine Zahl ein\\n\"))\n", "print(3 * number2)\n", "print(type(number2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bevor die Eingabe von `input()` für Berechnungen benutzt werden kann, muß sie noch explizit in den entsprechenden Datentyp umgewandelt werden.\n", "\n", "Für die `print()` Funktion haben Sie bereits viele Beispiele gesehen. Jedes `print()` beginnt eine neue Zeile und geben Sie mehrere Werte getrennt durch Komma ein, dann werden diese mit einem Leerzeichen getrennt ausgegeben. Diese Funktion ist in fast jedem Programm enthalten, da Sie ihre Ergebnisse meist direkt sehen wollen und nicht immer in einer Grafik unterbringen werden. Weitere Tipps zur Ausgabe mit `print()` und allgemeinen Strings befinden sich beim [Bonusmaterial](#Sec:bonus)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Umgang mit Dateien\n", "\n", "*python* bringt intern eine Funktion mit, um Dateien auszulesen und in diese auch hinein zu schreiben. Die Funktion `open()` öffnet Ihnen eine Datei. Das bedeutet aber nicht, dass sie eine Veränderung bemerken. Diese Datei steht nur zum Zugriff bereit. `open()` übernimmt mindestens ein Parameter, häufig verwenden wir zwei. Der erste Parameter ist der Name (Speicherort) des Dokuments, das sie öffnen wollen (Tipp: *python* kann mit Ordnerstrukturen umgehen und erkennt Sachen wie `../Ordner/`), in Stringform. Der zweite Parameter kann der Modus sein. Es gibt viele unterschiedliche Moden, die drei geläufigsten sind:\n", "* r - read (Sie können nichts in das Dokument schreiben)\n", "* a - append (Sie können dem Dokument nur etwas hinzufügen)\n", "* w - write (Sie können in das Dokument schreiben und Informationen auch entfernen)\n", "\n", "Wird kein Modus angegeben, ist die Datei im *read* Modus.
\n", "In diesem Ordner befindet sich eine Datei mit dem Namen `hallo.txt`. Öffnen wir diese zunächst nur zum lesen und lassen sie vorlesen." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fh = open(\"hallo.txt\", \"r\")\n", "\n", "for line in fh:\n", " print(line)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Einfacher vorlesen lassen können Sie die Datei mit der `read()` Funktion. Wollen Sie nur einzelne Zeilen lesen, können Sie `readline()` verwenden." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fh = open(\"hallo.txt\")\n", "print(fh.read())\n", "\n", "fh = open(\"hallo.txt\")\n", "print(fh.readline())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In die Datei können Sie mithilfe von `write()` einen String schreiben, insofern Sie die Datei entsprechenden geöffnet haben. Sind sie mit der Bearbeitung der Datei fertig, dann nutzen Sie `close()`, um die Datei zu schließen und somit die Systemressourcen wieder frei zu geben." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fh = open(\"hallo.txt\", \"a\")\n", "fh.write(\"\\nHier steht die vierte Zeile\")\n", "fh.close()\n", "fh = open(\"hallo.txt\", \"r\")\n", "print(fh.read())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "# 5. Module [^](#Inhalt)\n", "---\n", "\n", "Bisher haben Sie die alleinige Verwendung von *python* gesehen, so ist das jedoch noch ziemlich langweilig. Wirklich mächtig wird *python* erst durch die Unzahl an Modulen. Kein übliches *python* Programm kommt ohne Module aus. Module beinhalten meist eine Vielzahl an Klassen und Objekten/Funktionen, die den Arbeitsalltag deutlich vereinfacht. Von den lokalen Modulen abgesehen, werden die verwendbaren Module Bibliothek genannt und stehen kostenlos zur Verfügung. *python* bringt selbst Module mit, diese sind im [Python Module Index](https://docs.python.org/3/py-modindex.html) aufgelistet. Im Folgenden betrachten wir zwei Module von Drittanbietern, die für die meisten *python*-Nutzer zum Alltag gehören und die in der Praktikumsauswertung unverzichtbar sind.
\n", "Zunächst schauen wir uns noch kurz an, wie ein Modul eingebunden wird:\n", "\n", "```python\n", "import # Binde ganzes Modul ein. Rufe Funktionen mit . auf.\n", "import as # Binde ganzes Modul mit Abkürzung für den Namen ein. .\n", "from import # Binde nur aus dem Modul ein.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import math as m\n", "from math import (\n", " sin,\n", ") # Eigentlich kann m.sin() verwendet werden, aber wir wollen 'from' anschauen\n", "\n", "sin(m.pi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bei der Verwendung von mehreren Modulen ist es üblich zuerst alle verwendeten Module aufeinmal am Anfang zu importieren. Dies werden Sie in den Beispielskripten wiederfinden.\n", "\n", "*Haben Sie bereits bemerkt, dass sin$(\\pi)$ nicht Null ist? Die Funktion berechnet numerisch den Sinus von einem endlich $\\pi$ und kann damit das Ergebnis nicht ideal auflösen. Probieren Sie es einmal mit sin(0) aus.*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 5.1 _numpy_ \n", "---\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*numpy* ist ein sehr mächtiges Modul für den Umgang mit Listen. Es steht für \"Numerisches Python\" und stellt sicher, dass die kompilierten mathematischen und numerischen Funktionen eine größtmögliche Ausführungsgeschwindigkeit garantieren. Außerdem bringt es eine neue Datenstruktur mit für das effiziente Rechnen mit großen Listen (arrays) und Matrizen. Einige ausgewählte Funktionen und Funktionsweise\n", "betrachten wir kurz, jedoch ist damit *numpy* damit noch nicht im Geringsten ausgeschöpft.\n", "\n", "Wie bereits mehrfach angekündigt kommt ein neuer Datentyp mit *numpy*, der sehr viel Arbeit, Zeit und Schleifen erspart: `np.array()`. Dieser kann nur aus int oder float Zahlen bestehen. Auf ihn kann wie auf Liste mithilfe der Indizes zugegriffen werden. Jedoch verhält das Array sicher eher, wie Sie es von einem Vektor gewohnt wären. Alle arithmetischen Operatoren wirken nämlich elementweise." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arr = np.array([1, 2, 3, 4, 5])\n", "\n", "print(\"arr : \", arr)\n", "print(\"arr+1 : \", arr + 1)\n", "print(\"arr-2 : \", arr - 2)\n", "print(\"arr*3 : \", arr * 3)\n", "print(\"arr/4 : \", arr / 4)\n", "print(\"arr**5: \", arr**5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Erinnern Sie sich daran, was `3*Liste` produziert hat und dass wir Multiplikation mit einem Faktor selbst definieren mussten? *numpy*'s Datentypen braucht das nicht.
\n", "Vektor und Kreuzprodukte müssen Sie mit `np.dot()` bzw `np.cross()` angeben. Bei der Multiplikation zweier Arrays werden ebenfalls nur die \"gegenüberliegenden\" Elemente miteinander multipliziert. Damit geht die Vektor Analogie zwar verloren, ist jedoch besser, bei der Auswertung von Datensätzen." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "brr = np.array([2, 44, 7, 2, 6])\n", "\n", "print(\"Elementweises Produkt: \", arr * brr)\n", "print(\"Skalarprodukt : \", np.dot(arr, brr))\n", "print(\n", " \"Kreuzprodukt : \", np.cross(arr[:3], brr[:3])\n", ") # Kreuzprodukt nur in 3 Dimensionen definiert." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Manchmal kann es sinnvoll sein Arrays selbst zu definieren. Das kann mit der Hilfe von numpy ebenfalls deutlich schneller durchgeführt werden. Einige Beispiele:\n", "* `np.zeros(n)` - Array mit *n* Elementen; alle Elemente sind 0\n", "* `np.ones(n)` - Array mit *n* Elementen; alle Elemente sind 1\n", "* `np.arange(start, stop, step)` - Array des halboffenen Intervalls $[$*start*,*stop*) mit *step* Abstand zwischen zwei Elementen ; wenn *start* und/oder *step* nicht angegeben werden, dann sind sie 0 bzw. 1\n", "* `np.linspace(start,stop,num)` - Array mit *num* Elementen im geschlossenen Intervall $[$*start*,*stop*$]$ ; wenn *num* nicht angegeben ist, dann sind ist *num*=50" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(np.zeros(10))\n", "print(np.ones(10) * 5)\n", "print(np.arange(0, 5 * np.pi / 2, np.pi / 2))\n", "print(np.linspace(0, 5, 10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*numpy* beinhaltet viele Funktionen zur Linearen Algebra und Statistik. Einige Beispiele, die bestimmt sehr nützlich sein könnten:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "print(\"Summe : \", np.sum(arr))\n", "print(\"Mittelwert : \", np.mean(arr))\n", "print(\"Standardabweichung: \", np.std(arr))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In [Kapitel 4](#Sec:inoutput) lernten Sie kennen, wie *python* Dokumente öffnen kann. Mit `np.loadtxt()` können Sie Datensätze von vielen Formaten einlesen und durch die wählbaren Parameter eine große Reichweite an Datenformaten problemlos direkt als *numpy* Arrays abspeichern. Im Folgenden Beispiel öffnen wir eine *.csv* Datei:\n", "* Überspringen mit `skiprows=1` die erste Zeile, da diese der Header (die Überschriften) ist\n", "* Geben das Trennsymbol mit `delimiter=\",\"` an\n", "* Transponieren den Datensatz mit `unpack=True`, damit wir in der Form `x, y = np.loadtxt(...)` einlesen können" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x, y = np.loadtxt(\"quadrat.csv\", skiprows=1, delimiter=\",\", unpack=True)\n", "print(x)\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 5.2 _matplotlib_ \n", "---" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Für Sie das wird vermutlich wichtigste Modul zur Praktikumsauswertung aus der *matplotlib* Bibliothek das *pyplot* Teilmodul sein. Dies ermöglicht auf sehr intuitive Art und Weise die Darstellung der Daten. Auch hier bietet die Bibliothek eine scheinbar unendliche Anzahl an Möglichkeiten die Daten darzustellen. Von ganz einfachen Stilen bis hin zur Spielwiese für Perfektionisten, die sich stundenlang mit nur einem Plot beschäftigen, kann *matplotlib.pyplot* jede/n NutzerInn zufrieden stellen. Wir betrachten im Folgenden ebenfalls nur einen sehr kleinen Ausschnitt aus dem Topf der Möglichkeiten. \n", "\n", "Ein großer Vorteil von *matplotlib* ist, dass es Hand in Hand mit *numpy* geht und problemlos mit dessen Arrays umgehen kann. Im Unterkapitel importierten wir einen Daten Satz als $x$ und $y$. Die schnellste und hässlichste Art und Weise diese darzustellen wäre `plt.plot()` nur mit den zwei Variablennamen zu füttern." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.plot(x, y)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`plt.plot()` kann eine Vielzahl an Parametern übernehmen, wovon viele auch nur das Aussehen steuern. Durch die Angabe von einem String kann jedoch schon einiges am Aussehen geändert werden, da `plt.plot()` ein paar Abkürzungen kennt.\n", "\n", "* Markerformat:\n", " * `\"-\"` Durchgezogene Linie\n", " * `\"--\"` Gestichelte Linie\n", " * `-.` Strichpunktlinie\n", " * `o` Kreismarker\n", " * u.v.m.\n", "* Markerfarbe: b=blau, g=grün, r=rot, c=cyan, m=magenta, y=gelb, k=schwarz, w=weiß\n", "\n", "Ohne die Verwendung der Abkürzungen kann noch deutlich mehr bei den entsprechenden Parametern eingestellt werden. Ein unwissenschaftliches Beispiel zeigt die Verwendung." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_verlauf = np.linspace(0, 10, 1000)\n", "\n", "plt.plot(x_verlauf, x_verlauf**2, \"--c\")\n", "plt.plot(x, y, \"dm\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eine Abbildung benötigt jedoch noch mindestens **Achsenbeschriftung** und eine **Legende**. Ein **Grid** ist optional, doch meistens ebenfalls verwendet. An jeder Textstelle kann auch innerhalb von $\\$..\\$$ $\\LaTeX$-Code verwendet werden. Eine Grafik speicher Sie mit `plt.savefig(\"\") ab. Ein vollständiges Beispiel wäre dafür:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_achse = np.linspace(0, 2 * np.pi, 1000)\n", "y1 = np.cos(x_achse)\n", "y2 = np.sin(x_achse)\n", "\n", "plt.plot(x_achse, y1, \"-r\", label=\"cos($x$)\")\n", "plt.plot(x_achse, y2, \"--b\", label=\"sin($x$)\")\n", "plt.xlabel(\"$X$-Achse\")\n", "plt.ylabel(\"$Y$-Achse\")\n", "plt.grid()\n", "plt.legend() # plt.legend(loc=\"\") setzt die Postion manuell fest ; z.B. loc=\"upper right\" - Standard: loc=\"best\"\n", "# plt.savefig(\"sincos.pdf\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "---\n", "# 6. Bonusmaterial [^](#Inhalt)\n", "---\n", "\n", "Das Bonusmaterial beinhaltet weitere Operatoren und einige Ergänzungen zur Ausgabe von Strings. Der Inhalt ist nicht relevant zum Bestehen des Kurses, sondern eher eine Ergänzung und eine Empfehlung. Es gibt mehr als genug Bonusmaterial im Internet, schauen Sie also auch da vorbei." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 6.1 Operatoren Weiterführung \n", "---\n", "\n", "### Mitgliedschaftsoperatoren \n", "\n", "Mitgliedschaftsoperatoren überprüfen ob ein Wert in einer Sequenz enthalten ist. Die Sequenz kann eine Liste, ein String oder ein Tupel sein.\n", "\n", "* `in`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pets = [\"dog\", \"cat\", \"ferret\"]\n", "\"fox\" in pets" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"cat\" in pets" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"evolution\" in \"revolution\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*`not in`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"fox\" not in pets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Bitweise Operatoren \n", "\n", "Bitweise Operatoren agieren bitweise auf Operanden. Dazu müssen Sie die binäre Darstellung ihres Datums kennen. Die Operatoren können in zwei Gruppen aufgefassst werden: logische Bitweise-Operatoren und Shift-Operatoren.\n", "\n", "* Das binäres und `&` führt Bit für Bit die AND Operation durch. Denken Sie bei den folgenden Beispielen and Bitdarstellung von 4 (100), 3 (011), 2 (010), 1 (001) und 0 (000)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 & 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3 & 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Das binäre oder `|` führt das gleiche wie oben durch, nur mit dem Operator OR." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 | 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Das binäre xor `^` führt das gleiche wie oben durch, nur mit dem Operator XOR (\"exklusives oder\" - \"entweder oder\")." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 ^ 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Das binäre Kompliment `~` bildet für jedes Bit das Inverse. So wird aus einer 2 (0000 0010) eine -3 (1111 1101)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "~2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Der binäre Links-Shift `<<` verschiebt den linken Operanten um so viele Stellen, wie der rechte angibt. So wird aus einer 2 (0010) eine 8 (1000)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 << 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Der binäre Rechts-Shift `>>` führt das gleiche nach rechts aus." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 >> 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 >> 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6.2 print() und formatierte Ausgabe \n", "\n", "Die `print()` Funktion besitzt folgende Parameter: `print(value1, ...., sep=' ', end='\\n', file=sys.stdout, flush=False)`. Damit können Sie die Separation, das Ende und den Ausgabeort bestimmen. Sie können Beispielsweise vorher eine Datei öffnen und in diese hineinschreiben oder in andere Systemkanäle.\n", "\n", "```python\n", "import sys\n", "\n", "fh = open(\"daten.txt\",\"w\")\n", "print(\"Irgendetwas\",file=fh)\n", "fh.close()\n", "\n", "print(\"Error: 42\",file=sys.stderr)\n", "```\n", "\n", "Zwei Hinweise zur sinnvollen und automatisierten Ausgabe von Strings, wie zum Beispiel zur Beschriftung und Datendarstellung innerhalb von Grafiken:\n", "\n", "* Es gibt Zeichenfolgen, die den Textfluss steuern. Sie lassen sich nicht auf dem Bildschirm als einzelne Zeichen darstellen (wenn nicht explizit gefordert) und besitzen eine spezielle Zeichenfolge - Escape-Sequenzen. Eine Escape-Sequenz wird mit einem `\\` eingeleitet.\n", " * `\\` Zeilenfortsetzung\n", " * `\\\\` Backslash\n", " * `\\'` Einzelnes Anführungszeichen\n", " * `\\\"` Doppeltes Anführungszeichen\n", " * `\\a` Glocke\n", " * `\\b` Rückschritt\n", " * `\\e` Ausmaskieren\n", " * `\\0` Null\n", " * `\\n` Zeilenvorschub\n", " * `\\v` Vertikaler Tabulator\n", " * `\\t` Horizontaler Tabulator\n", " * `\\r` Wagenrücklauf\n", " * `\\f` Seitenvorschub\n", " * `\\0XX` Oktalerwert\n", " * `\\xXX` Hexadezimalerwert\n", " \n", "* Der zweite Hinweis ist besonders einfach bei dem Einfügen von Variablenwerten in Strings, wie einem Grafiklabel. Da die Erklärung sehr lange ist (und ich Einzelheiten auch meistens jedes mal neu nachschlage) ist hier der [Link](https://www.python-course.eu/python3_formatted_output.php) zur `.format()` Methode. Ich finde diese besser und variabler als die Alte. Hier das Beispiel von der Seite, damit Sie einen Eindruck erhalten:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"Art: {0:5d}, Price per Unit: {1:8.2f}\".format(453, 59.058))" ] } ], "metadata": { "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.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }