Zum Inhalt springen
Python – 06 While-Schleifen

Python – 06 While-Schleifen

while-Schleifen

Voraussetzungen

Bevor du mit diesem Modul startest, solltest du bereits vertraut sein mit:

Einführung

while-Schleifen sind anders als for-Schleifen nicht von Anfang an terminiert, das heißt die Anzahl der Durchläufe ist nicht per se vorgegeben. Stattdessen läuft die Schleife solange, bis eine bestimmte Bedingung erfüllt ist.

Schauen wir uns ein Beispiel an:

1
2
3
4
5
status = "" #Startwert, damit die erste Prüfung fehlerfrei stattfinden kann

while status != "stop": #Bedingung, hier: Ist status ungleich "stop"? Falls ja, weiter!
    status = input("Ich frage dich solange, bis du 'stop' eingibst.") #neuer Wert für status per input()
print("Programm beendet!") #diese Ausgabe kommt nach der while-Schleife

Beachte bitte folgende Eigenschaften bzw. Kriterien:

  • Die erste Prüfung der Bedingung muss erfolgen können. Deshalb ist in diesem Beispiel status erst ein mal mit einem leeren String übergeben. So kann in der while-Schleife geprüft werden, ob status den Wert hat, der zum Abbruch der Schleife führen soll. Du würdest sofort eine Fehlermeldung erhalten, weil status nicht definiert wäre.
  • Der Block in der while-Schleife wird so lange durchlaufen, bis die Bedingung erfüllt ist. Da muss aber nicht immer ein != als Operator eingesetzt werden. Auch andere Operatoren sind zulässig, wichtig ist nur, dass die Abfrage insgesamt True oder False zurückgibt.
    • Wenn status einen Wert ungleich “stop” hat, dann ist der Wert der Bedingung status != “stop” also True, weil die Bedingung fragt “Ist der Wert ungleich stop?” – “Ja (= True), ist er!”.
    • Wenn status einen Wert gleich “stop” hat, dann ist der Wert der Bedingung status != “stop” also False, weil die Bedingung fragt “Ist der Wert ungleich stop?” – “Nein (= False), ist er nicht!”.

Wann sollte man while-Schleifen nutzen?

Der grundlegende Unterschied

  • for-Schleife: wenn die Anzahl der Durchläufe vorher feststeht (z. B. genau 10-mal oder über alle Elemente einer Liste). range() zählt automatisch hoch, ein eigener Zähler entfällt.
  • while-Schleife: wenn die Anzahl der Durchläufe vorher nicht feststeht, sondern von einer Bedingung abhängt (z. B. von einer Nutzereingabe). Du musst selbst dafür sorgen, dass die Bedingung irgendwann falsch wird — sonst läuft die Schleife endlos.

while-Schleifen eignen sich bestens dafür, Fallunterscheidungen in einem Zug zu prüfen, auch hier schauen wir uns ein Beispiel an. Aus den Übungen zu if-else-Bedingungen kennen wir diesen Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
print('Willkommen zu meinem Ratespiel! Ich werde erraten, woran du denkst! Denke an ein Auto, einen Bär oder einen Menschen! Gib bitte immer ein ja oder nein als Antwort ein!\n')

aw = input('Ist es lebendig?\n')

if aw == 'nein':
    print('Es ist das Auto!\n')
else:
    if aw == 'ja':
        aw = input('Hat es vier Beine?\n')
        if aw == 'ja':
            print('Es ist der Bär!')
        else:
            print('Es ist der Mensch!\n')

Wenn du bei diesem Beispiel etwas anders als exakt “ja” oder “nein” eingibst, verlässt du den if-else-Block ohne Ausgabe. Jetzt ergänzen wir Prüfungsstrukturen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#für mehr Übersicht bereiten wir ein paar Stringvariablen vor, die wir dann einfach einsetzen
ersterGruß = 'Willkommen zu meinem Ratespiel! Ich werde erraten, woran du denkst! Denke an ein Auto, einen Bär oder einen Menschen! Gib bitte immer ein ja oder nein als Antwort ein!\n'
fehlermeldung = "--- Fehler --- \n"+"Schreibe exakt 'ja' oder 'nein'. Also bitte noch mal:\n"

fehler = 1 #Prüfvariable am Anfang 1

while fehler == 1: #solange ein Fehler vorliegt, wiederholt sich die Schleife
    print(ersterGruß)
    aw = input("Ist es lebendig?")
    if aw == 'nein':
        fehler = 0 #kein Fehler
        print('Es ist das Auto!\n')
    elif aw == 'ja':
        aw = input('Hat es vier Beine?\n')
        if aw == 'ja':
            fehler = 0 #kein Fehler
            print('Es ist der Bär!')
        elif aw == "nein":
            fehler = 0 #kein Fehler --> verlasse nach diesem Block die Schleife
            print('Es ist der Mensch!\n')
        else:
            fehler = 1 #Fehler --> wiederhole Schleife
            print(fehlermeldung)
    else:
        fehler = 1 #Fehler --> wiederhole Schleife
        print(fehlermeldung)

Besonders wichtig ist die Zeile mit fehler = 1, hier nimmt die Prüfungsvariable den Wert 1 an. Damit wird der Anweisungsblock in der while-Schleife erneut durchlaufen, eben solange ein Fehler existiert. In den anderen Anweisungsblöcken, in die ich mit einer gültigen Bedingung hineingelangt bin, wird der fehler = 0 gesetzt. Damit ist dann aber die Bedingung der while-Schleife nicht mehr erfüllt, deshalb kann ich sie verlassen.

while-Schleifen statt for-Schleifen

Es ist möglich, statt einer for-Schleife einfach eine while-Schleife zu konstruieren

Aufgaben

Aufgabe 1: while vs for

1
2
3
4
5
6
7
8
9
# Beispiel 1
k = 0
while k < 10:
  print(k)
  k += 1 #diese Stelle ist sehr wichtig! Ansonsten läuft dein Code endlos!

#Beispiel 2
for i in range(10):
    print(i)
  1. Probiere beide Codes aus. Du wirst feststellen, dass beide Codes genau die gleiche Ausgabe haben.
  2. Programmiere sowohl mit einer for- als auch while-Schleife einen Code, der 15 mal den gleichen Text ausgibt. (a)
  3. Beantworte die Fragen unten.

Aufgabe 2: break und continue

1
2
3
4
5
6
i = 1
while i < 8:
    if i == 5:
        break
    i += 1
print(i)
  1. Überlege, welchen Wert i haben könnte. Kommentiere anschließend den print()-Befehl aus und teste. Wie würdest du das erklären?
  2. Schreibe ein Skript, das i bis 20 iterieren würde, aber bei 14 aufhört. (a)
  3. Recherchiere, was der Befehl “continue” bei while-Schleifen bewirkt. Nutze ihn, um in einer while-Schleife alle Zahlen von 1 bis 100 zu überspringen, die durch 3 teilbar sind. Die Ausgabe soll also etwa so aussehen: 1,2,4,5,7,8,10,… (a)
  4. While-Schleifen können auch für den Fall, dass die Prüfbedingung nicht mehr stimmt, etwas ganz bestimmtes ausführen, bevor es einfach weitergeht. Prüfe den Code unten. Stimmt die Aussage?
1
2
3
4
5
6
7
8
k = 50
while k >= 0:
  print(k)
  k -= 1
else:
  print("k ist jetzt negativ!") #dieser else-Block gehört noch zur while-Schleife!

print("Du hast die Schleife offiziell verlassen.") #der Befehl kommt nach dem while-Block

Aufgabe 3: Eingabevalidierung

Schreibe ein Skript, dass folgende Kriterien erfüllt (a):

  • Nimmt Eingaben des Nutzers per input() an.
  • Prüfe die Eingaben per while-Schleife.
  • Solange die Bedingung nicht erfüllt ist, wird der Nutzer oder die Nutzerin erneut gefragt.
Tipp anzeigen
1
2
3
4
eingabe = input("Frage an Nutzer:in")

while eingabe != "prüftext": #prüft die Variable eingabe mit Vergleichsoperatoren
    #dein Code hier. Wichtig: Denke daran, erneut nach input() zu fragen!

Robuste Zahleneingabe mit try/except

In Python – 03 Wahrheitswerte und Kontrollstrukturen → Ausblick Fehler und Ausnahmen try except hast du try/except schon kurz kennengelernt: Mit try/except ValueError kann man verhindern, dass int(input(...)) das Programm zum Absturz bringt. Damals ohne Schleife war das aber nur ein einmaliger Rettungsanker. Kombiniert mit while wird daraus ein robuster Eingabeloop: Solange die Eingabe ungültig ist, fragt das Programm erneut.

Muster: Frage wiederholen, bis Eingabe gültig ist

1
2
3
4
5
6
7
8
9
while True:                                 # Schleife ohne feste Abbruchbedingung
    versuch = input("Gib eine ganze Zahl ein: ")
    try:
        zahl = int(versuch)                 # kann ValueError auslösen
        break                               # Eingabe war gültig → Schleife verlassen
    except ValueError:
        print("Das war keine Zahl. Versuch's noch mal.")

print("Danke, deine Zahl ist:", zahl)

So liest du das:

  • while True: ist eine Endlosschleife. Verlassen wird sie nur durch break.
  • Der try-Block enthält genau den Code, der schiefgehen könnte (int(versuch)).
  • Klappt die Umwandlung, wird break ausgeführt – die Schleife ist fertig.
  • Schlägt sie fehl, übernimmt except ValueError und wir landen wieder oben in der Schleife.

Warum while True statt einer Prüfvariable wie fehler = 1?

Beides funktioniert, und weiter oben im Ratespiel-Beispiel hast du ja schon fehler = 1 / fehler = 0 gesehen. while True + break ist in Python aber der idiomatische Stil für “wiederhole so lange, bis es klappt”, weil die Abbruchbedingung inhaltlich mit der gültigen Eingabe zusammenhängt und nicht mit einer künstlichen Zählvariable.

Aufgabe 3b: Zahleneingabe absichern

Erweitere das Muster von Aufgabe 3 um eine Zahleneingabe (a):

  1. Frage den Nutzer wiederholt nach einem Alter (ganze Zahl).
  2. Wenn er etwas eingibt, das keine Zahl ist (z.B. abc), darf dein Programm nicht abstürzen – fange den ValueError ab und frage erneut.
  3. Wenn die Eingabe eine Zahl ist, aber kleiner als 0 oder größer als 120, gib eine Fehlermeldung aus und frage erneut (das ist eine normale if-Prüfung, kein try/except).
  4. Erst bei gültiger Zahl: Gib das Alter aus und verlasse die Schleife.

Lösungsansatz

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
while True:
    versuch = input("Wie alt bist du? ")
    try:
        alter = int(versuch)
    except ValueError:
        print("Das war keine Zahl.")
        continue          # zurück an den Schleifenanfang

    if alter < 0 or alter > 120:
        print("Bitte ein realistisches Alter (0–120).")
        continue

    break                 # alles ok → raus

print("Alter gespeichert:", alter)

Aufgabe 4a: Zeitbasierte Schleifen

Insbesondere bei sich dynamisch und außerhalb des Loops ändernden Werten, bieten sich while-Loops an. Mit einer for-Schleife kann man bspw. nicht bzw. nicht sinnvoll mit Zeitpunkten oder Zeiträume umgehen.

  1. Analysiere den Code unten und stelle eine Vermutung auf, bevor du ihn ausführst.
  2. Führe den Code aus und beobachte. Was passiert? Schreibe Kommentare über die Blöcke oder hinter die Zeilen. (a)
  3. Ändere den Code so, dass er 20 Sekunden lang alle 3 Sekunden “tik” in der Konsole ausgibt.
  4. Schreibe verschiedene Codes mit while-Schleifen:
    1. Es wird abwechselnd “tik” und “tak” mit zeitlicher Verzögerung ausgegeben. (a)
    2. Eine Geschichte wird mit Pausen erzählt. Zwischendurch wird der Nutzer um eine Eingabe gebeten. (a)

Beispielcode:

1
2
3
4
5
6
7
8
import time #importiere Modul time
ende = time.time()+20 # jetzt = time.time(), +20 jetzt+20

while time.time() < ende:
    print("..tik..")
    time.sleep(1) # time.sleep(x) Warte x Sekunden
    print("..tak..")
    time.sleep(1)

Turtle-Exkurs

Aufgabe 4b: Turtle-Exkurs – Wachsende Spirale mit while

while-Schleifen eignen sich bei Turtle für Zeichnungen, bei denen du vorher nicht genau weißt, wie viele Schritte nötig sind.

Beispiel – Spirale, die wächst:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import turtle
t = turtle.Turtle()
t.speed(0)

laenge = 5

while laenge < 200:
    t.forward(laenge)
    t.left(91)           # knapp über 90° ergibt Spiraleffekt
    laenge += 3           # Schritte werden immer größer

turtle.done()
  1. Probiere den Code aus. Ändere den Startwert, den Winkel und die Schrittweite (laenge += 3). Was verändert sich?
  2. Erweitere den Code so, dass die Turtle die Farbe wechselt, wenn laenge einen bestimmten Schwellenwert überschreitet (z.B. ab 100 wird sie rot). Nutze dafür eine if-Bedingung innerhalb der while-Schleife. (a)
  3. Erstelle eine zufällige Irrfahrt (Random Walk): Die Turtle geht in jedem Schritt eine feste Strecke vorwärts, dreht sich aber um einen zufälligen Winkel. Die Schleife läuft, bis die Turtle mehr als 200 Pixel vom Startpunkt entfernt ist. Nutze t.distance(0, 0) für die Entfernung zum Ursprung und random.randint() für den zufälligen Winkel. (a)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Startcode für Aufgabe 3
import turtle
import random

t = turtle.Turtle()
t.speed(0)

while t.distance(0, 0) < 200:
    # dein Code hier
    pass

turtle.done()

Aufgabe 5 (extra): Komplexe Fallunterscheidungen

Überlege dir ein sinnvolles Beispiel, bei dem du while-Schleifen, if-else-Bedingungen (inkl. elif und else) sowie inputs und try-except nutzt. Brainstorme mit anderen, wenn dir keine guten Ideen einfallen.


Flask-Anwendung (Bonus)

Voraussetzung für diese Aufgabe

Du solltest bereits Flask – 01 Erste Schritte, Flask – 02 Jinja Templating Grundlagen und Flask – 03 Jinja Schleifen und Listen durchgearbeitet haben. Wenn nicht, überspringe diese Bonus-Aufgabe zunächst.

Bonus: Formular mit Eingabevalidierung

Erstelle eine Flask-App mit einem Formular, das Eingaben validiert – ähnlich wie in Aufgabe 3!

Anforderungen:

  1. Erstelle eine Route /registrierung mit GET und POST
  2. Zeige ein Formular mit folgenden Feldern:
    • Benutzername (mindestens 3 Zeichen)
    • Alter (muss zwischen 10 und 100 sein)
    • E-Mail (muss @ enthalten)
  3. Validiere die Eingaben mit if-Bedingungen
  4. Bei Fehlern:
    • Zeige eine Fehlerliste im Template
    • Zeige das Formular erneut an (wie while-Schleife!)
  5. Bei Erfolg:
    • Zeige eine Erfolgsmeldung

Tipp: In Flask ersetzt das wiederholte Anzeigen des Formulars mit Fehlermeldungen die while-Schleife!

Lösung zeigen

app.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from flask import Flask, render_template, request

app = Flask(__name__)

def validiere_benutzername(name: str) -> tuple[bool, str]:
    """Validiert den Benutzernamen. Gibt (ist_gültig, Fehlermeldung) zurück."""
    if not name:
        return (False, "Benutzername darf nicht leer sein")
    if len(name) < 3:
        return (False, "Benutzername muss mindestens 3 Zeichen haben")
    if not name.isalnum():
        return (False, "Benutzername darf nur Buchstaben und Zahlen enthalten")
    return (True, "")

def validiere_alter(alter_str: str) -> tuple[bool, str]:
    """Validiert das Alter. Gibt (ist_gültig, Fehlermeldung) zurück."""
    if not alter_str:
        return (False, "Alter darf nicht leer sein")

    try:
        alter = int(alter_str)
    except ValueError:
        return (False, "Alter muss eine Zahl sein")

    if alter < 10 or alter > 100:
        return (False, "Alter muss zwischen 10 und 100 liegen")

    return (True, "")

def validiere_email(email: str) -> tuple[bool, str]:
    """Validiert die E-Mail-Adresse. Gibt (ist_gültig, Fehlermeldung) zurück."""
    if not email:
        return (False, "E-Mail darf nicht leer sein")
    if "@" not in email or "." not in email:
        return (False, "E-Mail muss @ und . enthalten")
    if email.count("@") != 1:
        return (False, "E-Mail darf nur ein @ enthalten")
    return (True, "")

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/registrierung", methods=['GET', 'POST'])
def registrierung():
    if request.method == 'POST':
        # Formulardaten holen
        benutzername = request.form.get('benutzername', '')
        alter_str = request.form.get('alter', '')
        email = request.form.get('email', '')

        # Fehler sammeln (wie in einer while-Schleife Bedingungen prüfen!)
        fehler = []

        # Validierung durchführen
        gueltig, fehlertext = validiere_benutzername(benutzername)
        if not gueltig:
            fehler.append(fehlertext)

        gueltig, fehlertext = validiere_alter(alter_str)
        if not gueltig:
            fehler.append(fehlertext)

        gueltig, fehlertext = validiere_email(email)
        if not gueltig:
            fehler.append(fehlertext)

        # Wenn Fehler existieren, zeige Formular erneut (wie while-Schleife!)
        if fehler:
            return render_template("registrierung_formular.html",
                                   fehler=fehler,
                                   benutzername=benutzername,
                                   alter=alter_str,
                                   email=email)

        # Erfolg! Keine Fehler, zeige Erfolgsmeldung
        return render_template("registrierung_erfolg.html",
                               benutzername=benutzername)

    # GET-Request: Zeige leeres Formular
    return render_template("registrierung_formular.html")

if __name__ == "__main__":
    app.run(debug=True)

templates/registrierung_formular.html:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Registrierung</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 500px;
            margin: 50px auto;
            padding: 20px;
            background: #f0f0f0;
        }
        .container {
            background: white;
            padding: 30px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            text-align: center;
        }
        .fehler {
            background: #ffebee;
            color: #c62828;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
            border-left: 4px solid #c62828;
        }
        .fehler h3 {
            margin-top: 0;
        }
        label {
            display: block;
            margin-top: 15px;
            font-weight: bold;
            color: #555;
        }
        input {
            width: 100%;
            padding: 10px;
            margin-top: 5px;
            border: 2px solid #ddd;
            border-radius: 5px;
            font-size: 16px;
        }
        input:focus {
            outline: none;
            border-color: #4caf50;
        }
        button {
            width: 100%;
            padding: 12px;
            margin-top: 20px;
            background: #4caf50;
            color: white;
            border: none;
            border-radius: 5px;
            font-size: 16px;
            cursor: pointer;
            font-weight: bold;
        }
        button:hover {
            background: #45a049;
        }
        .info {
            background: #e3f2fd;
            padding: 10px;
            border-radius: 5px;
            margin-top: 20px;
            font-size: 14px;
            color: #1976d2;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Registrierung</h1>

        {% if fehler %}
        <div class="fehler">
            <h3>Bitte korrigiere folgende Fehler:</h3>
            <ul>
            {% for fehler_text in fehler %}
                <li>{{ fehler_text }}</li>
            {% endfor %}
            </ul>
        </div>
        {% endif %}

        <form method="POST">
            <label>Benutzername:</label>
            <input type="text" name="benutzername"
                   value="{{ benutzername if benutzername else '' }}"
                   placeholder="Mindestens 3 Zeichen">

            <label>Alter:</label>
            <input type="number" name="alter"
                   value="{{ alter if alter else '' }}"
                   placeholder="Zwischen 10 und 100">

            <label>E-Mail:</label>
            <input type="email" name="email"
                   value="{{ email if email else '' }}"
                   placeholder="deine@email.de">

            <button type="submit">Registrieren</button>
        </form>

        <div class="info">
            <strong>Tipp:</strong> Dieses Formular funktioniert wie eine while-Schleife!
            Es wird solange neu angezeigt, bis alle Eingaben korrekt sind.
        </div>
    </div>
</body>
</html>

templates/registrierung_erfolg.html:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Registrierung erfolgreich</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 500px;
            margin: 50px auto;
            padding: 20px;
            background: #f0f0f0;
        }
        .container {
            background: white;
            padding: 30px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            text-align: center;
        }
        h1 {
            color: #4caf50;
        }
        .erfolg {
            background: #e8f5e9;
            color: #2e7d32;
            padding: 20px;
            border-radius: 5px;
            margin: 20px 0;
            border-left: 4px solid #4caf50;
        }
        .check {
            font-size: 48px;
            color: #4caf50;
        }
        a {
            display: inline-block;
            margin-top: 20px;
            padding: 10px 20px;
            background: #2196f3;
            color: white;
            text-decoration: none;
            border-radius: 5px;
        }
        a:hover {
            background: #1976d2;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="check">OK</div>
        <h1>Registrierung erfolgreich!</h1>

        <div class="erfolg">
            <p><strong>Willkommen, {{ benutzername }}!</strong></p>
            <p>Deine Registrierung war erfolgreich. Alle Eingaben wurden validiert!</p>
        </div>

        <a href="/registrierung">← Zurück zur Registrierung</a>
    </div>
</body>
</html>

So funktioniert es wie eine while-Schleife:

  1. Erste Anzeige: Formular wird angezeigt (wie while fehler == 1:)
  2. Validierung: Eingaben werden geprüft
  3. Fehlerfall: Formular wird MIT Fehlermeldungen erneut angezeigt (Schleife wiederholt sich)
  4. Erfolgsfall: Erfolgsseite wird angezeigt (Schleife wird verlassen)
Zuletzt aktualisiert am