Füge LEHRPLAN.md (Schulabgleich rradlbauer) und Kapitel 07 Referenzen, Speicher & Stammbäume hinzu

This commit is contained in:
Alex Mueller 2026-08-29 14:13:26 +02:00
parent c620c6ab2e
commit 5fa0756c2f
10 changed files with 687 additions and 61 deletions

View file

@ -169,7 +169,7 @@
<div class="footer-nav">
<a href="../05_objekte_kombinieren/index.html" class="btn btn-secondary">&larr; Zurück zu Kapitel 05</a>
<a href="../index.html" class="btn">Zurück zur Hauptübersicht 🏠</a>
<a href="../07_referenzen_und_speicher/index.html" class="btn">Weiter zu Kapitel 07: Referenzen &rarr;</a>
</div>
</section>

View file

@ -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
```

View file

@ -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()])

View file

@ -0,0 +1,215 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kapitel 07: Referenzen, Speicher & Stammbäume</title>
<link rel="stylesheet" href="../assets/style.css">
</head>
<body>
<header>
<div class="header-container">
<nav class="nav-links">
<a href="../index.html">🏠 Zur Kursübersicht</a>
<span>&rsaquo;</span>
<a href="../06_abschlussprojekt_tamagotchi/index.html">Kapitel 06</a>
<span>&rsaquo;</span>
<span style="color: white; font-weight: 600;">Kapitel 07</span>
</nav>
<div class="header-badge">Kapitel 07 &bull; Fortgeschrittenes OOP</div>
<h1>Referenzen, Speicher &amp; Stammbäume 🧠🌳</h1>
<p>Verstehe, wie Python Objekte im Arbeitsspeicher verwaltet, was Aliasing bedeutet und baue einen echten Familienstammbaum.</p>
</div>
</header>
<main class="container">
<!-- 1. Das Konzept: Variablen sind Zeiger -->
<section class="card">
<h2>1. Was ist eine Referenz? (Variablen sind Namensschilder)</h2>
<p>
Viele glauben, eine Variable sei eine Box, in der das Objekt direkt drinliegt. In Python ist das anders:
<strong>Eine Variable ist in Wirklichkeit ein Zeiger (eine Referenz)</strong> auf einen Bereich im Arbeitsspeicher (RAM).
</p>
<div class="box box-analogie">
<div class="box-title">🏷️ Die Namensschild-Analogie:</div>
Stelle dir ein Haus vor. Das Haus steht an einer festen Adresse.
Die Variable ist nur ein <strong>Adresszettel</strong>. Wenn du schreibst <code>b = a</code>, baust du kein zweites Haus, sondern schreibst die gleiche Adresse einfach auf einen zweiten Zettel!
</div>
<h3>Das Phänomen: Was passiert bei <code>b = a</code>?</h3>
<div class="code-container">
<div class="code-header">
<span>Beispiel: Listen-Referenzen (Aliasing)</span>
</div>
<pre><span class="var">liste_a</span> = [<span class="num">1</span>, <span class="num">2</span>, <span class="num">3</span>]
<span class="var">liste_b</span> = <span class="var">liste_a</span> <span class="cm"># liste_b zeigt auf GENAU DIESELBE Liste im Speicher!</span>
<span class="var">liste_b</span>.<span class="fn">append</span>(<span class="num">99</span>)
<span class="fn">print</span>(<span class="var">liste_a</span>) <span class="cm"># Ausgabe: [1, 2, 3, 99] &lt;-- liste_a hat sich mitverändert!</span></pre>
</div>
<div class="box box-warning">
<div class="box-title">⚠️ Vorsicht bei veränderlichen Objekten (Mutable vs. Immutable):</div>
<ul>
<li><strong>Mutable (veränderlich):</strong> Listen, Dictionaries, eigene Klassenobjekte. Wenn du sie an einer Stelle änderst, ändern sich alle Variablen, die darauf zeigen!</li>
<li><strong>Immutable (unveränderlich):</strong> Zahlen (<code>int</code>, <code>float</code>), Texte (<code>str</code>), Tupel (<code>tuple</code>). Beim Ändern wird automatisch ein neues Objekt im Speicher erzeugt.</li>
</ul>
</div>
</section>
<!-- 2. is vs == -->
<section class="card">
<h2>2. Der Unterschied zwischen <code>==</code> und <code>is</code></h2>
<p>In Python gibt es zwei Arten von Vergleichen:</p>
<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">
<thead>
<tr style="background: var(--primary-light); text-align: left;">
<th style="padding: 10px; border: 1px solid var(--border-color);">Operator</th>
<th style="padding: 10px; border: 1px solid var(--border-color);">Bedeutung</th>
<th style="padding: 10px; border: 1px solid var(--border-color);">Frage im Hintergrund</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>==</code></td>
<td style="padding: 10px; border: 1px solid var(--border-color);"><strong>Wertegleichheit</strong></td>
<td style="padding: 10px; border: 1px solid var(--border-color);">Haben beide Objekte denselben Inhalt?</td>
</tr>
<tr style="background: #fafafa;">
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>is</code></td>
<td style="padding: 10px; border: 1px solid var(--border-color);"><strong>Identität</strong></td>
<td style="padding: 10px; border: 1px solid var(--border-color);">Sind beide Variablen exakt dasselbe Objekt an derselben Speicheradresse?</td>
</tr>
</tbody>
</table>
<div class="code-container">
<pre><span class="var">x</span> = [<span class="num">1</span>, <span class="num">2</span>, <span class="num">3</span>]
<span class="var">y</span> = [<span class="num">1</span>, <span class="num">2</span>, <span class="num">3</span>]
<span class="var">z</span> = <span class="var">x</span>
<span class="fn">print</span>(<span class="var">x</span> == <span class="var">y</span>) <span class="cm"># True (weil der Inhalt gleich ist)</span>
<span class="fn">print</span>(<span class="var">x</span> <span class="kw">is</span> <span class="var">y</span>) <span class="cm"># False (zwei getrennte Listen im Speicher)</span>
<span class="fn">print</span>(<span class="var">x</span> <span class="kw">is</span> <span class="var">z</span>) <span class="cm"># True (z zeigt direkt auf dieselbe Liste wie x)</span></pre>
</div>
</section>
<!-- 3. Das Praxisbeispiel: Familienstammbaum -->
<section class="card">
<h2>3. Praxisbeispiel: Der Familienstammbaum 🌳</h2>
<p>
Warum sind Referenzen so genial? Weil ein und dasselbe Objekt in vielen Beziehungen vorkommen kann.
Eine Person namens <strong>Susi</strong> ist gleichzeitig die <em>Mutter von Erika</em>, das <em>Kind von Fritz</em> und die <em>Schwester von Tom</em>.
</p>
<div class="code-container">
<div class="code-header">
<span>Stammbaum mit Klassen-Referenzen</span>
</div>
<pre><span class="kw">class</span> <span class="fn">Person</span>:
<span class="kw">def</span> <span class="fn">__init__</span>(<span class="var">self</span>, <span class="var">name</span>: <span class="fn">str</span>, <span class="var">geburtsjahr</span>: <span class="fn">int</span>):
<span class="var">self</span>.<span class="attr">name</span>: <span class="fn">str</span> = <span class="var">name</span>
<span class="var">self</span>.<span class="attr">geburtsjahr</span>: <span class="fn">int</span> = <span class="var">geburtsjahr</span>
<span class="var">self</span>.<span class="attr">mutter</span>: <span class="fn">Person</span> | <span class="kw">None</span> = <span class="kw">None</span> <span class="cm"># Referenz auf Mutter-Objekt</span>
<span class="var">self</span>.<span class="attr">vater</span>: <span class="fn">Person</span> | <span class="kw">None</span> = <span class="kw">None</span> <span class="cm"># Referenz auf Vater-Objekt</span>
<span class="var">self</span>.<span class="attr">kinder</span>: <span class="fn">list</span>[<span class="fn">Person</span>] = [] <span class="cm"># Liste von Referenzen auf Kinder</span>
<span class="kw">def</span> <span class="fn">mutter_setzen</span>(<span class="var">self</span>, <span class="var">mutter</span>: <span class="str">'Person'</span>) -> <span class="kw">None</span>:
<span class="var">self</span>.<span class="attr">mutter</span> = <span class="var">mutter</span>
<span class="kw">if</span> <span class="var">self</span> <span class="kw">not in</span> <span class="var">mutter</span>.<span class="attr">kinder</span>:
<span class="var">mutter</span>.<span class="attr">kinder</span>.<span class="fn">append</span>(<span class="var">self</span>)
<span class="kw">def</span> <span class="fn">__str__</span>(<span class="var">self</span>) -> <span class="fn">str</span>:
<span class="kw">return</span> <span class="str">f"{self.name} (*{self.geburtsjahr})"</span></pre>
</div>
</section>
<!-- 4. Deine Aufgaben -->
<section class="card">
<h2>4. 🎯 Deine Aufgaben in <code>aufgabe.py</code></h2>
<p>Öffne die Datei <code>07_referenzen_und_speicher/aufgabe.py</code> und vervollständige die Stammbaum-Klasse:</p>
<ul class="task-list">
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t7_1">
<label for="t7_1" class="task-label">
<strong>TODO 1:</strong> <code>Person.__init__</code> mit <code>name</code>, <code>geburtsjahr</code>, <code>mutter=None</code>, <code>vater=None</code> und <code>kinder=[]</code>.
</label>
</li>
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t7_2">
<label for="t7_2" class="task-label">
<strong>TODO 2 & 3:</strong> <code>mutter_setzen</code> und <code>vater_setzen</code> (verknüpft Elternteil und fügt das Kind zur Kinderliste des Elternteils hinzu).
</label>
</li>
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t7_3">
<label for="t7_3" class="task-label">
<strong>TODO 4:</strong> <code>geschwister(self) -> list[Person]</code>: Findet alle Personen, die dieselbe Mutter oder denselben Vater haben (aber nicht <code>self</code>!).
</label>
</li>
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t7_4">
<label for="t7_4" class="task-label">
<strong>TODO 5:</strong> <code>grosseltern(self) -> list[Person]</code>: Gibt eine Liste aller bekannten Großeltern zurück.
</label>
</li>
</ul>
<h3>💡 Lösungshinweise (Aufklappen bei Bedarf)</h3>
<details>
<summary>🔍 Tipp zu TODO 4 (Geschwister finden)</summary>
<div class="details-content">
<p>Gehe alle Kinder der Mutter und alle Kinder des Vaters durch. Achte darauf, dass du <code>kind is not self</code> prüfst, damit man nicht selbst als Geschwisterteil gelistet wird, und füge niemanden doppelt hinzu!</p>
</div>
</details>
<details>
<summary>🔍 Tipp zu TODO 5 (Großeltern finden)</summary>
<div class="details-content">
<div class="code-container">
<pre><span class="var">ge</span> = []
<span class="kw">if</span> <span class="var">self</span>.<span class="attr">mutter</span>:
<span class="kw">if</span> <span class="var">self</span>.<span class="attr">mutter</span>.<span class="attr">mutter</span>: <span class="var">ge</span>.<span class="fn">append</span>(<span class="var">self</span>.<span class="attr">mutter</span>.<span class="attr">mutter</span>)
<span class="kw">if</span> <span class="var">self</span>.<span class="attr">mutter</span>.<span class="attr">vater</span>: <span class="var">ge</span>.<span class="fn">append</span>(<span class="var">self</span>.<span class="attr">mutter</span>.<span class="attr">vater</span>)
<span class="kw">if</span> <span class="var">self</span>.<span class="attr">vater</span>:
<span class="kw">if</span> <span class="var">self</span>.<span class="attr">vater</span>.<span class="attr">mutter</span>: <span class="var">ge</span>.<span class="fn">append</span>(<span class="var">self</span>.<span class="attr">vater</span>.<span class="attr">mutter</span>)
<span class="kw">if</span> <span class="var">self</span>.<span class="attr">vater</span>.<span class="attr">vater</span>: <span class="var">ge</span>.<span class="fn">append</span>(<span class="var">self</span>.<span class="attr">vater</span>.<span class="attr">vater</span>)
<span class="kw">return</span> <span class="var">ge</span></pre>
</div>
</div>
</details>
</section>
<!-- 5. Testen & Navigation -->
<section class="card">
<h2>5. 🧪 Lösung überprüfen</h2>
<p>Führe im Terminal im Ordner <code>07_referenzen_und_speicher</code> folgenden Befehl aus:</p>
<div class="code-container">
<div class="code-header">
<span>Terminal</span>
</div>
<pre><code>python3 test_aufgabe.py</code></pre>
</div>
<div class="footer-nav">
<a href="../06_abschlussprojekt_tamagotchi/index.html" class="btn btn-secondary">&larr; Zurück zu Kapitel 06</a>
<a href="../index.html" class="btn">Zur Kursübersicht &rarr;</a>
</div>
</section>
</main>
</body>
</html>

View file

@ -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()])

View file

@ -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)

67
LEHRPLAN.md Normal file
View file

@ -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 |

View file

@ -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:

View file

@ -22,30 +22,31 @@
<section class="card">
<h2>👋 Willkommen zu deiner Übungsreihe!</h2>
<p>
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: <strong>Klassen & Objekte</strong>!
</p>
<p>
Damit du beim Programmieren nie an kleinen Syntaxfehlern verzweifelst, starten wir mit einem kurzen <strong>Warm-up zur Fehlersuche (Kapitel 00)</strong>, und steigen nach Kapitel 04 auf die Profi-Entwicklungsumgebung <strong>VS Code (Kapitel 04b)</strong> 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!
</p>
<div class="box box-analogie">
<div class="box-title">🏗️ Die Grundidee von OOP in einem Satz:</div>
Eine <strong>Klasse</strong> ist wie ein Bauplan (oder eine Plätzchen-Ausstechform). Ein <strong>Objekt</strong> ist das fertige Haus (oder das gebackene Plätzchen), das nach diesem Bauplan entstanden ist!
</div>
<div class="box box-tipp">
<div class="box-title">📚 Schulabgleich &amp; Lehrplan:</div>
Alle Kapitel sind 1:1 mit den Themen deines Informatik-Unterrichts (Type Hints, UML, Assoziationen, Referenzen, Vererbung, Tkinter) abgestimmt.
</div>
</section>
<!-- Roadmap Grid -->
<!-- PHASE 1: GRUNDLAGEN -->
<section>
<h2 style="margin: 30px 0 15px 0; color: var(--text-main); font-size: 1.5rem;">🗺️ Dein Lernpfad (Kapitel 00 bis 06)</h2>
<h2 style="margin: 30px 0 10px 0; color: var(--text-main); font-size: 1.4rem;">🌱 Phase 1: Grundlagen OOP &amp; Entwicklungsumgebung</h2>
<div class="roadmap-grid">
<!-- Kapitel 0 -->
<a href="00_fehlersuche_und_grundlagen/index.html" class="roadmap-card" style="border-left: 4px solid var(--purple);">
<div>
<span class="roadmap-number" style="background: var(--purple-light); color: var(--purple);">Vorkapitel 00</span>
<span class="roadmap-number" style="background: var(--purple-light); color: var(--purple);">Warm-up 00</span>
<div class="roadmap-title">🔍 Fehlersuche &amp; Bugs</div>
<div class="roadmap-desc">Tracebacks richtig lesen, Einrückungsfehler (IndentationError), Typfehler und eine interaktive Detektiv-Aufgabe.</div>
<div class="roadmap-desc">Tracebacks richtig lesen, Einrückungsfehler (IndentationError), Typfehler und Detektiv-Aufgabe.</div>
</div>
<div class="roadmap-footer">Vorkapitel öffnen &rarr;</div>
</a>
@ -55,7 +56,7 @@
<div>
<span class="roadmap-number">Kapitel 01</span>
<div class="roadmap-title">🐶 Die erste Klasse</div>
<div class="roadmap-desc">Was ist eine Klasse? Bauplan vs. Objekt, Instanziierung und erste Attribute am Haustier- &amp; Fahrrad-Beispiel.</div>
<div class="roadmap-desc">Bauplan vs. Objekt, Instanziierung, Punktnotation und Type Hints am Fahrrad- &amp; Haustier-Beispiel.</div>
</div>
<div class="roadmap-footer">Kapitel öffnen &rarr;</div>
</a>
@ -65,7 +66,7 @@
<div>
<span class="roadmap-number">Kapitel 02</span>
<div class="roadmap-title">💳 Konstruktor & self</div>
<div class="roadmap-desc">Wie <code>__init__</code> Objekte startklar macht und was <code>self</code> bedeutet (Smartphone- &amp; Bankkonto-App).</div>
<div class="roadmap-desc">Wie <code>__init__</code> Objekte startklar macht, was <code>self</code> bedeutet und erste UML-Klassendiagramme.</div>
</div>
<div class="roadmap-footer">Kapitel öffnen &rarr;</div>
</a>
@ -85,27 +86,27 @@
<div>
<span class="roadmap-number">Kapitel 04</span>
<div class="roadmap-title">🧾 Schöne Textausgabe</div>
<div class="roadmap-desc">Wie man <code>print(objekt)</code> mit <code>__str__</code> lesbar macht und Objekte im Warenkorb &amp; bei Pizza-Bestellungen sammelt.</div>
<div class="roadmap-desc">Wie man <code>print(objekt)</code> mit <code>__str__</code> lesbar macht und Rechnungsdruck im Warenkorb.</div>
</div>
<div class="roadmap-footer">Kapitel öffnen &rarr;</div>
</a>
<!-- Kapitel 4b (VS Code Exkurs) -->
<!-- Kapitel 4b -->
<a href="04b_umstieg_vscode/index.html" class="roadmap-card" style="border-left: 4px solid var(--secondary);">
<div>
<span class="roadmap-number" style="background: #e0f2fe; color: #0284c7;">Exkurs 04b</span>
<div class="roadmap-title">🚀 Umstieg auf VS Code</div>
<div class="roadmap-desc">Von Thonny zu VS Code: Die besten Plugins (Error Lens, Python), Shortcuts, Projektordner &amp; integriertes Terminal.</div>
<div class="roadmap-title">🚀 Umstieg &amp; Installation VS Code</div>
<div class="roadmap-desc">Installationsanleitung (Win/Mac/Linux), Plugins (Error Lens, Python), Shortcuts &amp; Terminal.</div>
</div>
<div class="roadmap-footer">VS Code Tutorial öffnen &rarr;</div>
<div class="roadmap-footer">VS Code Guide öffnen &rarr;</div>
</a>
<!-- Kapitel 5 -->
<a href="05_objekte_kombinieren/index.html" class="roadmap-card">
<div>
<span class="roadmap-number">Kapitel 05</span>
<div class="roadmap-title">🎵 Komposition & Playlists</div>
<div class="roadmap-desc">Objekte verwalten andere Objekte: Song-Suche, Längenberechnung und Filter in Spotify-Playlists &amp; Schulklassen.</div>
<div class="roadmap-title">🎵 Assoziation & Komposition</div>
<div class="roadmap-desc">Objekte verwalten andere Objekte: Song-Suche, Längenberechnung und Filter in Spotify-Playlists.</div>
</div>
<div class="roadmap-footer">Kapitel öffnen &rarr;</div>
</a>
@ -114,7 +115,7 @@
<a href="06_abschlussprojekt_tamagotchi/index.html" class="roadmap-card">
<div>
<span class="roadmap-number">Kapitel 06</span>
<div class="roadmap-title">🥚 Tamagotchi Mini-Projekt</div>
<div class="roadmap-title">🥚 Mini-Projekt: Tamagotchi</div>
<div class="roadmap-desc">Kombiniere alles in einem voll spielbaren, interaktiven virtuellen Haustier für dein Terminal!</div>
</div>
<div class="roadmap-footer">Kapitel öffnen &rarr;</div>
@ -123,8 +124,56 @@
</div>
</section>
<!-- PHASE 2: FORTGESCHRITTENES OOP -->
<section>
<h2 style="margin: 35px 0 10px 0; color: var(--text-main); font-size: 1.4rem;">🧠 Phase 2: Fortgeschrittenes OOP, Speicher &amp; Persistenz</h2>
<div class="roadmap-grid">
<!-- Kapitel 7 -->
<a href="07_referenzen_und_speicher/index.html" class="roadmap-card" style="border-left: 4px solid var(--success);">
<div>
<span class="roadmap-number" style="background: var(--success-light); color: var(--success);">Kapitel 07</span>
<div class="roadmap-title">🌳 Referenzen &amp; Stammbäume</div>
<div class="roadmap-desc">Speicherbereiche im RAM, Aliasing (<code>b = a</code>), <code>is</code> vs. <code>==</code> und Familienstammbaum-Klassen.</div>
</div>
<div class="roadmap-footer">Kapitel 07 öffnen &rarr;</div>
</a>
<!-- Vorschau Kapitel 8 -->
<div class="roadmap-card" style="opacity: 0.85;">
<div>
<span class="roadmap-number">Kapitel 08 &bull; Geplant</span>
<div class="roadmap-title">➕ Operator Overloading &amp; Dunder</div>
<div class="roadmap-desc">Eigene Klassen rechen- und vergleichbar machen mit <code>__add__</code>, <code>__eq__</code>, <code>__lt__</code> für 2D-Vektoren &amp; Kartenspiele.</div>
</div>
<div class="roadmap-footer" style="color: var(--text-muted);">In Vorbereitung &bull; Schulabgleich 28.0</div>
</div>
<!-- Vorschau Kapitel 9 -->
<div class="roadmap-card" style="opacity: 0.85;">
<div>
<span class="roadmap-number">Kapitel 09 &bull; Geplant</span>
<div class="roadmap-title">🧬 Vererbung &amp; super()</div>
<div class="roadmap-desc">Basisklassen, Kindklassen, Code-Wiederverwendung und <code>super().__init__()</code> für Fahrzeugflotten &amp; RPG-Helden.</div>
</div>
<div class="roadmap-footer" style="color: var(--text-muted);">In Vorbereitung &bull; Schulabgleich 25.0</div>
</div>
<!-- Vorschau Kapitel 10-12 -->
<div class="roadmap-card" style="opacity: 0.85;">
<div>
<span class="roadmap-number">Kapitel 10 - 12 &bull; Geplant</span>
<div class="roadmap-title">🛡️ Exceptions, Persistenz &amp; GUI</div>
<div class="roadmap-desc">Polymorphie (10), Eigene Fehlerklassen (11), Spielstände dauerhaft mit JSON/CSV sichern (12) und Desktop-Apps mit Tkinter (13).</div>
</div>
<div class="roadmap-footer" style="color: var(--text-muted);">Ausführlicher Plan in LEHRPLAN.md</div>
</div>
</div>
</section>
<!-- Wie lerne ich Card -->
<section class="card">
<section class="card" style="margin-top: 35px;">
<h2>🚀 Wie du vorgehst (Schritt-für-Schritt)</h2>
<ol style="margin-left: 20px; margin-bottom: 15px;">
<li style="margin-bottom: 8px;">Wähle das nächste offene Kapitel aus der Liste oben (starte mit Kapitel 00 zum Warm-up).</li>
@ -151,35 +200,6 @@
</div>
</section>
<!-- FAQ & Troubleshooting Card -->
<section class="card">
<h2>🩺 Erste Hilfe & Häufige Fragen</h2>
<details>
<summary>❌ Fehlermeldung: <code>TypeError: ... takes 0 positional arguments but 1 was given</code></summary>
<div class="details-content">
<p><strong>Ursache:</strong> Du hast bei einer Methode in deiner Klasse das <code>self</code> im Methodenkopf vergessen!</p>
<p><strong>Lösung:</strong> Schreibe <code>def meine_methode(self):</code> statt <code>def meine_methode():</code>. Python übergibt bei Methodenaufrufen immer automatisch das Objekt selbst als erstes Argument.</p>
</div>
</details>
<details>
<summary>❌ Fehlermeldung: <code>AttributeError: 'NoneType' object has no attribute '...'</code></summary>
<div class="details-content">
<p><strong>Ursache:</strong> Eine Funktion oder Methode hat nichts zurückgegeben (also <code>None</code>), und du versuchst, auf ein Attribut davon zuzugreifen.</p>
<p><strong>Lösung:</strong> Prüfe, ob du am Ende der Funktion das <code>return objekt</code> vergessen hast!</p>
</div>
</details>
<details>
<summary>❌ Der Test schlägt fehl, obwohl ich die richtige Ausgabe in der Konsole sehe?</summary>
<div class="details-content">
<p><strong>Ursache:</strong> Du hast vermutlich <code>print(...)</code> verwendet, anstatt den Wert mit <code>return ...</code> zurückzugeben.</p>
<p><strong>Lösung:</strong> Die automatischen Tests prüfen den Rückgabewert (<code>return</code>) deiner Funktionen/Methoden, nicht das, was auf dem Bildschirm ausgegeben wird.</p>
</div>
</details>
</section>
</main>
</body>

View file

@ -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():