lehrkraefte:snr:informatik:glf22:python:while

while-loops (while-Schleifen)

Schau dir das folgende Video zu while-loops an und löse die darin enthaltenen kleinen Aufgaben!

Video "while-loops"

Lösung der ersten Aufgabe aus dem Video

Lösung der ersten Aufgabe aus dem Video

zahlen-aufsummieren.py
summe = 0
eingabe = -1
while eingabe != 0:
    eingabe = int(input("Gib eine Zahl ein: "))
    summe = summe + eingabe
print(f"Die Summe der eingegebenen Zahlen ist {summe}.")

Lösung der zweiten Aufgabe aus dem Video

Lösung der zweiten Aufgabe aus dem Video

string-mit-mindestlaenge-10-einlesen.py
eingabe = ""
while len(eingabe) < 10:
    eingabe = input("Gib einen String der Länge mindestens 10 ein: ") 
print(f"Die Eingabe war: {eingabe}")

Lösung der dritten Aufgabe aus dem Video

Lösung der dritten Aufgabe aus dem Video

drei-potenzieren.py
produkt = 1
zaehler = 0
while produkt <= 1000000:
    produkt = 3 * produkt
    zaehler = zaehler + 1
print(f"3 hoch {zaehler} ist das erste Mal groesser als 1000000.")

Die Syntax von while-Schleifen ist ähnlich zu der von if-statements:

while <Ausführungsbedingung der Schleife>:
    Code-Block (auch Rumpf der Schleife genannt) 

Der eingerückte Code-Block wird solange wieder und wieder durchgeführt, wie die Ausführungsbedingung gilt.

Die Ausführungsbedingung einer while-Schleife hängt fast immer von Variablen ab. Diese müssen am Anfang initialisiert werden (oft so, dass die Schleife mindestens einmal ausgeführt wird) und im Rumpf der Schleife so verändert werden, dass die Schleife irgendwann verlassen wird.

Vermeide Endlosschleifen! Falls das doch passiert: Abbruch der Programms im Terminal mit Ctrl+c.

Jede for-loop kann durch eine while-loop ersetzt werden:

(1) Schreibe ein Programm mit einer while-Schleife und ohne for-Schleife, das dasselbe tut wie das folgende Programm:

einfache-for-schleife.py
for i in range(5, 20):
    print(i)

Hinweis

Hinweis

Verwende eine Variable i, die vor der while-Schleife zu initialisieren ist und in der while-Schleife erhöht wird. Die Ausführungsbedingung hängt vom Wert dieser Variablen ab.

Lösungsvorschlag

Lösungsvorschlag

for-per-while.py
i = 5
while i < 20:
    print(i)
    i = i + 1

(2) Verändere dein Programm so, dass es von 20 beginnend abwärts mit Schrittweite 3 alle Zahlen ausgibt, die echt grösser als -7 sind.

Lösungsvorschlag

Lösungsvorschlag

schrittweise-abwaerts-zaehlen-per-while.py
i = 20
while i > -7:
    print(i)
    i = i - 3

Gib in der Python-Shell den Befehl

  • import random

ein (dieser importiert alle Befehle aus der random-Bibliothek) und dann

  • random.randint(1,6)

Um den letzten Befehl noch einige weitere Male auszuführen: Drücke die Pfeiltaste (damit bekommt man die vorige Eingabe) und dann Enter. Wiederhole dies einige Male. Variiere die Argumente 1 und 6 im Befehl random.randint(1,6) und bekomme so heraus, was dieser Befehl macht.

Was liefert der Befehl random.random()?

Lösung

Lösung

Der Befehl random.randint(1,6) erzeugt eine ganzzahlige Zufallszahl zwischen 1 (einschliesslich) und 6 (einschliesslich). Alle Zahlen kommen gleich häufig vor (wie bei einem idealen Würfel).

Der Befehl random.random() liefert zufällig eine Kommazahl im Intervall $[0,1[$.

Genauer: Es kommen nur Kommazahlen heraus, die ab der 54. Nachkommastelle nur Nullen als Nachkommastellen haben. (Ich habe dies durch Eingabe von f“{random.random():.54f}” herausgefunden.)

Speichere das folgende Programm ab und ändere es so, dass der Benutzer nach jeder Additionsaufgabe gefragt wird, ob er noch eine weitere Aufgabe lösen möchte. Bei Eingabe von “n” oder “nein” soll das Programm enden, sonst (beispielsweise beim Drücken von Enter ohne vorherige Eingabe) soll eine weitere Additionsaufgabe gestellt werden.

additionstrainer.py
import random
a = random.randint(-10, 10)
b = random.randint(-10, 10)
eingabe = int(input(f"Berechne {a} plus {b}: "))
if eingabe == a + b:
    print("Korrekt!")
else:
    print(f"Falsch. Richtig wäre {a+b} gewesen.")

Hinweis

Hinweis

Packe den gesamten Programm-Code abgesehen von der ersten Zeile in eine while-Schleife. Initialisiere am Programmbeginn eine Boolesche Variable per weiter = True. Der Ausführungsteil der while-Schleife (auch Schleifenrumpf oder Schleifenkörper genannt) wird solange durchgeführt, wie diese Variable True ist. Am Ende des Ausführungsteils wird der Benutzer gefragt, ob er eine weitere Aufgabe lösen möchte.

Lösungsvorschlag

Lösungsvorschlag

additionstrainer-mehrfach.py
import random
 
weiter = True
while weiter:
    a = random.randint(-10, 10)
    b = random.randint(-10, 10)
    eingabe = int(input(f"Berechne {a} plus {b}: "))
    if eingabe == a + b:
        print("Korrekt!")
    else:
        print(f"Falsch. Richtig wäre {a+b} gewesen.")
    eingabe = input("Weitere Additionsaufgabe? ")
    if eingabe == "n" or eingabe == "nein":
        weiter = False

Bonus-Aufgabe: Wer mag, kann jedesmal abhängig von einer Zufallszahl (mit Werten 1, 2, 3 (und 4)) eine Additions-, Subtraktions- oder Multiplikationsaufgabe (oder “aufgehende” Divisionsaufgabe) stellen. (Achtung, Division durch Null vermeiden!)

Spieler A denkt sich eine (ganzzahlige) Zufallszahl zwischen 1 und 100 aus. Spieler B rät eine Zahl. Spieler A informiert ihn dann, ob er zu hoch bzw. zu tief bzw. richtig geraten hat. Spieler B wiederholt das Raten so lange, bis er die richtige Zahl herausbekommen hat.

Schreibe ein Python-Programm, so dass der Computer den Part von Spieler A übernimmt und der Benutzer den Part von Spieler B. Gib am Ende aus, wie viele Versuche Spieler B benötigt hat.

Lösungsvorschlag

Lösungsvorschlag

zahlenratespiel.py
import random
 
zahl = random.randint(1, 100)
print("Ich habe mir eine Zahl zwischen 1 und 100 ausgedacht.")
 
versuche = 0
gerateneZahl = 0 
# oder jede andere Zahl, die nicht zwischen 1 und 100 liegt: 
# Mit jeder solchen Wahl wird der Schleifenkörper (= der Ausführungsteil)
# der while-Schleife mindestens einmal ausgeführt. 
 
while zahl != gerateneZahl:
    gerateneZahl = int(input("Rate meine Zahl: "))
    versuche = versuche + 1
    if gerateneZahl > zahl:
        print("zu hoch!")
    elif gerateneZahl < zahl:
        print("zu niedrig")
    else:
        print("richtig!")
print(f"Du hast {versuche} Versuche benötigt.")

Bonus-Frage: Finde eine Rate-Strategie für B, so dass B mit möglichst wenig Fehlversuchen auskommt.

Lösung

Lösung

Starte mit 50 und halbiere dann jeweils den Bereich aller noch möglichen Zahlen. Wenn beispielsweise 50 zu niedrig war, sind noch alle Zahlen von 51 bis 100 möglich. Rate also 75.

Bonus-Material

Unter dem folgenden Link ist ein Skelett eines Programms, das du verbessern sollst (Download im Ordner deiner Wahl per rechter Maustaste).

(Achtung: Das Programm enthält eine Endlosschleife! Abbruch per Ctrl+c im Terminal.)

box-steuern.py

Wenn du das Programm in etwa verstehst, löse sofort die Aufgaben unten. Sonst schau dir das folgende Erklärvideo an:

Video zum Programm "box-steuern"

Ändere das Programm so, dass:

  • (1) Drücken der Escape-Taste, der Taste “q” oder Anklicken des Kreuzes rechts oben im Pygame-Fenster das Programm beenden.

Hinweis

Hinweis

Verändere die Variable fensterSchliessen bei den entsprechenden Eingaben.


  • (2) Die grüne Box (imfolgenden Schlange genannt, auch wenn sie sehr kurz ist) mit den Cursor-Tasten bewegt werden kann (Bewegung um ein Kästchen pro Tastendruck).

Hinweis

Hinweis

Die Variablen xSpieler und ySpieler speichern die aktuelle Position der Schlange. Diese Variablen sind bei den entsprechenden Eingaben zu verändern. Welche Koordinate muss beispielsweise beim Drücken der Pfeiltaste nach oben wie verändert werden?


  • (3) Die Schlange das Spielfeld nicht verlassen kann (wenn die Box etwa am rechten Rand ist und die rechte Pfeiltaste gedrückt wird, passiert nichts).

Hinweis

Hinweis

Zum Beispiel bei Eingabe “Pfeiltaste nach rechts”: Erhöhe die Variable xSpieler nur dann um eins, wenn die Schlange dadurch das Spielfeld nicht verlässt. (Die Breite des Spielfelds ist in ANZAHL_BOXEN_X gespeichert.)


  • (4) Wenn die Schlange auf das Feld mit der roten Box kommt (die Schlange frisst den Apfel), soll ein neuer Apfel an einer neuen Position erzeugt werden.
  • (5) Drücken der Taste “f” (wie Farbe) zum Farbwechsel der Schlange auf Blau bzw. zurück auf Grün führt.

Lösungsvorschlag

Lösungsvorschlag

aepfel-fressen.py
# Strongly inspired by a program by Al Sweigart, see
# https://inventwithpython.com/pygame/chapter6.html
# Creative Commons BY-NC-SA 3.0 US
 
import random, pygame
from pygame.locals import *
 
FRAMES_PER_SECOND = 30
 
ANZAHL_BOXEN_X = 10
ANZAHL_BOXEN_Y = 6
 
BOX_BREITE = 60
BOX_HOEHE = 60
 
FENSTER_BREITE = ANZAHL_BOXEN_X * BOX_BREITE
FENSTER_HOEHE = ANZAHL_BOXEN_Y * BOX_HOEHE
 
# Farben per Rot-, Grün- und Blauwert
# (jeweils auf Skala von 0 bis 255).
#          rot  grün  blau
ROT     = (255,    0,    0)
GRUEN   = (  0,  255,    0)
BLAU    = (  0,    0,  255)
WEISS   = (255,  255,  255)
SCHWARZ = (  0,    0,    0)
GRAU    = (150,  150,  150)
HINTERGRUND_FARBE = SCHWARZ
 
def zeichneBox(x, y, farbe):
    rechteck = pygame.Rect(x * BOX_BREITE + 1, y * BOX_HOEHE + 1, BOX_BREITE - 1, BOX_HOEHE - 1)
    pygame.draw.rect(leinwand, farbe, rechteck)
 
def zeichneGitter():
    for x in range(ANZAHL_BOXEN_X + 1):
        pygame.draw.line(leinwand, GRAU, (x * BOX_BREITE, 0), (x * BOX_BREITE, FENSTER_HOEHE))
    for y in range(ANZAHL_BOXEN_Y + 1):
        pygame.draw.line(leinwand, GRAU, (0, y * BOX_HOEHE), (FENSTER_BREITE, y * BOX_HOEHE))
 
pygame.init()
uhr = pygame.time.Clock()
leinwand = pygame.display.set_mode((FENSTER_BREITE + 1, FENSTER_HOEHE + 1))
pygame.display.set_caption('Green box')
 
xSpieler = random.randint(0, ANZAHL_BOXEN_X - 1)
ySpieler = random.randint(0, ANZAHL_BOXEN_Y - 1)
farbeSpieler = GRUEN
 
xApfel = random.randint(0, ANZAHL_BOXEN_X - 1)
yApfel = random.randint(0, ANZAHL_BOXEN_Y - 1)
while (xSpieler == xApfel) and (ySpieler == yApfel):
    xApfel = random.randint(0, ANZAHL_BOXEN_X - 1)
    yApfel = random.randint(0, ANZAHL_BOXEN_Y - 1)
 
fensterSchliessen = False
while not fensterSchliessen:
    leinwand.fill(HINTERGRUND_FARBE)
    zeichneGitter()
    zeichneBox(xApfel, yApfel, ROT)
    zeichneBox(xSpieler, ySpieler, farbeSpieler)
    pygame.display.update()
    uhr.tick(FRAMES_PER_SECOND)
 
    for ereignis in pygame.event.get():
        if ereignis.type == QUIT:
            print("Button zum Schliessen des Pygame-Fensters angeklickt.")
            fensterSchliessen = True
        elif ereignis.type == KEYDOWN:
            if ereignis.key == K_LEFT:
                print("Pfeiltaste links gedrückt.")
                if xSpieler > 0:
                    xSpieler = xSpieler - 1
            elif ereignis.key == K_RIGHT:
                print("Pfeiltaste rechts gedrückt.")
                if xSpieler < ANZAHL_BOXEN_X - 1:
                    xSpieler = xSpieler + 1
            elif ereignis.key == K_UP:
                print("Pfeiltaste hoch gedrückt.")
                if ySpieler > 0:            
                    ySpieler = ySpieler - 1
            elif ereignis.key == K_DOWN:
                print("Pfeiltaste runter gedrückt.")
                if ySpieler < ANZAHL_BOXEN_Y - 1:
                    ySpieler = ySpieler + 1
            elif ereignis.key == K_ESCAPE:
                print("Escape-Taste gedrückt.")
                fensterSchliessen = True
            elif ereignis.key == K_q:
                print("Taste 'q' gedrückt.")
                fensterSchliessen = True
            elif ereignis.key == K_f:
                if farbeSpieler == GRUEN:
                    farbeSpieler = BLAU
                else:
                    farbeSpieler = GRUEN 
    if xSpieler == xApfel and ySpieler == yApfel:
        print("Apfel gefressen.")
        xApfel = random.randint(0, ANZAHL_BOXEN_X - 1)
        yApfel = random.randint(0, ANZAHL_BOXEN_Y - 1)
        while (xSpieler == xApfel) and (ySpieler == yApfel):
            xApfel = random.randint(0, ANZAHL_BOXEN_X - 1)
            yApfel = random.randint(0, ANZAHL_BOXEN_Y - 1)

Bonus-Aufgaben (such dir aus, was dir gefällt):

  • (6) Wenn die grüne Box einen Spielfeldrand erreicht und weiter in diese Richtung gesteuert wird, erscheint sie am gegenüberliegenden Spielfeldrand.
  • (7) Für jeden gefressenen Apfel bekommt die Schlange 100 Punkte gutgeschrieben. Den aktuellen Punktestand kannst du im Terminal ausgeben.
  • (8) Der Apfel kann der Schlange davonlaufen: Steuere den Apfel etwa mit den Tasten “a”, “s”, “d”, “w”.
  • (9) Sei kreativ und erweitere das Spiel!
  • (10) Die Schlange läuft stets mit konstanter Geschwindigkeit (auch wenn keine Taste gedrückt wird). Drücken der Pfeiltasten ändert nur die Richtung.
  • (11) Wenn du Snake programmieren willst, solltest du lernen, was Listen sind! … vermutlich kommt das in einem der folgenden Abschnitte dran …
  • lehrkraefte/snr/informatik/glf22/python/while.txt
  • Last modified: 2022/10/25 12:05
  • by Olaf Schnürer