5.4 Kontrollstrukturen
Kontrollstrukturen sind eine der mächtigsten Funktionen von Programmiersprachen. Mit ihnen lässt sich die Ausführung einer Aktion an gewisse Bedingungen binden (if/else) oder bestimmte Aktionen mehrmals wiederholen (Schleifen). In diesem Lab lernen wir, wie Kontrollstrukturen funktionieren und wie wir sie anwenden.
Inhalt
Bedingte Ausdrücke
Bevor wir in die Kontrollstrukturen eintauchen, müssen wir uns kurz mit bedingten Ausdrücken auseinandersetzen. Ein bedingter Ausdruck ist eine Anweisung, deren Ausführung entweder wahr oder falsch sein kann. Ein Beispiel:
Bash
|
|
Python
|
|
In den obigen Beispielen definieren wir zwei Variablen und Vergleichen anschliessend die beiden Zahlen. Dabei prüfen wir, ob die erste Zahl grösser ist, als die zweite. In beiden Fällen ist dieser Ausdruck natürlich falsch.
In Python können wir zum vergleichen zweier Zahlen den grösser/kleiner Operator (>
, <
) verwenden. In Bash gibt es die sogenannten comparison operators. -gt
steht in diesem Fall für greater than. Es gibt aber noch viele weitere comparison operators (https://tldp.org/LDP/abs/html/comparison-ops.html
)
Bash
|
|
Python
|
|
If / If else / if elif else
Mit der If/else Anweisung lassen sich bestimmte Aktion ausführen, sofern eine Bedingung erfüllt ist. Die Syntax unterscheidet sich von Bash zu Python leicht:
Bash
|
|
Python
|
|
Die Bedingung enthält sowohl in Bash als auch in Python einen bedingten Ausdruck, während im Anweisungsblock beliebiger Code stehen kann. Wir können die bedingten Ausdrücke aus dem vorherigen Beispiel 1:1 einsetzen:
Bash
|
|
Python
|
|
In diesem Beispiel wird natürlich nichts ausgegeben, da 10 kleiner ist als 12. Wir können nun aber eine else
condition hinzufügen, welche dann ausgeführt, wenn der bedingte Ausdruck nicht zutrifft:
Bash
|
|
Python
|
|
Wie du siehst, ist die else Anweisung optional und nicht in jedem Fall nötig/gewünscht. Es gibt in beiden Programmiersprachen noch eine weitere optionale Anweisung: elif
. Mit elif
können mehrere bedingte Ausdrücke geprüft und jeweils die dazu passende Anweisung ausgeführt werden. Auch hierzu ein kurzes Beispiel:
Bash
|
|
Python
|
|
Der Interpreter der jeweiligen Programmiersprache arbeitet die einzelnen Bedingungen der Reihe nach ab. Sobald die Bedingung zutrifft, wird der entsprechende Anweisungsblock ausgeführt. Folgende Bedingungen werden übersprungen:
Schleifen
Schleifen führen die gleiche Anweisung 0, 1 oder mehrere male aus. Mit Schleifen kann man z.B. über eine Liste iterieren und für jedes Element in der Liste eine bestimmte Aktion ausführen.
while
Wie es der Name bereits vermuten lässt, wird bei der while Schleife eine Aktion solange ausgeführt, bis ein definierter Ausdruck zutrifft. Die Syntax einer while Schleife lautet:
if Bedingung: Anweisungsblock
Bash
|
|
Python
|
|
Im folgenden Beispiel führen wir eine while Schleife so lange aus, wie die Variable counter
kleiner als 3 ist. Im Anweisungsblock der Schleife erhöhen wir den counter jeweils um 1 und geben einen Text aus:
Bash
|
|
Python
|
|
Wenn du diese Beispiele bei dir durchspielst, wirst du feststellen, dass der Anweisungsblock insgesamt 3 mal ausgeführt wird. Sobald der Interpreter bei der Schleife ankommt, prüft er erstmals den Wert von counter
. Da wir diesen mit 0
starten, trifft diese Bedingung zu (0 < 3
). Nun wird der Anweisungsblock ausgeführt (Nachricht ausgeben und counter
um 1 erhöhen). Am Ende des Anweisungsblockes springt der Interpreter wieder zur Bedingung und prüft jetzt erneut den Ausdruck. Da wir counter
in der Schleife um 1 erhöht haben, lautet der Ausdruck neu 1 < 3
und trifft noch immer zu. Nun wird erneut der Anweisungsblock ausgeführt und das ganze wiederholt sich. In der letzten Wiederholung der Schleife wird counter
von 2 auf 3 erhöht. Der Interpreter prüft nun also den folgenden Ausdruck: 3 < 3
. Dieser trifft nun nicht mehr zu, der Anweisungsblock wird daher kein weiteres Mal ausgeführt.
for
For loops werden verwendet, um über eine bestimmte Sequenz zu iterieren (z.B. über alle Zahlen von 0 bis n):
Bash
|
|
Python
|
|
In Bash können wir brace expansion verwenden, um uns eine Liste von Zahlen zu generieren. Der Ausdruck {0..3}
generiert automatisch die Zeichenkette 0 1 2 3
. In Python verwenden wir für den gleichen Zweck die range
Funktion. Dieser Funktion können drei Parameter übergeben werden: range(start, stop, step)
. Die Parameter start
und step
sind optional und werden im obigen Beispiel nicht verwendet. Wir definieren ausschliesslich den stop
Parameter mit dem Wert 3
. Die Range Funktion beginnt standardmässig bei 0
und zählt dann bis zum definierten stop
Parameter in Schritten (gem. dem step
Parameter) hoch. Wichtig der definierte stop
Wert ist in der generierten Liste nicht enthalten. range(3)
generiert also die folgende Liste: 0 1 2
.
In beiden Beispielen geben wir den Wert der Variable index
aus. Das mag auf den ersten Blick etwas verwirrend wirken, da wir diese Variable ja nirgends explizit gesetzt habe. Die for
Schleife übernimmt das für uns und speichert in der Variable index
jeweils den Wert der aktuellen Iteration. Mit {0..3}
definieren wir, dass wir die Schleife mit den Werten 0
, 1
, 2
und 3
je einmal durchführen möchten. Die Schleife wählt also bei der ersten Iteration den ersten Wert unserer Liste (in diesem Fall 0
) und speichert in die Variable index
. Anschliessend wird der Anweisungsblock ausgeführt. Danach wird der nächste Wert aus der Liste (1
) in die Variable index
gespeichert und der Anweisungsblock wird erneut ausgeführt. Das Ganze wird so lange wiederholt, bis sämtliche Elemente in der Liste abgearbeitet wurden. Wichtig: der Name der Variable ist frei wählbar. Du kannst also anstatt index
auch z.B. zaehler
verwenden.
for
Schleifen werden sehr oft zusammen mit Arrays/Listen (siehe Lab 2) verwendet, um für jedes Element in der Liste eine bestimmte Aktion auszuführen.
Im folgenden Beispiel definieren wir eine Liste von Namen und wandeln dann diese Namen mit einer for
Schleife in GROSSBUCHSTABEN um:
Bash
|
|
Python
|
|
Die Syntax von for Schleifen ist in den einzelnen Programmiersprachen jeweils relativ unterschiedlich. In Bash kann eine for
Schleife auch so aussehen:
|
|
Funktional ist diese Schleife identisch mit:
|
|
Um diese Darstellungsform besser zu verstehen, schauen wir uns den Ausdruck (( c=1; c<=5; c++ ))
etwas genauer an. Dieser ist in drei Teile unterteilt:
c=1
: Das kennen wir bereits, wir definieren eine Variablec
und weisen ihr den Wert1
zu. Dieser Ausdruck wird ein einziges Mal vor dem ersten Durchlauf derfor
Schleife ausgeführtc<=5
: Das ist die Bedingung. Diese wird bei jedem Durchlauf geprüft. Solange die Variablec
kleiner oder gleich5
ist, wird die Schleife wiederholt.c++
: Dieser Ausdruck wird am Ende jedes Durchlaufs der Schleife ausgeführt. Wir erhöhen die Variablec
um 1.
Iterationen steuern
Manchmal kann es nötig sein, in einer Schleife bestimmte Elemente zu überspringen oder die Schleife vorzeitig zu beenden. Hierzu gibt es zwei Schlüsselwörter, mit welchen sich das Verhalten einer Schleife steuern lässt:
continue
: Aktuelle Iteration überspringenbreak
: Schleife beenden
Iteration überspringen oder beenden
In den folgenden Codebeispielen iterieren wir über eine Liste von Namen, überspringen jedoch die Iteration für den Namen Bob:
Bash
|
|
Resultat
|
|
Das Gleiche lässt sich natürlich auch in Python implementieren:
|
|
Schleife vorzeitig beenden
In den folgenden Codebeispielen iterieren wir erneut über eine Liste von Namen. Diesmal wollen wir die Schleife beenden, sobald wir den Namen Bob gefunden haben. Zusätzlich verwenden wir einen Counter, um die Position des gesuchten Namen herausfinden zu können:
Bash
|
|
Resultat:
|
|
Und analog dazu das Beispiel in Python:
|
|
Das Resultat ist identisch mit demjenigen der Bash Version. Durch die Verwendung von break
wird die Suche abgebrochen, sobald der Name gefunden wurde. Das Script läuft anschliessend nach der Schleife weiter.