Programmieren II - Kontrollstrukturen

Die Einführungsfolien finden sie hier.

Bedingte Statements

Es ist oft der Fall, dass gewisse Codeblöcke nur unter gewissen Bedingungen ausgeführt werden sollten. Etwa um zu überprüfen, ob ein Wort schon in der Wortliste ist, bevor man es hinzufügt. Um dies zu implementieren, nutzen wir das if Statement.

Erstellen sie eine neue Datei einfaches_if.py und fügen sie folgenden Code ein:

wort = 'Hallo'

if wort == 'Hallo':
    print('Einen schönen guten Tag')

Wenn sie den Code jetzt mit python einfaches_if.py ausführen, dann werden sie sehen, dass der Text 'Einen schönen guten Tag' ausgegeben wird. Ändern sie jetzt den Wert der Variablen wort auf einen beliebigen anderen Wert und führen sie das Program erneut aus. Sie werden sehen, dass jetzt nichts ausgegeben wird.

Wenn wir uns jetzt den Code etwas genauer ansehen, dann ist die erste Zeile ihnen schon bekannt, wir definieren einfach eine Variable mit dem Wert 'Hallo'. Wo es interessant wird ist in der nächsten Zeile, wo wir unser if Statement haben. Jedes if Statement besteht aus drei Teilen. Zuerst das Schlüsselwort if, danach kommt der sogenannte "Test" und dann in den darauf folgenden Zeilen der Block der ausgeführt wird, wenn der Test wahr ist.

In diesem Fall ist der Test wort == 'Hallo'. Dieser Gleichheitstest == überprüft einfach ob der Wert auf der linken Seite genau gleich dem Wert auf der rechten ist. Bei Variablen wird der Wert der Variable überprüft (wie auf der linken Seite im Beispiel), bei fixen Werten (wie auf der rechten Seite), wird einfach der fixe Wert überprüft. Wenn die zwei Werte genau gleich sind, dann sagt man, dass das if Statement true (also wahr) ist. Wenn das if Statement true ist, dann wird der Codeblock direkt unter dem if Statement ausgeführt.

Woher weiß der Computer welcher Code zum if Statement gehört? In Python wird das durch ein Einrücken mit 4 Leerzeichen markiert. Code der gleich weit eingerückt ist, gehört zum gleichen Block. In diesem Fall besteht der Block nur aus einer einzelnen Zeile, nämlich dem print Statement, aber wir werden später noch komplexere Beispiele sehen, in denen der Block aus mehreren Zeilen besteht.

Listen

Bevor wir mit den verschiedenen Vergleichsoperatoren weitermachen, werden wir kurz eine weitere Datenstruktur einführen und zwar die Liste. Die Liste ist eines der Grundelemente um komplexere Datenstrukturen zu bauen. Eerstellen sie eine neue Datei vergleichsoperatoren.py und fügen sie folgenden Code ein:

satz = ['To', 'be', 'or', 'not', 'to', 'be']

print(satz)

In Python wird eine Liste mittels der eckigen Klammeren [] definiert und die einzelnen Elemente der Liste werden mittels Beistrichen getrennt. In dem Beispiel haben wir der Variable satz eine Liste mit 6 Elementen zugewiesen. Jedes der einzelnen Element der Liste wird einfach so definiert, wie wenn sie einen Wert direkt einer Variablen zuweisen wollen. Es ist in Python auch möglich ein einer einzelnen Liste Elemente verschiedener Datentypen zu speichern, aber dies sollte generell vermieden werden.

Vergleichsoperatoren

Jetzt wo wir unsere Wortliste haben, können wir sie nutzen um die verschiedenen Vergleichsoperatoren auszuprobieren. Im Beispiel oben haben wir den Gleichheitsoperator == genutzt, aber es gibt noch eine Reihe anderer Operatoren. Fügen sie den folgenden Code in die vergleichsoperatoren.py Datei hinzu:

if len(satz) == 6:
    print('Der Satz hat sechs Wörter')

Den Operator kennen wir bereits, hier noch ein zusätzliches Stück Code im if Test selbst. Wir vergleichen auf der linken Seite hier nicht einen Wert (oder eine Variable) direkt, sondern wir nutzen zuerst die Funktion len um die Länge der Liste zu berechnen. Dann vergleichen wir das Ergebnis der Längenberechnung mit dem Wert 6. Es ist wichtig zu beachten, dass bei derartigen Strukturen immer zuerst das Ergebnis der linken Seite berechnet wird, dann das Ergebnis der rechten Seite und schlußendlich werden die zwei Ergebnisse dann verglichen.

Manchmal müssen wir auch vergleichen, ob zwei Werte ungleich sind. Fügen sie folgenden Code hinzu:

if len(satz) != 5:
    print('Der Satz hat nicht fünf Wörter')

Um in Python Ungleichheit zu testen, nutzen wir den != Vergleichsoperator. Dieser Vergleichsoperator, wie auch das == können auf Werte eines beliebigen Typs angewandt werden. Im Gegensatz dazu sind die folgenden vier Operatoren nur für numerische Werte wirklich sinnvoll. Fügen sie die folgenden Zeilen hinzu und führen sie das Programm aus:

if len(satz) > 5:
    print('Der Satz hat mehr als fünf Wörter')


if len(satz) >= 5:
    print('Der Satz hat sechs oder mehr Wörter')


if len(satz) < 10:
    print('Der Satz hat weniger als zehn Wörter')


if len(satz) <= 6:
    print('Der Satz hat sechs oder weniger Wörter')

Zusätzlich zu diesen numerischen Vergleichsoperatoren gibt es auch noch zwei Vergleichsoperatoren die primär für Listen nützlich sind. Fügen sie die folgenden Zeilen hinzu:

if 'be' in satz:
    print('Das Wort "be" erscheint im Satz')

if 'oh' not in satz:
    print('Das wort "oh" erscheint nicht im Satz')

Der in Operator (und sein Gegenstück not in) überprüfen, ob der Wert auf der linken Seite als Element der Liste mindestens einmal auftaucht. Wie wir beim 'be' sehen, ist es egal ob der Wert ein oder mehrmals auftaucht, er muss nur mindestens einmal auftauchen.

Spielen sie jetzt mit den verschiedenen Vergleichsoperatoren und den Werten um zu sehen, wie diese sich verhalten.

Der Alternative Fall

Bis jetzt haben wir immer nur eine Bedingung getestet und wenn das Ergebnis true war, dann haben wir zusätzlichen Code ausgeführt. Manchmal wollen wir aber auch Code ausführen, wenn das Ergebnis false (also nicht wahr) ist. Um dies auszuprobieren, erstellen sie eine neue Datei alternative.py und fügen sie den folgenden Code ein:

wort = 'Hallo'

if len(wort) == 5:
    print('Das Wort hat fünf Buchstaben')
else:
    print('Das Wort hat nicht fünf Buchstaben')

Führen sie den Code aus und sie werden sehen, dass der Text "Das Wort hat fünf Buchstaben" ausgegeben wird. Ändern sie dann den Wert der Variable wort, sodass sie nicht mehr fünf Buchstaben lang ist und führen sie den Code dann erneut aus. Sie werden sehen, dass jetzt der Text "Das Wort hat nicht fünf Buchstaben" ausgegeben wird.

Der Code der ausgeführt wird, wenn das if Statement false ist, wird mit dem Schlüsselwort else eingeleitet. Jedes else gehört zu genau einem if und jedes if kann höchsten ein else haben (aber es muss keines haben).

Komplexe if Statements

if und else geben uns die Grundwerkzeuge, um komplexe Logiken und Unterscheidungen in unserem Code abzubilden. Dazu werden in den meisten Fällen komplexere if ... else Strukturen erstellt. Dazu erstellen sie jetzt eine Datei komplexes_if.py und fügen folgenden Code ein:

satz = ['To', 'be', 'or', 'not', 'to', 'be']

if len(satz) == 6:
    if 'to' in satz:
        if 'be' in satz:
            print('Wahrscheinliches Hamlet Zitat')

Führen sie den Code aus um zu sehen, dass das print Statement ausgeführt wird. Was sie hier sehen ist eine geschachtelte if Struktur mit insgesamt drei Tests. Ändern sie jetzt die Werte der Liste (entfernen oder fügen sie Welche hinzu bzw. ändern sie die Werte) und führen sie das Programm immer wieder aus, um zu sehen, wie es sich verhält.

Die Schachtelung ist wichtig. Sie bedeutet nämlich, dass das zweite if Statement nur ausgeführt wird, wenn das erste if Statement true ist, das dritte if Statement nur wenn die ersten zwei true sind und das print Statement nur wenn alle drei true sind. Eine derart geschachtelte Struktur kann aber sehr schnell unübersichtlich werden, daher gibt es eine kompaktere Schreibweise. Fügen sie folgenden Code hinzu:

if len(satz) == 6 and 'to' in satz and 'be' in satz:
    print('Wahrscheinliches Hamlet Zitat')

Der and Operator funktioniert genau gleich, wie das verschachteln der if Statements. Er verlangt, dass damit das if Statement als ganzes true ist, alle einzelnen Vergleiche true sind.

Das Gegenstück zum and Operator ist der or Operator. Dieser definiert, dass das if Statement true ist, sobald auch nur einer der Teilvergleiche true ist. Fügen sie folgenden Code hinzu:

if len(satz) == 6 or 'to' in satz or 'be' in satz:
    print('Vielleicht ein Hamlet Zitat')

Jetzt verändern sie die Werte der Liste und sehen sie, wann die Texte "Wahrscheinliches Hamlet Zitat" und "Vielleicht ein Hamlet Zitat" ausgegeben werden. Sie werden sehen, dass der zweite Text viel häufiger ausgegeben wird, da ja nur einer der drei Vergleiche true sein muss.

Schleifen

if Statements erlauben es uns konditionelle Abläufe in unserem Programm abzubilden, aber trotzdem wird jede Zeile Code höchstens einmal ausgeführt. Es ist aber so, dass wir oft den Fall haben wo wir den gleichen Code mehrmals ausführen wollen und nur die Daten anpassen. Wir könnten das zwar händisch machen (so wie bis jetzt, wenn sie verschiedene Werte ausprobiert haben), aber das ist sehr ineffizient und funktioniert nicht für große Datenmengen. Die Kontrollstruktur die hier Sinn macht ist die sogenannte "Schleife". Eine Schleife erlaubt es einem Programm Teile des Programms mehrfach auszuführen.

For Schleifen

Die for Schleife ist die einfachste aller Schleifenarten. Erstellen sie eine neue Datei for_schleife.py und fügen sie folgenden Code ein:

satz = ['To', 'be', 'or', 'not', 'to', 'be']

for wort in satz:
    print(wort)

Wenn sie dieses Programm jetzt ausführen, werden sie sehen, dass jedes Wort in einer einzelnen Zeile ausgegeben wird. Im Code sehen wir, dass die for Schleife die folgende Struktur hat: zuerst das Schlüsselwort for, dann eine Variable, dann das Schlüsselwort in und dann eine weitere Variable. Die zweite Variable ist die Liste mit den Werten über die wir iterieren wollen. "Iterieren" bedeutet, dass der Code in der for Schleife (der eingrückte) Code einmal ausgeführt wird. In jeder Iteration verändert sich nur eines und das ist, dass der ersten Variablen (hier haben wir sie wort genannt) ein neuer Wert aus der Liste zugewisen wird.

Diese Zuweisung erfolgt linear. In der ersten Iteration wird das erste Listenelement der Variable zugewiesen (hier 'To') und dann wird das print Statement mit Variable aufgerufen und der Text "To" wird ausgegeben. In der nächsten Iteration wird das zweite Listenelement ('be') zugewiesen und das print Statement aufgerufen, wodurch der Text "be" ausgegeben wird. Das geht so weiter, bis alle Elemeent der Liste durchgearbeitet worten sind.

In diesem Beispiel wird daher für jedes einzelne Listenelement das print Statement ausgeführt und das jeweilige Wort ausgegeben.

Komplexere Strukturen

Oft wollen wir zuerst eine Bedingung testen und dann, falls die Bedingung false ist, eine weitere Bedingung prüfen und so weiter. Erstellen sie eine neue Datei komplexere_strukturen.py und fügen sie folgenden Code ein:

Interessant wird es, wenn wir for Schleifen und if Statements kombinieren.

satz = ['To', 'be', 'or', 'not', 'to', 'be']

for wort in satz:
    if wort.islower():
        print(wort)

Dies ist eine relativ häufige Struktur. Wir haben eine Schleife, welche über alle Elemente iteriert und darin ein if Statement das für jedes Listenelement eine Bedingung überprüft und dann gegebenenfalls eine Aktion setzt.

Übung

Probieren sie die folgenden Übungsaufgaben selbstständig aus. Erstellen sie dazu ein neues Verzeichnis "uebungen_2" und legen darin für jede Aufgabe eine eigene Datei an.

Aufgabe 1

Erstellen sie eine neue Datei aufgabe_1.py und schreiben sie den notwendigen Code um zwei Variablen a und b zu definieren, diesen zwei numerische Werte zuzuweisen und dann auf Ungleichheit zu überprüfen.

Aufgabe 2

Erstellen sie eine neue Datei aufgabe_2.py und schreiben sie den notwendigen Code um zwei Variablen a und b zu definieren, diesen zwei numerische Werte zuzuweisen und dann auf Gleichheit zu überprüfen.

Aufgabe 3

Erstellen sie eine neue Datei aufgabe_3.py und schreiben sie den notwendigen Code um eine Variable autor zu definieren und wenn diese Variable den Wert 'Sophie von La Roche' enthält, dann den Text "Autorin des 18. Jahrhunderts" auszugeben

Aufgabe 4

Erstellen sie eine neue Datei aufgabe_4.py und schreiben sie den notwendigen Code um eine Variable jahr zu definieren und dann den Text "19. Jahrhundert" auszugeben, wenn die Variable jahr einen Wert zwischen 1800 und 1899 (inklusive) enhält.

Aufgabe 5

Erstellen sie eine neue Datei aufgabe_5.py und schreiben sie den notwendigen Code um eine Variable note zu definieren und dann folgende Text auszugeben: "Sehr gut", wenn die note den Wert 100 oder 130 hat, "Gut" wenn die note den Wert 170, 200 oder 230 hat, "Befriedigend" wenn die note den Wert 270, 300 oder 330 hat, "Genügend" wenn die note den Wert 370, 400 oder 430 hat, und "Unbefriedigend" für alle anderen Werte.

Aufgabe 6

Erstellen sie eine neue Datei aufgabe_6.py und schreiben sie den Code um alle Zahlen von 1 bis 100 auszugeben. Um eine Liste von Zahlen zu erzeugen, nutzen sie die range Funktion.

Aufgabe 7

Erstellen sie eine neue Datei aufgabe_7.py und schreiben sie den notwendigen Code ein um für die Liste ['The', 'rain', 'in', 'Spain', 'falls', 'mainly', 'on', 'the', 'plains'] jene Wörter auszugeben, die mit einem Großbuchstaben beginnen. Dafür können sie die Funktion isupper() äquivalent zur islower() des Tutorials nutzen.

Aufgabe 8

Erstellen sie eine neue Datei aufgabe_8.py und schreiben sie den notwendigen Code um für eine Liste von numerischen Notenwerten den jeweiligen Text auszugeben. Nutzen sie dazu den Notenwert-zu-Textschlüssel von Aufgabe 5.

Aufgabe 9

Erstellen sie eine neue Datei aufgabe_9.py und schreiben sie den notwendigen Code ein um alle geraden Zahlen von 1 bis 100 auszugeben. Der einfachste Test für eine gerade Zahl ist wenn der Rest der ganzzahligen Division (siehe letzte Woche) der Zahl durch 2 als Ergebnis 0 hat.

Aufgabe 10

Erstellen sie eine neue Datei aufgabe_10.py und schreiben sie den notwendigen Code ein, um die ersten 10 Zahlen der Fibonacci Sequenz zu berechnen. In der Fibonacci Sequenz hat das erste Element den Wert 1, das zweite Element auch den Wert 1, und alle darauffolgenden Werte sind die Summe der zweit letzten Werte (z.B. das dritte Element ist die Summe des ersten und zweiten Elements, als 1 + 1 = 2).