Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
modul:m323:learningunits:lu01:loesungen:spaghetticode [2026/08/18 10:10] – Neue Loesung LU01.L11 - Spaghetticode entwirren adminmodul:m323:learningunits:lu01:loesungen:spaghetticode [2026/08/18 11:11] (aktuell) – Musterloesung via gh-Import aus dem solution-Branch admin
Zeile 6: Zeile 6:
 | ''i = 0'', ''fertig = False'', ''total = 0'' | Sequenz | Drei Zustandsvariablen, die von Hand gepflegt werden müssen. | | ''i = 0'', ''fertig = False'', ''total = 0'' | Sequenz | Drei Zustandsvariablen, die von Hand gepflegt werden müssen. |
 | ''while not fertig'' | Iteration | Endlosschleife mit Abbruchflagge statt echter Laufbedingung. | | ''while not fertig'' | Iteration | Endlosschleife mit Abbruchflagge statt echter Laufbedingung. |
-| ''if i >= len(...)'' | Selektion | Wird nur gebraucht, weil die Schleife nicht über die Elemente läuft. | +| ''%%if i >= len(bestellungen)%%'' | Selektion | Wird nur gebraucht, weil die Schleife nicht über die Elemente läuft. | 
-| ''if b["status"] == ...'' ''if b["menge"] <= 0'' | Selektion | Sachlich sinnvoll, aber unnötig verschachtelt. |+| ''%%if b["status"] == "storniert"%%'' und ''%%if b["menge"] <= 0%%'' | Selektion | Sachlich sinnvoll, aber unnötig verschachtelt. |
 | ''continue'' | **keine der drei** | Imitiert einen Sprung an den Schleifenanfang – genau das, was die strukturierte Programmierung vermeiden will. | | ''continue'' | **keine der drei** | Imitiert einen Sprung an den Schleifenanfang – genau das, was die strukturierte Programmierung vermeiden will. |
 | ''i = i + 1'' an drei Stellen | Sequenz | Klassische Fehlerquelle: Eine vergessene Stelle erzeugt eine Endlosschleife. | | ''i = i + 1'' an drei Stellen | Sequenz | Klassische Fehlerquelle: Eine vergessene Stelle erzeugt eine Endlosschleife. |
Zeile 14: Zeile 14:
 ===== 2. Musterlösung ===== ===== 2. Musterlösung =====
  
-<code python> +~~NOCACHE~~ 
-bestellungen +=== main.py === 
-    {"artikel": "Maus",     "status": "offen",     "menge": 3,  "preis": 24.90}, +{{gh>https://github.com/templates-python/m323-lu01-a11-umsatz-refactoring/blob/solution/main.py}}
-    {"artikel": "Tastatur", "status": "storniert", "menge": 2,  "preis": 79.50}, +
-    {"artikel""Monitor",  "status": "offen",     "menge": 0,  "preis": 249.00}, +
-    {"artikel": "Kabel",    "status": "geliefert", "menge": 10, "preis": 9.90}+
-    {"artikel": "Dock",     "status": "offen",     "menge": 1,  "preis": 189.00}+
-]+
  
 +Übrig bleiben genau die drei Grundstrukturen: Sequenz (Initialisierung und Rückgabe), Iteration (''for''), Selektion (''if'').
  
-def umsatz_alt(bestellungen): +===== 3. Was durch den Umbau verschwunden ist =====
-    """Ausgangsfassung - bleibt zum Vergleich stehen.""" +
-    i +
-    fertig False +
-    total +
-    while not fertig: +
-        if i >len(bestellungen): +
-            fertig True +
-        else: +
-            b = bestellungen[i] +
-            if b["status"] == "storniert": +
-                i i + 1 +
-                continue +
-            else: +
-                if b["menge"] <0: +
-                    i i + 1 +
-                    continue +
-                else: +
-                    total total + b["menge"] * b["preis"+
-                    i i + 1 +
-    return total+
  
 +  * **Der Index ''i''.** Damit auch jede Möglichkeit, ihn falsch zu initialisieren, an einer Stelle nicht hochzuzählen (Endlosschleife!) oder um eins danebenzuliegen.
 +  * **Die Flagge ''fertig''.** Die ''for''-Schleife kennt ihr Ende selbst.
 +  * **Die Sprünge.** Ohne ''continue'' liest sich der Ablauf von oben nach unten.
 +  * **Zwei Verschachtelungsebenen.** Die beiden Bedingungen sind zu einer benannten Frage zusammengefasst, die man laut vorlesen kann: //Wenn die Bestellung verrechenbar ist, zähle sie dazu.//
  
-def ist_verrechenbar(bestellung): +===== 4. Wie geprüft wird =====
-    """Selektion: Zaehlt diese Bestellung zum Umsatz?""" +
-    return bestellung["status"] !"storniert" and bestellung["menge"] > 0+
  
 +Die Gleichwertigkeit prüft ''test_umsatz_wie_referenz'' gegen ''umsatz_alt'' aus ''referenz.py'' – über vier Datensätze, inklusive leerer Liste, komplett stornierter Liste und ungültiger Mengen.
  
-def umsatz(bestellungen): +Die //Struktur// lässt sich mit einem gewöhnlichen Test nicht messenBeide Fassungen liefern 362.70. Darum lesen zwei Tests die Datei ''main.py'' als Syntaxbaum ein:
-    """Sequenz - Iteration - Selektion, je genau einmal.""" +
-    total = 0 +
-    for bestellung in bestellungen: +
-        if ist_verrechenbar(bestellung): +
-            total += bestellung["menge"] * bestellung["preis"+
-    return total+
  
 +=== main_test.py ===
 +{{gh>https://github.com/templates-python/m323-lu01-a11-umsatz-refactoring/blob/solution/main_test.py}}
  
-if __name__ == '__main__'+''test_iteration_ohne_while'' verlangt eine ''for''-Schleife und verbietet ''while'', ''test_keine_spruenge'' verbietet ''continue'' und ''break''Beide prüfen zusätzlich das korrekte Ergebnis – sonst wären sie mit einer leeren Datei erfüllbar.
-    print(f"Umsatz alt: {umsatz_alt(bestellungen):.2f}"  # 362.70 +
-    print(f"Umsatz neu: {umsatz(bestellungen):.2f}"      # 362.70+
  
-    assert umsatz(bestellungen) == umsatz_alt(bestellungen) +Eine Abgabe, die richtig rechnetaber die alte Struktur behältkommt damit auf 9 von 11 Testpunkten.
-    assert umsatz([]) == umsatz_alt([]) == 0 +
-    assert umsatz([{"status": "storniert", "menge": 5, "preis": 10.0}]) == 0 +
-    assert umsatz([{"status": "offen", "menge": -2, "preis": 10.0}]) == 0 +
-    print("Beide Fassungen liefern dasselbe Ergebnis."+
-</code> +
- +
-===== 3. Was durch den Umbau verschwunden ist ===== +
- +
-  * **Der Index ''i''.** Damit auch jede Möglichkeit, ihn falsch zu initialisieren, an einer Stelle nicht hochzuzählen (Endlosschleife!) oder um eins danebenzuliegen. +
-  * **Die Flagge ''fertig''.** Die ''for''-Schleife kennt ihr Ende selbst. +
-  * **Die Sprünge.** Ohne ''continue'' liest sich der Ablauf von oben nach unten. +
-  * **Zwei Verschachtelungsebenen.** Die beiden Bedingungen sind zu einer benannten Frage zusammengefasst, die man laut vorlesen kann: //„Wenn die Bestellung verrechenbar istzähle sie dazu."// +
- +
-Übrig bleiben genau die drei Grundstrukturen: Sequenz (Initialisierung und Rückgabe)Iteration (''for''), Selektion (''if'').+
  
-===== 4. Antworten auf die Zusatzfragen =====+===== 5. Antworten auf die Zusatzfragen =====
  
 ==== Frage 1: Vergessenes Hochzählen ==== ==== Frage 1: Vergessenes Hochzählen ====
Zeile 89: Zeile 48:
 ==== Frage 2: Böhm und Jacopini ==== ==== Frage 2: Böhm und Jacopini ====
  
-Der Ausgangscode brauchte scheinbar Sprünge (''continue''), um „diesen Fall zu überspringen". Die neue Fassung zeigt: Dieselbe Wirkung entsteht durch **Selektion** – statt zu überspringen, wird nur im passenden Fall etwas getan. Das ist genau die Aussage des Theorems: Jeder berechenbare Algorithmus lässt sich allein mit Sequenz, Selektion und Iteration ausdrücken. Sprünge sind bequem, aber nie zwingend nötig.+Der Ausgangscode brauchte scheinbar Sprünge (''continue''), um einen Fall zu überspringen. Die neue Fassung zeigt: Dieselbe Wirkung entsteht durch **Selektion** – statt zu überspringen, wird nur im passenden Fall etwas getan. Das ist genau die Aussage des Theorems: Jeder berechenbare Algorithmus lässt sich allein mit Sequenz, Selektion und Iteration ausdrücken. Sprünge sind bequem, aber nie zwingend nötig.
  
 ==== Frage 3: Deklarative Formulierung ==== ==== Frage 3: Deklarative Formulierung ====
  
-//Der Umsatz ist die Summe aus Menge mal Preis über alle nicht stornierten Bestellungen mit positiver Menge."//+//Der Umsatz ist die Summe aus Menge mal Preis über alle nicht stornierten Bestellungen mit positiver Menge.//
  
 In Python direkt so ausdrückbar: In Python direkt so ausdrückbar:
Zeile 99: Zeile 58:
 <code python> <code python>
 def umsatz_deklarativ(bestellungen): def umsatz_deklarativ(bestellungen):
-    return sum(b["menge"] * b["preis"] for b in bestellungen if ist_verrechenbar(b))+    return sum(b['menge'] * b['preis'] for b in bestellungen if ist_verrechenbar(b))
 </code> </code>
  
  • modul/m323/learningunits/lu01/loesungen/spaghetticode.1787040636.txt.gz
  • Zuletzt geändert: 2026/08/18 10:10
  • von admin