# Python-Kontrollstrukturen

import sys
import random
import time

# if / elif / else - vollständige und unvollständige Alternativen

# Hinweis: Python kennt keine Anweisung für die Mehrfachauswahl (analog switch
# bei C, Java, PHP, ...).

for z in range(-3, 3):
    if z < 0:
        print(z, 'kleiner 0')
    elif z == 0:
        print(z, 'ist 0')
    else:
        print(z, 'größer 0')

for z in 0, 1:
    if z: print('z ungleich 0:', z)

print('===')

# Major- und Minor-Version von Python ermitteln
major, minor = sys.version_info[:2]
#major, minor = sys.version_info.major, sys.version_info.minor

# Python-Version testen
if major == 3 or major == 2 and not minor < 7:
    print('modern: Python 3 oder 2.7')

if major != 3:
    print('kein Python 3')

# Mehrfachzuweisung
a = b = c = 5

# unvollständige Alternative
if a == b == c:
    # verketteter Vergleich
    print('alle gleich')

# vollständige Alternative in Ausdrucksform (ternärer Operator)
print(('' if a == b == c else 'nicht ') + 'alle gleich')
print()

# ---------------------

# while-Schleife / break / continue

n = 15
while n:
    if n < 2:
        break
    n -= 1
    if n % 3 == 0: # oder: if not n % 3:
        # Rest der Division durch 3 == 0; n ist also ganzzahliges Vielfaches von 3;
        # dann die nächste Schleifeniteration einleiten
        continue
    print(n)

print()

# ---------------------

# for-Schleife / break / continue

n = 0
with open('/etc/services') as f:
    # with schließt die geöffnete Datei am Ende automatisch
    for line in f:
        # ohne with:
        # for line in open('/etc/services'):
        line = line.strip()
        if not line or line.startswith('#'):
            # Leer- und Kommentarzeilen übergehen
            continue
        n += 1
        if n > 4:
            # Schleifenabbruch
            break
        print(line)

print()

# den Zufallszahlengenerator initialisieren
random.seed()

# Stop-Flag als Zufallszahl generieren
stop = (random.randint(0, 5) if 0 else int(time.time())) % 2

for preis in range(1, 60, 5):
    if 25 <= preis <= 40:
        # verketteter Vergleich
        print(preis, 'OK')
    elif preis < 20 or preis > 50:
        print(preis, 'kein Kauf')
    else:
        print(preis, 'grenzwertig')
        if stop:
            break

else:
    print('Schleife normal beendet')

print()

# ---------------------

# try / except - Ausnahmebehandlung (Exception Handling)

try:
    print(1 / 0)
except:
    # Ausnahme ignorieren
    pass

try:
    f = open('/etc/shadow')
except Exception as e:
    # Ausnahme protokollieren, aber nicht erneut auswerfen
    print('Problem:', e)

print()

try:
    # die im Kommandozeilenargument 1 benannte Datei öffnen
    f = open(sys.argv[1])

except Exception as e:
    # Ausnahme protokollieren und dann mit raise erneut auswerfen
    print('denkste:', e)
    raise

else:
    # alles hat geklappt, dann den Namen der geöffneten Datei ausgeben
    print('alles prima:', f.name)

finally:
    # wird immer ausgeführt; eine unbehandelte Ausnahme wird danach erneut
    # ausgeworfen
    print('finally')

print()

# dividiere die Zahl 5 durch ein nichtnegatives geradzahliges d
def div5(d):
    assert d >= 0, 'negativer Divisor ist unzulässig'
        # oder kurz:
        # assert d >= 0
    
    if d % 2:
        raise ValueError('ungerader Divisor')

    return 5 / d

# div5 für mehrere Divisoren aufrufen
for div in 1, 3, 0, -4, 0, 5:
    print(f'{div}: ', end='')
    try:
        print(div5(div))

    except AssertionError as e:
        print(f'{e}, nochmal mit negiertem Vorzeichen:', div5(-div))

    except ZeroDivisionError as e:
        print(e) # division by zero

    except ValueError as e:
        print(f'{e}, nochmal mit {div+1}:', div5(div + 1))
