Python Einführungskurs für das Physikalische Anfängerpraktikum der Universität Heidelberg | Startseite


102 - Control Flow

Wir können Variablen nun Werte verschiedener Typen zuweisen:

In [ ]:
a = 1
b = 3.14
c = 'hello'
d = [a, b, c]

Doch um ein sinnvolles Programm zu schreiben benötigen wir sog. Control Flow Anweisungen, die steuern, wie sich das Programm je nach Situation zu verhalten hat. Dazu gehören vor allem if-Abfragen und for- und while-Schleifen.

if-Abfragen

Die einfachste Form von control flow ist die if-Abfrage. Ein Codeblock wird nur dann ausgeführt, wenn eine Bedingung den bool-Wert True ergibt. Ein optionaler else-Codeblock kann ausgeführt werden, wenn die Bedingung nicht True ergibt. Die Syntax für if-Abfragen lautet wie folgt:

if condition:
    # do something
elif condition:
    # do something else
else:
    # do yet something else

Beachtet, dass die Codeblöcke nicht durch Steuerzeichen begrenzt werden. Stattdessen endet die Bedingung lediglich mit einem Doppelpunkt (:) und der zugehörige der Codeblock ist eingerückt.

Hinweis: In Python werden Codeblöcke durch Doppelpunkte und Einrückungen begrenzt. Per Konvention werden dazu jeweils vier Leerzeichen pro Einrückungslevel verwendet.

Verändere bspw. im folgenden Code den Wert von a und schaue, wie sich der Output verändert.

In [ ]:
a = 1
if a < 5:
    print("a ist zu klein, setze auf 5")
    a = 5
else:
    print("a ist groß genug.")
print("a ist nun {}.".format(a))

Der erste Aufruf der print-Funktion und die Änderung des Werts von a wird nur ausgeführt, wenn der Wert von a kleiner als 5 ist. Ansonsten wird der else-Block ausgeführt. Der letzte Aufruf der print-Funktion wird jedoch immer ausgeführt.

Vergleichs-Operatoren produzieren Booleans

Die Bedingung der if-Abfrage kann alles sein, was einen bool-Wert zurückgibt.

Werte von Datentypen, die Vergleiche unterstützen, können mit Vergleichs-Operatoren zu einem Boolean kombiniert werden:

In [ ]:
1 == 3 # "gleich"
In [ ]:
1 != 3 # "ungleich"
In [ ]:
1 > 3 # "größer"
In [ ]:
3 <= 3.4 # "kleiner oder gleich"

Die einfachsten Bedingungen sind die expliziten bool-Werte True und False. Beachte, dass True und False in Python mit großem Anfangsbuchstaben geschrieben werden.

Logische Operatoren kombinieren Booleans

Booleans können mit den logischen Operatoren and, or und not kombiniert werden:

In [ ]:
True and False
In [ ]:
True or False
In [ ]:
not True
In [ ]:
(False and (True or False)) or (False and True)

Aufgabe 1 - Raumtemperatur

a) Schreibe eine if-Abfrage, die die Temperatur T mit der Raumtemperatur T_Raum vergleicht und mit print ausgibt, ob die Temperatur zu warm, zu kalt oder genau bei Raumtemperatur ist.

b) Setze den Boolean-Wert der Variable heating auf True, wenn die Temperatur unter der Raumtemperatur liegt, und andernfalls auf False. Du kannst dies entweder explizit in die if-Abfrage integrieren oder separat durch einen Boolean-Ausdruck setzen. Gib je nach dem Wert von heating mit print aus, ob geheizt wird oder nicht.

Probiere dein erstes kleines Programm aus, indem du den Wert von T veränderst.

In [ ]:
T = 20
T_Raum = 21
heating = False
### BEGIN SOLUTION
if T == T_Raum:
    print("Temperatur bei Raumtemperatur.")
elif T < T_Raum:
    print("zu kalt!")
elif T > T_Raum:
    print("zu warm!")
heating = T < T_Raum
if heating:
    print("Es wird geheizt.")
else:
    print("Heizung ist aus.")
### END SOLUTION
In [ ]:
from nose.tools import assert_equal
assert_equal(heating, T < T_Raum, "Der Wert von `heating` passt nicht. Setze den Wert nur dann auf `True`, wenn `T < T_R` ist.")
print("👏 Easy.")

Weitere Bool'sche Operatoren

Python stellt noch einige weitere nützliche Operatoren zur Verfügung.

  • Der in Operator prüft, ob ein Wert in einer Reihe enthalten ist:
In [ ]:
3 in [ 1, 3, 5 ]
  • Der is Operator prüft, ob zwei Objekte identisch sind, also ein und dasselbe Objekt sind.
In [ ]:
s = "Hello World"
t = "Hello World"
s == t, s is t
In [ ]:
1000 == 10**3, 1000 is 10**3

Meistens sind wir nur an der Gleichheit von Werten interessiert und verwenden den Gleichheits-Operator (==). Die Identität von Objekten wird erst in der Objektorientierten Programmierung relevant wenn wir mit Reference-Typen arbeiten, statt wie bisher mit Value-Typen.

Ein häufiger Anwendungsfall für den Identitäts-Operator is ist jedoch der Vergleich mit None. Das Symbol None stellt das Nicht-Vorhandensein eines Wertes in Python dar:

In [ ]:
a = None
if a is None:
    print("a hat keinen Wert!")
else:
    print("a ist {}.".format(a))

for-Schleifen

Mit Schleifen kann ein Codeblock mehrmals ausgeführt werden. Die meistverwendete Schleife ist die for-Schleife mit folgender Syntax:

for value in iterable:
    # do things

iterable kann dabei eine beliebige Reihe sein, also bspw. eine Liste, ein Tupel oder auch ein String:

In [ ]:
for x in [3, 1.2, 'a']:
    print(x)
In [ ]:
for letter in 'hello':
    print(letter)

Einen Codeblock n-mal ausführen

Manchmal soll ein Codeblock eine bestimmte Zahl von Iterationen ausgeführt werden. Dazu können wir die range Funktion verwenden:

In [ ]:
for i in range(5):
    print(i)

Du kannst nachschauen, wie die range Funktion definiert ist und welche Optionen sie bietet, indem du die ?-Dokumentation aufrufst. Entferne das #-Zeichen und führe die Zelle aus:

In [ ]:
#range?

Wir können die Funktion also auch mit den Argumenten start, stop und (optional) step aufrufen:

In [ ]:
for i in range(2, 10, 2):
    print(i)

Eine Schleife abbrechen oder Schritte überspringen

  • Mit dem Befehl break kann eine Schleife abgebrochen werden:
In [ ]:
for i in range(100):
    if i > 3:
        break
    print(i)
  • Mit dem Befehl continue wird lediglich der aktuelle Schritt der Schleife abgebrochen:
In [ ]:
for i in range(3):
    if i == 1:
        continue
    print(i)

Listen mit for-Schleifen erstellen

Ein sehr praktisches Konzept um in Python mit Listen zu arbeiten nennt sich list comprehension. Mit folgender Syntax wird eine Operation auf jedes Element der gegebenen Reihe angewendet. Zurückgegeben wird dann eine Liste mit den so berechneten Elementen:

new_elements = [operation(element) for element in iterable]

Hier wird bspw. die Operation $x^2$ auf alle $x \in [0,10]$ angewendet:

In [ ]:
[x**2 for x in range(11)]

Aufgabe 2 - Primzahlen

Schreibe ein Programm, das alle Primzahlen kleiner 50 bestimmt. Füge sie der Liste primes hinzu.

Hinweis: Der %-Operator gibt den Rest der Division zweier Integer zurück.

Möglicher Ansatz: Versuch's mal mit einer Boolean-Variable is_prime für jede der Zahlen bis 50, die zunächst True ist und dann in einer zweiten for-Schleife ggfs. auf False gesetzt wird.

Erinnerung: Mit der append Methode können wir Elemente einer Liste hinzufügen.

In [ ]:
primes = []
### BEGIN SOLUTION
for n in range(50):
    is_prime = True
    for m in range(2, n):
        if n % m == 0:
            is_prime = False
            break
    if is_prime:
        primes.append(n)
### END SOLUTION
primes
In [ ]:
from nose.tools import assert_equal
trimmed_primes = primes
for x in [ 0, 1 ]:
    try:
        trimmed_primes.remove(x)
    except ValueError:
        pass
assert_equal([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47], trimmed_primes, "Die Liste von Primzahlen sollte bei 0, 1 oder 2 beginnen und die Primzahlen bis inkl. 47 enthalten")
print("Sehr gut! 🎉🎉🎉")

while-Schleifen

Eine while-Schleife führt einen Codeblock so oft aus, bis eine Bedingung False ergibt und ist durch folgende Syntax definiert:

while condition:
    # do something
In [ ]:
a = 1
while a < 10:
    print("a ist kleiner als 10 ({}), multipliziere mit 1.5.".format(a))
    a = a * 1.5
print("Schleife beendet, a ist nun {}.".format(a))

Aufgabe 3 - Fibonacci

Verwende eine while-Schleife um die Zahlen der Fibonacci-Reihe bis 100 der Liste fib_numbers hinzuzufügen. Die ersten zwei Zahlen sind 0 und 1 und jede weitere Zahl ist die Summe der beiden vorherigen.

Erinnerung: Auf das letzte Element einer Reihe können wir mit dem Subskript l[-1] zugreifen. Das vorletzte Element ist dann entsprechend l[-2].

In [ ]:
fib_numbers = [ 0, 1 ]
### BEGIN SOLUTION
while fib_numbers[-1] + fib_numbers[-2] < 100:
    fib_numbers.append(fib_numbers[-1] + fib_numbers[-2])
### END SOLUTION
fib_numbers
In [ ]:
from nose.tools import assert_equal
assert_equal([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89], fib_numbers, "Die Liste sollte mit [ 0, 1, 1, 2, ...] beginnen und die Fibonacci-Zahlen bis einschließlich 89 enthalten.")
print("👌 Richtig!")

Du kannst jetzt Programme in Python schreiben, die dir etwas ausrechnen! Lerne in der nächsten Lektion, wie du Code als "Bausteine" deines Programms in Funktionen verpackst. Für viele Probleme gibt es schon Funktionen und du musst sie nur aus Modulen laden.

Startseite | >> 103 - Funktionen und Module