Newer
Older
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Chapter 7: Iteration](http://greenteapress.com/thinkpython2/html/thinkpython2008.html) \n",
"Dieses Kapitel handelt von der Iteration - der Möglichkeit, eine Folge von Anweisungen zu wiederholen. Wir haben eine Art der Iteration unter Verwendung der Rekursion schon im [Abschnitt 5.8](seminar05.ipynb#5.8-Rekursion) gesehen und eine andere Art, mit Hilfe der `for`-Schleife, in [Abschnitt 4.2](seminar04.ipynb#4.2-Einfache-Wiederholung). In diesem Kapitel lernen wir eine weitere Variante unter Verwendung der `while`-Anweisung kennen. Aber vorher schauen wir uns noch einmal die Zuweisung eines Wertes an eine Variable an. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1>Inhaltsverzeichnis<span class=\"tocSkip\"></span></h1>\n",
"<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#7-Iteration\" data-toc-modified-id=\"7-Iteration-1\"><span class=\"toc-item-num\">1 </span>7 Iteration</a></span></li><li><span><a href=\"#Ihre-Lernziele:\" data-toc-modified-id=\"Ihre-Lernziele:-2\"><span class=\"toc-item-num\">2 </span>Ihre Lernziele:</a></span></li><li><span><a href=\"#Exkurs:-Was-mir-an-Python-gefällt\" data-toc-modified-id=\"Exkurs:-Was-mir-an-Python-gefällt-3\"><span class=\"toc-item-num\">3 </span>Exkurs: Was mir an Python gefällt</a></span></li><li><span><a href=\"#Neuzuweisung\" data-toc-modified-id=\"Neuzuweisung-4\"><span class=\"toc-item-num\">4 </span>Neuzuweisung</a></span></li><li><span><a href=\"#Variablen-aktualisieren\" data-toc-modified-id=\"Variablen-aktualisieren-5\"><span class=\"toc-item-num\">5 </span>Variablen aktualisieren</a></span></li><li><span><a href=\"#Die-while-Anweisung\" data-toc-modified-id=\"Die-while-Anweisung-6\"><span class=\"toc-item-num\">6 </span>Die <code>while</code>-Anweisung</a></span></li><li><span><a href=\"#break\" data-toc-modified-id=\"break-7\"><span class=\"toc-item-num\">7 </span><code>break</code></a></span></li><li><span><a href=\"#Quadratwurzeln\" data-toc-modified-id=\"Quadratwurzeln-8\"><span class=\"toc-item-num\">8 </span>Quadratwurzeln</a></span></li><li><span><a href=\"#Algorithmen\" data-toc-modified-id=\"Algorithmen-9\"><span class=\"toc-item-num\">9 </span>Algorithmen</a></span></li><li><span><a href=\"#Debugging\" data-toc-modified-id=\"Debugging-10\"><span class=\"toc-item-num\">10 </span>Debugging</a></span></li><li><span><a href=\"#Glossar\" data-toc-modified-id=\"Glossar-11\"><span class=\"toc-item-num\">11 </span>Glossar</a></span></li><li><span><a href=\"#7.9-Übung\" data-toc-modified-id=\"7.9-Übung-12\"><span class=\"toc-item-num\">12 </span>7.9 Übung</a></span><ul class=\"toc-item\"><li><span><a href=\"#Aufgabe-1\" data-toc-modified-id=\"Aufgabe-1-12.1\"><span class=\"toc-item-num\">12.1 </span>Aufgabe 1</a></span></li><li><span><a href=\"#Aufgabe-2\" data-toc-modified-id=\"Aufgabe-2-12.2\"><span class=\"toc-item-num\">12.2 </span>Aufgabe 2</a></span></li><li><span><a href=\"#Aufgabe-3\" data-toc-modified-id=\"Aufgabe-3-12.3\"><span class=\"toc-item-num\">12.3 </span>Aufgabe 3</a></span></li></ul></li></ul></div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ihre Lernziele:\n",
"Beschreiben Sie in 2-3 Stichpunkten kurz was Sie im Seminar heute lernen wollen. Klicken Sie dazu doppelt auf diesen Text und bearbeiten Sie dann den Text:\n",
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In dieser Rubrik, die immer am Anfang eines Kapitels steht, möchte ich Ihnen zeigen, wofür ich Python nutze und warum ich es mag. Sie werden vielleicht noch nicht verstehen, was ich genau mache, aber Sie sehen damit schon einmal die Möglichkeiten von Python und können später darauf zurückgreifen. Da dies auch ein Exkurs ist, können Sie diese Rubrik gerne auch erst einmal überspringen.\n",
"\n",
"Mit den Operatoren aus diesem Kapitel können wir ganz leicht das Verfahren zur Umwandlung einer Dezimalzahl in ihre Binärdarstellung implementieren:"
"cell_type": "code",
"execution_count": null,
"# Umwandlung einer positiven, ganzen Dezimalzahl in Binärdarstellung (als Zeichenkette)\n",
"def dez_zu_bin(n):\n",
" ergebnis = \"\"\n",
" while n > 0:\n",
" ergebnis = str(n % 2) + ergebnis\n",
" n = n // 2\n",
" return ergebnis\n",
"\n",
"print(dez_zu_bin(42))\n",
"\n",
"# Und weil wir heute beim Thema Rekursion sind ...\n",
"def dez_zu_bin_rekursiv(n):\n",
" if n == 0:\n",
" return \"\"\n",
" return dez_zu_bin_rekursiv(n // 2) + str(n % 2)\n",
"\n",
"print(dez_zu_bin_rekursiv(42))\n",
"\n",
"# Warum eigentlich auf ein Zahlensystem festlegen?\n",
"def dez_zu_allem(n, s):\n",
" if n == 0:\n",
" return \"\"\n",
" return dez_zu_allem(n // len(s), s) + s[n % len(s)]\n",
"\n",
"print(dez_zu_allem(42, \"01\"))\n",
"print(dez_zu_allem(42, \"0123456789\"))\n",
"print(dez_zu_allem(42, \"01234567\"))\n",
"print(dez_zu_allem(42, \"0123456789ABCDEF\"))\n",
"print(dez_zu_allem(42, \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"Wie Sie vielleicht schon herausgefunden haben, ist es erlaubt, mehr als nur eine Zuweisung an die selbe Variable durchzuführen. Durch eine neue Zuweisung verweist eine existierende Variable auf einen neuen Wert (und nicht mehr auf den alten Wert)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 5\n",
"print(x)\n",
"x = 7\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Wenn wir `x` beim ersten Mal ausgeben, ist sein Wert 5; beim zweiten Mal ist sein Wert 7.\n",
"\n",
"Die folgende Abbildung zeigt, wie diese **Neuzuweisung** (*reassignment*) in einem Zustandsdiagramm aussieht:\n",
"\n",
"\n",
"\n",
"An dieser Stelle wollen wir auf eine häufige Ursache für Verwechslungen hinweisen: Da Python das Gleichheitszeichen (`=`) für die Zuweisung verwendet, ist es verlockend, eine Anweisung wie `a = b` wie eine mathematische Aussage der Gleichheit zu interpretieren, das heisst, die Behauptung, dass `a` und `b` gleich seien. Aber diese Interpretation ist falsch! \n",
"Zum Einen ist Gleichheit eine symmetrische Beziehung und die Zuweisung ist es nicht. Beispielsweise gilt in der Mathematik: wenn $a=7$, dann ist auch $7=a$. Aber in Python ist die Anweisung `a = 7` erlaubt und `7 = a` ist es nicht. \n",
"Zum Anderen ist in der Mathematik eine Aussage über die Gleichheit entweder wahr oder falsch und gilt durchgängig. Wenn $a = b$ jetzt gilt, dann wird $a$ stets gleich $b$ sein. In Python kann eine Zuweisung zwei Variablen gleich machen, sie müssen aber nicht durchgängig gleich bleiben:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 5\n",
"b = a # a und b sind jetzt gleich\n",
"a = 3 # a und b sind nicht mehr gleich\n",
"print(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Die dritte Zeile ändert den Wert von `a`, aber dadurch ändert sich nicht der Wert von `b`, so dass die beiden Variablen nicht mehr gleich sind.\n",
"\n",
"Variablen neue Werte zuzuweisen ist oft nützlich, aber Sie sollten vorsichtig damit umgehen. Wenn sich die Werte von Variablen häufig ändern, ist der Code schwerer zu lesen und zu debuggen. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"Eine übliche Art der Neuzuweisung ist eine **Aktualisierung** (*update*), bei der der neue Wert vom alten Wert abhängt:\n",
"\n",
"```python\n",
"x = x + 1\n",
"```\n",
"\n",
"Das bedeutet \"nimm' den aktuellen Wert von `x`, füge eins hinzu und aktualisiere dann `x` mit dem neuen Wert\".\n",
"\n",
"Wenn wir versuchen eine Variable zu aktualisieren, die nicht existiert, erhalten wir einen Fehler, denn Python evaluiert die rechte Seite der Zuweisung bevor es den Wert der Variablen auf der linken Seite zuweist:\n"
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y = y + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Bevor wir eine Variable aktualisieren können, müssen wir sie **initialisieren**, typischerweise mittels einer Zuweisung:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y = 0\n",
"y = y + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das Aktualisieren einer Variable mittels Addition der Zahl 1 wird **inkrementieren** genannt, das Subtrahieren einer 1 **dekrementieren**.\n",
"\n",
"\n",
"\n",
"([Footnote Labyrinths](https://xkcd.com/1208/), Randall Munroe) [Erklärung des Comics](https://www.explainxkcd.com/wiki/index.php/1208:_Footnote_Labyrinths) falls Sie mehr wissen möchten."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Computer werden häufig zur Automatisierung sich wiederholender Aufgaben genutzt. Identische oder ähnliche Aufgaben zu wiederholen ohne dabei Fehler zu machen, ist etwas was Computer sehr gut können und Menschen eher schlecht. In einem Computerprogramm wird die Wiederholung auch als **Iteration** bezeichnet. \n",
"Wir haben bereits zwei Funktionen gesehen, `countdown` und `print_t`, die mit Hilfe einer Rekursion eine Wiederholung durchführen. Da Wiederholung sehr häufig benötigt wird, gibt es in Python Sprachkonstrukte, die das vereinfachen. Eines ist die `for`-Anweisung, die wir in [Abschnitt 4.2](seminar04.ipynb#4.2-Einfache-Wiederholung) kennengelernt haben. Darauf kommen wir später noch einmal zurück.\n",
"Eine andere Möglichkeit ist die `while`-Anweisung. Dies ist eine Version von `countdown`, die eine `while`-Schleife verwendet:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def countdown(n):\n",
" while n > 0:\n",
" print(n)\n",
" n = n - 1\n",
" print(\"Abheben!\")\n",
" \n",
"# probieren Sie die Funktion aus\n",
"countdown(3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Wir können die `while`-Anweisung fast so lesen, als wäre es natürliche Sprache: \"Solange `n` größer als 0 ist, zeige den Wert von `n` an und dann dekrementiere `n`. Sobald 0 erreicht ist, gib das Wort `Abheben!` aus.\"\n",
"\n",
"Der Kontrollfluss der `while`-Schleife etwas formaler ausgedrückt sieht so aus:\n",
"\n",
"1. Bestimme ob die Bedingung wahr oder falsch ist.\n",
"2. Wenn die Bedingung unwahr ist, beende die `while`-Schleife und fahre mit der Ausführung der nächsten Anweisung nach der eingerückten Folge von Anweisungen fort.\n",
"3. Wenn die Bedingung wahr ist, führe die eingerückte Folge von Anweisungen im Schleifenrumpf aus und gehe dann zu Schritt 1 zurück.\n",
"\n",
"Diese Art von Kontrollfluss wird Schleife genannt, weil der dritte Schritt wieder zum ersten Schritt springt und damit den Kreis (Schleife) schließt. (Im Englischen Original passt es besser: *This type of flow is called a loop because the third step loops back around to the top*.)\n",
"\n",
"Der Schleifenrumpf sollte den Wert einer oder mehrerer Variablen ändern, sodass die Bedingung irgendwann einmal unwahr wird und die Schleife beendet wird. Ansonsten wiederholt sich die Schleife für immer, was **Endlosschleife** (*infinite loop*) genannt wird.\n",
"\n",
"\n",
"\n",
"[Joe Ravi](https://commons.wikimedia.org/wiki/File:Apple_Campus_One_Infinite_Loop_Sign.jpg)\n",
"\n",
"Im Fall von `countdown` können wir zeigen, dass die Schleife beendet wird: wenn `n` Null oder negativ ist, dann wird die Schleife niemals ausgeführt. Ansonsten wird `n` bei jedem Schleifendurchlauf verringert, so dass wir irgendwann 0 erreichen.\n",
"\n",
"Bei anderen Schleifen ist das nicht unbedingt so einfach zu sehen, zum Beispiel hier:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def sequence(n):\n",
" while n != 1:\n",
" print(n)\n",
" if n % 2 == 0: # n ist gerade\n",
" else: # n ist ungerade\n",
" n = n*3 + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Die Schleifenbedingung ist hier `n != 1`, daher läuft die Schleife so lange, bis `n` gleich `1` ist, wodurch die Bedingung nicht mehr erfüllt ist.\n",
"\n",
"Bei jedem Schleifendurchlauf gibt das Programm den Wert von `n` aus und prüft dann, ob es eine gerade oder eine ungerade Zahl ist. Falls `n` eine gerade Zahl ist, wird `n` durch zwei geteilt. Falls `n` ungerade ist, wird der Wert von `n` ersetzt durch `n*3 + 1`. Übergeben wir der Funktion `sequence` beispielsweise 3 als Argument, dann sind die sich ergebenden Werte von `n` 3, 10, 5, 16, 8, 4, 2, 1. Probieren Sie es selbst für verschiedene Argumente aus:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sequence(23)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Da `n` manchmal wächst und manchmal schrumpft gibt es keinen offensichtlichen Beweis, dass `n` jemals 1 erreichen wird oder das Programm beendet wird. Für einige bestimmte Werte von `n` können wir zeigen, dass das Programm beendet wird. Wenn beispielsweise der Startwert eine Potenz von 2 ist (2, 4, 8, 16, 32, ...), dann ist `n` bei jedem Schleifendurchlauf eine gerade Zahl (und wird daher halbiert) bis die Schleife den Wert 1 erreicht. Das eben genannte Beispiel endet mit einer solchen Folge, die mir der Zahl 16 beginnt.\n",
"Die schwierige Frage ist, ob wir beweisen können, dass dieses Programm für *jeden* positiven Wert von `n` beendet wird. Bis jetzt hat es noch niemand geschafft, dies zu beweisen. \n",
"Es hat aber auch noch niemand geschafft das Gegenteil zu beweisen. [Collatz-Problem](https://de.wikipedia.org/wiki/Collatz-Problem).\n",
"\n",
"\n",
"([Collatz Conjecture](https://xkcd.com/710/), Randall Munroe) [Erklärung des Comics](https://www.explainxkcd.com/wiki/index.php/710:_Collatz_Conjecture) falls Sie mehr wissen möchten.\n",
"Schreiben Sie als Übung die Funktion `print_n` aus [Abschnitt 5.11](seminar05.ipynb#5.11-Rekursion) so um, dass eine Schleife statt der Rekursion verwendet wird:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def print_n(s, n):\n",
" # Implementieren Sie hier die Funktion mit Hilfe einer Schleife und ohne Rekursion\n",
" \n",
"\n",
"# Testaufruf\n",
"print_n(\"hallo\", 3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Manchmal wissen wir nicht, dass es Zeit wird eine Schleife zu beenden, bis wir den Schleifenrumpf bereits zur Hälfte ausgeführt haben. In einem solchen Fall können wir die `break`-Anweisung nutzen, um eine Schleife zu verlassen.\n",
"Nehmen wir beispielsweise an, wir wollen eine Eingabe von der Nutzer_in einlesen bis sie `fertig` eingibt. Dann könnten wir folgendes schreiben:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"while True:\n",
" line = input('> ')\n",
" if line == 'fertig':\n",
" break\n",
" print(line)\n",
"\n",
"print('Fertig!')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Die Schleifenbedingung ist `True`, was stets wahr ist, daher läuft die Schleife so lange, bis die `break`-Anweisung erreicht wird.\n",
"\n",
"Bei jedem Durchlauf wird die Nutzer_in aufgefordert, etwas einzugeben. Wenn Sie `fertig` eingibt, dann beendet die `break`-Anweisung die Schleife. Ansonsten gibt das Programm einfach nur aus, was die Nutzer_in eingegeben hat und geht zurück zum Anfang der Schleife. Probieren Sie es selbst einmal aus.\n",
"\n",
"Diese Art eine `while`-Schleife zu nutzen ist üblich, denn wir können die Bedingung überall innerhalb der Schleife prüfen (nicht nur am Anfang) und wir können die Abbruchbedingung positiv formulieren (\"beende die Schleife, wenn folgendes passiert\") statt negativ (\"fahre fort bis folgendes passiert\")."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"([Estimation](https://xkcd.com/612/), Randall Munroe) [Erklärung des Comics](explainxkcd.com/wiki/index.php/612:_Estimation) falls Sie mehr wissen möchten.\n",
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
"Schleifen werden häufig in Programmen genutzt, die numerische Werte berechnen, indem sie mit einem Näherungswert beginnen und diesen iterativ verbessern. \n",
"\n",
"Beispielsweise kann die Quadratwurzel einer Zahl mit dem [Newton-Verfahren](https://de.wikipedia.org/wiki/Newton-Verfahren) berechnet werden. Angenommen, wir wollen die Quadratwurzel von $a$ berechnen. Wenn wir mit einem (fast beliebigen) Näherungswert $x$ beginnen, können wir einen besseren Näherungswert $y$ mit der folgenden Formel berechnen:\n",
"\n",
"\\begin{equation}\n",
"y = \\frac{x + a/x}{2}\n",
"\\end{equation}\n",
"\n",
"Wenn beispielsweise $a$ gleich 4 ist und $x$ gleich 3:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 4\n",
"x = 3\n",
"y = (x + a/x) / 2\n",
"y"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das Ergebnis ist näher an der richtigen Antwort ($\\sqrt{4} = 2$). Wenn wir den Vorgang mit dem neuen Näherungswert wiederholen, kommen wir noch näher heran:"
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = y\n",
"y = (x + a/x) / 2\n",
"y "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nach ein paar mehr Aktualisierungen ist die Näherung fast exakt:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = y\n",
"y = (x + a/x) / 2\n",
"y"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = y\n",
"y = (x + a/x) / 2\n",
"y "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Im Allgemeinen wissen wir anfangs nicht, wie viele Schritte nötig sind, um die richtige Antwort zu erhalten, aber wir wissen es, wenn sich der Näherungswert nicht mehr verändert:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = y\n",
"y = (x + a/x) / 2\n",
"y "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = y\n",
"y = (x + a/x) / 2\n",
"y "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sobald `x == y` gilt, können wir abbrechen. Im Folgenden eine Schleife, die mit einem Näherungswert `x` beginnt und diesen verbessert, bis er sich nicht mehr ändert:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 4\n",
"x = 3\n",
"\n",
"while True:\n",
" print(x)\n",
" y = (x + a/x) / 2\n",
" if y == x:\n",
" break\n",
" x = y\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Für die meisten Werte von `a` funktioniert das sehr gut aber im Allgemeinen ist es gefährlich, die Gleichheit von Gleitkommazahlen zu testen. Gleitkommazahlen sind nur ungefähr exakt: die meisten rationalen Zahlen wie z.B. 1/3 und irrationale Zahlen wie z.B. $\\sqrt{2}$ können nicht exakt als Gleitkommazahl repräsentiert werden. \n",
"\n",
"Statt zu prüfen ob `x` und `y` exakt gleich sind ist es sicherer, die eingebaute Funktion `abs` zu nutzen, um den Absolutbetrag des Unterschieds zwischen den beiden Zahlen zu berechnen:\n",
"\n",
"```python\n",
"if abs(y-x) < epsilon:\n",
" break\n",
"```\n",
"\n",
"Wobei wir für `epsilon` einen sehr kleinen Wert wie z.B. `0.0000001` wählen sollten, der bestimmt, welche Näherung gut genug für uns ist. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"([Algorithms](https://xkcd.com/1667/), Randall Munroe) [Erklärung des Comics](https://www.explainxkcd.com/wiki/index.php/1667:_Algorithms) falls Sie mehr wissen möchten.\n",
"Das Newton-Verfahren ist ein klassisches Beispiel für einen **Algorithmus**: ein Prozess zur Lösung einer bestimmten Problemklasse (in diesem Fall die Berechnung von Quadratwurzeln). \n",
"\n",
"Um zu verstehen, was ein Algorithmus ist, hilft es vielleicht, sich etwas anzuschauen, was kein Algorithmus ist. Als Sie (wohl in der Grundschule) gelernt haben, Zahlen mit nur einer Ziffer zu multiplizieren, haben Sie wahrscheinlich die Multiplikationstabelle (das [Kleine Einmaleins](https://de.wikipedia.org/wiki/Einmaleins)) auswendig gelernt. Effektiv haben Sie sich damit also 100 verschiedene Lösungen gemerkt. Diese Art von Wissen ist nicht algorithmisch.\n",
"\n",
"Aber wenn Sie \"faul\" waren, haben Sie vielleicht ein paar Tricks gelernt. Beispielsweise kann man das Produkt einer Zahl $n$ mit 9 berechnen, indem man $n-1$ als erste Ziffer des Ergebnisses aufschreibt und dann $10-n$ als zweite Ziffer anhängt. Dieser Trick ist eine allgemeine Lösung, um jede Zahl mit nur einer Ziffer mit 9 zu multiplizieren. Das ist ein Algorithmus!\n",
"Genauso sind die Verfahren zur schriftlichen Addition (mit Übertrag), Subtraktion und Division Algorithmen. Eine Eigenschaft von Algorithmen ist, dass Sie keine Intelligenz benötigen, um ausgeführt zu werden. Sie sind mechanische Prozesse bei denen jeder Schritt auf den vorherigen mittels einfacher und eindeutiger Regeln folgt.\n",
"Algorithmen auszuführen ist langweilig aber sie zu entwerfen ist interessant, intellektuell herausfordernd und ein wesentlicher Teil der Informatik.\n",
"\n",
"Einige Dinge die Menschen natürlicherweise tun - ohne Schwierigkeiten oder bewusst einen Gedanken daran zu verschwenden - gehören zu den am schwersten repräsentierbaren Algorithmen. Sprachverstehen ist ein gutes Beispiel. Wir alle machen das ständig aber noch niemand konnte richtig erklären *wie* wir das machen - zumindest nicht in Form eines Algorithmus.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sobald Sie größere Programme schreiben werden Sie bemerken, dass Sie mehr Zeit mit Debuggen verbringen. Mehr Programmcode bedeutet halt auch, dass es mehr Möglichkeiten gibt, einen Fehler zu machen und mehr Stellen, an denen sich \"Bugs\" verstecken können.\n",
"Eine Möglichkeit die Zeit für das Debuggen zu reduzieren ist \"Debugging durch Halbieren\" (denken Sie an die binäre Suche). Wenn Ihr Programm beispielsweise 100 Zeilen hat und Sie jede Zeile einzeln prüfen würden, dann bräuchten Sie 100 Schritte zum Debuggen.\n",
"Stattdessen können Sie versuchen, das Problem zu halbieren. Gehen Sie (ungefähr) zur Hälfte des Programms und suchen Sie dort nach einem Zwischenwert (eine Variable), den Sie überprüfen können. Fügen Sie eine `print`-Anweisung, die den Zwischenwert ausgibt (oder etwas anderes, was einen prüfbare Auswirkung hat), hinzu und starten Sie das Programm.\n",
"\n",
"Wenn diese Überprüfung in der Mitte das falsche Ergebnis ausgibt, muss das Problem in der ersten Hälfte des Programms liegen, ansonsten in der zweiten Hälfte.\n",
"\n",
"Jedes Mal wenn Sie einen solchen Test durchführen, haben Sie die Anzahl an Codezeilen halbiert, die Sie prüfen müssen. Nach sechs Schritten (was deutlich weniger als 100 ist), sind Sie bei ein oder zwei Programmzeilen angekommen, in denen der Fehler stecken sollte - zumindest theoretisch.\n",
"\n",
"In der Praxis ist oft nicht klar, was die \"Mitte des Programms\" ist und es ist nicht immer möglich, dort einen Test hinzuzufügen. Es ist nicht sinnvoll, die Zeilen zu zählen und die exakte Mitte zu finden. Denken Sie stattdessen an Stellen im Programm, die Fehler enthalten könnten und bei denen es einfach ist, eine Überprüfung (Debug-Ausgabe) hinzuzufügen. Suchen Sie dann nach einer Stelle, bei der Sie denken, dass die Chance, dass der Fehler davor oder danach ist ungefähr gleich ist. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"Legen wir uns eine Liste mit den wichtigsten Begriffen an, die wir im Kapitel 7 gelernt haben:\n",
"\n",
"- Neuzuweisung: \n",
"- Aktualisierung:\n",
"- Initialisierung: Das Erstellen einer Variablen und die damit verbundene erste Zuweisung eines Wertes\n",
"- inkrementieren:\n",
"- dekrementieren:\n",
"- Iteration:\n",
"- Endlosschleife:\n",
"- Algorithmus: \n",
"\n",
"Ergänzen Sie die Liste in eigenen Worten. Das ist eine gute Erinnerungs- und Übungsmöglichkeit."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
"## 7.9 Übung\n",
"\n",
"### Aufgabe 1\n",
"\n",
"Kopieren Sie die Schleife aus [Abschnitt 7.8](#7.8-Quadratwurzeln) und verkapseln Sie sie in eine Funktion `mysqrt` die einen Parameter `a` erwartet, einen sinnvollen Wert für `x` wählt und eine Näherung für die Quadratwurzel von `a` zurückliefert.\n",
"\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">1. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Schreiben Sie den Kopf der Funktion, überlegen Sie welche Argumente der Funktion übergeben müssen.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">2. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Kopieren Sie, wie oben bereits erwähnt die Funktion. \n",
" \n",
" </div> \n",
"</details> \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">3. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Wenn Sie das Notebook aufmerksam gelesen haben, werden Sie sich an einige Verbesserungen erinnern, die wir vornehmen müssen.\n",
" \n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">4. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Die bedeutet, dass Sie den Betrag der Differenz zwischen `x` und `y` berechnen müssen. Anschließend vergleichen Sie, ob dieser Wert kleiner als `epsilon` ist. Nutzen Sie dazu die Betragsfunktion `abs()`. Lösung: $abs(x-y)<epsilon$ wobei Sie einen passenden Wert für `epsilon` wählen müssen (z.B. 0.001). Fügen Sie diese Änderungen in Ihren Code ein. \n",
" </div> \n",
"</details>\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">5. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Wählen Sie einen geeigneten Wert für `x` in Abhängigkeit von `a`. Dies können Sie durch Ausprobieren ermitteln. Stellen Sie sicher, dass `x` ungleich null ist. \n",
"\n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">6. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Vergessen Sie nicht Ihre Funktion mit Werten zu testen, die Sie überprüfen können.\n",
" \n",
" </div> \n",
"</details>\n"
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Implementieren Sie hier die Funktion mysqrt\n",
"\n",
"\n",
"# Testen Sie hier die Funktion\n",
"print(\"Die Wurzel von 2 ist ungefähr \", mysqrt(2))\n",
"print(\"Die Wurzel von 23 ist ungefähr \", mysqrt(23))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Testen Sie die Funktion, indem Sie eine Funktion `test_square_root` schreiben, die eine Tabelle der folgenden Art ausgibt:\n",
"```\n",
"a mysqrt(a) math.sqrt(a) diff\n",
"- --------- ------------ ----\n",
"1.0 1.0 1.0 0.0\n",
"2.0 1.41421356237 1.41421356237 2.22044604925e-16\n",
"3.0 1.73205080757 1.73205080757 0.0\n",
"4.0 2.0 2.0 0.0\n",
"5.0 2.2360679775 2.2360679775 0.0\n",
"6.0 2.44948974278 2.44948974278 0.0\n",
"7.0 2.64575131106 2.64575131106 0.0\n",
"8.0 2.82842712475 2.82842712475 4.4408920985e-16\n",
"9.0 3.0 3.0 0.0\n",
"```\n",
"\n",
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
"Dabei ist die erste Spalte eine Zahl, `a`; die zweite Spalte ist die Quadratwurzel von `a` die mit `mysqrt` berechnet wurde; die dritte Spalte ist die Quadratwurzel, die mittels `math.sqrt` berechnet wurde; und die vierte Spalte ist der Absolutbetrag des Unterschieds zwischen den beiden Werten. \n",
"\n",
"Wenn ihre Funktion funktiniert, können Sie anfange, die Tabelle zu implementieren. Dazu können Sie folgendermaßen anfangen:\n",
"\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">1. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Der Kopf der Funktion ist bereits gegeben, aber Sie können bereits den Tabellenkopf schreiben. Dafür schreiben Sie eine `print`-Anweisung für jede Zeile des Tabellenkopfs.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">2. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Als nächstes müssen Sie entscheiden ob Sie die Tabelle von oben ausgeben wollen, dann muss `a` die Werte 1 bis 9 annehmen - Sie brauchen eine Schleife - oder ob Sie die Tabelle für ein beliebiges `a` berechnen wollen, dann müssen Sie User-Input einrichten.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">3. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Wir planen für die Schleife, für diesen Fall können Sie eine `While` oder eine `For` Schleife verwenden. \n",
" \n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">4. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Prüfen Sie zunächst, ob beide Funktionen (`mysqrt()` und `math.sqrt()` Werte zurückgeben. Trifft dies auf Ihre Funktion zu? Wenn nicht, nutzen Sie die return-Anweisung an der richtigen Stelle in `mysqrt()`. \n",
" \n",
" </div> \n",
"</details>\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">5. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Die Ergebnisse der Funktionen müssen in Variablen gespeichert werden.\n",
" \n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">6. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Berechnen Sie die Differenz zwischen `mysqrt()` und `math.sqrt()` und speichern Sie diese in einer neuen Variablen.\n",
" </div> \n",
"</details>\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">7. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
"\n",
"\n",
"Fügen Sie die `print`-Anweisung hinzu, die die einzelnen Tabellenzeilen ausgibt.\n",
"\n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">8. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Vergessen Sie nicht den Wert für `a` bei jedem Schleifendurchlauf zu erhöhen. \n",
" </div> \n",
"</details>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def test_square_root():\n",
" # Implementieren Sie hier die Funktion test_square_root\n",
"# Rufen Sie hier die Funktion test_square_root auf\n",
"test_square_root()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"([Spoiler Alert](https://xkcd.com/109/), Randall Munroe) [Erklärung des Comics](https://www.explainxkcd.com/wiki/index.php/109:_Spoiler_Alert) falls Sie mehr erfahren wollen.\n"
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def mysqrt(a):\n",
" if a==1:\n",
" x=a\n",
" else:\n",
" x=a-1\n",
" \n",
" epsilon=0.00000000001\n",
" while True:\n",
" y=(x+a/x)/2\n",
" if abs(y-x) < epsilon:\n",
" break\n",
" x=y\n",
" return x\n",
" \n",
" \n",
"mysqrt(25)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"def test_square_root():\n",
" a=1.0\n",
" print('a mysqrt(a) math.sqrt(a) diff')\n",
" print('- --------- ------------ ----')\n",
" while a<10:\n",
" E= mysqrt(a)\n",
" M= math.sqrt(a)\n",
" if E<M:\n",
" diff=M-E\n",
" else:\n",
" diff=E-M\n",
" E=str(E)\n",
" M=str(M)\n",
" print(a,E,(18-len(E))*' ',M,(18-len(M))*' ',diff)\n",
" a=a+1\n",
"\n",
" \n",
"test_square_root()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Aufgabe 2\n",
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
"Die eingebaute Funktion `eval` erwartet eine Zeichenkette und führt sie dann mit dem Python-Interpreter aus. Beispielsweise:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eval('1 + 2 * 3')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"eval('math.sqrt(5)')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eval('type(math.pi)')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Schreiben Sie eine Funktion `eval_loop`, die den Nutzer iterativ bittet etwas einzugeben, die eingegebene Zeichenkette mittels `eval` ausführt und schließlich das Ergebnis ausgibt. \n",
"\n",
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
"Die Funktion sollte so lange laufen, bis der Nutzer `fertig` eingibt und dann sollte der Rückgabewert des letzten ausgeführten Ausdrucks ausgegeben werden.\n",
"\n",
"\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">1. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Schreiben Sie den Funktionskopf.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">2. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Richten Sie die Nutzereingabe ein und weisen Sie diese einer Variablen zu, damit wir den Input weiter verwenden können.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">3. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Da der Nutzer mehrfach eine Eingabe machen soll, muss diese Zuweisung innerhalb einer Schleife stattfinden. \n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">4. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Überlegen Sie, welche Schleife Sie verwenden müssen, was ist hier die Abbruchbedingung? Ist Sie positiv oder negativ?\n",
" \n",
" </div> \n",
"</details>\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">5. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Wenn `fertig` eingegeben wird, soll der letzte berechnete Wert zurückgegeben werden, daher muss dieser in einer Variablen temporär gespeichert werden.\n",
" \n",
" </div> \n",
"</details>\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">6. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Wenn nicht `fertig` eingegeben wird, wird der neue Ausdruck evaluiert und die temporären Variable wird mit dem neuen Ergebnis überschrieben.\n",
" \n",
" </div> \n",
"</details>\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">7. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
"\n",
"Vergessen Sie nicht, dass die temporäre Variable initialisiert werden muss, bevor wir sie zum Speichern von Werten verwenden können.\n",
" \n",
" </div> \n",
"</details>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Implementieren Sie hier die Funktion eval_loop"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"([Spoiler Alert](https://xkcd.com/109/), Randall Munroe) [Erklärung des Comics](https://www.explainxkcd.com/wiki/index.php/109:_Spoiler_Alert) falls Sie mehr erfahren wollen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def eval_loop():\n",
" Eval=0\n",
" while True:\n",
" line = input('> ')\n",
" if line == 'fertig':\n",
" return(Eval)\n",
" break\n",
" Eval=eval(line)\n",
" print(Eval)\n",
" print('Fertig!')\n",
" \n",
"eval_loop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Aufgabe 3\n",
"\n",
"\n",
"\n",
"Der Mathematiker [Srinivasa Ramanujan](https://de.wikipedia.org/wiki/S._Ramanujan) hat eine unendliche Folge gefunden die genutzt werden kann, um eine numerische Näherung für 1/$\\pi$ zu berechnen:\n",
"\n",
"\\begin{equation}\n",
"\\frac{1}{\\pi} = \\frac{2\\sqrt{2}}{9801} \\cdot \\sum_{k=0}^{\\infty} \\frac{(4\\cdot k)! \\cdot (1103+26390 \\cdot k)}{(k!)^4 \\cdot 396^{4\\cdot k}}\n",
"\\end{equation}\n",
"\n",
"(Eventuell ist die Formel [in der Original-Aufgabenstellung](http://greenteapress.com/thinkpython2/html/thinkpython2008.html#hevea_default541) besser zu lesen.)\n",
"\n",
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
"Schreiben Sie eine Funktion `estimate_pi` die diese Formel nutzt, um einen Näherungswert für $\\pi$ zu berechnen und zurückzugeben. Sie sollten eine `while`-Schleife nutzen, um die Terme der Summe zu solange berechnen, bis der letzte Term kleiner ist als `1e-15` (was die Python-Notation für $10^{-15}$ ist). Sie können Ihr Ergebnis prüfen, indem Sie es mit `math.pi` vergleichen.\n",
"\n",
"\n",
"\n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">1. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" Auf den ersten Blick sieht diese Formel sehr überwältigend aus. Machen Sie sich keine Sorgen, wir können die Formel in ihre einzelnen Bestandteile aufteilen und diese einzeln berechnen.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">2. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Wie Sie sehen können wird in der Formel zweimal eine Fakultät berechnet. Dafür können Sie die Funktion, die Sie in Seminar 6 geschrieben haben, verwenden.\n",
" \n",
" </div> \n",
"</details> \n",
" \n",
"<details>\n",
" <summary type=\"button\" class=\"btn btn-primary\">3. Hinweis</summary>\n",
" <div class=\"alert alert-info\" role=\"alert\">\n",
" \n",
"Berechnen Sie zuerst die Konstante vor dem Summenzeichen und speichern Sie den Wert in einer Variablen. In unserer Lösung wird diese Variable `faktor` genannt.\n",
" \n",