====== Programmieren II: Python Grundlagen ====== Slides: {{ :gf_informatik:2022_programmieren_ii.pdf |}} ===== - Von Struktogrammen zu Python ===== Du kannst nun mit Struktogrammen einfache Programme schreiben. Damit wir diese auch einem Computer zum Ausführen geben können, müssen wir diese in einer Sprache formulieren, die ein Computer versteht. Wir wählen dazu die Programmiersprache **Python**. Die Elemente, die wir bei den Struktogrammen kennengelernt haben, gibt es auch in Python. === Struktogramm === === Python === In einer **Variablen** kann ein Wert //gespeichert// werden. Zum Beispiel kann man der Variablen `x` den Wert $42$ oder der Variablen `name` den Wert `"Albert Einstein"` zuweisen. {{ :gf_informatik:x_42.png?300 |}} {{ :gf_informatik:meinnameistalbert.png?300 |}} x = 42 name = "Albert Einstein" Variablen haben unterschiedliche **Datentypen:** * `x` ist ein **Integer** (kurz **int**), also eine *ganze Zahl* * `name` ist ein **String**, also //Text//. Dafür werden Anführungs- & Schlusszeichen (`'` oder `"`) verwendet. \\ \\ Mit einer **Schleife** kann man einen Codeblock wiederholt ausführen lassen und zwar solange, wie eine vorgegebene *Bedingung erfüllt* ist. {{ :gf_informatik: struktogramme_solange.png?300 |}} Der Balken auf der linken Seite (hier blau) gibt an, welche Zeilen Code genau zum Codeblock der Schleife gehören. while : # Anweisung 1 # Anweisung 2 # ... Alle Zeilen Code, die zum Codeblock der Schleife gehören werden //gleichmässig eingerückt//. Verwende dazu die //Tab//-Taste oben links. Nachdem der ganze Codeblock ausgeführt wurde, wird die Bedingung erneut überprüft. Ist sie immer noch erfüllt, wird der gleiche Codeblock wieder ausgeführt usw. Zeilen die mit `#` beginnen, sind **Kommentare**. Diese Zeilen werden von Python *nicht als Code* aufgefasst und deshalb *ignoriert*. So kann man seinem Code Anmerkungen anfügen. In Python verwendet man die gleichen **Vergleichsoperatoren** wie in Struktogrammen: `==,<,>,<=,>=,!=` (`!=` steht für 'ungleich'). \\ \\ Mit einer **Verzweigung** kann man das Programm eine Entscheidung treffen: Je nach dem, ob eine vorgegebene Bedingung erfüllt ist oder nicht, nimmt der Code einen anderen Verlauf. {{ :gf_informatik:struktogramme_verzweigungen.png?300 |}} if : # Codeblock der ausgeführt wird, # falls (if) Bedingung erfüllt (True) ist else: # Codeblock der ausgeführt wird, # der ansonsten ausgeführt wird, # falls also Bedingung NICHT erfüllt ist (False) Auch hier muss auf eine korrekte Einrückung geachtet werden. \\ \\ **Eingabe** und **Ausgabe**: {{ :gf_informatik: struktogramme_input.png?300 |}} {{ :gf_informatik: struktogramme_input_str.png?300 |}} {{ :gf_informatik: struktogramme_output.png?300 |}} x = int(input("Gib eine Zahl ein")) # Aufforderung, etwas einzugeben, wird sichergestellt, dass Zahl (int für Integer) ist, dann in Variable x gespeichert s = str(input("Gib einen String ein")) # wie oben, wird aber als Text (String) gespeichert print(x) # der Wert der Variablen x wird in Konsole ausgegeben x = int(input("Gib eine Zahl ein")) s = str(input("Gib einen String ein")) print(x) ===== - Weitere Grundlagen ===== ++++Gruppenpuzzle| === Gruppenpuzzle === == Phase I: Expert:in werden! == * Zeit: 10' * Alle mit gleichem Thema (A,B,C) treffen sich. * Einzeln Theorie durchlesen ... * ... dann zusammen besprechen ... * ... und Fragen beantworten. * Bei Bedarf darf auch mit TigerJython ausprobiert werden. == Phase II: Austausch mit anderen Expert:innen == * Zeit: 15’ * Dreiergruppen: je A,B,C mit gleicher Nummer (z.B. A4,B4,C4) * Jede Expert:in stellt anderen ihr Thema vor. * Ziel: Alle verstehen alles! ++++ ==== - Kommentare ==== Auf den unteren Zeilen des obigen Beispiels findest du **Kommentare.** Diese beginnen mit einem Hashtag `#`. Sämtlicher Code der folgt, wird von Python //ignoriert//. Damit kann man seinem Code zum Beispiel Überschriften oder Erklärungen anfügen. Möchte man Kommentare über mehrere Zeilen schreiben, verwendet man drei Anführungszeichen: # single line comment """ multi line comment """ ++++Leitfragen| * Warum sollte man seinem Code Kommentare anfügen? * Wann braucht man `#` und wann `"""` für Kommentare? ++++ ==== - Vergleichsoperatoren ==== Für Bedingungen in Verzweigungen und Schleifen benötigen wir **Vergleichsoperatoren:** ^ Operator ^ Erklärung ^ | `x == 4` | x ist Zahl und hat Wert von genau 4 | | `s == "Hallo"` | s ist String und hat genau den Inhalt "Hallo" | | `x != 4` | x ist NICHT eine Zahl vom Wert (Ungleich-Operator). Verwende NICHT den `<>` Operator (veraltet) | | `x > 5` | x ist Zahl grösser als 5 | | `x >= 5` | x ist Zahl grösser gleich 5 | | `x < 5` | x ist Zahl kleiner als 5 | | `x <= 5` | x ist Zahl kleiner gleich 5 | ++++Leitfragen| * Bisher nicht gebraucht haben wir den `!=` Operator. Wozu ist dieser nützlich? * Mache ein konkretes Beispiel für den `!=` Operator. * Was ist der Unterschied zwischen dem `>` und dem `>=` Operator? ++++ ==== - Mathematische Operationen ==== Neben dem `+` gibt es eine Vielzahl an **mathematischen Operatoren**: ^ Funktion ^ Python-Code ^ | Addition | `7 + 3` | | Subtraktion | `7 - 3` | | Multiplikation | `7 * 3` | | Division (mit Nachkommastellen) | `7 / 3` | | Ganzzahldivision | `7 // 3` | | Hoch (z.B. 2 hoch 5) | `2**5` | | Wurzel (z.B. Wurzel von 2, sqrt für square-root) | `sqrt(2)` | | Modulo (Rest der Ganzzahl-Division, Bsp. `17 % 5 = 2`) | `17 % 2`| ++++Leitfragen| * Wie rechnet man hoch (Potenzen)? * Was ist der Unterschied zwischen `/` und `//`? * Was macht der Modulo Operator `%`? Wozu ist dieser nützlich? ++++ ==== - Strings ==== Strings werden bekanntlich mit Anführungs- und Schlusszeichen geschriebene, zum Beispiel: name = "Albert Einstein" # Ob doppeltes Anfuehrungs-/Schlusszeichen oder.... job = 'Physicist' # ... einfaches spielt keine Regel. In einem String darf man einfach nicht mischen. Oft möchte man mehrere Strings und Zahlen zu einem einzelnen String kombinieren. Einzelne Strings können mit `+` zusammengefügt werden. Möchte man eine Zahl-Variable `x` an einen String anfügen, so muss man diese zuerst in einen String umwandeln: `str(x)`. Ein String, der aus mehreren einzelnen Strings und Zahlen zusammengesetzt wurde, nennt man einen **formatierten String**. Wird der String mit print ausgegeben, so spricht man von einer **formatierten Ausgabe**. Beispiel: firstname = "Albert" lastname = "Einstein" print("Full name is " + firstname + " " + lastname + "!") Beachte, dass der **Plus-Operator** `+` komplett **unterschiedliche Bedeutungen** haben kann, je nach Situation, in der er angewendet wird: * `3 + 7`: Wird er auf *zwei Zahlen* angewendet, so handelt es sich um die normale **mathematische Addition**. Das Resultat ist also `10`. * `"Hallo " + "Klasse"` oder `"3" + "7"`: Wird er auf *zwei Strings* angewendet, werden diese **aneinander gehängt**. Resultat: `"Hallo Klasse"`, resp. `"37"` * **Mischt** man die beiden, z.B. `"Meine Lieblingszahl ist " + x` (wobei `x = 42`), so erhält man einen **Fehler**. Um diesen zu beheben, muss man den Wert von `x` vorher noch in einen String umwandeln: `"Meine Lieblingszahl ist " + str(x)` Praktisch sind auch die Befehle `lower(s)` und `upper(s)`, mit denen ein String `s` in kleinbuchstaben, resp. GROSSBUCHSTABEN umgewandelt werden. ++++Leitfragen| * Wie fügt man Strings mit Zahlen zu einem neuen String zusammen? * Dies ist nützlich, um z.B. ein mathematisches Resultat in einem Satz schön zu präsenteren. Mache ein Beispiel. * In welchen Situationen darf man den `+`-Operator (nicht) anwenden? Was sind die Unterschiede? * Wozu braucht man `lower()` und `upper()`. In welcher Situation könnten diese Funktionen nützlich sein? ++++ ==== - Zufallszahlen ==== Mithilfe des **random**-Moduls können ganz einfach Zufallszahlen erzeugt werden. Folgender Code simuliert den Wurf eines Würfels: import random z = random.randint(1,6) # bestimmt eine Zufallszahl aus Bereich 1,2,3,4,5,6 print(z) Beachte, dass die Zufallsfunktion **randint** heisst. Dies steht für '**rand**om **int**eger', also 'zufällige ganze Zahl'. Ganze Zahlen sind Zahlen ohne Nachkommastellen, also $\ldots, -3,-2,-1,0,1,2,3,\ldots$. ===== - Debugger ===== Verwende den Debugger (Breakpoints in VSCode), um deinen Code anzuhalten resp. verlangsamt durchlaufen zu lassen. Dies ist sehr nützlich um **Bugs**, also Fehler im Code, zu identifizieren. Daher auch der Name **Debugger**. ===== - Verzweigungen im Detail ===== Im Kapitel haben wir bereits **if-else-Verzweigungen** kennengelernt: if : # Codeblock der ausgeführt wird, # falls (if) Bedingung erfüllt (True) ist else: # Codeblock der ausgeführt wird, # der ansonsten ausgeführt wird, # falls also Bedingung NICHT erfüllt ist (False) Diese sind sehr praktisch, wenn man im Code zwischen **zwei verschiedenen Fällen** unterscheiden will. Gibt es aber **drei oder mehr Fälle**, muss man if-else-Verzweigungen ineinander verschachteln, wie zum Beispiel in der Schnaps, Bier & Sirup Aufgabe. Dadurch wird der Code sehr schnell unübersichtlich und fehleranfällig. Es ist dann besser, eine **if-elif-else-Verzweigung** zu programmieren, da man mit dieser **beliebig viele Fälle** unterscheiden kann: if BEDINGUNG1: # Code, falls BEDINGUNG1 erfüllt ist. elif BEDINGUNG2: # Code, falls BEDINGUNG2 erfüllt ist, aber nicht BEDINGUNG1. else: # Code, falls keine der Bedingungen erfüllt ist. Bemerkungen: * Man kann **beliebig viele** elif-Befehle hintereinander schalten. * Falls die Bedingung bei //if// oder einem //elif// erfüllt ist, werden alle darauffolgenden //elif//s gar **nicht mehr überprüft**. ===== - Funktionen ===== ++++Links zu Online-Tutorials| * Dreiteiliges Tutorial zum Thema Funktionen vom Kanal "Programmieren Starten": * Funktionen: [[https://youtu.be/LQCfN5HS9xI]] * Funktionen mit Parametern: [[https://youtu.be/af9ORp1Pty0]] * Funktionen mit Rückgabewert: [[https://youtu.be/ehSP-sYoKCY]] ++++ Wir haben gesehen, dass man mit einer while-Schleife den gleichen Codeblock mehrfach hintereinander ausführen kann. Was ist nun aber, wenn man den gleichen Codeblock //nicht// direkt hintereinander, sondern an verschiedenen Orten im Code aufrufen möchte? Nach unserem jetztigen Wissensstand bleibt uns nur Copy-Paste! Gleichzeitig wissen wir aber, dass wir uns schlecht fühlen sollen, wenn wir dies machen! Damit wir uns nicht schlecht fühlen müssen, wurden **Funktionen** erfunden: Diese erlauben es uns, den gleichen Codeblock von verschiedenen Stellen im Code aufzurufen. Funktionen sind auch nützlich, um komplexe Programme in kleinere, leichter zu programmierende Teilprogramme zu zerlegen. Beispiele: * In einem Zahlenspiel wollen wir oft überprüfen, ob eine Benutzereingabe eine nicht-negative Zahl ist. Diese Überprüfung könnte man in eine Funktion `check_user_input(...)` 'aussourcen'. * Du möchtest oft die gleiche Art Rechnung ausführen, z.B. eine lineare Gleichung lösen -> Funktion `linear_equation_solver(...)` Übrigens hast du schon viele Funktionen kennengelernt - ohne dass du es wahrscheinlich gemerkt hast. Zum Beispiel ist die Funktion `forward(...)` für Turtles eine Funktion, die ein Turtle eine gewisse Anzahl Pixel vorwärts laufen lässt. In Python wird eine Funktion wie folgt programmiert: def name_der_funktion(): # Argumente/Parameter sind optional # Codeblock # der Funktion return # ist optional * Das Schlüsselwort **def** leitet immer die Definition einer Funktion ein. * Darauf folgt der **Funktionsname**. Typischerweise schreibt man diesen mit ausschliesslich Kleinbuchstaben und Underlines _ * Direkt anschliessend werden **runde Klammern** geschrieben. Diese enthalten die **Parameter**. Das sind Werte, die an die Funktion übergeben werden. Funktionen können auch ohne Parameter definiert werden, die Klammern sind dann halt einfach leer. * Nach einem **Doppelpunkt** ... * kommt der **Funktionskörper**, welcher den eigentlichen Code der Funktion beinhaltet. Dieser Code muss **eingerückt** sein. * Eine Funktion kann (muss aber nicht) mit `return` etwas **zurückgeben**. Nachdem du eine Funktion definiert hast, kannst du sie ganz einfach aufrufen. Dazu mehr in den Beispielen unten. === Beispiel 1: Funktion ohne Parameter und Rückgabewert === Die Funktion gibt einfach "Hallo du!" aus, wenn sie aufgerufen wird. Die ersten beiden Zeilen definieren die Funktion. Unten wird sie zweimal aufgerufen, dementsprechend wird 2x "Hallo du!" ausgegeben. def say_hi(): print("Hallo du!") say_hi() say_hi() === Beispiel 2: Funktion mit Parameter und ohne Rückgabewert === Nun soll unsere Begrüss-Funktion persönlicher werden. Wir wollen sowohl Silvia wie auch Gabriele grüssen. Der Code dazu ist identisch, mit Ausnahme des Namens. Dazu können wir der Funktion einen **Parameter** (hier: den Name) übergeben. Dazu müssen wir die Funktion 'vorwarnen': In den runden Klammern schreiben wir einen Parameter hinein, hier `name` in `def say_hi(name)`. Dies sagt der Funktion, dass man ihr einen Parameter übergeben muss. Wird der Funktionskörper ausgeführt ist `name` wie eine gewöhnliche Variable, die eben diesen Parameterwert trägt. Beim ersten Funktionsaufruf unten hat `name` also den Wert `"Silvia"` und beim zweiten den Wert `"Gabriele"`. def say_hi(name): print("Hallo " + name + "!") say_hi("Silvia") say_hi("Gabriele") === Beispiel 3: Funktion ohne Parameter aber mit Rückgabewert === In einem Glücksspiel wollen wir oft einen Würfelwurf simulieren. Dazu wollen wir eine Würfelfunktion `wuerfle()` programmieren, die uns eine Zufallszahl von $1$ bis $6$ gibt: import random def wuerfle(): rand_nr = random.randint(1,6) return rand_nr print(wuerfle()) print(wuerfle()) print(wuerfle()) === Beispiel 4: Funktion mit Parameter und mit Rückgabewert === Nun wollen wir auch andere Würfel (z.B. 12er-Würfel) simulieren können. Dazu führen wir einen Parameter ein, der den maximalen Wert des Würfels festlegt: import random def wuerfle(max_nr): rand_nr = random.randint(1,max_nr) return rand_nr print(wuerfle(12)) print(wuerfle(12)) print(wuerfle(12)) In Realität ist es aber so, dass die meisten Würfel bis $6$ gehen. Wir können nun unser Leben einfacher machen, indem wir die Funktion mit einem **Standardargument** ausstatten: import random def wuerfle(max_nr=6): rand_nr = random.randint(1,max_nr) return rand_nr print(wuerfle(12)) # 12er-Wuerfel print(wuerfle()) # 6er-Wuerfel, verwendet Standardargument Der erste Funktionsaufruf simuliert natürlich einen 12er-Würfel. Der zweite einen 6er-Würfel: Da kein Parameter übergeben wird, wird das Standardargument (`max_nr=6`) verwendet. Hier ist es üblich, //keinen// Abstand links und rechts vom Operator zu machen. ===== - Listen ===== {{ :gf_informatik:2023_listen.pdf |}} Bisher haben wir in Variablen einzelne Werte gespeichert. Kann man auch *mehrere Werte* in einer Variablen speichern? Ja! Mit Listen! Eine Liste erstellt man wie folgt: alphabet = ['a','b','c','d','e'] Die Liste im Beispiel oben hat die **Elemente** 'a','b','c','d' und 'e'. Jedes dieser Elemente hat einen bestimmten **Index**, seine **Position** in der Liste: ^ Position Index ^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ |Element| 'a' | 'b' | 'c' | 'd' | 'e' | Beachte, dass das erste Element den **Index 0** hat! Über den Index kann man auf ein **Element zugreifen**. Dazu schreibt man zuerst den Namen der Liste und dann den Index in eckigen Klammern: print(alphabet[2]) # gibt 'c' aus alphabet[3] = 'z' # ändert Element an Position 3 (also 'd') zu 'z' print(alphabet) # Ausgabe: ['a','b','c','z','e'] Einer Liste kann man Elemente **hinzufügen** und **entfernen** alphabet.append('f') # Fügt Element hinten an, Liste nachher: ['a','b','c','z','e','f'] alphabet.insert(1,'q') # Fügt Element 'q' an Position 1 ein, Liste nachher: ['a','q','b','c','z','e','f'] alphabet.pop(3) # Entfernt Element an Position 3, Liste nachher: ['a','q','b','z','e','f'] alphabet.pop() # Entfernt letztes Element, Liste nachher: ['a','q','b','z','e'] Die Länge einer Liste bestimmt man wie folgt: len(alphabet) # Anzahl Elemente in Liste Oft möchte man durch alle Elemente einer Liste **durchgehen** und etwas mit diesen machen, z.B. sie in die Konsole printen: alphabet = ['a','b','c','d','e'] i = 0 # Startindex, 0, weil wir zuerst das vorderste Element (hier 'a') auslesen möchten while i < len(alphabet): # Bedingung while-Schleife print(alphabet[i]) # lese Element aus Liste aus, alphabet[i], und printe dieses i = i + 1 # erhöhe Index In der Bedingung `i < len(alphabet)` ermitteln wir mit len(alphabet) die Länge der Liste. Wichtig ist auch, dass der Index `i` *kleiner* (und nicht kleiner gleich) ist als diese Länge, da sonst versucht wird, auf Element zuzugreifen, welches nicht existiert. Mit folgendem Code überprüft man, ob ein Element in einer Liste steht: if 'b' in ['a','c','e','g']: print('kommt in Liste vor') else: print('kommt nicht in Liste vor') ===== - Logikoperatoren ===== Sowohl in Schleifen wie auch in Verzweigungen werden Aussagen überprüft (Bedingungen). Mit **Logikoperatoren** können mehrere Aussagen **verknüpft** (`and`, `or`) oder eine Aussage **negiert** (`not`) werden: ^ Operator ^ Erklährung ^ | `A and B` | ist `True` nur falls beide Aussagen `A` und `B` `True` sind | | `A or B` | ist `True` nur falls mindestens eine der Aussagen `A` und `B` `True` ist | | `not A` | negiert Aussage `A` | ===== - Strings im Detail ===== Ein String ist eine **Zeichenkette**, also eine Aneinanderreihung mehrerer Zeichen, zum Beispiel `s = "KSR!"`. Ein String hat viele Ähnlichkeiten mit einer Liste, deren Elemente einzelne Zeichen sind, wie `l = ['K','S','R','!',']`: * String hat **Länge**: `len("KSR!")` -> 4 * Auf **einzelnes Element** in String zugreifen: `s[2]` * Kann durch einzelne Zeichen **durchgehen**: s = "KSR!" i = 0 while i < len(s): print(s[i]) i = i + 1 Man kann einfach auf einen **Bereich** eines Strings zugreifen: s = "I love KSR!" s[2:6] # -> "love" (Zeichen an Position 2 bis und mit 5) s[:6] # -> "I love" (Zeichen von Anfang bis und mit 5 s[7:] # -> "KSR!" (Zeichen an Position bis Ende) Beachte, dass Stings **nicht veränderbar (immutable)** sind. Deshalb kann man weder einzelne Zeichen eines Strings ändern, noch Zeichen entfernen oder hinzufügen. Befehle wie `s[2] = 'A'`, `s.append('A')`, oder `s.pop()`, die du von den Listen kennst, funktionieren also *nicht*. Möchte man deshalb einen String 'ändern', muss man einen *neuen* String erzeugen: * **Zusammenführen** mehrerer Strings: mit dem Plus-Operator `+`: s = "KSR!" s = "I love " + s # s ist jetzt String "I love KSR!" * **Zeichen entfernen:** Mithilfe von Teilstrings (`:`) s = "I love KSR!" s = s[:2] + s[7:] # -> "I KSR!" (Zeichen an Position 2 bis und mit 6 'entfernt') ===== - For-Schleifen (optional) ===== Dieses Kapitel ist empfohlen für alle, die beim Programmieren wenig Mühe haben und **while-Schleifen** sehr gut verstehen. For-Schleifen sind eine Alternative zu while-Schleifen. Da es nichts gibt, was man mit for machen kann, was man mit while nicht auch tun könnte, ist es aber nicht zwingend notwendig, über diese Bescheid zu wissen. For-Scheifen haben aber den Vorteil, dass sie kürzer zu programmieren sind als while-Schleifen. ==== Durch Listen iterieren ==== Eine while-Schleife kann alles, was eine Schleife machen kann. Sie ist aber ein bisschen umständlich zu programmieren. Der folgende Code geht durch sämtliche Elemente einer Liste durch und printet diese: nrs = [2,3,5,7,11,13,17,19] i = 0 while i < len(nrs): print(nrs[i]) i = i + 1 Für diese simple Schleife brauchen wir also vier Zeilen Code. Auch ist der Code relativ fehleranfällig, zum Beispiel hat man gleich eine Endlosschleife, wenn man die Erhöhung des Index `i = i + 1` vergisst. Mit einer **for-Schleife** kann man (fast) das Gleiche machen, allerdings mit nur zwei Zeilen Code (für die Schleife): nrs = [2,3,5,7,11,13,17,19] for el in nrs: print(el) Die for-Schleife geht automatisch der Reihe nach durch alle Elemente der Liste hindurch und speichert sie in der angegebenen Variablen (hier: `el`). Damit sind *Endlosschleifen unmöglich*! Programmiert man eine for-Schleife wie oben angegeben, kann man nur auf die Elemente selber, aber *nicht* auf deren Index zugreifen. Betrachte folgenden Code: nrs = [2,3,5,7,11,13,17,19] i = 0 while i < len(nrs): print("Das Element mit Index " + str(i) + " ist: " + str(nrs[i])) i = i + 1 In dieser while-Schleife gehen wir durch alle Indizes der Liste durch und lesen jeweils das entsprechende Element aus. Wie man diese mit eine for-Schleife umsetzen kann, erfährst du weiter unten. ==== Zählen ==== Der folgende Code zählt von $0$ auf $9$: i = 0 while i < 10: print(i) i = i + 1 Dies kann man auch mit einer for-Schleife realisieren. Dazu verwendet man die `range(...)` Funktion, die einem eine Zahlensequenz zurück gibt. Der folgende Code zählt ebenfalls von $0$ bis $9$: for i in range(0,9): print(i) Beachte, dass in einer for-Schleife der **Index automatisch erhöht** wird! Ein `i = i + 1` ist hier also unnötig! **Range-Funktion:** * Die `range(...)` verlangt eins bis drei Argumente: `range(,,)` * Werden nur **zwei Argumente** angegeben, werden diese als Start- und Endwert aufgefasst, die Schrittgrösse wird auf $1$ gesetzt. * Wird nur **ein Argument** angegeben, wird weiter der Startwert auf $0$ gesetzt. **Beispiele:** for i in range(3,15,2): print(i) # Ausgabe: 3,5,7,9,11,13 for j in range(3,15): print(j) # Ausgabe: 3,4,5,6,7,8,9,10,11,12,13,14 for k in range(15): print(k) # 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 ==== Durch Listen iterieren II ==== Nun können wir das Gelernte der beiden letzten Unterkapitel kombinieren, um durch Listen zu iterieren, ohne dass wir den Index verlieren: nrs = [2,3,5,7,11,13,17,19] for i in range(len(nrs)): print("Das Element mit Index " + str(i) + " ist: " + str(nrs[i])) Noch einfacher umsetzbar ist dies mit enumerate: nrs = [2,3,5,7,11,13,17,19] for i, el in enumerate(nrs): print("Das Element mit Index " + str(i) + " ist: " + str(el)) ==== while vs. for ==== * Alles was eine for-Schleife kann, kann eine while-Schleife auch. Man kann also komplett auf for-Schleifen verzichten. * Das Umgekehrte gilt aber nicht! Es gibt Situationen, die nur mit einer for- sondern nur mit einer while-Schleife umgesetzt werden können. * Beispiel: Endlosschleife `while True` in Game, welches beliebig oft wiederholt werden soll. * Tipp: * Verwende **for-Schleife**, wenn im Vorhinein *klar* ist, *wie oft etwas wiederholt* werden soll. * Verwende **while-Schleife** in allen anderen Fällen. ===== - Schleifen abbrechen (optional) ===== Mit `break` bricht man eine Schleife ab. Verwendet man mehrere ineinander verschachtelte Schleifen, so wird nur die *innerste* abgebrochen. Mit `continue` bricht man nur den aktuellen Durchgang einer Schleife (aber nicht die ganze Schleife) ab. Beide Befehle funktionieren sowohl für while- als auch für for-Schleifen. Beispiel: Studiere den Code unten und versuche vorherzusagen, welchen Output dieser erzeugt. Führe dann den Code aus und überprüfe deine Vorhersage: i = 0 while True: i = i + 1 if i == 3: continue elif i == 7: break print(i) ===== - Python-Hacks (optional) ===== In Python kann Code meist viel kürzer geschrieben werden als vergleichbarer Code in anderen Programmiersprachen. Dieses Kapitel beinhaltet eine Sammlung von praktischen Python-Hacks, die es dir erlauben, deinen Code kürzer zu schreiben. Es ist empfohlen, dies nur zu tun, wenn du die längere Schreibweise sehr gut verstanden hast. === Veränderung von Index === In while-Schleifen muss typischerweise nach jedem Durchgang der Schleife der Index angepasst werden, z.B. mit `i = i + 1`. Dies kann mit `i += 1` abgekürzt werden und macht genau das gleiche. Dies funktioniert auch für andere mathematischen Operationen wie `a -= 2` anstelle von `a = a - 2` oder `b *= 3` anstelle von `b = 3 * b`. ===== Aufgaben ===== ==== Aufgaben A ==== **Thema: Von Struktogrammen zu Python** **Vorwissen:** [[gf_informatik:programmieren_ii_sca#von_struktogrammen_zu_python|Von Struktogrammen zu Python]] Alle Befehle, die wir in Struktogrammen kennengelernt haben, gibt es in ganz ähnlicher Form auch für die (richtige) Programmiersprache Python. In diesem ersten Aufgabenblock geht es darum, Struktogramme in Python und umgekehrt zu 'übersetzen'. Löse diese Aufgaben zuerst auf **Papier** und erst dann am Computer, wenn dies im Auftrag vorgegeben wird. === Aufgabe A1 === == Teil I== Schlage deine Lösung zur Aufgabe 'Taschenrechner I' nach. Sie sollte in etwa so aussehen: {{ :gf_informatik:taschenrechner_1op.png?250 |}} Schreibe das entsprechende Programm in Python (auf Papier). == Teil II== Wie Teil 1, aber für 'Taschenrechner II'. Schreibe den Python-Code zuerst für die einfachere Lösung: {{ :gf_informatik:taschenrechner_2op.png?250 |}} und dann für die etwas anspruchsvollere Lösung: {{ :gf_informatik:taschenrechner_1op_b.png?250 |}} Beide Codes sollen wieder auf Papier geschrieben werden. ==Teil III== Probiere deine Lösungen (eine nach der anderen) am Computer in **TigerJython** aus: Tippe deinen Code ab, verwende für **Einrückungen** die *Tabulator* Taste (oben links). Führe dann den Code aus (grüner Pfeil oder F5) === Aufgabe A2 === Übersetze das Struktogramm zur Aufgabe "Countdown" auf Python: {{ :gf_informatik:struktogramm_countdown.png?250 |}} 1. zuerst auf Papier. 1. Probiere deine Lösung dann am Computer aus. === Aufgabe A3 === Übersetze das Struktogramm zur Aufgabe "Sirup, Bier oder Schnaps" auf Python: 1. zuerst auf Papier. 1. Probiere deine Lösung dann am Computer aus. === Aufgabe A4 === Übersetze alle Teilaufgabe aus der Aufgabe D2 "Struktogramme aufschreiben" auch Python und zwar direkt am Computer. === Zusatzaufgaben A === Übersetze die Struktogramme der Zusatzaufgaben auf Python. ==== Aufgaben B ==== **Vorwissen:** [[gf_informatik:programmieren_ii_sca#weitere_grundlagen|Weitere Grundlagen]] === Aufgabe B1 === Python ist super im rechnen und macht jeden Taschenrechner vergessen. Studiere das folgende kurze Kapitel zu den [[gf_informatik:programmieren_ii_sca#mathematische_operationen|mathematischen Operationen]], welches eine Übersicht über die wichtigsten mathematischen Rechenoperationen beinhaltet. Berechne mit Python und gib das Resultat aus: - Addiere $7777$ und $8888$ - Subtrahiere $27312$ von $101432$ - Wie oft kommt $29$ in $1447$ vor? - Ist $1764$ eine Quadratzahl oder nicht? Beispiel für Quadratzahlen: $49$, weil $7^2 = 49$ === Aufgabe B2: Personendetails === Studiere das [[gf_informatik:programmieren_ii_sca#strings|Kapitel zu Strings.]] Schreibe ein Programm, in welchem eine Person der Reihe nach aufgefordert wird, ihren Namen, Wohnort und Alter (als *Zahl*, nicht String) einzugeben. Die Werte werden in passenden Variablen gespeichert. Die Details zur Person werden dann in einem schön formatierten String ausgegeben, z.B. "Fritz wohnt in Romanshorn und ist 42 Jahre alt!" === Aufgabe B3: Verbotenes Wort === Studiere das [[gf_informatik:programmieren_ii_sca#vergleichsoperatoren|Kapitel zu Vergleichsoperatoren.]] Schreibe ein Programm, in welchem man aufgefordert wird, ein Wort einzugeben. Alle Eingaben sind ok bis auf eine: Die des verbotenen Wortes **"Voldemort"**. Gibt man dieses Wort ein, soll eine deutliche Warnung angezeigt werden mit der Aufforderung, dieses Wort nie wieder einzugeben! Ansonsten erhält man die Rückmeldung, dass das Wort in Ordnung sei. Verwende dazu den Ungleich-Operator. === Aufgabe B4: Kettenrechnung === Weise der Variablen `x` der Wert $7$ zu. Verändere nun die Variable nacheinander wie folgt: - verdopple sie - multipliziere mit 100 - dividiere ganzzahlig (keine Nachkommazahlen) durch 80 - rechne hoch drei - subtrahiere 13 - ziehe die Quadratwurzel - dividiere durch 10 Nun solltest du wieder 7 erhalten. === Aufgabe B5: Zähler === 1. Gib alle Zahlen $0,1,2, \ldots, 9$ mithilfe einer *Schleife* aus. 1. Gib nun alle Werte von $0$ bis und mit $99$ aus. Hast du den Code im ersten Schritt richtig programmiert, musst du nur einen *einzigen Wert* ändern. === Aufgabe B6: Alter === Berechne dein Alter in Tagen, Stunden und Sekunden. Speichere zuerst dein Alter in Jahren in einer passenden Variablen, z.B. my_age_in_years = 14 Berechne nun das Alter in: - Tagen - Stunden - Sekunden Jeder Wert soll in einer Variablen mit passendem Namen, z.B. `my_age_in_seconds` gespeichert werden. Gib nun die Berechneten Werte in formatierten Strings als Sätze aus, z.B.: - "I am 14 years old." - "I am ... day old." - "..." Wichtig! Ändert man nun den Wert von `my_age_in_years`, so müssen sich alle daraus berechneten Werte entsprechend anpassen! === Aufgabe B7: Ganzzahldivision === Es sollen zwei Zahlen eingegeben werden. Der Code berechnet dann die Ganzzahldivision inklusive Rest der beiden Zahlen und gibt diese in einem formatierten String aus. Beispiel: Werden $23$ und $5$ eingegeben, so ist die Ausgabe: "23 : 5 = 4 Rest 3" ==== Aufgaben C ==== **Vorwissen:** [[gf_informatik:programmieren_ii_sca#weitere_grundlagen|Weitere Grundlagen]] In einer alten Aufgabe hast du mithilfe von `repeat` ein Turtle ein Quadrat zeichnen lassen. Der `repeat` befehlt ist eine Eigenheit von TigerJython und *kein richtiges Python*. Verwendest du repeat, outest du dich als **uncool**, weshalb wir von nun an **an die Finger von repeat lassen** und stattdessen **while-Schleifen** verwenden! Bei allen weiteren **Prüfungen** ist das Verwenden von repeat verboten! === Aufgabe C1 === Lasse eine Turtle ein Quadrat ablaufen, diesmal aber mithilfe der **while**-Schleife. === Aufgabe C2 === Du hast hoffentlich herausgefunden, wie man in einer quadratischen Spirale die Abstände zwischen den Linien kleiner und grösser machen kann. Zeichne nun in eine Figur zwei solche Spiralen ähnlich wie im Bild. Zeichne dazu mit einer while-Schleife die eine. Versetze dann die Position deiner Turtle mit `setX` und `setY` (oder `setPos`) und zeichne die Zweite Spirale mit einer neuen while-Schleife. {{ : gf_informatik:spiralen_duo.png?250 |}} ++++Tipps| Definiere für die Seitenlänge eine Variable. Nach jedem Durchgang der Schleife wird die Variable um einen bestimmten Wert vergrössert. ++++ === Aufgabe C3 === Zeichne folgende Figur: {{ : gf_informatik:spirale.png?200 |}} === Aufgabe C4 (optional) === Zeichne folgende Figur: {{ : gf_informatik:spirale_rechteckig.png?250 |}} === Zusatzaufgabe C (Uhr) === Nutze TurtleGraphics, um eine Uhr zu simulieren. Wähle selbst aus, ob es eine traditionelle SBB-Uhr oder eine Digitaluhr sein soll: * SBB-Uhr: https://sca.ksr.ch/doku.php?id=gf_informatik:programmieren_zusatzaufgaben#sbb-uhr * Digitaluhr: https://sca.ksr.ch/doku.php?id=gf_informatik:programmieren_zusatzaufgaben#digitale_uhr Schicke das Endresultat per Teams der Lehrperson. ==== Aufgaben D ==== **Vorwissen:** [[gf_informatik:programmieren_ii_sca#verzweigungen_im_detail|Verzweigungen im Detail]] Bei diesen Aufgaben geht es um folgendes: * Schleifen mit elif zu programmieren * etwas längere Programme schreiben === Aufgabe D1 === Programmiere die Schnaps, Bier & Wein Aufgabe mit einer if-elif-else-Verzweigung. === Aufgabe D2 === Die Benutzerin wird aufgefordert, eine Zahl einzugeben. Der Code analysiert, ob die Zahl positiv, Null oder negativ ist und gibt eine entsprechende Nachricht. === Aufgabe D3 === == Teil I == Der Benutzer wird aufgeforder, eine der folgenden Eingaben zu machen: * "q" für Quadrat * "k" für Kreis * "r" für Rechteck * "..." für eigene Figur Die Turtle zeichnet dann die entsprechende Figur. Vermeide Code-Repetitionen, verwende stattdessen Schleifen! Wird etwas anderes eingegeben, so soll eine der folgenden Varianten zum Zug kommen (entscheide selbst): * Variante 1: einfach eine Rückmeldung, dass unzulässige Eingabe * Variante 2: Turtle läuft ein Fragezeichen ab == Teil II == Erweitere nun deinen Code wie folgt: 1. Nach der Eingabe für die Form soll der Benutzer die Farbe für den Stift und die Füllfarbe auswählen können (//Tipp:// `askColor(...)`). Mehr zu Farben findest du [[gf_informatik:programmieren_i#farben_optional|hier]]. 1. Der Stift wird auf die entsprechende Farbe gesetzt ... 1. und die Form mit der ausgewählten Füllfarbe ausgefüllt. //Tipp:// `fill(x,y)` === Aufgabe D4 === == Schritt 1 == Schreibe ein kleines **Mathe-Quiz-Spiel**. Der Benutzer soll eine Additionsrechnung erhalten, die er lösen soll. Nachdem er das Resultat eingegeben hat, soll er die Rückmeldung erhalten, ob das Resultat korrekt war oder nicht. == Schritt 2 == Erweitere nun dein Mathe-Quiz. In diesem soll die Aufgabe per Zufall generiert werden. Nutze den Zufallsgenerator von Python, um die beiden Zahlen, die addiert werden sollen, zufällig zu wählen. Dazu musst du das //random//-Modul einbinden. import random # schreibe dies ganz oben in deinem Code ... x = random.randint(0,10) # wählt zufällig eine Zahl aus den Zahlen 0,1,2,3,...,9,10 aus ... == Schritt 3 == Erweitere nun dein Spiel wie folgt: Insgesamt sollen 10 Runden gespielt werden, wobei in jeder Runde eine Zufallsaufgabe generiert wird (wie in Schritt 2). Es soll mitgezählt werden, wie viele Aufgaben richtig gelöst wurden. Am Schluss soll der Spieler eine entsprechende Rückmeldung erhalten, z.B.: ''Du hast 7 von 10 Aufgaben richtig gelöst.'' == Schritt 4 == Gleich wie Schritt 3, die Rückmeldung soll aber erweitert werden. Je nach erreichter Anzahl Punkte soll eine andere Meldung erscheinen: |**Erreichte Punkte**|**Meldung**| |10|Perfekt, du hast alle Aufgaben richtig gelöst!| |8-9|Sehr gut, du hast fast alle Aufgaben richtig gelöst!| |6-7|Nicht schlecht, du hast mehr als die Hälfte der Aufgaben richtig gelöst!| |5|Genügend, du hast die Häfte der Aufgaben richtig gelöst| |1-4|Ungenügend, du hast leider weniger als die Hälfte der Aufgaben richtig gelöst| |0|Leider hast du alle Aufgaben falsch gelöst. Zurück in die Primarschule!| === Aufgabe D5 (optional) === Mache eine Kopie von deinem Mathe-Quiz. Erweitere deinen Code nun so, dass neben der Addition auch Subtraktionen und Multiplikationen vorkommen können. Die Division sollte weggelassen werden, da es dort schnell Aufgaben gibt, die man kaum lösen kann. Welche der drei Operationen an der Reihe ist, soll ebenfalls der Zufall entscheiden. ==== Aufgaben E ==== **Vorwissen:** * [[gf_informatik:programmieren_ii_sca#funktionen|Funktionen]] * Bis und mit Beispiel 2 "Funktion mit Parameter und ohne Rückgabewert" Bei diesen Aufgaben geht es um folgendes: * Verstehen, was Funktionen sind und wozu sie nützlich sind * einfache Funktionen programmieren === Aufgabe E1 === **Nette Begrüssung:** Schreibe eine Funktion, der man den Namen und den Wohnort einer Person als Argumente übergibt. Die Funktion begrüsst diese Person dann ganz herzlich. Beispiel: "Hallo, mein lieber Oskar aus Amriswil, ich wünsche dir einen ganz tollen Tag!" === Aufgabe E2 === Schreibe eine Funktion `head_or_tail()`, die einen Münzenwurf simuliert. Zufällig soll Kopf oder Zahl ausgewählt und ausgegeben werden. ++++Tipps:| Bestimme mithilfe des random-Moduls (siehe oben) eine Zufallszahl ($1$ oder $2$). Falls die Zufallszahl $1$ ($2$) hast, gibst du "Zahl" ("Kopf") aus. Verwende dazu eine Verzweigung. ++++ === Aufgabe E3 === Schreibe eine Funktion `fortune_cookie()`, die ein Glückskeks-Spruch-Generator ist: Jedesmal wenn die Funktion aufgerufen wird, wird zufällig einer von mehreren Sprüchen ausgewählt und ausgegeben. Erfinde selber Sprüche oder klaue sie dreist aus dem Internet. Rufe die Funktion auf. ++++Tipps:| Ähnlich wie Münzwurf-Funktion oben. Bestimme wieder eine Zufallszahl (z.B. im Bereich $1-5$, falls du fünf Sprüche hast). Falls die Zufallszahl $2$ ist, gibst du den zweiten Spruch aus. Verwende dazu eine if-elif-...-else-Verzweigung. Simuliere nun 20 Münzenwürfe. ++++ === Aufgabe E4 === TurtleGraphics: Schreibe eine Funktion `square(x)`, die eine Zahl $x$ als Argument entgegen nimmt und ein Quadrat mit dieser Länge zeichnet. === Aufgabe E5 === Schreibe folgende Funktionen: * `square(x,y,l)`: Zeichnet Quadrat mit Seitenlänge l, startend an Position $(x,y)$ * `circle(x,y,r)`: Zeichnet Kreis mit Radius r, startend an Position $(x,y)$ * `rectange(x,y,a,b)`: Zeichnet Rechteck mit Seitenlängen a und b, startend an Position $(x,y)$ * `triangle(x,y,l)`: Zeichnet gleichseitiges Dreieck mit Seitenlänge l, startend an Position $(x,y)$ * Funktion für selbst gewählte geometrische Figur Mache nun moderne Kunst, indem du diese Funktionen aufrufst. **Challenge (optional):** Erstelle mit möglichst vielen Zufallswerten moderne Kunst. Ziel: Kunst von deinem Programm soll besser und schöner sein wie die vom Programm der Lehrperson! Vom Zufall abhängen können z.B. folgende Werte: * Anzahl, wie oft jede Funktion aufgerufen wird. * Position von Figuren * Grössen von Figuren * Drehung von Figuren * Farben (Stift- und Füllfarbe), dazu kannst du den Funktionen weitere Argumente übergeben Tipps: * Es lohnt sich, z.B. eine Funktion `draw_random_shape()` zu definieren, die dann zufällig eine der Formen zeichnet. * Du kannst auch weitere Funktionen definieren, die dir das Leben erleichtern. ==== Aufgaben F ==== **Vorwissen:** * [[gf_informatik:programmieren_ii_sca#funktionen|Funktionen]] * Bis und mit Beispiel 4 "Funktion mit Parameter und Rückgabewert" Bei diesen Aufgaben geht es um folgendes: * Funktionen mit Rückgabewert verstehen und anwenden. * Lernen, wann man eine Funktion (k)einen Rückgabewert haben sollte. === Aufgabe F1 === Definiere eine Funktion mit einem Argument `volume_cube(x)`, die das Volumen eines Würfels mit Seitenlänge $x$ (in cm) berechnet und zurückgibt (also NICHT printed). Speichere das Resultat in einer Variablen und gebe es dann aus. Welches Volumen hat ein Würfel mit Seitenlänge 13 cm? === Aufgabe F2 === **Satz von Pythagoras:** Schreibe eine Funktion `pythagoras(a,b)`, mit der du die Hypotenuse eines rechtwinkligen Dreiecks mit Katheten $a$ und $b$ berechnen kannst. Das Resultat soll *zurückgegeben* werden. //Tipp:// Die Wurzel einer Zahl ziehst du mit `sqrt(x)`, dazu musst du aber zuerst das math-Modul importieren: `import math`. //Kontrolle:// Für die Katheten 3 und 4 ist die Hypothenuse 5. Die Codezeile `print(pythagoras(3,4))` soll dann also `5.0` ausgeben. === Aufgabe F3 === Das Volumen einer Kugel mit Radius $R$ ist: $$V = \frac{4\pi}{3}\cdot R^3$$ Definiere eine Funktion `volume_sphere(...)`, der man als Argument den Radius übergibt und die dann das Volumen zurückgibt. Die Kreiszahl Pi ($\pi$) kannst du mit `math.pi` aufrufen, dazu muss aber auch wieder zuerst das math-Modul importiert werden (`import math`). === Aufgabe F4 === Schreibe eine Funktion `grade(points)`, die dir die Note (grade) für eine gegebene Punktzahl berechnet und zurückgibt. Lege die Punktzahl, die für die Note $6$ notwendig ist in einer Konstanten (wie Variable, aber alles Grossbuchstaben) fest. Die Formel geht wie folgt: $$\text{Note} = \frac{5 \cdot \text{(erreichte Punkte)}}{\text{Punktzahl für Note 6}} + 1$$ Beachte: * Um die Noten schön zu runden, kannst du die //vordefinierte Funktion// `round` verwenden: `round(3.14159,2)` rundet dir die Zahl $3.14159$ auf zwei Nachkommastellen, man erhält also $3.14$. * Erreicht man mehr Punkte als notwendig für Note 6, soll man trotzdem die Note 6 erhalten. === Aufgabe F5 === Die **Fakultät** ist eine Funktion, welche jeder ganzen natürlichen Zahl das Produkt aller natürlichen Zahlen (ohne Null) kleiner und gleich dieser Zahl zuordnet. Sie wird mit einem Ausrufezeichen geschrieben. Als Beispiel: $5!=1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 =120$. Schreibe eine Funktion `faculty(...)`, welcher als Argument eine ganze Zahl übergeben wird und welche dir dann die Fakultät dieser Zahl zurückgibt. **optionale Challenge für absolute Freaks**: Kannst du die Fakultät ganz ohne Schleife berechnen? Dann hast du das Prinzip der *Rekursion* (Selbst-Aufruf) entdeckt! === Aufgabe F6 (optional) === **Mitternachtsformel:** Eine quadratische Funktion kann immer in die Form $$ax^2 + bx + c = 0$$ gebracht werden. Die Lösung ist gegeben durch: $$x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$$ Schreibe eine Funktion `mitternachtsformel(...)`, die die drei Werte für $a,b,c$ entgegennimmt und die Lösung(en) zurück gibt. Beachte, dass es drei Fälle gibt: * keine Lösung: gib `None` zurück, dies ist der Fall, wenn der Term in der Wurzel negativ ist * eine Lösung, dies ist der Fall, wenn der Term in der Wurzel genau 0 ist * zwei Lösungen: gib Liste mit den beiden Werten zurück Tipp: Verwende die Diskriminante, um den richtigen Fall zu ermitteln. Kontrolle: Die quadratische Gleichung ... * $3 x^2 - 6 x - 5 = 0$ hat die zwei Lösungen: $-0.632993$ und $2.63299$ * $x^2 - 4 x + 4 = 0$ hat eine Lösung: $2$ * $x^2 + 2 x + 7 = 0$ hat keine Lösung ==== Aufgaben G ==== **Vorwissen:** * [[gf_informatik:programmieren_ii_sca#listen|Listen]] Bei diesen Aufgaben geht es um folgendes: * Verstehen, was Listen sind und wofür diese gut sind. * Einfache Aufgaben mit Listen lösen. === Aufgabe G1 === Betrachte die Liste `alphabet = ["B","C","X","D","Z","F","G","I","J"]`. Korrigiere die Liste, indem du: * am Anfang ein "A" einfügst * das "X" entfernst * dem Element mit Wert "Z" den korrekten Wert "E" zuweist * am richtigen Ort ein "H" einfügst * am Ende ein "K" anhängst === Aufgabe G2 === Betrachte die Liste: likeable_football_clubs = ["bvb", "liverpool", "st. gallen", "bayern", "freiburg", "breitenrain"] 1. Gehe mit einer Schleife der Reihe nach durch alle Elemente der Liste durch und gebe sie aus. 1. Die Bayern haben nichts in dieser Liste verloren. Bitte entferne sie, danke! Füge weiter deinen Lieblingsklub hinzu. === Aufgabe G3 === Erzeuge mithilfe einer while-Schleife eine Liste, die alle Zahlen $0,1,2,\ldots,99,100$ beinhaltet. //Tipp:// Erstelle zuerst eine leere Liste `numbers = []`. Erzeuge dann in eine while-Schleife die gesuchten Zahlen. Füge diese der Liste hinzu. ==== Aufgaben H ==== **Vorwissen:** * [[gf_informatik:programmieren_ii_sca#strings_im_detail|Strings im Detail]] * [[gf_informatik:programmieren_ii_sca#logikoperatoren|Logikoperatoren]] Bei diesen Aufgaben geht es um folgendes: * Strings 'manipulieren' können. * Verstehen, was Strings und Listen gemeinsam haben und wie sie sich unterscheiden. * Mehrere Bedingungen mithilfe von Logikoperatoren miteinander verknüpfen. === Aufgabe H1 === Studiere zuerst das Kapitel zu den [[gf_informatik:programmieren_ii_sca#logikoperatoren|Logikoperatoren]]. Nutze Logikoperatoren, um die folgende Aufgabe zu lösen: Um eine **geheime Nachricht** lesen zu können, muss man nacheinander zwei verschiedene Passwörter eingeben. == a) == Die geheime Nachricht soll nur angezeigt werden, wenn man //beide// Passwörter korrekt eingibt. Realisiere dies a) zuerst mit zwei ineinander verschachtelten Verzweigungen und dann b) mit dem passenden Logikoperator. == b) == Die geheime Nachricht soll nur angezeigt werden, wenn man //mindestens eines// der Passwörter korrekt eingibt. === Aufgabe H2 === Studiere zuerst das Kapitel zu den [[gf_informatik:programmieren_ii_sca#strings_im_detail|Strings im Detail]]. Betrachte den String `s = "Mein Name ist Mani Matter und ich komme aus Herzogenbuchsee"`. Passe in diesem String den Namen und Ort so an, dass er zu dir passt. Extrahiere also die Teile, die du verwenden kannst und kombiniere sie mit neuen (z.B. deinem Namen). Erinnerung: Einen Teilstring erhältst du z.B. mit `s[2:5]`. === Aufgabe H3 === 1. Schreibe eine Funktion `count_char_in_string(s,c)`, welcher ein String s und ein Buchstabe c (engl. char, character) übergeben wird. Die Funktion zählt, wie oft c in s vorkommt und gibt diesen Wert zurück (nicht print!). Versuche die Aufgabe zuerst alleine zu lösen. Falls du nicht weiter kommst, findest du in den Tipps unten eine Schritt-für-Schritt Anweisung.\\ \\ 1. Wende deine Funktion an: Wie oft kommt im Lied "Ich han es Zündhölzli azündt" von Mani Matter der Buchstabe "z" vor? ++++Liedtext Mani Matter| lyrics = "i han es zündhölzli azündt, und das het e flamme gäh, und i ha für d'zigarette, welle füür vom hölzli näh, aber s'hölzli isch dervo-, gspickt und uf e deppich cho, und es hätt no fasch es loch in deppich gäh dervo, ja me weis was cha passiere, we me nit ufpasst mit füür, und für d'gluet and' zigarette, isch e deppich doch denn z'tüür, und vom deppich hätt o grus, chönne s'füür is ganze hus, und wär weis, was da nit no wär worde drus, s'hätt e brand gäh im quartier, und s'hätti d'füürwehr müesse cho, hätti ghornet i de strasse, und dr schluuch vom wage gno, und sie hätte wasser gsprützt, und das hätti glych nüt gnützt, und die ganzi stadt hätt brönnt, es hätt si nüt meh gschützt, und d'lüt wären, umenandgsprunge, i dr angscht um hab und guet, hätte gmeint s'heig eine füür gleit, hätte d'sturmgwehr gno ir wuet, alls hätt' brielet: wär isch tschuld?, ds ganze land in eim tumult, dass me gschosse hätt uf d'bundesrät am rednerpult, d'uno hätt interveniert, und d'uno-gägner sofort o, für ir'd schwyz dr fride z'rette, wäre beid mit panzer cho, s'hätt sech usdehnt nad inah uf europa, afrika, s'hätt e wältchrieg gäh und d'mönschheit wär jitz nümme da, ja i han es zündhölzli azündt, und das het e flamme gäh, und i ha für d'zigarette, welle füür vom hölzli näh, aber ds hölzli isch dervo-, gspickt und uf de deppich cho -, gottseidank dass i's vom deppich wider furt ha gno" ++++ ++++Tipps| 1. Definiere die Funktion `count_char_in_string(s,c)` 1. Erstelle einen Counter: Eine Variable, die zu Beginn den Wert 0 hat. 1. Gehe den String Buchstabe um Buchstabe durch. (Stichwort: Schleife!) 1. Überprüfe, ob der jeweilige Buchstabe gleich c ist. 1. Falls ja, wird der Counter um 1 erhöht. 1. Gebe ganz am Ende der Funktion den Counter zurück. ++++ === Aufgabe H4 === 1. Schreibe eine Funktion `my_max(l)`, welche das Maximum (die grösste Zahl) einer Liste l bestimmt und zurückgibt. Programmiere dies selbst und verwende keine vordefinierten Funktionen wir `max()`.\\ \\ 1. Wende deine Funktion auf die Liste unten an und zeige, dass die $76$ deren Maximum ist. [28, 21, 67, 41, 59, 14, 47, 2, 58, 4, 76, 65, 36, 23, 60, 64, 35, 5, 49, 63, 49, 62, 7, 30, 60, 13, 14, 60, 48, 10, 76, 52, 68, 58, 51, 38, 24, 12, 51, 5] ++++Tipps| * Lege eine Variable für das Maximum mit einem vernünftigen Startwert fest (welchen?). * Gehe in der Funktion die Liste Zahl für Zahl durch. * Vergleiche diese Zahl mit der Variablen für das Maximum. Ist die Zahl grösser, so soll diese das neue Maximum werden. ++++ === Aufgabe H5 === 1. Schreibe eine Funktion `quersumme(x)`, die die Quersumme einer Zahl $x$ berechnet und zurück gibt. Beispiel: Die Quersumme der Zahl 413 ist $8$, weil $4+1+3 = 8$.\\ \\ 1. Speiche alle Zahlen unter $1000$, die die Quersumme $19$ haben, in einer Liste. Wie viele sind es? Nutze deine Funktion vom ersten Teil. ++++Tipps| 1. * Wandle die Zahl mit `str()` in einen String um. * Jetzt kannst du diesen String Zahl für Zahl durchgehen und aufaddieren. * Um diese Addition machen zu können, musst du die einzelne Zahl zuerst wieder mit `int()` in einen Integer umwandeln. 2. Es sind $45$ Stück. ++++ ==== Zusatzaufgaben H: Textanalyse ==== Mit Python kann man ziemlich einfach Text auf gewisse Merkmale analysieren. Davor solltest du folgende Theoriekapitel studiert haben: * [[gf_informatik:programmieren_ii_sca#strings|Strings]] * [[gf_informatik:programmieren_ii_sca#logikoperatoren|Logikoperatoren]] * [[gf_informatik:programmieren_ii_sca#for-schleifen_optional|For-Schleifen]] === Häufigster Buchstabe: Mani Matter === Nutze deine Funktion `count_char_in_string(s,c)`, um auf *systematische* Art und Weise herauszufinden, welcher Buchstabe am häufigsten vorkommt im Lied von Mani Matter. Nutze dazu die folgende Liste mit allen gängigen Kleinbuchstaben: alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'ü', 'ö', 'ä', 'è', 'é', 'à'] ++++Antwort| Buchstabe 'e': 102x ++++ === Buchstaben zählen === Wie oft kommt jeder Buchstabe des Alphabets in Goethes Buch "Faust" vor? Solche Fragen lassen sich einfach mit Python beantworten. Auf https://www.gutenberg.org/ findest du jede Menge Bücher im einfachen Textformat, zum Beispiel eben Faust: https://www.gutenberg.org/files/2229/2229-0.txt Tipps: * Verwende `lower(...)`, um String in Kleinbuchstaben umzuwandeln. * Mit dem folgenden Code kannst du ein Buch direkt über ein URL einlesen: import urllib2 data = urllib2.urlopen() for line in data: line = line.replace('\n', '').decode('utf-8') # replace(...): entfernt nervige Zeilenumbrueche, decode(): Umlaute usw richtig anzeigen print(line) # Achtung: keine gute Idee, wenn File sehr viele Zeilen beinhaltet! Baue z.B. Counter ein, damit nach z.B. 100 Ausgaben abbricht === Bible-Study I === Wie oft kommt der Buchstabe 'x' (gross oder klein) in der Bibel vor? Link: [[https://www.sermon-online.com/de/contents/6068]] ==== Weitere Aufgaben I ==== === Aufgabe I1: Sortieren (easy) === Schreibe Code um als Funktion `my_sort(a,b,c)`, die die drei Zahlen a,b,c sortiert und richtig geordnet in eine Liste schreibt. Die Liste wird zurückgegeben. Verwende keine vordefinierten Sortierfunktionen. === Aufgabe I2: Subtraction Game (intermediate) === * Spiele mit einer Kollegin/einem Kollegen nochmals das **Subtraction Game** (Spiel mit 21 Stiften). * Programmiere es dann in Python. Die Spielerin soll gegen den Computer spielen und beginnen dürfen. Der Computer soll immer gewinnen, wenn die Spielerin einen unklugen Zug macht. === Aufgabe I3: Ratespiel (intermediate) === Eine geheime Zahl zwischen $0$ und $100$ wird in einer Variablen gespeichert. Der Spieler versucht solange die geheime Zahl zu erraten, bis er erfolgreich ist. Zusatzpunkte: * Das Programm gibt dem Spieler Tipps, z.B. ’Ausgabe: «Die eingegebene Zahl ist zu klein»’ * Die Anzahl Fehlversuche wird gezählt und am Schluss ausgegeben. === Aufgabe I4: Ratespiel umgekehrt (intermediate) === Der Spieler merkt sich eine geheime Zahl zwischen $0$ und $100$, der Computer soll sie erraten. Der Spieler soll dem Computer bei jedem Versuch mitteilen, ob die gesuchte Zahl kleiner oder grösser als die Vermutung ist: * Ist die geheime Zahl kleiner als die Vermutung, muss der Spieler `<` eingeben. * Ist die geheime Zahl grösser als die Vermutung, muss der Spieler `>` eingeben. * Ist die geheime Zahl erraten, soll `=` eingegeben werden. Zusatzpunkte: * Der Computer detektiert, wenn der Spieler gelogen hat. ===== Lösungen Aufgaben ===== ++++Lösungen Aufgaben A| ==== Aufgaben A ==== === Aufgabe A1 === == Teil I== x = int(input('Gib eine Zahl ein')) y = int(input('Gib eine Zahl ein')) print(x + y) == Teil II== Einfach: x = int(input('Gib eine Zahl ein')) y = int(input('Gib eine Zahl ein')) op = str(input('Gib die Operation (a oder s) ein')) if op == 'a': print(x + y) else: print(x - y) Etw. anspruchsvoller: x = int(input('Gib eine Zahl ein')) y = int(input('Gib eine Zahl ein')) op = str(input('Gib die Operation (a oder s) ein')) if op == 'a': print(x + y) else: if op == 's': print(x - y) else: print("Falsche Eingabe") === Aufgabe A2 === n = int(input("Gib Startzahl von Countdown ein!")) while n > 0: print(n) n = n - 1 print("Los!") === Aufgabe A3 === age = int(input("Gib dein Alter ein")) if age >= 16: if age >= 18: print("Schnaps!") else: print("Bier!") else: print("Sirup!") === Aufgabe A4 === == Maximum == x = int(input("Gib Zahl ein")) y = int(input("Gib Zahl ein")) if x >= y: print(x) else: print(y) == Sortieren == z1 = int(input("Gib Zahl ein")) z2 = int(input("Gib Zahl ein")) z3 = int(input("Gib Zahl ein")) if z1 >= z2: if z2 >= z3: print(z1) print(z2) print(z3) else: if z1 >= z3: print(z1) print(z3) print(z2) else: print(z3) print(z1) print(z2) else: if z2 >= z3: print(z2) if z1 >= z3: print(z1) print(z3) else: print(z3) print(z1) else: print(z3) print(z2) print(z1) == 2er-Potenzen == n = int(input("Gib eine Zahl ein")) x = 2 while n > 0: print(x) x = x * 2 n = n - 1 ++++ ++++Lösungen Aufgaben B| ==== Aufgaben B ==== === Aufgabe B1 === # 1. print(7777+8888) # 2. print(101432-27312) # 3. print(1447//29) # 4. print(sqrt(1764)) # ja, ist Quadratzahl Bemerkung: Einzelne Werte können auch in Variablen gespeichert werden. Dann kann mit den Variablen gerechnet werden. Es macht den Code aber nur länger. === Aufgabe B2 === name = input("Wie heisst du?") city = input("Wo wohnst du?") age = input("Wie alt bist du?") print(name + " wohnt in " + city + " und ist " + str(age) + " Jahre alt!") === Aufgabe B3 === === Aufgabe B4 === x = 7 x = x*2 x = x*100 x = x // 80 x = x**3 x = x - 13 x = sqrt(x) x = x // 10 print(x) === Aufgabe B5 === Zählen von $0$ bis $9$: i = 0 while i < 10: print(i) i = i + 1 Zählen von $0$ bis $99$, es muss nur $10$ durch $9$ ersetzt werden. i = 0 while i < 100: print(i) i = i + 1 Beachte, Code kann auch z.B. mit `while i <= 9` geschrieben werden. Die Notation `while i < 10` hat aber den Vorteil, dass man sofort sieht, wieviele Zahlen ($10$) angezeigt werden. Natürlich muss dafür $i$ bei $0$ starten. === Aufgabe B6 === my_age_in_years = 14 my_age_in_days = my_age_in_years * 365 my_age_in_hours = my_age_in_days * 24 my_age_in_seconds = my_age_in_hours * 3600 print("I am " + str(my_age_in_years) + " years old.") print("I am " + str(my_age_in_days) + " day old.") print("I am " + str(my_age_in_hours) + " hours old.") print("I am " + str(my_age_in_seconds) + " seconds old.") ++++ ++++Lösungen Aufgaben C| ==== Aufgaben C ==== === Aufgabe C1 === from gturtle import * turi = Turtle() turi.hideTurtle() i = 0 while i < 4: turi.forward(200) turi.left(90) === Aufgabe C2 === from gturtle import * monika = Turtle() monika.hideTurtle() monika.setPos(-200,0) i = 0 while i < 39: monika.forward(10*i) monika.left(90) i = i + 1 monika.setPos(200,0) i = 0 while i < 96: monika.forward(4*i) monika.left(90) i = i + 1 === Aufgabe C3 === from gturtle import * t = Turtle() t.hideTurtle() i = 0 l = 5 while i < 150: t.rightArc(l,20) l = l + 2 # increase radius i = i + 1 === Aufgabe C4 === ++++ ++++Lösungen Aufgaben D| ==== Aufgaben D ==== === Aufgabe D1 === age = int(input("Gib dein Alter ein")) if age >= 18: print("Schnaps!") elif age >= 16: print("Bier!") else: print("Sirup!") === Aufgabe D2 === x = int(input("Gib eine Zahl ein")) if x > 0: print("Positiv!") elif x == 0: print("Null!") else: print("Negativ!") === Aufgabe D3 === from gturtle import * turi = Turtle() turi.setPos(-100,-50) turi.hideTurtle() shape = str(input("Gib ein q (Quadrat), k (Kreis) oder r (Rechteck)")) pen_color = askColor("Waehle die Stiftfarbe","red") fill_color = askColor("Waehle die Füllfarbe","green") turi.setPenColor(pen_color) turi.setPenWidth(10) turi.setFillColor(fill_color) if shape == "q": i = 0 while i < 4: turi.forward(200) turi.right(90) i = i + 1 turi.setPos(30,30) turi.fill() elif shape == "k": turi.rightCircle(100) turi.setPos(30,30) turi.fill() elif shape == "r": i = 0 while i < 2: turi.forward(200) turi.right(90) turi.forward(400) turi.right(90) i = i + 1 turi.setPos(30,30) turi.fill() else: print("ungueltige Eingabe!") === Aufgabe D4 === ++++ ++++Lösungen Aufgaben E| ==== Aufgaben E ==== === Aufgabe E1 === def greetings(name,residence): print("Hallo, mein(e) liebe(r) " + name + " aus " + residence + ". Ich wünsche dir einen ganz tollen Tag!") greetings("Fritz","Romanshorn") greetings("Monika","Amriswil") === Aufgabe E2 === import random """ Ganz wichtig: Die Ermittlung der Zufallszahl mit randint und die Verzweigung (Kopf oder Zahl) muss IN der Funktion drin gemacht werden und nicht auserhalb! """ def head_or_tail(): r = random.randint(1,2) if r == 1: print("Head!") else: print("Tail!") head_or_tail() head_or_tail() === Aufgabe E3 === import random def fortune_cookie(): r = random.randint(1,3) if r == 1: print("Spruch 1") elif r == 2: print("Spruch 2") else: print("Spruch 3") === Aufgabe E4 === from gturtle import * turi = Turtle() turi.hideTurtle() def square(l): i = 0 while i < 4: turi.forward(l) turi.right(90) i = i + 1 square(50) square(100) square(150) square(200) === Aufgabe E5 === from gturtle import * t = Turtle() t.hideTurtle() def square(x,y,l): t.home() t.setPos(x,y) i = 0 while i < 4: t.fd(l) t.right(90) i = i + 1 def circle(x,y,r): t.home() t.setPos(x,y) t.rightCircle(r) def rectangle(x,y,a,b): t.home() t.setPos(x,y) i = 0 while i < 2: t.fd(a) t.right(90) t.fd(b) t.right(90) i = i + 1 def triangle(x,y,l): t.home() t.setPos(x,y) i = 0 while i < 3: t.fd(l) t.right(120) i = i + 1 square(-200,-300,150) circle(0,150,40) rectangle(-150,50,20,100) triangle(100,150,40) ++++ ++++Lösungen Aufgaben F| ==== Aufgaben F ==== === Aufgabe F1 === def volume_cube(x): return x**3 v = volume_cube(13) print(v) === Aufgabe F2 === def pythagoras(a,b): return sqrt(a*a + b*b) print(pythagoras(3,4)) === Aufgabe F3 === import math def volume_sphere(r): return 4*math.pi/3 * r**3 print(volume_sphere(3)) === Aufgabe F4 === def grade(points,points_6): gr = 5*points/points_6 + 1 if gr > 6: gr = 6.0 return round(gr,1) print(grade(23,51)) === Aufgabe F5 === def faculty(n): product = 1 i = 1 while i <= n: product = product * i i = i + 1 return product print(faculty(5)) === Aufgabe F6 === def mitternachtsformel(a,b,c): d = b*b - 4*a*c if d < 0: return None elif d == 0: return -b / (2*a) else: r = -b / (2*a) return [(-b - sqrt(d)) / (2*a), (-b + sqrt(d)) / (2*a)] print(mitternachtsformel(3,-6,-5)) # 2 Loesungen print(mitternachtsformel(1,-4,4)) # 1 Loesung print(mitternachtsformel(1,2,7)) # keine Loesung ++++ ++++Lösungen Aufgaben G| ==== Aufgaben G ==== === Aufgabe G1 === alphabet = ["B","C","X","D","Z","F","G","I","J"] alphabet.insert(0,"A") alphabet.pop(3) # oder: alphabet.remove("X") alphabet[4] = "E" alphabet.insert(7,"H") alphabet.append("K") print(alphabet) === Aufgabe G2 === likeable_football_clubs = ["bvb", "liverpool", "st. gallen", "bayern", "freiburg", "breitenrain"] # 1) i = 0 while i < len(likeable_football_clubs): print(likeable_football_clubs[i]) i = i + 1 # 2) likeable_football_clubs.remove("bayern") # oder mit pop likeable_football_clubs.append("winterthur") print(likeable_football_clubs) === Aufgabe G3 === numbers = [] i = 0 while i <= 100: numbers.append(i) i += 1 print(numbers) ++++ ++++Lösungen Aufgaben H| ==== Aufgaben H ==== === Aufgabe H1 === inp_1 = input("Gib das erste Passwort ein") inp_2 = input("Gib das zweite Passwort ein") pw_1 = "informatik" pw_2 = "ksr" # a) if inp_1 == pw_1 and inp_2 == pw_2: print("Zugang gewaehrleistet!") else: print("Zugang verweigert!") # b) if inp_1 == pw_1 or inp_2 == pw_2: print("Zugang gewaehrleistet!") else: print("Zugang verweigert!") === Aufgabe H2 === s = "Mein Name ist Mani Matter und ich komme aus Herzogenbuchsee" s = s[:14] + "Heiri Mueller" + s[25:44] + "Hintertupfingen" print(s) === Aufgabe H3 === def count_char_in_string(s,c): count = 0 i = 0 while i < len(lyrics): if lyrics[i] == c: count += 1 i = i + 1 return count lyrics = "i han es zündhölzli azündt, und das het e flamme gäh, und i ha für d'zigarette, welle füür vom hölzli näh, aber s'hölzli isch dervo-, gspickt und uf e deppich cho, und es hätt no fasch es loch in deppich gäh dervo, ja me weis was cha passiere, we me nit ufpasst mit füür, und für d'gluet and' zigarette, isch e deppich doch denn z'tüür, und vom deppich hätt o grus, chönne s'füür is ganze hus, und wär weis, was da nit no wär worde drus, s'hätt e brand gäh im quartier, und s'hätti d'füürwehr müesse cho, hätti ghornet i de strasse, und dr schluuch vom wage gno, und sie hätte wasser gsprützt, und das hätti glych nüt gnützt, und die ganzi stadt hätt brönnt, es hätt si nüt meh gschützt, und d'lüt wären, umenandgsprunge, i dr angscht um hab und guet, hätte gmeint s'heig eine füür gleit, hätte d'sturmgwehr gno ir wuet, alls hätt' brielet: wär isch tschuld?, ds ganze land in eim tumult, dass me gschosse hätt uf d'bundesrät am rednerpult, d'uno hätt interveniert, und d'uno-gägner sofort o, für ir'd schwyz dr fride z'rette, wäre beid mit panzer cho, s'hätt sech usdehnt nad inah uf europa, afrika, s'hätt e wältchrieg gäh und d'mönschheit wär jitz nümme da, ja i han es zündhölzli azündt, und das het e flamme gäh, und i ha für d'zigarette, welle füür vom hölzli näh, aber ds hölzli isch dervo-, gspickt und uf de deppich cho -, gottseidank dass i's vom deppich wider furt ha gno" print(count_char_in_string(lyrics,'z')) === Aufgabe H4 === x = [28, 21, 67, 41, 59, 14, 47, 2, 58, 4, 76, 65, 36, 23, 60, 64, 35, 5, 49, 63, 49, 62, 7, 30, 60, 13, 14, 60, 48, 10, 76, 52, 68, 58, 51, 38, 24, 12, 51, 5] def my_max(l): m = x[0] i = 1 while i < len(x): if x[i] > m: m = x[i] i = i + 1 return m print(my_max(x)) === Aufgabe H5 === def quersumme(x): x = str(x) q = 0 # Quersumme i = 0 # Index, um alle einzelnen Zahlen durchzugehen while i < len(x): q = q + int(x[i]) i = i + 1 return q l = [] for i in range(1000): if quersumme(i) == 19: l.append(i) print(len(l)) ++++