diff --git a/06_abschlussprojekt_tamagotchi/index.html b/06_abschlussprojekt_tamagotchi/index.html index f2a570a..96a0eb5 100644 --- a/06_abschlussprojekt_tamagotchi/index.html +++ b/06_abschlussprojekt_tamagotchi/index.html @@ -169,7 +169,7 @@ diff --git a/07_referenzen_und_speicher/README.md b/07_referenzen_und_speicher/README.md new file mode 100644 index 0000000..bef53a2 --- /dev/null +++ b/07_referenzen_und_speicher/README.md @@ -0,0 +1,36 @@ +# Kapitel 07: Referenzen, Speicher & Stammbäume 🧠🌳 + +In diesem Kapitel lernst du ein fundamentales Konzept moderner Programmiersprachen: **Objektreferenzen und Arbeitsspeicher (RAM)**. + +--- + +## 🎯 Was du lernst + +1. **Variablen als Zeiger:** Eine Variable enthält nicht das Objekt selbst, sondern zeigt auf dessen Speicherplatz. +2. **Aliasing (`b = a`):** Zwei Variablen können auf dasselbe veränderliche Objekt zeigen. +3. **`is` vs. `==`:** + - `==` prüft, ob zwei Objekte den **gleichen Wert** haben. + - `is` prüft, ob es sich um **dasselbe Objekt** an derselben Speicherstelle (`id(a) == id(b)`) handelt. +4. **Mutable vs. Immutable:** + - *Mutable:* Listen, Dictionaries, eigene Objekte (können verändert werden). + - *Immutable:* Zahlen, Strings, Tupel (sind unveränderlich). +5. **Stammbaum-Strukturen:** Ein Objekt wird von mehreren anderen Objekten referenziert. + +--- + +## 📁 Die Dateien in diesem Ordner + +- **`index.html`**: Die interaktive Lernseite mit visuellen Boxen & Erklärungen. +- **`aufgabe.py`**: Dein Arbeitsblatt zum Implementieren der `Person`-Stammbaum-Klasse. +- **`test_aufgabe.py`**: Automatische Tests (`python3 test_aufgabe.py`). +- **`musterloesung.py`**: Vollständig ausprogrammierte Beispiellösung. + +--- + +## 🚀 Schnellstart + +```bash +# 1. Bearbeite aufgabe.py +# 2. Teste deine Lösung: +python3 test_aufgabe.py +``` diff --git a/07_referenzen_und_speicher/aufgabe.py b/07_referenzen_und_speicher/aufgabe.py new file mode 100644 index 0000000..0e05d03 --- /dev/null +++ b/07_referenzen_und_speicher/aufgabe.py @@ -0,0 +1,93 @@ +""" +Kapitel 07: Referenzen, Speicher & Stammbäume 🧠🌳 +================================================= +Aufgabe: Erstelle eine Stammbaum-Klasse 'Person'. +Jede Person kann Verweise (Referenzen) auf Mutter, Vater und Kinder enthalten. +""" + +from typing import Optional, List + + +class Person: + # ========================================================================== + # TODO 1: Konstruktor __init__ + # Parameter: name (str), geburtsjahr (int) + # Attribute: + # - self.name: str + # - self.geburtsjahr: int + # - self.mutter: Person | None (Startwert: None) + # - self.vater: Person | None (Startwert: None) + # - self.kinder: list[Person] (Startwert: leere Liste []) + # ========================================================================== + def __init__(self, name: str, geburtsjahr: int): + pass + + # ========================================================================== + # TODO 2: Methode mutter_setzen(self, mutter: 'Person') -> None + # 1. Setze self.mutter = mutter + # 2. Füge self zur Liste mutter.kinder hinzu (falls self noch nicht drin ist) + # ========================================================================== + def mutter_setzen(self, mutter: "Person") -> None: + pass + + # ========================================================================== + # TODO 3: Methode vater_setzen(self, vater: 'Person') -> None + # 1. Setze self.vater = vater + # 2. Füge self zur Liste vater.kinder hinzu (falls self noch nicht drin ist) + # ========================================================================== + def vater_setzen(self, vater: "Person") -> None: + pass + + # ========================================================================== + # TODO 4: Methode geschwister(self) -> list['Person'] + # Gibt eine Liste aller Personen zurück, die dieselbe Mutter ODER denselben + # Vater haben wie self. + # WICHTIG: + # - self darf NICHT in der eigenen Geschwisterliste sein! + # - Keine Person darf doppelt in der Rückgabeliste sein. + # ========================================================================== + def geschwister(self) -> List["Person"]: + pass + + # ========================================================================== + # TODO 5: Methode grosseltern(self) -> list['Person'] + # Gibt eine Liste aller bekannten Großeltern zurück: + # (Mutter der Mutter, Vater der Mutter, Mutter des Vaters, Vater des Vaters) + # Nur Großeltern hinzufügen, die nicht None sind! + # ========================================================================== + def grosseltern(self) -> List["Person"]: + pass + + # ========================================================================== + # TODO 6: Dunder-Methode __str__(self) -> str + # Gibt einen String im Format: "Name (*Geburtsjahr)" zurück. + # Beispiel: "Mia (*2008)" + # ========================================================================== + def __str__(self) -> str: + pass + + +# ============================================================================== +# Kleiner Test zum Ausprobieren im Terminal: +# (python3 aufgabe.py) +# ============================================================================== +if __name__ == "__main__": + oma_anna = Person("Anna", 1955) + opa_karl = Person("Karl", 1952) + mama_susi = Person("Susi", 1980) + papa_tom = Person("Tom", 1978) + kind_mia = Person("Mia", 2008) + kind_leo = Person("Leo", 2011) + + # Verknüpfungen herstellen + mama_susi.mutter_setzen(oma_anna) + mama_susi.vater_setzen(opa_karl) + kind_mia.mutter_setzen(mama_susi) + kind_mia.vater_setzen(papa_tom) + kind_leo.mutter_setzen(mama_susi) + kind_leo.vater_setzen(papa_tom) + + print("Kind:", kind_mia) + print("Mamas Kinder:", [str(k) for k in mama_susi.kinder]) + print("Mias Geschwister:", [str(g) for g in kind_mia.geschwister()]) + print("Mias Großeltern:", [str(ge) for ge in kind_mia.grosseltern()]) diff --git a/07_referenzen_und_speicher/index.html b/07_referenzen_und_speicher/index.html new file mode 100644 index 0000000..b5200c4 --- /dev/null +++ b/07_referenzen_und_speicher/index.html @@ -0,0 +1,215 @@ + + + + + + Kapitel 07: Referenzen, Speicher & Stammbäume + + + + +
+
+ +
Kapitel 07 • Fortgeschrittenes OOP
+

Referenzen, Speicher & Stammbäume 🧠🌳

+

Verstehe, wie Python Objekte im Arbeitsspeicher verwaltet, was Aliasing bedeutet und baue einen echten Familienstammbaum.

+
+
+ +
+ + +
+

1. Was ist eine Referenz? (Variablen sind Namensschilder)

+ +

+ Viele glauben, eine Variable sei eine Box, in der das Objekt direkt drinliegt. In Python ist das anders: + Eine Variable ist in Wirklichkeit ein Zeiger (eine Referenz) auf einen Bereich im Arbeitsspeicher (RAM). +

+ +
+
🏷️ Die Namensschild-Analogie:
+ Stelle dir ein Haus vor. Das Haus steht an einer festen Adresse. + Die Variable ist nur ein Adresszettel. Wenn du schreibst b = a, baust du kein zweites Haus, sondern schreibst die gleiche Adresse einfach auf einen zweiten Zettel! +
+ +

Das Phänomen: Was passiert bei b = a?

+ +
+
+ Beispiel: Listen-Referenzen (Aliasing) +
+
liste_a = [1, 2, 3]
+liste_b = liste_a     # liste_b zeigt auf GENAU DIESELBE Liste im Speicher!
+
+liste_b.append(99)
+
+print(liste_a)  # Ausgabe: [1, 2, 3, 99] <-- liste_a hat sich mitverändert!
+
+ +
+
⚠️ Vorsicht bei veränderlichen Objekten (Mutable vs. Immutable):
+
    +
  • Mutable (veränderlich): Listen, Dictionaries, eigene Klassenobjekte. Wenn du sie an einer Stelle änderst, ändern sich alle Variablen, die darauf zeigen!
  • +
  • Immutable (unveränderlich): Zahlen (int, float), Texte (str), Tupel (tuple). Beim Ändern wird automatisch ein neues Objekt im Speicher erzeugt.
  • +
+
+
+ + +
+

2. Der Unterschied zwischen == und is

+ +

In Python gibt es zwei Arten von Vergleichen:

+ + + + + + + + + + + + + + + + + + + + + +
OperatorBedeutungFrage im Hintergrund
==WertegleichheitHaben beide Objekte denselben Inhalt?
isIdentitätSind beide Variablen exakt dasselbe Objekt an derselben Speicheradresse?
+ +
+
x = [1, 2, 3]
+y = [1, 2, 3]
+z = x
+
+print(x == y)  # True  (weil der Inhalt gleich ist)
+print(x is y)  # False (zwei getrennte Listen im Speicher)
+print(x is z)  # True  (z zeigt direkt auf dieselbe Liste wie x)
+
+
+ + +
+

3. Praxisbeispiel: Der Familienstammbaum 🌳

+ +

+ Warum sind Referenzen so genial? Weil ein und dasselbe Objekt in vielen Beziehungen vorkommen kann. + Eine Person namens Susi ist gleichzeitig die Mutter von Erika, das Kind von Fritz und die Schwester von Tom. +

+ +
+
+ Stammbaum mit Klassen-Referenzen +
+
class Person:
+    def __init__(self, name: str, geburtsjahr: int):
+        self.name: str = name
+        self.geburtsjahr: int = geburtsjahr
+        self.mutter: Person | None = None   # Referenz auf Mutter-Objekt
+        self.vater: Person | None = None    # Referenz auf Vater-Objekt
+        self.kinder: list[Person] = []      # Liste von Referenzen auf Kinder
+
+    def mutter_setzen(self, mutter: 'Person') -> None:
+        self.mutter = mutter
+        if self not in mutter.kinder:
+            mutter.kinder.append(self)
+
+    def __str__(self) -> str:
+        return f"{self.name} (*{self.geburtsjahr})"
+
+
+ + +
+

4. 🎯 Deine Aufgaben in aufgabe.py

+ +

Öffne die Datei 07_referenzen_und_speicher/aufgabe.py und vervollständige die Stammbaum-Klasse:

+ + + +

💡 Lösungshinweise (Aufklappen bei Bedarf)

+ +
+ 🔍 Tipp zu TODO 4 (Geschwister finden) +
+

Gehe alle Kinder der Mutter und alle Kinder des Vaters durch. Achte darauf, dass du kind is not self prüfst, damit man nicht selbst als Geschwisterteil gelistet wird, und füge niemanden doppelt hinzu!

+
+
+ +
+ 🔍 Tipp zu TODO 5 (Großeltern finden) +
+
+
ge = []
+if self.mutter:
+    if self.mutter.mutter: ge.append(self.mutter.mutter)
+    if self.mutter.vater: ge.append(self.mutter.vater)
+if self.vater:
+    if self.vater.mutter: ge.append(self.vater.mutter)
+    if self.vater.vater: ge.append(self.vater.vater)
+return ge
+
+
+
+
+ + +
+

5. 🧪 Lösung überprüfen

+

Führe im Terminal im Ordner 07_referenzen_und_speicher folgenden Befehl aus:

+
+
+ Terminal +
+
python3 test_aufgabe.py
+
+ + +
+ +
+ + + diff --git a/07_referenzen_und_speicher/musterloesung.py b/07_referenzen_und_speicher/musterloesung.py new file mode 100644 index 0000000..3456073 --- /dev/null +++ b/07_referenzen_und_speicher/musterloesung.py @@ -0,0 +1,85 @@ +""" +Kapitel 07: Referenzen, Speicher & Stammbäume – Musterlösung +============================================================ +""" + +from typing import Optional, List + + +class Person: + def __init__(self, name: str, geburtsjahr: int): + self.name: str = name + self.geburtsjahr: int = geburtsjahr + self.mutter: Optional["Person"] = None + self.vater: Optional["Person"] = None + self.kinder: List["Person"] = [] + + def mutter_setzen(self, mutter: "Person") -> None: + self.mutter = mutter + if self not in mutter.kinder: + mutter.kinder.append(self) + + def vater_setzen(self, vater: "Person") -> None: + self.vater = vater + if self not in vater.kinder: + vater.kinder.append(self) + + def geschwister(self) -> List["Person"]: + ergebnis = [] + + # Kinder der Mutter durchgehen + if self.mutter: + for kind in self.mutter.kinder: + if kind is not self and kind not in ergebnis: + ergebnis.append(kind) + + # Kinder des Vaters durchgehen + if self.vater: + for kind in self.vater.kinder: + if kind is not self and kind not in ergebnis: + ergebnis.append(kind) + + return ergebnis + + def grosseltern(self) -> List["Person"]: + ergebnis = [] + + # Großeltern mütterlicherseits + if self.mutter: + if self.mutter.mutter and self.mutter.mutter not in ergebnis: + ergebnis.append(self.mutter.mutter) + if self.mutter.vater and self.mutter.vater not in ergebnis: + ergebnis.append(self.mutter.vater) + + # Großeltern väterlicherseits + if self.vater: + if self.vater.mutter and self.vater.mutter not in ergebnis: + ergebnis.append(self.vater.mutter) + if self.vater.vater and self.vater.vater not in ergebnis: + ergebnis.append(self.vater.vater) + + return ergebnis + + def __str__(self) -> str: + return f"{self.name} (*{self.geburtsjahr})" + + +if __name__ == "__main__": + oma_anna = Person("Anna", 1955) + opa_karl = Person("Karl", 1952) + mama_susi = Person("Susi", 1980) + papa_tom = Person("Tom", 1978) + kind_mia = Person("Mia", 2008) + kind_leo = Person("Leo", 2011) + + mama_susi.mutter_setzen(oma_anna) + mama_susi.vater_setzen(opa_karl) + kind_mia.mutter_setzen(mama_susi) + kind_mia.vater_setzen(papa_tom) + kind_leo.mutter_setzen(mama_susi) + kind_leo.vater_setzen(papa_tom) + + print("Kind:", kind_mia) + print("Mamas Kinder:", [str(k) for k in mama_susi.kinder]) + print("Mias Geschwister:", [str(g) for g in kind_mia.geschwister()]) + print("Mias Großeltern:", [str(ge) for ge in kind_mia.grosseltern()]) diff --git a/07_referenzen_und_speicher/test_aufgabe.py b/07_referenzen_und_speicher/test_aufgabe.py new file mode 100644 index 0000000..dfd0924 --- /dev/null +++ b/07_referenzen_und_speicher/test_aufgabe.py @@ -0,0 +1,98 @@ +import unittest +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent)) + +try: + import aufgabe +except ImportError as e: + raise ImportError(f"Konnte 'aufgabe.py' nicht importieren: {e}") + + +class TestKapitel07(unittest.TestCase): + + def setUp(self): + Person = getattr(aufgabe, "Person", None) + self.assertIsNotNone(Person, "Klasse 'Person' nicht gefunden!") + self.Person = Person + + def test_01_init(self): + """Prüft Initialisierung und Default-Werte für Referenzen.""" + p = self.Person("Mia", 2008) + self.assertEqual(p.name, "Mia") + self.assertEqual(p.geburtsjahr, 2008) + self.assertIsNone(p.mutter) + self.assertIsNone(p.vater) + self.assertEqual(p.kinder, []) + + def test_02_mutter_vater_setzen(self): + """Prüft gegenseitige Referenzverknüpfung.""" + kind = self.Person("Mia", 2008) + mama = self.Person("Susi", 1980) + papa = self.Person("Tom", 1978) + + kind.mutter_setzen(mama) + kind.vater_setzen(papa) + + # Referenzprüfung + self.assertIs(kind.mutter, mama) + self.assertIs(kind.vater, papa) + self.assertIn(kind, mama.kinder) + self.assertIn(kind, papa.kinder) + + # Kein doppeltes Hinzufügen + kind.mutter_setzen(mama) + self.assertEqual(len(mama.kinder), 1) + + def test_03_geschwister(self): + """Prüft Finden aller Geschwister (ohne self und ohne Duplikate).""" + mama = self.Person("Susi", 1980) + papa = self.Person("Tom", 1978) + kind1 = self.Person("Mia", 2008) + kind2 = self.Person("Leo", 2011) + halbbruder = self.Person("Max", 2005) + + kind1.mutter_setzen(mama) + kind1.vater_setzen(papa) + kind2.mutter_setzen(mama) + kind2.vater_setzen(papa) + halbbruder.vater_setzen(papa) # Nur gleicher Vater + + geschwister_mia = kind1.geschwister() + self.assertNotIn(kind1, geschwister_mia, "self darf nicht in den eigenen Geschwistern sein!") + self.assertIn(kind2, geschwister_mia) + self.assertIn(halbbruder, geschwister_mia) + self.assertEqual(len(geschwister_mia), 2) + + def test_04_grosseltern(self): + """Prüft Ermittlung der Großeltern über Referenzketten.""" + oma1 = self.Person("Anna", 1955) + opa1 = self.Person("Karl", 1952) + oma2 = self.Person("Monika", 1956) + + mama = self.Person("Susi", 1980) + mama.mutter_setzen(oma1) + mama.vater_setzen(opa1) + + papa = self.Person("Tom", 1978) + papa.mutter_setzen(oma2) + + kind = self.Person("Mia", 2008) + kind.mutter_setzen(mama) + kind.vater_setzen(papa) + + grosseltern = kind.grosseltern() + self.assertIn(oma1, grosseltern) + self.assertIn(opa1, grosseltern) + self.assertIn(oma2, grosseltern) + self.assertEqual(len(grosseltern), 3) + + def test_05_str(self): + """Prüft __str__ Formatierung.""" + p = self.Person("Mia", 2008) + self.assertEqual(str(p), "Mia (*2008)") + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/LEHRPLAN.md b/LEHRPLAN.md new file mode 100644 index 0000000..4d9cfb4 --- /dev/null +++ b/LEHRPLAN.md @@ -0,0 +1,67 @@ +# 📚 Didaktischer Lehrplan & Abgleich mit dem Schulskriptum + +Dieses Dokument dient als didaktischer Leitfaden für die Python-Nachhilfe. +Es gleicht die Übungsreihe mit dem offiziellen Lehrplan und Skriptum des Lehrers (**`rradlbauer/python_skriptum`**) ab. + +--- + +## 🎯 Didaktische Leitlinien für die Nachhilfe + +1. **Type Hints als Standard:** Da der Lehrer in Teil 2 strikt Typ-Annotationen verwendet (`name: str`, `def alter(self) -> int:`), führen wir diese ab den Klassen sauber ein. +2. **UML-Klassendiagramme:** Das Skriptum fordert UML-Diagramme (`22.1_UML.md`). Jedes Kapitel enthält visuelle UML-Karten. +3. **Praxisnahe Analogien:** Statt trockener Theorie nutzen wir greifbare Alltagsbeispiele (Fahrrad-Verleih, Spotify-Playlists, Stammbäume, Geldautomaten). +4. **Automatische Tests & Sofort-Feedback:** Jedes Kapitel hat ein Testskript (`test_aufgabe.py`), das bei `python3 test_aufgabe.py` oder `python3 test_all.py` sofort anzeigt, was schon klappt. +5. **Autonomes Lernen:** Die Schülerin kann alle Kapitel über die modernen, interaktiven HTML-Seiten im Browser selbstständig durcharbeiten. + +--- + +## 🗺️ Der Gesamtlehrplan im Überblick + +``` +PHASE 1: GRUNDLAGEN DER OBJEKTORIENTIERUNG (OOP) & TOOLING + ├── Kapitel 00: Fehlersuche & Python-Debugging (Warm-up) + ├── Kapitel 01: Erste Klasse & Baupläne (Lehrer 22.0) + ├── Kapitel 02: Konstruktor __init__, self & UML (Lehrer 22.0 / 22.1) + ├── Kapitel 03: Methoden & Objekt-Interaktion (Lehrer 22.0) + ├── Kapitel 04: Schöne Textausgabe mit __str__ (Lehrer 28.0) + ├── Kapitel 04b: Umstieg & Installation von VS Code (Lehrer 20.1 / 20.2) + ├── Kapitel 05: Assoziation & Aggregation: Spotify Playlists (Lehrer 23.0) + └── Kapitel 06: Mini-Abschlussprojekt: Tamagotchi Terminal-Game + +PHASE 2: FORTGESCHRITTENES OOP, SPEICHER & DATEN-PERSISTENZ + ├── Kapitel 07: Referenzen, Speicher & Stammbäume (Lehrer 24.0) 🧠 + ├── Kapitel 08: Operator Overloading & Dunder-Methoden (Lehrer 28.0) ➕ + ├── Kapitel 09: Vererbung (Inheritance) & super() (Lehrer 25.0) 🧬 + ├── Kapitel 10: Polymorphie & Duck Typing (Lehrer 25.1) 🎭 + ├── Kapitel 11: Exceptions & Robuste Fehlerbehandlung (Lehrer 26.0) 🛡️ + └── Kapitel 12: Speichern & Laden: JSON & CSV Persistenz (Lehrer 14.0) 💾 + +PHASE 3: GRAFISCHE OBERFLÄCHEN & PROFESSIONS-MODULE + ├── Kapitel 13: Grafische Oberflächen mit Tkinter / CustomTkinter (Lehrer 27.0) 🖥️ + ├── Kapitel 14: Erweiterte Parameter (*args, **kwargs) & Container (Lehrer 29.0 / 30.0) 📦 + └── Kapitel 15: Master-Abschlussprojekt: Grafische Desktop-App mit Savegame 🏆 +``` + +--- + +## 📑 Detaillierte Kapitel-Übersicht & Abgleich + +| Kapitel | Titel / Thema | Lehrerskript-Referenz | Kerninhalte & Praxisaufgabe | +| :--- | :--- | :--- | :--- | +| **00** | **Fehlersuche & Debugging** | *04.1 & 07.1* | Tracebacks von unten lesen, `IndentationError`, `SyntaxError`, `TypeError`, Detektiv-Aufgabe | +| **01** | **Einstieg in Klassen** | *22.0 & 21.0* | Bauplan vs. Objekt, Instanziierung, Punktnotation, erste Type Hints (`Fahrrad`) | +| **02** | **Konstruktor & self** | *22.0 & 22.1* | `__init__`, `self`, Startwerte, erstes UML-Klassendiagramm (`Bankkonto` & `Smartphone`) | +| **03** | **Methoden & Verhalten** | *22.0* | Methoden definieren, Rückgabewerte, Interaktion zweier Objekte (`Rennauto` & RPG-Duell) | +| **04** | **`__str__` & Darstellung** | *28.0* | Dunder-Methode `__str__`, lesbare Ausgabe von Objekten, Kassenzettel (`Warenkorb`) | +| **04b** | **VS Code Umstieg** | *20.1 & 20.2* | Installation (Windows/Mac/Linux), Plugins (Error Lens, Python), Shortcuts, Projektordner | +| **05** | **Objekte kombinieren** | *23.0* | Assoziation & Aggregation (1:1 und 1:n), Listen von Objekten filtern (`Spotify Playlist`) | +| **06** | **Abschlussprojekt OOP 1** | *Konsolidierung* | Tamagotchi-Konsolenspiel (Lebenszyklus, Hunger, Müdigkeit, Zufallsevents) | +| **07** | **Referenzen & Speicher** | *24.0 Referenzen* | RAM-Visualisierung, Mutable vs. Immutable, `is` vs. `==`, Aliasing, `Stammbaum`-Projekt | +| **08** | **Operator Overloading** | *28.0 Spezielle Methoden*| `__add__`, `__sub__`, `__eq__`, `__lt__`, `__len__` (2D-Vektoren & Kartenspiel) | +| **09** | **Vererbung & `super()`** | *25.0 Vererbung* | Basisklassen, Kindklassen, Vermeidung von Code-Duplikaten, `super().__init__()` (`Fahrzeuge`) | +| **10** | **Polymorphie & Interfaces**| *25.1 Polymorphie* | Methoden überschreiben, gemeinsames Interface, Geometrie- & Grafik-Engine (`Formen`) | +| **11** | **Exceptions & Fehler** | *26.0 Exceptions* | `try/except/else/finally`, `raise`, eigene Exception-Klassen (`Geldautomat`) | +| **12** | **JSON & CSV Speichern** | *14.0 CSV / Persistenz* | `with open()`, `json.dump`/`json.load`, Spielstände dauerhaft sichern (`Savegame`) | +| **13** | **Tkinter Desktop-GUI** | *27.0 Tkinter* | Fenster, Buttons, Labels, Eingabefelder, Event-Handling in OOP-Klassen | +| **14** | **Parameter & Container** | *29.0 & 30.0 Parameter*| `*args`, `**kwargs`, Dunder `__getitem__`, `__iter__` für eigene Listen-Container | +| **15** | **Master-Abschlussprojekt**| *Meisterstück* | Vollständige Desktop-App mit grafischer Oberfläche, Speichern & Laden | diff --git a/README.md b/README.md index d3b47b8..b4bec31 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,35 @@ Willkommen zu deiner Übungsreihe für **Objektorientierte Programmierung (OOP)** in Python! 🎉 -Hier lernst du Schritt für Schritt, wie man mit Klassen arbeitet, warum sie die Programmierung übersichtlicher machen und wie du deine eigenen, mächtigen Objekte baust. +Diese Übungsreihe ist didaktisch aufbereitet und **1:1 mit dem offiziellen Lehrplan des Informatik-Unterrichts** ([`LEHRPLAN.md`](./LEHRPLAN.md)) abgeglichen. --- ## 🗺️ Der Lernpfad -Die Übungen sind so aufgebaut, dass jedes Kapitel auf dem vorherigen aufbaut: - +### 🌱 Phase 1: Grundlagen OOP & Entwicklungsumgebung | Kapitel | Thema | Was du lernst | | :--- | :--- | :--- | | **[00. Fehlersuche & Grundlagen](./00_fehlersuche_und_grundlagen/)** | Warm-up & Debugging | Tracebacks lesen, Einrückungen (`IndentationError`), Typfehler & Detektiv-Aufgabe | -| **[01. Einstieg in Klassen](./01_einstieg_klassen/)** | Warum Klassen? | Bauplan vs. Objekt, Instanziierung & Attribute | -| **[02. Konstruktor & self](./02_init_und_self/)** | `__init__` & `self` | Objekte sauber mit Startwerten initialisieren | -| **[03. Methoden & Verhalten](./03_methoden_und_verhalten/)** | Methoden & Interaktion | Objekte können handeln & miteinander interagieren | -| **[04. Schöne Textausgabe](./04_str_und_darstellung/)** | `__str__` Dunder-Methode | Wie Objekte lesbar mit `print()` ausgegeben werden | -| **[04b. Umstieg auf VS Code](./04b_umstieg_vscode/)** | **Exkurs: IDE-Wechsel** | **Von Thonny zu VS Code: Plugins (Error Lens, Python), Shortcuts & Terminal** | -| **[05. Objekte kombinieren](./05_objekte_kombinieren/)** | Komposition | Listen von Objekten & komplexe Datenstrukturen | -| **[06. Abschlussprojekt](./06_abschlussprojekt_tamagotchi/)** | Mini-Projekt: Tamagotchi | Ein interaktives Konsolenspiel mit allem Gelernten | +| **[01. Einstieg in Klassen](./01_einstieg_klassen/)** | Warum Klassen? | Bauplan vs. Objekt, Instanziierung, Punktnotation & Type Hints | +| **[02. Konstruktor & self](./02_init_und_self/)** | `__init__`, `self` & UML | Objekte sauber initialisieren und erste UML-Klassendiagramme | +| **[03. Methoden & Verhalten](./03_methoden_und_verhalten/)** | Methoden & Interaktion | Objekte können handeln & miteinander im Duell interagieren | +| **[04. Schöne Textausgabe](./04_str_und_darstellung/)** | `__str__` Dunder-Methode | Wie Objekte lesbar mit `print()` ausgegeben werden (Warenkorb & Bon) | +| **[04b. Umstieg & Installation VS Code](./04b_umstieg_vscode/)** | **Exkurs: IDE-Wechsel** | **Installation (Win/Mac/Linux), Plugins (Error Lens, Python), Shortcuts & Terminal** | +| **[05. Objekte kombinieren](./05_objekte_kombinieren/)** | Assoziation & Komposition | Listen von Objekten & Spotify-Playlists filtern und berechnen | +| **[06. Abschlussprojekt OOP 1](./06_abschlussprojekt_tamagotchi/)** | Mini-Projekt: Tamagotchi | Ein interaktives Konsolenspiel mit allem Gelernten | + +### 🧠 Phase 2: Fortgeschrittenes OOP, Speicher & Persistenz +| Kapitel | Thema | Was du lernst | +| :--- | :--- | :--- | +| **[07. Referenzen, Speicher & Stammbäume](./07_referenzen_und_speicher/)** | **Speicher & RAM** | **Referenzen, Aliasing (`b = a`), Mutable vs. Immutable, `is` vs. `==` & Familienstammbaum** | +| *08. Operator Overloading* | *Dunder-Methoden* | *`__add__`, `__eq__`, `__lt__` (2D-Vektoren & Kartenspiele)* | +| *09. Vererbung & `super()`* | *Inheritance* | *Basisklassen, Kindklassen & `super().__init__()` (Fahrzeuge & RPG-Helden)* | +| *10. Polymorphie & Interfaces* | *Polymorphism* | *Methoden überschreiben, Geometrie- & Grafik-Engine* | +| *11. Exceptions & Fehler* | *Robustes Coding* | *`try/except/else/finally`, `raise`, eigene Exception-Klassen* | +| *12. JSON & CSV Speichern* | *Persistenz* | *Spielstände dauerhaft mit JSON/CSV auf der Festplatte sichern* | + +*(Den vollständigen didaktischen Masterplan für alle Kapitel bis 15 findest du in [`LEHRPLAN.md`](./LEHRPLAN.md).)* --- @@ -36,7 +47,7 @@ In jedem Kapitelordner findest du: ## 🚀 Wie du vorgehst -1. Öffne den Ordner des aktuellen Kapitels (z.B. `00_fehlersuche_und_grundlagen`). +1. Öffne den Ordner des aktuellen Kapitels (z.B. `07_referenzen_und_speicher`). 2. Öffne die `index.html` im Browser oder lies die `README.md`. 3. Öffne `aufgabe.py` und bearbeite die Aufgaben. 4. Führe die Tests aus, um deine Lösung zu prüfen: diff --git a/index.html b/index.html index 51d0ef9..4dbea7c 100644 --- a/index.html +++ b/index.html @@ -22,30 +22,31 @@

👋 Willkommen zu deiner Übungsreihe!

- Bisher hast du in Python schon viel gelernt: Variablen, Schleifen, Bedingungen, Listen, Dictionaries und Funktionen. - Jetzt machen wir den nächsten großen Schritt in der Softwareentwicklung: Klassen & Objekte! -

-

- Damit du beim Programmieren nie an kleinen Syntaxfehlern verzweifelst, starten wir mit einem kurzen Warm-up zur Fehlersuche (Kapitel 00), und steigen nach Kapitel 04 auf die Profi-Entwicklungsumgebung VS Code (Kapitel 04b) um. + Dieser Kurs begleitet dich durch die gesamte Objektorientierte Programmierung in Python – exakt abgestimmt auf dein Schulskriptum, aber mit viel mehr Erklärungen, Analogien, Visualisierungen und automatischen Tests!

🏗️ Die Grundidee von OOP in einem Satz:
Eine Klasse ist wie ein Bauplan (oder eine Plätzchen-Ausstechform). Ein Objekt ist das fertige Haus (oder das gebackene Plätzchen), das nach diesem Bauplan entstanden ist!
+ +
+
📚 Schulabgleich & Lehrplan:
+ Alle Kapitel sind 1:1 mit den Themen deines Informatik-Unterrichts (Type Hints, UML, Assoziationen, Referenzen, Vererbung, Tkinter) abgestimmt. +
- +
-

🗺️ Dein Lernpfad (Kapitel 00 bis 06)

+

🌱 Phase 1: Grundlagen OOP & Entwicklungsumgebung

- Vorkapitel 00 + Warm-up 00
🔍 Fehlersuche & Bugs
-
Tracebacks richtig lesen, Einrückungsfehler (IndentationError), Typfehler und eine interaktive Detektiv-Aufgabe.
+
Tracebacks richtig lesen, Einrückungsfehler (IndentationError), Typfehler und Detektiv-Aufgabe.
@@ -55,7 +56,7 @@
Kapitel 01
🐶 Die erste Klasse
-
Was ist eine Klasse? Bauplan vs. Objekt, Instanziierung und erste Attribute am Haustier- & Fahrrad-Beispiel.
+
Bauplan vs. Objekt, Instanziierung, Punktnotation und Type Hints am Fahrrad- & Haustier-Beispiel.
@@ -65,7 +66,7 @@
Kapitel 02
💳 Konstruktor & self
-
Wie __init__ Objekte startklar macht und was self bedeutet (Smartphone- & Bankkonto-App).
+
Wie __init__ Objekte startklar macht, was self bedeutet und erste UML-Klassendiagramme.
@@ -85,27 +86,27 @@
Kapitel 04
🧾 Schöne Textausgabe
-
Wie man print(objekt) mit __str__ lesbar macht und Objekte im Warenkorb & bei Pizza-Bestellungen sammelt.
+
Wie man print(objekt) mit __str__ lesbar macht und Rechnungsdruck im Warenkorb.
- +
Exkurs 04b -
🚀 Umstieg auf VS Code
-
Von Thonny zu VS Code: Die besten Plugins (Error Lens, Python), Shortcuts, Projektordner & integriertes Terminal.
+
🚀 Umstieg & Installation VS Code
+
Installationsanleitung (Win/Mac/Linux), Plugins (Error Lens, Python), Shortcuts & Terminal.
- +
Kapitel 05 -
🎵 Komposition & Playlists
-
Objekte verwalten andere Objekte: Song-Suche, Längenberechnung und Filter in Spotify-Playlists & Schulklassen.
+
🎵 Assoziation & Komposition
+
Objekte verwalten andere Objekte: Song-Suche, Längenberechnung und Filter in Spotify-Playlists.
@@ -114,7 +115,7 @@
Kapitel 06 -
🥚 Tamagotchi Mini-Projekt
+
🥚 Mini-Projekt: Tamagotchi
Kombiniere alles in einem voll spielbaren, interaktiven virtuellen Haustier für dein Terminal!
@@ -123,8 +124,56 @@
+ +
+

🧠 Phase 2: Fortgeschrittenes OOP, Speicher & Persistenz

+
+ + + +
+ Kapitel 07 +
🌳 Referenzen & Stammbäume
+
Speicherbereiche im RAM, Aliasing (b = a), is vs. == und Familienstammbaum-Klassen.
+
+ +
+ + +
+
+ Kapitel 08 • Geplant +
➕ Operator Overloading & Dunder
+
Eigene Klassen rechen- und vergleichbar machen mit __add__, __eq__, __lt__ für 2D-Vektoren & Kartenspiele.
+
+ +
+ + +
+
+ Kapitel 09 • Geplant +
🧬 Vererbung & super()
+
Basisklassen, Kindklassen, Code-Wiederverwendung und super().__init__() für Fahrzeugflotten & RPG-Helden.
+
+ +
+ + +
+
+ Kapitel 10 - 12 • Geplant +
🛡️ Exceptions, Persistenz & GUI
+
Polymorphie (10), Eigene Fehlerklassen (11), Spielstände dauerhaft mit JSON/CSV sichern (12) und Desktop-Apps mit Tkinter (13).
+
+ +
+ +
+
+ -
+

🚀 Wie du vorgehst (Schritt-für-Schritt)

  1. Wähle das nächste offene Kapitel aus der Liste oben (starte mit Kapitel 00 zum Warm-up).
  2. @@ -151,35 +200,6 @@
- -
-

🩺 Erste Hilfe & Häufige Fragen

- -
- ❌ Fehlermeldung: TypeError: ... takes 0 positional arguments but 1 was given -
-

Ursache: Du hast bei einer Methode in deiner Klasse das self im Methodenkopf vergessen!

-

Lösung: Schreibe def meine_methode(self): statt def meine_methode():. Python übergibt bei Methodenaufrufen immer automatisch das Objekt selbst als erstes Argument.

-
-
- -
- ❌ Fehlermeldung: AttributeError: 'NoneType' object has no attribute '...' -
-

Ursache: Eine Funktion oder Methode hat nichts zurückgegeben (also None), und du versuchst, auf ein Attribut davon zuzugreifen.

-

Lösung: Prüfe, ob du am Ende der Funktion das return objekt vergessen hast!

-
-
- -
- ❌ Der Test schlägt fehl, obwohl ich die richtige Ausgabe in der Konsole sehe? -
-

Ursache: Du hast vermutlich print(...) verwendet, anstatt den Wert mit return ... zurückzugeben.

-

Lösung: Die automatischen Tests prüfen den Rückgabewert (return) deiner Funktionen/Methoden, nicht das, was auf dem Bildschirm ausgegeben wird.

-
-
-
- diff --git a/test_all.py b/test_all.py index 6d4ac61..4854224 100644 --- a/test_all.py +++ b/test_all.py @@ -18,6 +18,7 @@ KAPITEL = [ ("Kapitel 04: __str__ & Darstellung", "04_str_und_darstellung"), ("Kapitel 05: Objekte kombinieren", "05_objekte_kombinieren"), ("Kapitel 06: Abschlussprojekt Tamagotchi", "06_abschlussprojekt_tamagotchi"), + ("Kapitel 07: Referenzen & Stammbäume", "07_referenzen_und_speicher"), ] def main():