mirror of
https://gitlab.rlp.net/pgp/pgp1-python-einfuehrung
synced 2024-11-16 13:48:11 +00:00
Musterloesung mit Pythonfehlermeldungen erweitert.
This commit is contained in:
parent
780a609371
commit
b89a9d149b
2 changed files with 278 additions and 4 deletions
|
@ -4,7 +4,256 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Bestimmen der Fallbeschleunigung des Planeten X:\n",
|
||||
"# Musterlösung:\n",
|
||||
"\n",
|
||||
"Die Musterlösugen der einzelnen Aufgaben befindet sich direkt in den entsprechenden Jupyter-Notebooks. In diesem Notebook möchte ich nochmal auf einige beliebte Fehler so wie die Auswertungsaufgabe zum Thema Fitten eingehen. \n",
|
||||
"\n",
|
||||
"## Fehlermeldungen in Python:\n",
|
||||
"Einigen von euch sind über ein paar Fehlermeldungen gestolpert und wussten nicht genau wie diese zu beheben sind. Im Grunde sind Fehlermeldungen in Python sehr einfach zu verstehen und es bedarf lediglich ein wenig Übung. Schauen wir uns zunächst einmal eine typische Fehlermeldung in Python an:\n",
|
||||
"\n",
|
||||
"<img src=\"images/ExampleTraceback.png\" alt=\"Tab-Taste\" width=\"1000\"/>\n",
|
||||
"\n",
|
||||
"Diese sieht erst einmal schrecklich kompliziert aus, die wichtigsten Informationen sind jedoch farbig hervorgehoben. Gehen wir diese doch einmal Schritt für Schritt durch.\n",
|
||||
"\n",
|
||||
"1. Art der Fehlermeldung. Meistens ist dies ein erster guter Indikator wie der Fehler zustanden gekommen ist.\n",
|
||||
"2. Beschreibung des Fehlers, hier steht meistens etwas ausführlicher was genau das Problem ist. Wir werde uns im Nachfolgenden noch ein paar Beispiele angucken.\n",
|
||||
"3. Ort in eurem Hauptprogramm an dem der Fehler aufgetreten ist. \n",
|
||||
"4. Exakte Position an welcher der Fehler aufgetreten ist. Dies kann gleich sein mit Punkt 3. sofern eure Funktion nicht innerhalb einer weiteren Funktion (hier `curve_fit`) verwendet wird. \n",
|
||||
"\n",
|
||||
"Der schwarz umrandete Teil kann bei sehr komplexen Funktionen sehr länglich ausfallen. In der Regel können wir dies jedoch ignorieren und uns nur auf den Anfang und das Ende der Fehlermeldung konzentrieren.\n",
|
||||
"\n",
|
||||
"### Beispiele:\n",
|
||||
"\n",
|
||||
"Im Folgenden möchte euch ein paar beliebte Fehler vorstellen. Führt einfach die entsprechenden Zellen aus um die Fehlermeldung euch anzugucken.\n",
|
||||
"\n",
|
||||
"Fangen wir einfach an:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nicht_definiert"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Diese Fehlermeldung ist relative selbsterklärend. Der Fehlertyp ist ein `NameError` und der dazugehörige Fehlertext sagt uns, dass die Variable `nicht_definiert` noch nicht definiert wurde. \n",
|
||||
"\n",
|
||||
"Außerdem verrät uns Python, dass `nicht_definiert` in Zeile 1 unserer Zelle ausgeführt wird. Um die Zellennummerierung angezeigt zubekommen müsst ihr die Zelle anwählen und mit Esc in den Editiermodus wechseln. Nun könnt ihr mit dem Buchstaben \"L\" die Zeilennummerierung aktivieren. Dies kann bei längeren Code-Blöcken sehr hilfreich sein. \n",
|
||||
"\n",
|
||||
"Ein ähnlicher Fehler tritt auf sofern ihr versucht eine Funktion aus einem Package zu laden welche nicht existiert. Zum Beispiel, weil ihr euch verschrieben habt:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"plt.plott([1,2,3,4]) # vertippt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Da es sich hierbei jedoch um eine Funktion innerhalb eins Packages handelt spricht man von einem `AttributeError` (Warum es sich um ein Attribut handelt lernt ihr noch ausführlicher in anderen Programmierveranstaltungen). \n",
|
||||
"\n",
|
||||
"Richtig wäre:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.plot([1,2,3,4]) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ein weiterer beliebter Fehler ist der folgende:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"a = 1+1\n",
|
||||
"b = 2\n",
|
||||
"[[1,a,b,4] # Beispiel verschachtelte Liste"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Bei diesem Fehler handelt es sich um einen Syntaxfehler, der besagt, dass Python das Ende eures Codes erreicht hat (end of file EOF), jedoch nicht alle Code-Blöcke abgeschlossen sind. In diesem konkreten Beispiel liegt es daran, dass wir vergessen haben die Klammer der zweiten Liste zu schließen. Korrigiert sieht die Zelle wie folgt aus:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"a = 1+1\n",
|
||||
"b = 2\n",
|
||||
"[[1,a,b,4]] # Beispiel verschachtelte Liste"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Dieser Fehler kann auch vorkommen sofern ihr Code-Blöcke in for-Schleifen vergesst."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for i in range(4):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Manche von euch haben versehentlich einen Zeilenumbruch innerhalb eines string verwendet. Hier bekommt ihr eine ähnliche Fehlermeldung."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(\"String mit \n",
|
||||
" Zeilenumbruch\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So wäre es richtig:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(\"String mit \" \n",
|
||||
" \"Zeilenumbruch\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ein anderer Fehler, welcher mal leicht durch das überdefinieren von Variablen passieren kann, ist der folgende:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def quadrat(x):\n",
|
||||
" return x**2\n",
|
||||
"\n",
|
||||
"quadrat = [1**2, 2**2, 3**2]\n",
|
||||
"\n",
|
||||
"quadrat(3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"oder"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"quadrat = 2\n",
|
||||
"quadrat(3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Bei dieser Art von Fehler handelt es sich um einen TypeError. Ein TypeError besagt, dass ein Objekt (hier `quadrat`) nicht mit dem vom Python erwartenden Typ übereinstimmt. In unserem obigen Beispiel erwarten wir ein Objekt vom Typ `callable` was im Allgemeinen eine Funktion represntiert z.B.: unsere Funktion:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"def quadrat(x):\n",
|
||||
" return x**2\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Leider haben wir diese jedoch versehentlich einmal mit einer Liste und einmal mit einem Intiger überdefiniert. Python weiß hierdurch leider nicht, was `[1**2, 2**2, 3**2](3)` bzw. `3(3)` bedeuten soll. Versucht daher eindeutige Variablennamen zu benutzen. \n",
|
||||
"\n",
|
||||
"Als letztes hier noch ein Fehler, welcher euch beim Plotten und Fitten unterlaufen kann:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"xWerte = [1, 2, 3, 4]\n",
|
||||
"yWerte = [1, 2, 4]\n",
|
||||
"\n",
|
||||
"plt.plot(xWerte, yWerte)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Dieser Fehler besagt euch, dass eure Liste für die x-Werte und eure Liste für die y-Werte nicht die gleiche länge haben. Dies kann leicht beim Abtippen von Messdaten passieren.\n",
|
||||
"\n",
|
||||
"Ich hoffe, dass diese Beispiele euch helfen werden in Zukunft besser mit Fehlermeldungen umzugehen. Hier noch drei allgemeine Tipps zum Programmieren und Fehlerbeheben in Jupyter-Notebooks:\n",
|
||||
"\n",
|
||||
"1. Wenn ihr euren Code schreibt führt nach jeder neuen Zeile/Funktion euren Code aus und überprüft ob das Resultat mit euren Erwartungen übereinstimmt. \n",
|
||||
"2. Solltet ihr eine Fehlermeldung bekommen und ihr seht nicht genau wie dieser Fehler zu beheben ist, kopiert euch Zeile für Zeile (bzw. Funktion) den Code in eine neue Zelle und führte diesen aus. Meistens findet man hierdurch sehr schnell wo das Problem liegt. \n",
|
||||
"3. Da ihr in einem Notebook Zellen in willkürlicher Reihenfolge ausführen könnt, kann es leicht passieren, dass ihr Variablen überdefiniert. Solltet ihr also mal komplett verloren sein kann es hilfreich sein den Kernal neu zu starten, um alle Variablen zu löschen.\n",
|
||||
" * Geht hierzu in der Menüleiste auf Kernal.\n",
|
||||
" * Klickt anschließend auf Restart.\n",
|
||||
" * Anschließend müsst ihr erneut alle Zellen (in der richtigen Reihenfolge) ausführen.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Lösungen zum Thema Fitten:\n",
|
||||
"\n",
|
||||
"In diesem Abschnitt wollen wir uns den Lösungen zum Thema Fitten widmen. Neben den Musterlösungen zu den Aufgaben, befindet sich am Ende nochmal ein weiteres Beispiel zu illustration.\n",
|
||||
"\n",
|
||||
"## Bestimmen der Fallbeschleunigung des Planeten X:\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"**Versuchsbeschreibung:**\n",
|
||||
|
@ -43,13 +292,38 @@
|
|||
"time = [0.74, 0.8, 0.87, 0.94, 1.03, 1.1, 1.15, 1.17, 1.24] # in s\n",
|
||||
"dtime = [12, 11, 9, 8, 11, 12, 13, 80, 10] # in ms\n",
|
||||
"\n",
|
||||
"# Zeitfehler in s umrechnen:\n",
|
||||
"dtime = [i/1000 for i in dtime]\n",
|
||||
"# Achtung: Zeitfehler in s umrechnen, da in ms angegeben.\n",
|
||||
"dtime = [i/1000 for i in dtime]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Beim fitten von Messdaten versuchen wir immer eine eine Funktion $y$ \n",
|
||||
"\n",
|
||||
"$$y(x, p1, p2, p3) = ... $$\n",
|
||||
"\n",
|
||||
"mit den Parameter $p_i$ an unsere Messdaten anzupassen. Genau nach diesem Schema müsst ihr auch eure Funktion in Python definieren:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def fallhoehe(t, g):\n",
|
||||
" return 0.5 * g * t**2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ein paar von euch haben leider die Funktion als $h(g, t)$ oder g(t, h) definiert statt $h(t, g)$. Dies funktioniert leider nicht. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -1094,7 +1368,7 @@
|
|||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.3"
|
||||
"version": "3.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
|
BIN
images/ExampleTraceback.png
Normal file
BIN
images/ExampleTraceback.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 291 KiB |
Loading…
Reference in a new issue