Einfache Verzweigungen#

Bis jetzt konnten wir Befehle nur der Reihe nach ausführen. Um den Ablauf zu steuern gibt es Verzweigungen. Dazu brauchen wir zuerst einen Datentyp für logische Aussagen:

Boolean#

  • Benannt nach dem Englischen Mathematiker George Boole (1815 - 1864)

  • Kann nur die werte True (Wahr) oder False (Falsch) annehmen

  • versteht die Operationen and, or, und not

A

B

A and B

A or B

True

True

True

True

True

False

False

True

False

True

False

True

False

False

False

False

x = True
print("x =",x,"ist vom Typ",type(x))
print("not x =", not x)
y = False
print("x and y =", x and y)
print("x or y =", x or y)
x = True ist vom Typ <class 'bool'>
not x = False
x and y = False
x or y = True

Vergleichsoperatoren#

Der Datentyp bool wird hauptsächlich verwendet, um das Ergebnis von Vergleichsoperationen zu speichern. In Python gibt es die grundlegenden Vergleiche

  • == Überprüfung auf Gleichheit

  • != Überprüfung auf Ungleichheit

  • < echt kleiner

  • > echt größer

  • <= kleiner gleich

  • >= größer gleich

x = 3 < 4
print("x =", x, "ist vom Typ", type(x))
y = 3 > 4
print("y =", y, "ist vom Typ", type(y))
print("3 == 3:", 3 == 3)
print("3 != 3:", 3 != 3)
x = True ist vom Typ <class 'bool'>
y = False ist vom Typ <class 'bool'>
3 == 3: True
3 != 3: False

Logische Verkettung#

Im Unterschied zu vielen anderen Programmiersprachen erlaubt Python das Verketten von Vergleichsoperatoren:

  • a<b<c überprüft also beispielsweise ob a<b und b<c gilt

  • Man könnte auch (a<b) and (b<c) schreiben

print("3 > 2 > 1:", 3 > 2 > 1, "ist äquivalent zu (3 > 2) and (2 > 1):", (3 > 2) and (2 > 1))
print("4 < 5 <= 5:", 4 < 5 <= 5)
print("1 < 2 > 3:", 1 < 2 > 3)
a = 1
b = 1
c = 1
print("a == b == c:", a == b == c, " ist äquivalent zu a == b and b == c:", a == b and b == c)
3 > 2 > 1: True ist äquivalent zu (3 > 2) and (2 > 1): True
4 < 5 <= 5: True
1 < 2 > 3: False
a == b == c: True  ist äquivalent zu a == b and b == c: True

If-Else Verzweigung#

Die einfachste Verzweigung führt Befehle nur dann aus, wenn eine Bedingung wahr ist. Die Syntax ist:

if Bedingung:
    Anweisungen wenn Bedingung wahr ist

Wichtig ist die Einrückung (meist 4 Leerzeichen oder ein Tabulator). Alle Befehle die zu if gehören müssen gleich weit eingerückt sein.

  • Wichtig: Man darf Tabulatoren und Leerzeichen nicht mischen.

  • Achtung: Doppelpunkt nach Bedingung nicht vergessen!

x = 3
y = 4
if x!=y:
    print(x, "is not equal to", y)
3 is not equal to 4

Mit dem else Schlüsselwort kann man auch spezifizieren, was passiert, falls die Bedingung falsch ist, d.h.

if Bedingung:
    Anweisungen, wenn Bedingung wahr ist
else:
    Anweisungen, wenn Bedingung falsch ist

Wichtig: Die else Anweisung muss auf der gleichen Einrückungsebene wie das if stehen.

x = 3.14
if x>0:
    print(x, "is positive")
else:
    print(x, "is not positive")
3.14 is positive

Das ist besonders nützlich zusammen mit User Input (Achtung: input liefert immer str und muss zuerst in eine Zahl umgewandelt werden)

input_text = input("Enter an integer: ")
input_int = int(input_text)
if input_int%2 == 0:
    print(input_int, "is even")
else:
    print(input_int, "is odd")
4 is even

Es gibt noch weitere Verzweigungen, z.B. elif (else if), um mehrere Bedingungen zu testen. Die Syntax lautet:

if Bedingung1:
    Anweisungen wenn Bedingung1 wahr ist
elif Bedingung2:
    Anweisungen wenn Bedingung2 wahr ist
else:
    Anweisungen wenn keine der Bedingungen wahr ist

Es kann beliebig viele elif-Teile geben. Wichtig ist, dass die Einrückung für alle Teile gleich ist.

input_text = input("Enter a number: ")
input_float = float(input_text)
if input_float>0:
    print(input_float, "is positive")
elif input_float<0:
    print(input_float, "is negative")
else:
    print(input_float, "is zero")
3.14 is positive

Beispiele zu If-Else Verzweigungen#

Zwei Zahlen aufsteigend sortieren:

  • Eingabe von zwei Zahlen

  • Gegebenenfalls vertauschen

  • Ausgabe in sortierter Reihenfolge

x = float(input("Enter a number: "))
y = float(input("Enter another number: "))
if x>y:
    tmp = x
    x = y
    y = tmp
print("In ascending order:", x, y)
In ascending order: 2.0 5.0

Innen oder Außen?:

  • Einlesen von Kreismittelpunkt \(m\in \mathbb{R}^2\)

  • Einlesen von Kreisradius \(r>0\)

  • Einlesen von Punkt \(z\in\mathbb{R}^2\)

  • Überprüfen ob Abstand \(|m-z|^2 > r^2\)

m_x = float(input("Enter x coordinate of m "))
m_y = float(input("Enter y coordinate of m "))
r = float(input("Enter radius "))
z_x = float(input("Enter x coordinate of z "))
z_y = float(input("Enter y coordinate of z "))
dist2 = (m_x - z_x)**2 + (m_y - z_y)**2
if dist2 < r**2:
    print("Point is inside the circle")
elif dist2>r**2:
    print("Point is outside the circle")
else:
    print("Point is on the circle")
Point is inside the circle

Zur Erinnerung: = ist eine Zuweisung, == ist ein Vergleich auf Gleichheit. Bei If-Else Bedingungen muss man daher immer == verwenden.

Beispiel: Schere-Stein-Papier#

Wir haben bereits alle nötigen Bausteine kennengelernt, um ein kleines Spiel zu programmieren.

Ziel: User spielt gegen den Computer

  • User gibt Schere, Stein oder Papier ein

  • Computer wählt zufällig Schere, Stein oder Papier

  • Gewinner wird bestimmt

  • Ergebnis wird ausgegeben

import random
throw_computer = random.randint(1,3) # 1: Schere, 2: Stein, 3: Papier
throw_user = int(input("Schere(1), Stein(2), Papier(3): "))
if throw_computer == throw_user:
    print("Unentschieden")
elif throw_computer == 1 and throw_user == 2:
    print("Stein bricht Schere, du gewinnst!")
elif throw_computer == 1 and throw_user == 3:
    print("Schere schneidet Papier, Computer gewinnt!")
elif throw_computer == 2 and throw_user == 1:
    print("Stein bricht Schere, Computer gewinnt!")
elif throw_computer == 2 and throw_user == 3:
    print("Papier bedeckt Stein, du gewinnst!")
elif throw_computer == 3 and throw_user == 1:
    print("Schere schneidet Papier, du gewinnst!")
elif throw_computer == 3 and throw_user == 2:
    print("Papier bedeckt Stein, Computer gewinnt!")
else:
    print("Ungültige Eingabe")
Schere schneidet Papier, Computer gewinnt!

Man kann mathematisch zeigen, dass die zufällige Wahl des Computers die beste Strategie ist.

  • Menschen sind schlechte Zufallszahlengeneratoren

  • Im Durschnitt wird der Computer gewinnen

Da der Computer den Wurf des Users kennt, könnte man den Computer natürlich auch schummeln lassen.

  • z.B. kann der Computer immer einen Gewinnerwurf wählen, nachdem der User seinen Wurf eingegeben hat

  • um das nicht zu offensichtlich zu machen, könnte der Computer auch nur mit einer gewissen Wahrscheinlichkeit (1/3) schummeln

should_i_cheat = random.random() < 1/3
throw_user = int(input("Schere(1), Stein(2), Papier(3): "))

if should_i_cheat:
    # cheat
    if throw_user == 1:
        throw_computer = 2
    elif throw_user == 2:
        throw_computer = 3
    else:
        throw_computer = 1
else:
    # fair play
    throw_computer = random.randint(1,3)

# Check result
if throw_computer == throw_user:
    print("Unentschieden")
elif throw_computer == 1 and throw_user == 2:
    print("Stein bricht Schere, du gewinnst!")
elif throw_computer == 1 and throw_user == 3:
    print("Schere schneidet Papier, Computer gewinnt!")
elif throw_computer == 2 and throw_user == 1:
    print("Stein bricht Schere, Computer gewinnt!")
elif throw_computer == 2 and throw_user == 3:
    print("Papier bedeckt Stein, du gewinnst!")
elif throw_computer == 3 and throw_user == 1:
    print("Schere schneidet Papier, du gewinnst!")
elif throw_computer == 3 and throw_user == 2:
    print("Papier bedeckt Stein, Computer gewinnt!")
else:
    print("Ungültige Eingabe")

if should_i_cheat:
    print("... aber ich habe geschummelt!")
Papier bedeckt Stein, Computer gewinnt!
... aber ich habe geschummelt!

Geschachtelte If-Else Verzweigungen#

If-Else Verzweigungen können auch ineinander geschachtelt werden. Dabei ist darauf zu achten, dass die Einrückung immer korrekt ist:

  • Jede neue Ebene wird weiter eingerückt

  • Jede Ebene endet, wenn die Einrückung wieder zurückgesetzt wird Geschachtelte IF-Else Verzweigungen können schnell unübersichtlich werden und sollten, wenn möglich, durch elif ersetzt werden.

a = float(input("Enter first number: "))
b = float(input("Enter second number: "))
c = float(input("Enter third number: "))
if a>b:
    if a>c:
        print("The largest number is", a)
    else:
        print("The largest number is", c)
else:
    if b>c:
        print("The largest number is", b)
    else:
        print("The largest number is", c)
The largest number is 6.0

Inline If-Else#

Python erlaubt auch eine kompakte Schreibweise für If-Else Verzweigungen, die sogenannte Inline If-Else Anweisung. Die Syntax lautet:

Anweisung_wenn_wahr if Bedingung else Anweisung_wenn_falsch
a = float(input("Enter first number: "))
b = float(input("Enter second number: "))
max_va = a if a>b else b
print("The largest number is", max_va)
The largest number is 5.0

Für einfache Bedingungen kann dies die Lesbarkeit verbessern, bei komplexeren Bedingungen ist meist die klassische Schreibweise vorzuziehen.