{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "# Level 2" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "## Einstieg\n", "In diesem Level werden wir lernen, wie die Ausführung von bestimmten Code an Bedingungen knüpfen. Dafür werden wir erst den Typ des __boolean__ und im Anschluss unsere ersten Kontrollstrukturen, die if-Bedingung und die while-Schleife einführen. Dabei werden wir die Schlüsselwörter `True`, `False`, `if`, `elif`, `else`, `is`, `while`, `break` und `continue` kennenlernen.\n", "\n", "Die if-Bedingung wird es uns ermöglichen Code auszuführen, wenn eine Bedingung erfüllt ist.\n", "Die while-Schleife wird es uns ermöglichen Code __solange__ auszuführen, wie eine Bedingung erfüllt ist." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bitte etwas eingeben: 3\n", "3\n" ] } ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "zahl = int(eingabe)\n", "print(zahl)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Schauen wir uns obigen Code an. Wir erwarten eine Eingabe und versuchen aus dieser Eingabe einen integer zu entnehmen. Dies klappt auch, wenn der Benutzer eine ganze Zahl eingibt - gibt er jedoch stattdessen zum Beispiel eine Zeichenkette ein, wird ein `ValueError` geworfen. Ebenso wird ein Fehler geworfen, wenn der Benutzer nichts eingibt.\n", "Im Verlauf dieses Levels werden wir, lernen Benutzereingaben zu prüfen und entsprechend zu reagieren." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "## Der Typ boolean\n", "Der __boolean__ ist ein Typ, der genau zwei Werte besitzt: `True` und `False`. In Python3 sind diese beiden Literale Schlüsselwörter und können somit nicht als Variablennamen benutzt werden. Mit der `bool()`Funktion kann ein Wert in einen boolean umgewandelt werden." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "b1 = True\n", "b2 = False\n", "print(type(b1))\n", "print(type(b2))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Der Typ eines Objektes bestimmt, wie dieses in einen boolean umgewandelt wird. Für die bisherigen Typen integer, float und string gilt:\n", "* ein integer ist `True`, solange er nicht `0` ist\n", "* ein float ist `True`, solange er nicht `0.0` ist\n", "* ein string ist `True`, solange er nicht leer, d.h. `''` ist" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "False\n", "False\n" ] } ], "source": [ "print(bool(\"\"))\n", "print(bool(0))\n", "print(bool(0.0))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Genauso wie integer und floats gibt es auch für booleans Operatoren:\n", "* `and` das logische \"und\"\n", "* `or` das logische \"oder\"\n", "* `not` die logische Negation\n", "\n", "Außerdem lässt sich auch xor (`^`) auf booleans anwenden." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "not True: False\n", "True or False: True\n", "True and False: False\n", "True ^ False: True\n" ] } ], "source": [ "print(\"not True:\", not True)\n", "print(\"True or False:\", True or False)\n", "print(\"True and False:\", True and False)\n", "print(\"True ^ False:\", True ^ False)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Häufig möchte man Werte mit einander vergleichen, dafür gibt es die Vergleichsoperatoren, die für viele Typen definiert sind:\n", "\n", "* `==`: prüft auf Äquivalenz\n", "* `!=`: prüft auf Nicht-Äquivalenz\n", "* `>`: echtes größer\n", "* `<`: echtes kleiner\n", "* `>=`: größer gleich\n", "* `<=`: kleiner gleich\n", "* `is`: prüft auf Gleichheit\n", "\n", "Diese Operatoren liefern alle einen boolschen Wert, d.h. einen Wert vom Typ boolean zurück." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(5 < 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### \"==\" und \"is\"\n", "`==` prüft, ob die Objekte, auf die die Variablen zeigen, äquivalent sind.
\n", "`is` prüft, ob die Variablen auf dasselbe Objekt zeigen." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "==: True\n", "is: False\n" ] } ], "source": [ "print(\"==:\", 10**3 == 1000)\n", "print(\"is:\", 10**3 is 1000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## if-Bedingung\n", "Nun da wir gelernt haben, was boolean-Werte sind, können wir diese in einer if-Abfrage benutzen: Codeteile nur dann ausführen, wenn eine Bedingung erfüllt ist. Sehen wir uns zunächst die Syntax einer if-Abfrage in Python an:\n", "```python\n", "if Bedingung:\n", " Befehle\n", "```\n", "Wir starten mit dem Schlüsselwort `if`, dann kommt eine Bedingung, diese sollte einen boolschen Ausdruck zurückgeben, wir können diesen explizit angeben, der Interpreter ruft allerdings auf unsere Bedingung `bool()` auf und führt unsere Befehle aus, wenn dies `True`zurück gibt. Nach der Bedingung folgt ein Doppelpunkt `:`. Die nächste Zeile wird nun eingerückt, hierbei hat man sich auf __vier Leerzeichen__ geeinigt." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bitte etwas eingeben: 3\n", "3\n" ] } ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "if eingabe: # alternativ: bool(eingabe) oder eingabe != \"\"\n", " print(eingabe)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Im obigen Codebeispiel prüft die if-Bedingung, ob der String `eingabe` leer ist. Dies geschieht implizit, d.h. es wird ausgenutzt, dass der Interpreter die Bedingung in einen boolean umwandelt. In dem Kommentar sind alternative Bedingungen beschrieben, die daselbe erreichen, allerdings umständlicher sind.
\n", "Wenn wir uns aber an unser Problem aus der Einleitung erinnern, war unser Ziel eine Zahl aus der Eingabe zu lesen und Fehler durch falsche Benutzereingaben abzufangen. Wir wollen also darauf reagieren, wenn nichts eingegeben wurde, wenn eine Zahl eingegeben wurde und wenn eine Zeichenkette eingegeben wurde, die nicht als integer interpretiert werden kann." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bitte etwas eingeben: 3\n", "3\n" ] } ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "\n", "if eingabe.isdigit():\n", " zahl = int(eingabe)\n", " print(zahl)\n", "\n", "else:\n", " print(\"Ungültige Eingabe:\", eingabe)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Wie wir sehen können, passiert im obigen Codebeispiel eine Menge auf einmal, gehen wir es also in Ruhe durch.\n", "In der if-Abfrage wird mit der `str.isdigit()` Methode geprüft, ob der string `eingabe` nicht leer ist und nur aus Ziffern besteht; wenn dem so ist, erstellen wir einen integer `zahl` aus der Eingabe und geben diesen aus. In einem `else` Zweig, der ausgeführt wird, wenn die Bedingung der if-Abfrage nicht zutraf, geben wir dem Benutzer Feedback über seine falsche Eingabe zurück." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bitte eine Zahl eingeben: 3\n", "3 ist eine gültige Zahl.\n" ] } ], "source": [ "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", "\n", "if eingabe:\n", " # die Eingabe ist nicht leer.\n", " if eingabe.isdigit():\n", " zahl = int(eingabe)\n", " print(zahl, \"ist eine gültige Zahl.\")\n", " else:\n", " print(\"Die Eingabe ''\" + eingabe + \"' ist keine gültige Zahl\")\n", "else:\n", " print(\"Die Eingabe ist leer.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "if-Bedingungen können auch verschachtelt werden, d.h. wir können also in einer if-Bedingung eine weitere if-Bedingung definieren. Allerdings können wir dies durch die Benutzung des Schlüsselwortes `elif` vereinfachen:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bitte eine Zahl eingeben: 3\n", "3 ist eine gültige Zahl.\n" ] } ], "source": [ "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", "\n", "if eingabe.isdigit():\n", " # die Eingabe ist eine gültige Zahl\n", " zahl = int(eingabe)\n", " print(zahl, \"ist eine gültige Zahl.\")\n", " \n", "elif not eingabe:\n", " # die Eingabe ist leer\n", " print(\"Die Eingabe ist leer\")\n", " \n", "else:\n", " # die Eingabe ist nicht leer, aber auch keine\n", " # gültige Zahl\n", " print(\"Die Eingabe '\" + eingabe + \"' ist keine gültige Zahl\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eine if-Bedingung enthält einen if-Zweig, beliebig viele optionale elif-Zweige und optional einen else-Zweig. Dabei wird immer der erste Zweig, dessen Bedingung zutrifft ausgeführt und nachher keine weiteren.\n", "Daher ist es wichtig auf die Reihenfolge der Zweige zu achten." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## while-Schleife\n", "Bisher ist es sehr schwierig Code mehrfach auszuführen, wenn wir unsere Programme wiederholen müssen wir sie neu starten. Nicht nur das, sondern haben wir keine Möglichkeit Befehle beliebig häufig auszuführen. Die Möglichkeit Code wiederholt auszuführen ist allerdings für viele Programme ein elementarer Bestandteil. Daher möchten wir uns im dritten Abschnitt dieses Levels mit der while-Schleife beschäftigen, die diese Probleme löst.\n", "\n", "Die while-Schleife ist im Aufbau ähnlich der if-Bedingung:\n", "```python\n", "while Bedingung:\n", " Befehle\n", "```\n", "Der Unterschied ist, dass unsere Befehle, solange wiederholt werden, wie die Bedingung gültig (d.h. == True) ist. Hierbei ist Vorsicht geboten, da es zu Endlosschleifen kommen kann." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "counter = 0\n", "while counter < 10:\n", " print(counter)\n", " counter += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Im obigen Codeblock sehen wir eine einfache Anwendung der while-Schleife. Kommentieren wir jedoch die letzte Zeile aus, kommt es zu einer Endlosschleife. In diesem Zusammenhang der Hinweis, dass sich im Interpreter Python Programme durch drücken von Strg + C abbrechen lassen.\n", "\n", "Innerhalb einer while-Schleife ist es möglich mit dem Schlüsselwort `break` den Durchlauf der Schleife abzubrechen oder mit dem Schlüsselwort `continue` den aktuellen Durchlauf zu überspringen. Bei der Benutzung von `continue`müssen wir wieder darauf achten keine Endlosschleifen zu erstellen." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start.\n", "Bitte etwas eingeben: Hallo\n", "Hallo\n", "-----\n", "Bitte etwas eingeben: C\n", "Bitte etwas eingeben: Q\n", "Fertig.\n" ] } ], "source": [ "print(\"Start.\")\n", "while True:\n", " eingabe = input(\"Bitte etwas eingeben: \")\n", " if not eingabe:\n", " break\n", " elif eingabe == \"Q\":\n", " break\n", " elif eingabe == \"C\":\n", " continue\n", " else:\n", " print(eingabe)\n", " print(len(eingabe)*\"-\")\n", " \n", "print(\"Fertig.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Das Schlüsselwort `else` kann nicht nur in einer if-Bedingung, sonder auch in Verbindung mit einer while-Schleife benutzt werden. Dabei wird der else-Zweig ans Ende der entsprechenden while-Schleife angefügt. Der Code des else-Zweiges wird dann nur ausgeführt, wenn die Schleife __nicht__ durch ein `break` abgebrochen wurde." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Die gesuchte Zahl x ist 0 < x < 100.\n", ": 50\n", "Größer\n", "Noch 9 Versuche.\n", ": 75\n", "Kleiner.\n", "Noch 8 Versuche.\n", ": 62\n", "Kleiner.\n", "Noch 7 Versuche.\n", ": 56\n", "Richtig!\n" ] } ], "source": [ "# Zahlen raten\n", "gesucht = 56\n", "versuche = 10\n", "zähler = 0\n", "print(\"Die gesuchte Zahl x ist 0 < x < 100.\")\n", "\n", "while zähler < versuche:\n", " eingabe = input(\": \")\n", " zähler += 1\n", " # eingabe überprüfen\n", " if eingabe.isdigit():\n", " zahl = int(eingabe)\n", " else:\n", " print(\"Ungültige Eingabe.\")\n", " continue\n", " \n", " # Benutzer Feedback\n", " if zahl == gesucht:\n", " print(\"Richtig!\")\n", " break\n", " else:\n", " if zahl > gesucht:\n", " print(\"Kleiner.\")\n", " else:\n", " print(\"Größer\")\n", " print(\"Noch\", versuche-zähler, \"Versuche.\")\n", " \n", "\n", "else:\n", " # kein break <=> zahl wurde nicht erraten\n", " print(\"Die Zahl wurde nicht erraten.\")\n", " print(\"Die richtige Zahl war:\", gesucht)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Rückblick\n", "Vor diesem Level konnten wir nur sehr begrenzte Programme schreiben. Wir konnten Eingaben entgegennehmen, mit dieser Eingabe Berechnungen (im weitesten Sinne) durchführen und die Ergebnisse dieser Berechnungen wieder ausgeben. Dieses Level hat nun die if-Bedingung und die while-Schleife eingeführt. Diese beiden Kontrollstrukturen ermöglichen uns das Schreiben komplexer Programme und die Implementation anspruchsvoller Algorithmen. die if-Bedingung sorgt dafür, dass unsere Programme nun auf Eingaben zu reagieren und Fehler abzufangen. Die while-Schleife ermöglicht es uns Befehle beliebig häufig auszuführen. Damit sind schon im zweiten Level wichtige Bausteine für komplexe Programme eingeführt worden." ] } ], "metadata": { "celltoolbar": "Raw Cell Format", "kernelspec": { "display_name": "Python 3", "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.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }