MINT lernen

Übung — AFB III (Verallgemeinern und Reflektieren)

Zehn Aufgaben zum Begründen und Beurteilen — hier zählt, dass du erklären kannst, warum ein Programm genau das tut, was es tut.

Dein Fortschritt:
0 / 0 Aufgaben
3

Aufgabenblock — AFB III

Begründen statt nur ausführen: Fehlermeldungen deuten, Programme vergleichen, Aussagen beurteilen und Programme weiterentwickeln. Formuliere deine Antwort erst selbst in ganzen Sätzen, bevor du die Musterlösung aufklappst.

A1
print oder return?
AFB III

Lina erwartet die Ausgabe 11. Stattdessen erscheint 10 und danach eine Fehlermeldung. Erkläre, was passiert, und gib die Korrektur an.

def verdopple(x):    print(2 * x)ergebnis = verdopple(5)print(ergebnis + 1)
10
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Hinweis: Überlege, was in der Variablen ergebnis gespeichert wird.

Strategie: Eine Funktion ohne return gibt automatisch None zurück.Warum so? Man muss zwischen „etwas anzeigen“ und „etwas zurückgeben“ unterscheiden.
Lösungsskizze: print zeigt 10 an · Rückgabewert None · None + 1 → TypeError · Korrektur: return 2 * x.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Die Funktion zeigt 2 · 5 = 10 zwar mit print in der Konsole an, gibt aber nichts zurück. Eine Funktion ohne return liefert den besonderen Wert None. In Zeile 4 wird also ergebnis = None gespeichert. In Zeile 5 soll None + 1 gerechnet werden — das geht nicht, deshalb der TypeError. Richtig ist return 2 * x statt print: Dann ist ergebnis = 10 und die Ausgabe 11.

def verdopple(x):    return 2 * xergebnis = verdopple(5)print(ergebnis + 1)
A2
/ oder //?
AFB III

Das Programm soll dreimal einen Stern ausgeben, bricht aber mit TypeError: 'float' object cannot be interpreted as an integer ab. Begründe den Fehler, obwohl 9 durch 3 doch aufgeht, und vergleiche zwei Möglichkeiten der Korrektur.

anzahl = 9for i in range(anzahl / 3):    print("*")

Hinweis: Welchen Datentyp liefert / — und welchen braucht range()?

Strategie: Frag nicht nach dem Zahlenwert, sondern nach dem Datentyp.Warum so? Python entscheidet über den Typ am Operator, nicht am Ergebnis.
Lösungsskizze: 9 / 3 = 3.0 (float) · range braucht int · Korrektur: // oder int(anzahl / 3) · // bleibt immer ganzzahlig.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Der Operator / liefert in Python immer einen float, auch wenn die Division aufgeht: 9 / 3 ergibt 3.0. range() kann aber nur mit ganzen Zahlen (int) zählen — mit 3.0 weiß Python nicht, wie oft wiederholt werden soll. Korrektur 1: anzahl // 3 teilt ganzzahlig und liefert 3. Korrektur 2: int(anzahl / 3) wandelt 3.0 in 3 um. Beide funktionieren hier; // ist kürzer und macht schon beim Lesen klar, dass eine ganze Zahl gemeint ist. Bei anzahl = 10 liefern beide 3 — der Rest fällt jeweils weg.

anzahl = 9for i in range(anzahl // 3):    print("*")
A3
for oder while?
AFB III

Beide Programme geben 2, 4, 6, 8, 10 untereinander aus. Vergleiche sie und erläutere an einem eigenen Beispiel, wann nur eine while-Schleife in Frage kommt.

for zahl in range(2, 11, 2):    print(zahl)
zahl = 2while zahl <= 10:    print(zahl)    zahl = zahl + 2

Hinweis: Frag dich, ob man vor dem Start weiß, wie oft wiederholt wird.

Strategie: Zähle, wie viele Zeilen sich um die Zählvariable kümmern.Warum so? Vergleichen heißt: Gemeinsamkeiten und Unterschiede nennen.
Lösungsskizze: for: Anzahl vorher bekannt, Zähler automatisch · while: Bedingung, Zähler selbst verwalten · Beispiel: Eingabe wiederholen, bis sie stimmt.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Beide Programme liefern dieselbe Ausgabe. Bei der for-Schleife kümmert sich range(2, 11, 2) um alles: Startwert, Schrittweite und Ende. Bei der while-Schleife muss man den Startwert selbst setzen, die Bedingung formulieren und zahl in der Schleife erhöhen — vergisst man die letzte Zeile, entsteht eine Endlosschleife. Deshalb nimmt man for, wenn die Anzahl der Durchläufe vorher feststeht. while braucht man, wenn eine Bedingung entscheidet und niemand vorher weiß, wie oft es nötig ist — zum Beispiel eine PIN-Abfrage, die so lange wiederholt wird, bis die richtige PIN kommt:

pin = input("PIN? ")while pin != "1234":    print("Falsch, noch einmal.")    pin = input("PIN? ")print("Entsperrt!")
A4
Der teure Brief
AFB III

Ein Porto-Programm soll für Briefe bis 500 g „Kompaktbrief“ ausgeben. Bei 300 g erscheint aber „Großbrief“. Begründe, warum der elif-Zweig nie ausgeführt werden kann, und korrigiere das Programm.

gewicht = 300if gewicht <= 1000:    print("Großbrief: 1.80 Euro")elif gewicht <= 500:    print("Kompaktbrief: 1.10 Euro")else:    print("Paket")

Hinweis: Ein Brief mit 300 g ist auch leichter als 1000 g.

Strategie: Suche einen Wert, für den Zeile 4 wahr ist, Zeile 2 aber falsch.Warum so? Bei elif kommt ein Zweig nur dran, wenn alle Bedingungen darüber falsch waren.
Lösungsskizze: Jeder Wert ≤ 500 ist auch ≤ 1000 → erster Zweig fängt alles ab · engere Bedingung nach oben.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Python prüft von oben nach unten und führt nur den ersten wahren Zweig aus. Jedes Gewicht, das kleiner oder gleich 500 ist, ist automatisch auch kleiner oder gleich 1000. Damit ist schon die erste Bedingung wahr, und der elif-Zweig wird gar nicht mehr geprüft — er kann nie laufen. Man muss die engere Bedingung zuerst prüfen:

gewicht = 300if gewicht <= 500:    print("Kompaktbrief: 1.10 Euro")elif gewicht <= 1000:    print("Großbrief: 1.80 Euro")else:    print("Paket")
A5
Endet das Programm?
AFB III

Tarek behauptet: „Die Variable i wird in jedem Durchlauf verändert — also kann das keine Endlosschleife sein.“ Beurteile die Aussage.

i = 0while i != 10:    print(i)    i = i + 3

Hinweis: Schreib die ersten Werte von i auf.

Strategie: Prüfe, ob die Bedingung jemals falsch wird.Warum so? Eine Schleife endet nur, wenn ihre Bedingung irgendwann False ergibt.
Lösungsskizze: i: 0, 3, 6, 9, 12, … · 10 wird übersprungen · i != 10 bleibt wahr · Korrektur: i < 10.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Tareks Aussage stimmt so nicht. Dass sich i ändert, ist nötig, reicht aber nicht aus: Die Bedingung muss irgendwann falsch werden. i nimmt die Werte 0, 3, 6, 9, 12, 15, … an und springt an der 10 vorbei. Deshalb ist i != 10 immer wahr, und das Programm läuft endlos. Mit while i < 10: endet es nach der Ausgabe 0, 3, 6, 9. Allgemein: Bei Schleifen mit Schrittweite ist < bzw. > sicherer als !=.

A6
Wo liegt der Fehler wirklich?
AFB III

Nach der Eingabe 15 erscheint die Meldung unten. Erkläre die Fehlermeldung und begründe, warum der eigentliche Fehler nicht in Zeile 2, sondern in Zeile 1 steckt.

alter = input("Wie alt bist du? ")if alter >= 16:    print("Du darfst allein ins Kino.")
Traceback (most recent call last):
  File "programm.py", line 2, in <module>
    if alter >= 16:
TypeError: '>=' not supported between instances of 'str' and 'int'

Hinweis: Lies die letzte Zeile der Meldung zuerst.

Strategie: Zerlege die letzte Zeile: Fehlerart, Operator, beteiligte Datentypen.Warum so? Python meldet die Zeile, in der es nicht weitergeht — nicht die Zeile, in der der Denkfehler passiert ist.
Lösungsskizze: TypeError: str und int lassen sich nicht mit >= vergleichen · alter ist str, weil input Text liefert · Korrektur: int(input(…)) in Zeile 1.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Die letzte Zeile nennt die Fehlerart TypeError: Der Vergleich >= ist zwischen einem str und einem int nicht möglich. Darüber steht „line 2“ — dort bricht Python ab. Der str ist die Variable alter: input() liefert immer Text, also ist alter = "15". Zeile 2 ist korrekt geschrieben; falsch ist, dass in Zeile 1 die Umwandlung in eine Zahl fehlt. Korrektur: alter = int(input("Wie alt bist du? ")). Merke: Die gemeldete Zeile zeigt, wo es knallt, die Ursache kann weiter oben liegen.

A7
Immer neue Runde
AFB III

Egal, was man eintippt — auch bei „nein“ erscheint „Neue Runde!“. Python meldet keinen Fehler. Erkläre dieses Verhalten und gib zwei korrekte Schreibweisen an.

antwort = input("Weiterspielen? ")if antwort == "ja" or "Ja":    print("Neue Runde!")else:    print("Tschüss!")

Hinweis: Python liest die Bedingung nicht so, wie wir sie sprechen.

Strategie: Klammere die Bedingung so, wie Python sie auswertet: (antwort == "ja") or ("Ja").Warum so? Ein logischer Fehler ist ein Programm, das läuft, aber das Falsche tut.
Lösungsskizze: or verbindet zwei vollständige Bedingungen · "Ja" allein gilt als wahr · Lösung: antwort == "ja" or antwort == "Ja" bzw. antwort.lower() == "ja".
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Python wertet (antwort == "ja") or "Ja" aus. Rechts von or steht keine Bedingung, sondern nur der Text "Ja" — und ein nicht leerer Text zählt in einer Bedingung als wahr. Damit ist die ganze or-Verknüpfung immer wahr, der else-Zweig läuft nie. Weil das Programm trotzdem ohne Meldung läuft, ist das ein logischer Fehler. Richtig: if antwort == "ja" or antwort == "Ja": — beide Seiten sind vollständige Vergleiche. Noch kürzer: if antwort.lower() == "ja":, das fängt auch „JA“ ab.

A8
Aus Hund wird Mund
AFB III

Das Programm soll „Mund“ ausgeben, bricht aber mit TypeError: 'str' object does not support item assignment ab. Erkläre den Fehler, entwickle zwei verschiedene korrekte Lösungen und vergleiche sie.

tier = "Hund"tier[0] = "M"print(tier)

Hinweis: Bei einer Liste würde liste[0] = "M" funktionieren.

Strategie: Einen String kann man nicht ändern — aber man kann einen neuen bauen und der Variablen zuweisen.Warum so? Aus dem Unterschied zwischen Liste und String folgt die Lösung.
Lösungsskizze: Strings sind unveränderbar · Lösung 1: "M" + tier[1:] · Lösung 2: tier.replace("H", "M") · replace ersetzt jedes H.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Zeichenketten sind in Python unveränderbar: Man kann ein einzelnes Zeichen lesen (tier[0]), aber nicht überschreiben. Deshalb der TypeError. Man muss einen neuen String bilden und in der Variablen speichern. Lösung 1 setzt ihn aus „M“ und dem Rest ab Index 1 zusammen: tier = "M" + tier[1:]. Lösung 2 nutzt tier = tier.replace("H", "M"). Beide liefern „Mund“. Unterschied: Lösung 1 ersetzt genau das erste Zeichen, egal welches es ist; replace ersetzt jedes „H“ im Wort — bei „HaHa“ würden beide ersetzt.

tier = "Hund"tier = "M" + tier[1:]print(tier)
A9
Die Funktion hört zu früh auf
AFB III

Die Funktion soll True liefern, wenn in der Liste mindestens eine negative Zahl steht. Für [-1, 2] klappt es. Überprüfe die Funktion mit [3, -5], erkläre das Ergebnis und korrigiere sie.

def hat_negative(zahlen):    for z in zahlen:        if z < 0:            return True        else:            return False

Hinweis: Überlege, wie oft die Schleife höchstens läuft.

Strategie: Verfolge den Aufruf mit [3, −5] Zeile für Zeile.Warum so? return beendet die Funktion sofort — auch mitten in einer Schleife.
Lösungsskizze: z = 3 → else → return False → Schleife endet nach 1 Durchlauf · False erst nach der Schleife zurückgeben.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Beim Aufruf mit [3, −5] ist z zuerst 3. 3 < 0 ist falsch, also läuft der else-Zweig mit return False — und return beendet die Funktion sofort. Die −5 wird nie angeschaut, das Ergebnis False ist falsch. Die Funktion prüft also in Wahrheit nur das erste Element. Richtig ist: Sobald eine negative Zahl gefunden ist, sofort True zurückgeben; False erst dann, wenn die Schleife ganz durchgelaufen ist, also nach der Schleife:

def hat_negative(zahlen):    for z in zahlen:        if z < 0:            return True    return False
A10
Das Quiz erweitern
AFB III

Im Quiz-Projekt soll jede Frage einen zweiten Versuch bekommen. Entwickle eine Funktion frage(text, loesung), die höchstens zweimal fragt und True oder False zurückgibt, und begründe, warum die Funktion return statt print verwenden sollte.

Hinweis: Die Funktion soll selbst nichts zählen — das macht das Hauptprogramm.

Strategie: Nutze eine for-Schleife mit range(2) und beende die Funktion mit return True, sobald die Antwort stimmt.Warum so? Eine Funktion mit Rückgabewert lässt sich in einer if-Bedingung verwenden.
Lösungsskizze: for versuch in range(2): input · Vergleich mit strip/lower · richtig → return True · nach der Schleife return False · Hauptprogramm: if frage(…): punkte = punkte + 1.
Musterlösung anzeigen (zählt als erledigt)

Musterlösung: Die Funktion fragt in einer Schleife höchstens zweimal. Ist die Antwort richtig, beendet return True die Funktion sofort — ein zweiter Versuch ist dann nicht mehr nötig. Erst wenn beide Versuche falsch waren, erreicht Python die Zeile nach der Schleife und gibt False zurück. Weil frage() einen Wahrheitswert zurückgibt, kann das Hauptprogramm damit weiterarbeiten: if frage(…): erhöht die Punkte. Mit print würde das Ergebnis nur angezeigt; das Hauptprogramm bekäme None und könnte nicht zählen. Außerdem bleibt die Funktion so für jede Frage wiederverwendbar.

def frage(text, loesung):    for versuch in range(2):        antwort = input(text + " ")        if antwort.strip().lower() == loesung:            return True        print("Leider falsch.")    return Falsepunkte = 0if frage("Wie viele Bits hat ein Byte?", "8"):    punkte = punkte + 1if frage("Welche Farbe entsteht aus Blau und Gelb?", "grün"):    punkte = punkte + 1print("Punkte:", punkte)