Füge LEHRPLAN.md (Schulabgleich rradlbauer) und Kapitel 07 Referenzen, Speicher & Stammbäume hinzu
This commit is contained in:
parent
c620c6ab2e
commit
5fa0756c2f
10 changed files with 687 additions and 61 deletions
|
|
@ -169,7 +169,7 @@
|
|||
|
||||
<div class="footer-nav">
|
||||
<a href="../05_objekte_kombinieren/index.html" class="btn btn-secondary">← 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 →</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
|
|||
36
07_referenzen_und_speicher/README.md
Normal file
36
07_referenzen_und_speicher/README.md
Normal 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
|
||||
```
|
||||
93
07_referenzen_und_speicher/aufgabe.py
Normal file
93
07_referenzen_und_speicher/aufgabe.py
Normal 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()])
|
||||
215
07_referenzen_und_speicher/index.html
Normal file
215
07_referenzen_und_speicher/index.html
Normal 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>›</span>
|
||||
<a href="../06_abschlussprojekt_tamagotchi/index.html">Kapitel 06</a>
|
||||
<span>›</span>
|
||||
<span style="color: white; font-weight: 600;">Kapitel 07</span>
|
||||
</nav>
|
||||
<div class="header-badge">Kapitel 07 • Fortgeschrittenes OOP</div>
|
||||
<h1>Referenzen, Speicher & 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] <-- 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">← Zurück zu Kapitel 06</a>
|
||||
<a href="../index.html" class="btn">Zur Kursübersicht →</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
85
07_referenzen_und_speicher/musterloesung.py
Normal file
85
07_referenzen_und_speicher/musterloesung.py
Normal 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()])
|
||||
98
07_referenzen_und_speicher/test_aufgabe.py
Normal file
98
07_referenzen_und_speicher/test_aufgabe.py
Normal 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
67
LEHRPLAN.md
Normal 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 |
|
||||
33
README.md
33
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:
|
||||
|
|
|
|||
118
index.html
118
index.html
|
|
@ -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 & 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 & 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 & 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 →</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- & Fahrrad-Beispiel.</div>
|
||||
<div class="roadmap-desc">Bauplan vs. Objekt, Instanziierung, Punktnotation und Type Hints am Fahrrad- & Haustier-Beispiel.</div>
|
||||
</div>
|
||||
<div class="roadmap-footer">Kapitel öffnen →</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- & 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 →</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 & 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 →</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 & integriertes Terminal.</div>
|
||||
<div class="roadmap-title">🚀 Umstieg & Installation VS Code</div>
|
||||
<div class="roadmap-desc">Installationsanleitung (Win/Mac/Linux), Plugins (Error Lens, Python), Shortcuts & Terminal.</div>
|
||||
</div>
|
||||
<div class="roadmap-footer">VS Code Tutorial öffnen →</div>
|
||||
<div class="roadmap-footer">VS Code Guide öffnen →</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 & 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 →</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 →</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 & 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 & 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 →</div>
|
||||
</a>
|
||||
|
||||
<!-- Vorschau Kapitel 8 -->
|
||||
<div class="roadmap-card" style="opacity: 0.85;">
|
||||
<div>
|
||||
<span class="roadmap-number">Kapitel 08 • Geplant</span>
|
||||
<div class="roadmap-title">➕ Operator Overloading & 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 & Kartenspiele.</div>
|
||||
</div>
|
||||
<div class="roadmap-footer" style="color: var(--text-muted);">In Vorbereitung • Schulabgleich 28.0</div>
|
||||
</div>
|
||||
|
||||
<!-- Vorschau Kapitel 9 -->
|
||||
<div class="roadmap-card" style="opacity: 0.85;">
|
||||
<div>
|
||||
<span class="roadmap-number">Kapitel 09 • Geplant</span>
|
||||
<div class="roadmap-title">🧬 Vererbung & super()</div>
|
||||
<div class="roadmap-desc">Basisklassen, Kindklassen, Code-Wiederverwendung und <code>super().__init__()</code> für Fahrzeugflotten & RPG-Helden.</div>
|
||||
</div>
|
||||
<div class="roadmap-footer" style="color: var(--text-muted);">In Vorbereitung • 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 • Geplant</span>
|
||||
<div class="roadmap-title">🛡️ Exceptions, Persistenz & 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>
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
Loading…
Reference in a new issue