====== LU07.L01 - Smell-Detektiv ====== ^ Nr. ^ Smell ^ Problem ^ Technik ^ | 1 | Kryptische Namen, Kommentar-Bedarf; zusätzlich ''if ...: return True / return False'' | ''b["a"]'' und ''b["s"]'' sagen nichts, die Bedingung muss entschlüsselt werden | Rename, Extract Variable; die Bedingung direkt zurückgeben | | 2 | Magic Numbers | Woher kommen 2, 10, 7.0, 12.5, 24.9? Eine Preisänderung erfordert Suchen im Code | Replace Magic Number with Named Constant, besser noch eine Tariftabelle als Datenstruktur | | 3 | Lange Parameterliste | Acht Parameter, beim Aufruf leicht zu vertauschen, Python meldet nichts | Introduce Parameter Object (frozen Dataclass) | | 4 | Query und Modifier vermischt | Wer nur den Bestand lesen will, verändert dabei die Zugriffszähler; zwei Aufrufe haben verschiedene Wirkung | Separate Query from Modifier | | 5 | Schleife mit Akkumulator | Beschreibt das //Wie// statt das //Was//, Zwischenvariable und ''append'' als Rauschen | Replace Loop with Pipeline | | 6 | Globaler Zustand (unpure function) | Ergebnis hängt von der Programmgeschichte ab, nicht testbar ohne Zurücksetzen von ''zaehler'' | Zustand als Parameter und Rückgabewert, alternativ Closure | ===== Hinweise ===== **Ausschnitt 1** enthält zwei Smells. Beide Antworten sind richtig, wenn sie begründet sind: def ist_kaufberechtigt(kunde): volljaehrig = kunde["alter"] >= 18 aktiv = kunde["status"] == 1 hat_guthaben = kunde["guthaben"] > 0 return volljaehrig and aktiv and hat_guthaben **Ausschnitt 2** wird oft als «verschachtelte Bedingungen» genannt - das stimmt hier nicht, die Guard Clauses sind bereits sauber. Der Smell sind die Zahlen. **Ausschnitt 5** ist der Smell mit dem stärksten Modulbezug: namen = [k["name"].upper() for k in kunden if k["aktiv"]] ---- {{tag>M323-LU07 M323-D1B}} [[https://creativecommons.org/licenses/by-nc-sa/4.0/ch/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] (c) Kevin Maurizi