{ "cells": [ { "cell_type": "markdown", "id": "06e817b5", "metadata": {}, "source": [ "# Python Einführung\n", "\n", "In diesem Jupyter Notebook lernen wir die Grundlegenden Funktionen von Python kennen. Hierbei werden wir die folgenden Kapitel behandeln:\n", "
print( )
wird eine Bildschirmausgabe erzeugt."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "3e3c66fe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello World!\n"
]
}
],
"source": [
"print(\"Hello World!\")"
]
},
{
"cell_type": "markdown",
"id": "9e5706bd",
"metadata": {},
"source": [
"# 1. Datentypen\n",
"\n",
"In Python gibt es die üblichen Datentypen:\n",
"\n",
" - Integer (int)\n",
" - Float (float)\n",
" - Complex (complex)\n",
" - String (str)\n",
" - Boolean (bool)\n"
]
},
{
"cell_type": "markdown",
"id": "a9bb60ab",
"metadata": {
"tags": []
},
"source": [
"## Achtung: Python Besonderheit\n",
"\n",
"Bevor wir starten, hier eine kleine Besonderhiet von Python (zumindest im Vergleich zu MATLAB, Java, R,...):\n",
"\n",
"In Python wird der Code durch Einrückungen struckturiert, bei den oben genannten Sprachen geschieht das durch Klammern. Du kannst also nicht beiebig zwischen verscheidenen Einrückungen wechseln.\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "7e7201c9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Uneingerückt läuft ohne Probleme\n"
]
}
],
"source": [
"print(\"Uneingerückt läuft ohne Probleme\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "7aa53b2c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Eingerückt wirft keinen Fehler\n"
]
}
],
"source": [
" print(\"Eingerückt wirft keinen Fehler\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "d94f7350",
"metadata": {},
"outputs": [
{
"ename": "IndentationError",
"evalue": "unexpected indent (Temp/ipykernel_25964/440451899.py, line 2)",
"output_type": "error",
"traceback": [
"\u001b[1;36m File \u001b[1;32m\"C:\\Users\\rieder\\AppData\\Local\\Temp/ipykernel_25964/440451899.py\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m print(\"Und eingerückt macht Probleme\")\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n"
]
}
],
"source": [
"print(\"Aber uneinegerückt\")\n",
" print(\"Und eingerückt macht Probleme\")"
]
},
{
"cell_type": "markdown",
"id": "cc3266bc",
"metadata": {},
"source": [
"Am besten achtest du, dass dein ganzer Code linksbündig ist, außer du bist gerade in Funktionen oder Schleifen."
]
},
{
"cell_type": "markdown",
"id": "167ed5c4",
"metadata": {
"tags": []
},
"source": [
"## Grundlegendes\n",
"\n",
"Mit type()
kann der Datentyp eines Objektes ausgegeben werden.\n",
"\"Zahlen\" werden immer als \"naheliegenden\" Datentype initialisiert, können jedoch mit z.B. int( )
als Integer umgewandelt werden. \n",
"\n",
"Strings werden mit \" \"
oder ' '
erstellt. \n",
"Außerdem wird der Imagiänarteil einer komplexen Zahl mit j
gekennzeichnet"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "51d4d26f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"#
wird ein Kommentar markiert, d.h. der Inteprter ignoeriert was nach # kommt."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "7a1a84a5",
"metadata": {},
"outputs": [],
"source": [
"# wichtige Inforamtion zum Verstehen des Codes"
]
},
{
"cell_type": "markdown",
"id": "6c81d456",
"metadata": {},
"source": [
"Selbstverständlich können Werte auch in Variablen gespeichert werden. Dies geschieht mit =
.\n",
" \n",
"So wird zum Beispiel durch x=3
wird eine Variable x mit dem Wert 3 erstellt."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "a8f7de1b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3\n"
]
}
],
"source": [
"x=3\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"id": "c3759d6c",
"metadata": {},
"source": [
"Für numerische Datentypen funktioneren die Grundrechenarten wie zu erwarten. Eine Potenz $a^b$ erhält man durch a**b
.\n",
"\n",
"Der Modulo-Operator wird in Python mit %%
aufgerufen und mit //
wird ganzzahlig geteilt."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "d17f7804",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6\n",
"12\n",
"63.699999999999996\n",
"2.0\n",
"9\n",
"1\n",
"1\n",
"0\n"
]
}
],
"source": [
"print(3+3)\n",
"print(16-4)\n",
"print(7*9.1)\n",
"print(4/2)\n",
"print(3**2)\n",
"\n",
"print(5%2)\n",
"print(3//2)\n",
"print(3//4)"
]
},
{
"cell_type": "markdown",
"id": "72002ad6",
"metadata": {},
"source": [
"Booleans nehmen die Werte True
und False
an.\n",
"Python verfügt über die üblichen logischen Operatoren: \"und\", \"oder\", \"nicht\" und \"xor\".\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "c8093ef5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n",
"False\n",
"True\n",
"True\n",
"False\n",
"True\n",
"True\n",
"True\n"
]
}
],
"source": [
"x=True\n",
"y=False\n",
"print(x&y) #und\n",
"print( x and y) #alterntaives und\n",
"\n",
"print(x|y) #oder\n",
"print(x or y) #alternatives oder\n",
"\n",
"print(not x) #nicht\n",
"print(x^y) #xor, exclusives oder\n",
"\n",
"\n",
"print(x is True) #Werteabfrage für True oder False\n",
"#print(x is 1) #klappt nur mit Booleans....1 und 0 wirft einen Fehler\n",
"print(x==1) #Vergleich mit \"numerischen True\"\n"
]
},
{
"cell_type": "markdown",
"id": "5694efb3",
"metadata": {},
"source": [
"Hier wurde schon einer der in Python implementierten Vergleichsoperatoren benutzt.\n",
"Vergleichsoperatoren vergleichen zwei Objekte und liefern einen Boolen zurück. Für skalare Zahlen sind in Python die folgenden Operatoren definiert."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "24ff5cc2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n",
"False\n",
"True\n",
"False\n",
"True\n",
"False\n"
]
}
],
"source": [
"print(1==1) #gleich\n",
"print(1!=1) #ungleich\n",
"print(1<2) #kleiner als\n",
"print(1>2) #größer als\n",
"print(1<=2) #kleiner oder gleich\n",
"print(1>=2) #größer oder gleich"
]
},
{
"cell_type": "markdown",
"id": "28fc2449",
"metadata": {
"tags": []
},
"source": [
"## Listen\n",
"\n",
"In python lassen sich Listen mit [ ]
initialisieren und diverse Operationen darauf ausführen."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "65f17ad8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5, 6, 0]\n",
"[0, 1, 2, 3, 4, 5, 6]\n",
"7\n"
]
}
],
"source": [
"l=[1,2,3,4,5,6]\n",
"l.append(0)\n",
"print(l)\n",
"l.sort()\n",
"print(l)\n",
"print(len(l))\n"
]
},
{
"cell_type": "markdown",
"id": "406a3705",
"metadata": {},
"source": [
"# 2. Packages\n",
"\n",
"Bis jetzt haben wir nur mit der Basisfunktion von Python gearbeitet, jedoch gibt es unzählige Packages, die Funktionen und Datensätze enthalten.\n",
"Diese müssen einmalig mit dem Befehl import
im Skript geladen werden. \n",
"Um nicht immer den kompletten Namen des Packages tippen zu müssen ist es übliche ein Package unter einer Abkürzung zu importieren.\n",
"Das wohl wichtigste Package in Python ist numpy, meist mit np abgekürzt. Die Python Basisversion kann zum Beipsiel nicht mit Matrizen oder Vektoren umgehen, deshalb beginnt in der Regel jedes Skript mit import numpy as np
um mathematische Grundoperationen auszuführen.\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "aba8fb9b",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "markdown",
"id": "8f95f182",
"metadata": {},
"source": [
"## Vektoren und Matrizen\n",
"\n",
"### Vektoren\n",
"\n",
"Wie gerade schon angedeuted lassen sich Werte auch in Arrays speichern. Arrays sind ein, zwei oder n- dimensionale Objekte in denen sich mehrere Werte speichern lassen.\n",
"Aufgrund des mathematischen Schwerpunkts benutzen wir hier in dieser Einfühung die Worte Array und Vektor, bzw. 2D Array und Matrix synonym.\n",
"Mit der Funktion np.array( )
können wir einen Vektor erstellen"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "faea4ed4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1 2 7]\n",
"[1 2 7 4 5 6]\n"
]
}
],
"source": [
"x=np.array([1,2,7])\n",
"y=np.array([4,5,6])\n",
"\n",
"print(x)\n",
"print(np.append(x,y))\n"
]
},
{
"cell_type": "markdown",
"id": "0410b6a4",
"metadata": {},
"source": [
"Die oben beschriebenen Grundrechenarten können auch Vektoren angewendet werden und werden dabei elementweise verstanden."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "f0534878",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 5 7 13]\n",
"[ 4 5 10]\n"
]
}
],
"source": [
"print(x+y)\n",
"print(x+3)"
]
},
{
"cell_type": "markdown",
"id": "f9fbdb5e",
"metadata": {},
"source": [
"Die grundlegenden Funktionen wie log(),exp(),min(),sin(),..
sind in numpy implementiert und lassen sich einfach auf Vektoren anwenden.\n",
"Besonders nützlich ist die Funktion len()
, welche die Länge des Vektors ausgibt.\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "a308e84c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0. 0.69314718 1.94591015]\n",
"[0.84147098 0.90929743 0.6569866 ]\n",
"7\n",
"7\n",
"3\n",
"(3,)\n"
]
}
],
"source": [
"print(np.log(x))\n",
"print(np.sin(x))\n",
"print(x.max())\n",
"print(max(x))\n",
"\n",
"print(len(x))\n",
"print(np.shape(x))"
]
},
{
"cell_type": "markdown",
"id": "a6420741",
"metadata": {},
"source": [
"Informationen zu Funktionnen können mit help()
ausgegeben werden.\n",
"Übrigens: Durch drücken von \"Tab\" öffnet sich ein drop-down-Menü, welches Funktionen auflistet, die auf dem Object (z.B. auf dem Vektor) ausgeführt werden können, oder gibt mögliche Vervollständigungen einer bereits begonnenen Funktion."
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "f679e25b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on ufunc:\n",
"\n",
"sqrt = np.array(...)
initialisieren. Eigentlich gibt es in numpy die Subklasse np.matrix(...)
welche strikt zwei-dimensional ist und deshalb sehr selten verwendet wird. "
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "5ec251fe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1 2 3]\n",
" [4 5 6]\n",
" [7 8 9]]\n",
"[[2. 2. 2.]\n",
" [2. 2. 2.]\n",
" [2. 2. 2.]]\n"
]
}
],
"source": [
"Telefon=np.array([[1,2,3],[4,5,6],[7,8,9]])\n",
"Eins=np.ones([3,3])\n",
"\n",
"print(Telefon)\n",
"print(Eins+1)"
]
},
{
"cell_type": "markdown",
"id": "5738babc",
"metadata": {},
"source": [
"Und der Zugriff erfolgt entweder elementweise, oder spalten/zeilenweise"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "44027b68",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"8\n",
"[1 2 3]\n",
"[2 5 8]\n"
]
}
],
"source": [
"print(Telefon[2,1]) # Eintrag an Stelle 3,2\n",
"print(Telefon[0,:]) # 1. Zeile\n",
"print(Telefon[:,1]) # 2. Spalte\n",
" "
]
},
{
"cell_type": "markdown",
"id": "bbea23fe",
"metadata": {},
"source": [
"Auch für Matrizen gibt es unzählige Rechenoperationen. Hier eine kleine Auswahl"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "e0bcc46a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 1 4 9]\n",
" [16 25 36]\n",
" [49 64 81]]\n",
"[[ 1 4 9]\n",
" [16 25 36]\n",
" [49 64 81]]\n",
"[[ 30 36 42]\n",
" [ 66 81 96]\n",
" [102 126 150]]\n",
"[[ 2. 3. 4.]\n",
" [ 5. 6. 7.]\n",
" [ 8. 9. 10.]]\n",
"[[5. 5. 5.]\n",
" [5. 5. 5.]\n",
" [5. 5. 5.]]\n",
"[[6. 6. 6.]\n",
" [6. 6. 6.]\n",
" [6. 6. 6.]]\n",
"[[1 4 7]\n",
" [2 5 8]\n",
" [3 6 9]]\n",
"[-0.33333333 0.66666667 0. ]\n"
]
}
],
"source": [
"print(Telefon*Telefon) #elementweise Multiplikation\n",
"print(np.multiply(Telefon,Telefon)) #Alternative elementweise Mulitplikation\n",
"print(Telefon@Telefon) #Matrixmultiplikation\n",
"\n",
"print(Telefon+Eins) #Matrixaddition\n",
"print(5*Eins) #Mulitplikation mit einer Konstanten\n",
"print(5+Eins) #Addition mit einer Konstanten\n",
"\n",
"print(Telefon.T) #Transponieren\n",
"\n",
"b=np.array([1,2,3]) \n",
"x=np.linalg.solve(Telefon,b) # Löse Ax=b\n",
"\n",
"print(x)\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "6a43e413",
"metadata": {},
"source": [
"# 3. Funktionen\n",
"\n",
"Durch Funktionen lassen sich gewisse Operationen leichter an verscheidenen Stellen ausführen und der Code wird dadurch übersichtlicher. Definiert werden Funktionen in einer Funktionsumgebung und können dann an einer beliebeigen Stelle im Skript aufgerufen werden.\n",
"\n",
"Innerhalb einer Funktion können Variablen definiert werden, diese überschreiben keine gleichnamigen Variablen außerhalb der Funktion.\n",
"\n",
"Falls es lokal, innerhalb einer Funktion eine Variable nicht gibt, wird auf die globale Variable mit dem gleichen Namen zugegriffen.\n",
"\n",
"Mit return
wird ein Wert zurück gegeben. Ohne das Stichwort return wird die letzte Zeile inerhalb der Funktion zurückgegeben.\n",
"\n",
"Achtung: Anders als in R, MATLAB oder Java werden in Python Funktionen(und Schleifen, usw.) nicht durch Klammern oder ähnliches definiert, sondern durch def
und Einrückungen. Eine Funktion endet in der letzten Zeile die noch einerückt ist.\n",
"Beachte den Doppelpunkt am Ende der def-Zeile\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "c6c78b90",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"8\n",
"8\n",
"1\n",
"19\n"
]
}
],
"source": [
"def addition(a,b,c):\n",
" a=a+b+c #hier wird a lokal in der Funktion überschrieben\n",
" print(a)\n",
" return a\n",
"\n",
"def globalerZugriff(): #Funktion ohne Argument\n",
" return d\n",
"a=1\n",
"b=2\n",
"c=5\n",
"d=19\n",
"\n",
"print(addition(a,b,c)) #ausführen der Funktion\n",
"print(a) #das globale a wurde nicht überschrieben\n",
"\n",
"print(globalerZugriff())"
]
},
{
"cell_type": "markdown",
"id": "c3b5d334",
"metadata": {},
"source": [
"Bei der Übergabe können default-Parameter festgelegt werden, die benutzt werden, sofern nichts anderes angegeben wird. "
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "df77366f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.8660254037844386\n",
"0.8660254037844386\n",
"1.7320508075688772\n"
]
}
],
"source": [
"def sinus(x,ampl=1,shift=0):\n",
" return ampl*np.sin(x-shift)\n",
"\n",
"x=np.pi/3\n",
"\n",
"print(sinus(x))\n",
"print(sinus(x,1,0))\n",
"print(sinus(x,2))"
]
},
{
"cell_type": "markdown",
"id": "7470a04f",
"metadata": {},
"source": [
"Außerdem kann die Reihenfolge der Inputparamter vertauscht werden, wenn diese mit =
übergeben werden"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "d9b699fc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.2622064772118446\n"
]
}
],
"source": [
"print(sinus(ampl=1.5,x=1))"
]
},
{
"cell_type": "markdown",
"id": "81aff41b",
"metadata": {},
"source": [
"# 4. Schleifen und Bedingungen\n",
"\n",
"## 4.1 If - Bedingungen\n",
"Eine If Bedigung hat eine Boolean als Input und führt je nach Zustand eine Operation aus.\n",
"\n",
"Die einfachste If- Bedingung hat die Gestalt\n",
"\n",
" if Bedingung:\n",
" Anweisung \n",
"
\n",
"\n",
"Dies lässt sich zu einem \"Entweder, oder\" erweitern\n",
"\n",
" if Bedingung:\n",
" Anweisung \n",
"else:\n",
" Anweisung alternativ\n",
"
\n",
"\n",
"Mit else if
lassen sich mehrere Fälle abfragen, wobei immer der erste Fall der zutrifft eintritt\n",
"\n",
" if Bedingung:\n",
" Anweisung \n",
"elif Bedinung 2:\n",
" Anweisung alternativ\n",
"else:\n",
" Anweisung alternativ 2\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "e0177829",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Kleine Zahl\n",
"Null oder positiv\n",
"Bleibt nur noch Null\n"
]
}
],
"source": [
"x=0\n",
"\n",
"if x<10:\n",
" print(\"Kleine Zahl\")\n",
" \n",
"if x<0:\n",
" print(\"neativ\")\n",
"else:\n",
" print(\"Null oder positiv\")\n",
" \n",
"if x>0:\n",
" print(\"positiv\")\n",
"elif x<0:\n",
" print(\"negativ\")\n",
"else:\n",
" print(\"Bleibt nur noch Null\")\n",
" \n",
" \n"
]
},
{
"cell_type": "markdown",
"id": "e0205a38",
"metadata": {},
"source": [
"Diese Art von If-Bedinung ist jedoch nur skalarwertig. Wollen wir Vektoren abfragen, können wir dies mit der Hilfe einer Schleife oder folgendermaßen machen"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "cbe8b790",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['negativ' 'positiv oder Null' 'positiv oder Null' 'positiv oder Null'\n",
" 'negativ']\n"
]
}
],
"source": [
"vector=np.array([-1,3,6,3,-6])\n",
"\n",
"if_output=np.where(vector<0,\"negativ\",\"positiv oder Null\")\n",
"\n",
"print(if_output)"
]
},
{
"cell_type": "markdown",
"id": "495845e5",
"metadata": {},
"source": [
"## 4.2 For Schleife\n",
"\n",
"In einer for-Schleife läuft ein Zähler über jedes Element eines Vektors. In der Regel sind dies Integer von 0 bis n-1, da man so auf andere Vektoren und Matrizen zugreifen kann, doch ist es auch möglich über z.B. Floats, Booleans oder andere Objekte zu iterieren.\n",
"\n",
"Der Vektor von 0 bis n-1 kann mit range(n)
erzeugt werden. Alternativ kann auch ein Vektor von n1 bis n2-1 mit range(n1,n2)
erzeugt werden."
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "6828ff26",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Apfel\n",
"Banane\n",
"Kiwi\n",
"Birne\n",
"Mango\n",
"Start bei 3\n",
"3\n",
"4\n",
"5\n",
"Treffer\n",
"Daneben\n",
"Treffer\n",
"Treffer\n",
"Daneben\n",
"Treffer\n",
"0.0\n",
"0.3333333333333333\n",
"0.6666666666666666\n",
"1.0\n",
"1.3333333333333333\n",
"1.6666666666666665\n",
"2.0\n",
"2.333333333333333\n",
"2.6666666666666665\n",
"3.0\n"
]
}
],
"source": [
"frucht=['Apfel','Banane','Kiwi','Birne','Mango']\n",
"\n",
"for zähler in range(len(frucht)):\n",
" print(frucht[zähler])\n",
"\n",
" \n",
"print(\"Start bei 3\")\n",
" \n",
"for zähler in range(3,6):\n",
" print(zähler)\n",
" \n",
"for bool in [True,False,True,True,False,True,]:\n",
" if bool:\n",
" print(\"Treffer\")\n",
" else:\n",
" print(\"Daneben\")\n",
" \n",
"for float in np.linspace(0,3,10):\n",
" print(float)"
]
},
{
"cell_type": "markdown",
"id": "5d5d3450",
"metadata": {},
"source": [
"## 4.3 While-Schleife\n",
"\n",
"Prinzipiell kann jede for-Schleife durch eine while-Schleife ersetzt werden und umgekehrt. Jedoch gibt es durchaus Anwendungen bei dennen das eine sinnvoller ist als das andere.\n",
"\n",
"Eine while-Schleife wiederholt so lange einen Prozess, bis eine Bedingung erfüllt ist.\n",
"\n",
"Insbesondere beim hochzählen eines Zählers ist der Operator +=
nützlich. Er addiert zum Wert davor den Wert danach.\n",
"(Analog gibt es auch -=,*=
und /=
)"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "027dce26",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"apfel\n",
"birne\n",
"banane\n",
"nutella\n",
"yap\n",
"yap\n",
"yap\n",
"yap\n",
"100\n",
"90\n",
"900\n",
"90.0\n"
]
}
],
"source": [
"zähler=0\n",
"\n",
"output=['apfel','birne','banane','nutella']\n",
"\n",
"while zähler np.random.choice(x,n,replace,prob)
, welcher n Elemente aus x zieht. Mit dem Boolean replace kann \"Zurücklegen\" aktiviert, bzw. deaktiviert werden. Mit dem Vektor prob kann die Wahrscheinlichkeit, dass ein Element gezogen wird gewichtet werden.\n",
"\n",
"Alle am PC generierten Zufallszahlen sind nicht echt zufällig, siehe [Wikipedia](https://de.wikipedia.org/wiki/Pseudozufall). Sie werden mit einem Algorithmus berechnet und können nicht vom echten Zufall unterscheiden werden, jedoch können sie reproduziert werden, indem der selbe Startwert, ein sog. Seed übergeben wird. Wird kein Seed übergeben wird bei Python die Systemzeit als Seed benutzt.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 97,
"id": "0f9a7652",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.653995701646616\n",
"[0.01816794 0.68804102 0.06483648]\n",
"[[0.40824512 0.71706737 0.87340484]\n",
" [0.22356456 0.09396803 0.62469893]\n",
" [0.48677466 0.50133861 0.04151941]]\n",
"[7 4 7]\n",
"[2 2 1]\n"
]
}
],
"source": [
"import numpy.random as nr\n",
"\n",
"nr.seed(None) #Wird normal nicht gebraucht, nur hier da der seed der weiter unten angewählt wird bei mehrmaliger Ausführung nicht gelöscht wird\n",
"\n",
"print(nr.rand()) #Zufällige Zahl zwischen 0 und 1\n",
"print(nr.rand(3)) #Vetor mit zufällligen 3 Zahlen \n",
"print(nr.rand(3,3)) #Zufällige 3x3 Matrix\n",
"\n",
"nr.seed(440) #Alle Werte über dieser Zeile sind bei jeder Ausführung\n",
" #des Skripts anders, alle unterhalb immer gleich\n",
"\n",
"print(nr.randint(1,10,3)) #3 zufällige Integer zwischen 1 und 9\n",
"\n",
"print(nr.choice(range(10),3,True)) #3 Zufällige zahlen aus range(10), mit zurücklegen\n"
]
},
{
"cell_type": "markdown",
"id": "117a2fd3",
"metadata": {},
"source": [
"Es können auch Zufallszahlen nach bestimmten Verteilungen erzeugt werden. Mehr Verteilungen findest du [hier](https://numpy.org/doc/1.16/reference/routines.random.html)."
]
},
{
"cell_type": "code",
"execution_count": 272,
"id": "b2042903",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.02090791080071198\n",
"-1.2084068982801401\n",
"4.330125065193528\n",
"7\n",
"8\n"
]
}
],
"source": [
"## Stetige Verteilungen\n",
"print(nr.beta(1,2))\n",
"print(nr.normal(0,1))\n",
"print(nr.exponential(3))\n",
"#[...]\n",
"\n",
"## Diskrete Verteilungen\n",
"print(nr.binomial(10,0.5))\n",
"print(nr.poisson(10))"
]
},
{
"cell_type": "markdown",
"id": "8b243eda",
"metadata": {},
"source": [
"# 6. Plotten\n",
"In Python gibt es mehrere Methoden zu plotten. Die wahrscheinlich üblichste ist mit Hilfe des packages matplotlib und der Funktion subplots.\n",
"\n",
"Die Funktion subplots()
gibt zwei Objekte zurück, eine \"Figure\" und \"Achsen\". Diese Bezeichnungen sind nicht unbedingt intuitiv, jedoch kann man es sich so merken:\n",
"\n",
"Figure bzeichnet das \"Bild\", welches später z.B. abgespeichert werden kann und Achsen, den Plot an sich, welchem dann Elemente wie Kurven oder Punkten hinzugefügt werden können.\n",
"\n",
"Dieses Konzept wird gleich etwas klarer.\n"
]
},
{
"cell_type": "markdown",
"id": "6b0769d4",
"metadata": {},
"source": [
"## 6.1 Lineplots, Scatterplots \n",
"\n",
"Einfach nur eine Kurve zu plotten ist sehr einfach. Dies wird mit der Methode .plot() auf dem Achsenobjekt gemacht."
]
},
{
"cell_type": "code",
"execution_count": 99,
"id": "021d0808",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"