it-praxisportal/lehrpfad_2_oop_einstieg/05_objekte_kombinieren/index.html

398 lines
23 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kapitel 05: Komposition und Playlists</title>
<link rel="stylesheet" href="../../assets/style.css">
</head>
<body>
<div class="app-layout">
<aside class="app-sidebar">
<div class="sidebar-header">
<a href="../../index.html" class="sidebar-brand-link">
<div class="sidebar-logo">🐍</div>
<div>
<div class="sidebar-title">Python Portal</div>
<div class="sidebar-subtitle">Lernplattform</div>
</div>
</a>
</div>
<div class="sidebar-quick-nav">
<a href="../../index.html" class="sidebar-link">🏠 Startseite</a>
<a href="../../index.html#tutorial" class="sidebar-link">📖 Tutorial &amp; Workflow</a>
<a href="../../index.html#zertifikate" class="sidebar-link">🏆 Zertifikate</a>
</div>
<div class="sidebar-nav">
<div class="sidebar-group">
<div class="sidebar-group-title">
<span>🌱 1. Grundlagen</span>
<span style="background: rgba(255,255,255,0.1); padding: 2px 6px; border-radius: 99px; font-size: 0.7rem;">G01–G10</span>
</div>
<div style="display: flex; flex-direction: column; gap: 2px;">
<a href="../../lehrpfad_1_grundlagen/01_erste_schritte_taschenrechner/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🧮</span>
<span class="sidebar-link-text">G01. Taschenrechner</span>
</a>
<a href="../../lehrpfad_1_grundlagen/02_variablen_und_datentypen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">📦</span>
<span class="sidebar-link-text">G02. Variablen & Typen</span>
</a>
<a href="../../lehrpfad_1_grundlagen/03_ein_und_ausgabe/index.html" class="sidebar-link">
<span class="sidebar-link-icon">💬</span>
<span class="sidebar-link-text">G03. Ein- & Ausgabe</span>
</a>
<a href="../../lehrpfad_1_grundlagen/04_verzweigungen_und_bedingungen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🚦</span>
<span class="sidebar-link-text">G04. Bedingungen (if)</span>
</a>
<a href="../../lehrpfad_1_grundlagen/05_schleifen_und_wiederholungen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🎡</span>
<span class="sidebar-link-text">G05. Schleifen (for/while)</span>
</a>
<a href="../../lehrpfad_1_grundlagen/06_funktionen_und_module/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🪄</span>
<span class="sidebar-link-text">G06. Funktionen & Module</span>
</a>
<a href="../../lehrpfad_1_grundlagen/07_listen_und_sequenzen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">📋</span>
<span class="sidebar-link-text">G07. Listen & Sequenzen</span>
</a>
<a href="../../lehrpfad_1_grundlagen/08_textverarbeitung_und_strings/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🔤</span>
<span class="sidebar-link-text">G08. String-Methoden</span>
</a>
<a href="../../lehrpfad_1_grundlagen/09_dictionaries_und_sets/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🗃️</span>
<span class="sidebar-link-text">G09. Dicts & Sets</span>
</a>
<a href="../../lehrpfad_1_grundlagen/10_comprehensions_datum_algorithmen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🚀</span>
<span class="sidebar-link-text">G10. Comprehensions</span>
</a>
</div>
</div>
<div class="sidebar-group">
<div class="sidebar-group-title">
<span>🏗️ 2. OOP Einstieg</span>
<span style="background: rgba(255,255,255,0.1); padding: 2px 6px; border-radius: 99px; font-size: 0.7rem;">00–06</span>
</div>
<div style="display: flex; flex-direction: column; gap: 2px;">
<a href="../../lehrpfad_2_oop_einstieg/00_fehlersuche_und_grundlagen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🔍</span>
<span class="sidebar-link-text">00. Fehlersuche & Debug</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/01_einstieg_klassen/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🏗️</span>
<span class="sidebar-link-text">01. Einstieg in Klassen</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/02_init_und_self/index.html" class="sidebar-link">
<span class="sidebar-link-icon">⚙️</span>
<span class="sidebar-link-text">02. Konstruktor & self</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/03_methoden_und_verhalten/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🏎️</span>
<span class="sidebar-link-text">03. Methoden & Verhalten</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/04_str_und_darstellung/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🧾</span>
<span class="sidebar-link-text">04. __str__ Darstellung</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/04b_umstieg_vscode/index.html" class="sidebar-link">
<span class="sidebar-link-icon">💻</span>
<span class="sidebar-link-text">04b. VS Code Setup</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/04c_git_und_versionskontrolle/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🌿</span>
<span class="sidebar-link-text">04c. Git-Versionskontrolle</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/05_objekte_kombinieren/index.html" class="sidebar-link active">
<span class="sidebar-link-icon">🎵</span>
<span class="sidebar-link-text">05. Objekte kombinieren</span>
</a>
<a href="../../lehrpfad_2_oop_einstieg/06_abschlussprojekt_tamagotchi/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🥚</span>
<span class="sidebar-link-text">06. Projekt: Tamagotchi</span>
</a>
</div>
</div>
<div class="sidebar-group">
<div class="sidebar-group-title">
<span>🚀 3. Fortgeschritten</span>
<span style="background: rgba(255,255,255,0.1); padding: 2px 6px; border-radius: 99px; font-size: 0.7rem;">07–16</span>
</div>
<div style="display: flex; flex-direction: column; gap: 2px;">
<a href="../../lehrpfad_3_fortgeschrittenes_oop/07_referenzen_und_speicher/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🧠</span>
<span class="sidebar-link-text">07. Referenzen & Speicher</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/08_operator_overloading_dunder/index.html" class="sidebar-link">
<span class="sidebar-link-icon">➕</span>
<span class="sidebar-link-text">08. Operator Overloading</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/09_eigene_unit_tests_schreiben/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🧪</span>
<span class="sidebar-link-text">09. Unit Tests & TDD</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/10_vererbung_und_super/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🧬</span>
<span class="sidebar-link-text">10. Vererbung & super()</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/11_polymorphie_und_interfaces/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🎭</span>
<span class="sidebar-link-text">11. Polymorphie</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/12_exceptions_und_fehlerbehandlung/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🛡️</span>
<span class="sidebar-link-text">12. Exceptions & Fehler</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/13_persistenz_json_und_csv/index.html" class="sidebar-link">
<span class="sidebar-link-icon">💾</span>
<span class="sidebar-link-text">13. Persistenz (JSON/CSV)</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/14_gui_mit_tkinter/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🖥️</span>
<span class="sidebar-link-text">14. Desktop-GUIs (Tkinter)</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/15_parameter_und_container/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🎒</span>
<span class="sidebar-link-text">15. Container & *args</span>
</a>
<a href="../../lehrpfad_3_fortgeschrittenes_oop/16_master_abschlussprojekt/index.html" class="sidebar-link">
<span class="sidebar-link-icon">🏆</span>
<span class="sidebar-link-text">16. Master-Abschlussprojekt</span>
</a>
</div>
</div>
</div>
<div class="sidebar-footer">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="font-size: 0.85rem; font-weight: 700; color: white;" id="sidebar-level-text">⭐ Level 1</div>
<div style="font-size: 0.82rem; font-weight: 700; color: #38bdf8;" id="sidebar-xp-text">0 XP</div>
</div>
</div>
</aside>
<div class="app-main">
<header>
<div class="header-container">
<nav class="nav-links">
<a href="../../index.html">🏠 Zur Kursübersicht</a>
<span>&rsaquo;</span>
<a href="../04c_git_und_versionskontrolle/index.html">Kapitel 04c (Git)</a>
<span>&rsaquo;</span>
<span style="color: white; font-weight: 600;">Kapitel 05</span>
</nav>
<div class="header-badge">Kapitel 05</div>
<h1>Komposition: Objekte kombinieren &amp; filtern 🎵</h1>
<p>Baue einen eigenen Spotify-Playlist-Manager und lerne, wie Objekte andere Objekte suchen, berechnen und filtern.</p>
</div>
</header>
<main class="container">
<!-- 📂 Schnellzugriff & Download aller Dateien dieser Einheit -->
<div style="background: #ffffff; border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 14px 20px; margin-bottom: 25px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; box-shadow: var(--shadow-sm);">
<div style="font-weight: 700; color: var(--text-main); display: flex; align-items: center; gap: 8px;">
<span>📂 Dateien dieser Einheit:</span>
</div>
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
<a href="aufgabe.py" class="btn" style="padding: 6px 14px; font-size: 0.88rem; background: var(--primary);" download>📄 aufgabe.py (Startercode)</a>
<a href="test_aufgabe.py" class="btn btn-secondary" style="padding: 6px 14px; font-size: 0.88rem;" download>🧪 test_aufgabe.py (Tests)</a>
<a href="musterloesung.py" class="btn btn-secondary" style="padding: 6px 14px; font-size: 0.88rem;" download>💡 musterloesung.py (Lösung)</a>
<a href="README.md" class="btn btn-secondary" style="padding: 6px 14px; font-size: 0.88rem;">📖 README.md</a>
</div>
</div>
<!-- 1. Was ist Komposition -->
<section class="card">
<h2>1. Was ist Komposition?</h2>
<p>
In großen Anwendungen (wie Spotify, Netflix oder Schulsoftware) arbeiten viele Klassen zusammen. Wenn eine Klasse Objekte einer anderen Klasse als Attribute speichert, nennt man das <strong>Komposition</strong> (oder *"hat-ein"-Beziehung*):
</p>
<ul style="margin-left: 20px; margin-bottom: 15px;">
<li>Eine <strong>Schulklasse</strong> <em>hat</em> viele <strong>Schüler</strong>.</li>
<li>Eine <strong>Playlist</strong> <em>hat</em> viele <strong>Songs</strong>.</li>
<li>Ein <strong>Kino</strong> <em>hat</em> viele <strong>Säle</strong>.</li>
</ul>
</section>
<!-- 2. Vollständiges Beispiel: Notenmanager -->
<section class="card">
<h2>2. 🎒 Vollständiges Beispiel: Schüler &amp; Schulklasse Notenmanager</h2>
<p>Hier siehst du ein vollständiges Beispiel aus dem Schulalltag: Die Klasse <code>Schueler</code> speichert Name und Note. Die Klasse <code>Schulklasse</code> verwaltet alle Schüler, berechnet den Notendurchschnitt und sucht die Klassenbesten:</p>
<div class="code-container">
<div class="code-header">
<div class="code-dots">
<span class="code-dot dot-red"></span>
<span class="code-dot dot-yellow"></span>
<span class="code-dot dot-green"></span>
</div>
<span>Python (Komplettes Beispiel: schulklasse.py)</span>
</div>
<pre><span class="cm"># ==============================================================================</span>
<span class="cm"># KLASSE 1: Ein einzelner Schüler</span>
<span class="cm"># ==============================================================================</span>
<span class="kw">class</span> <span class="fn">Schueler</span>:
<span class="kw">def</span> <span class="fn">__init__</span>(<span class="var">self</span>, <span class="var">name</span>, <span class="var">note</span>):
<span class="var">self</span>.<span class="attr">name</span> = <span class="var">name</span>
<span class="var">self</span>.<span class="attr">note</span> = <span class="fn">float</span>(<span class="var">note</span>)
<span class="kw">def</span> <span class="fn">__str__</span>(<span class="var">self</span>):
<span class="kw">return</span> <span class="str">f"{self.name} (Note: {self.note:.1f})"</span>
<span class="cm"># ==============================================================================</span>
<span class="cm"># KLASSE 2: Die Schulklasse verwaltet viele Schüler-Objekte</span>
<span class="cm"># ==============================================================================</span>
<span class="kw">class</span> <span class="fn">Schulklasse</span>:
<span class="kw">def</span> <span class="fn">__init__</span>(<span class="var">self</span>, <span class="var">klassen_name</span>):
<span class="var">self</span>.<span class="attr">klassen_name</span> = <span class="var">klassen_name</span>
<span class="var">self</span>.<span class="attr">schueler_liste</span> = []
<span class="kw">def</span> <span class="fn">hinzufuegen</span>(<span class="var">self</span>, <span class="var">schueler</span>):
<span class="var">self</span>.<span class="attr">schueler_liste</span>.<span class="fn">append</span>(<span class="var">schueler</span>)
<span class="kw">def</span> <span class="fn">notendurchschnitt</span>(<span class="var">self</span>):
<span class="kw">if</span> <span class="kw">not</span> <span class="var">self</span>.<span class="attr">schueler_liste</span>:
<span class="kw">return</span> <span class="num">0.0</span>
<span class="var">summe</span> = <span class="fn">sum</span>(<span class="var">s</span>.<span class="attr">note</span> <span class="kw">for</span> <span class="var">s</span> <span class="kw">in</span> <span class="var">self</span>.<span class="attr">schueler_liste</span>)
<span class="kw">return</span> <span class="var">summe</span> / <span class="fn">len</span>(<span class="var">self</span>.<span class="attr">schueler_liste</span>)
<span class="kw">def</span> <span class="fn">beste_schueler</span>(<span class="var">self</span>):
<span class="cm"># Findet alle Schüler mit einer 1 (Note &lt;= 1.5)</span>
<span class="kw">return</span> [<span class="var">s</span> <span class="kw">for</span> <span class="var">s</span> <span class="kw">in</span> <span class="var">self</span>.<span class="attr">schueler_liste</span> <span class="kw">if</span> <span class="var">s</span>.<span class="attr">note</span> &lt;= <span class="num">1.5</span>]
<span class="cm"># Ausprobieren:</span>
<span class="kw">if</span> <span class="var">__name__</span> == <span class="str">"__main__"</span>:
<span class="var">klasse_9a</span> = <span class="fn">Schulklasse</span>(<span class="str">"Klasse 9a"</span>)
<span class="var">s1</span> = <span class="fn">Schueler</span>(<span class="str">"Emma"</span>, <span class="num">1.0</span>)
<span class="var">s2</span> = <span class="fn">Schueler</span>(<span class="str">"Lukas"</span>, <span class="num">2.3</span>)
<span class="var">s3</span> = <span class="fn">Schueler</span>(<span class="str">"Mia"</span>, <span class="num">1.3</span>)
<span class="var">klasse_9a</span>.<span class="fn">hinzufuegen</span>(<span class="var">s1</span>)
<span class="var">klasse_9a</span>.<span class="fn">hinzufuegen</span>(<span class="var">s2</span>)
<span class="var">klasse_9a</span>.<span class="fn">hinzufuegen</span>(<span class="var">s3</span>)
<span class="fn">print</span>(<span class="str">f"Durchschnitt: {klasse_9a.notendurchschnitt():.2f}"</span>) <span class="cm"># 1.53</span>
<span class="fn">print</span>(<span class="str">"\nBeste Schüler:"</span>)
<span class="kw">for</span> <span class="var">einserschueler</span> <span class="kw">in</span> <span class="var">klasse_9a</span>.<span class="fn">beste_schueler</span>():
<span class="fn">print</span>(<span class="str">f"- {einserschueler}"</span>)</pre>
</div>
</section>
<!-- 3. Nützliche Kniffe -->
<section class="card">
<h2>3. Nützliche Kniffe für die Song-Aufgabe</h2>
<h3>⏱️ Sekunden in "MM:SS" umrechnen</h3>
<div class="code-container">
<pre><span class="var">minuten</span> = <span class="var">self</span>.<span class="attr">dauer_sekunden</span> // <span class="num">60</span>
<span class="var">sekunden</span> = <span class="var">self</span>.<span class="attr">dauer_sekunden</span> % <span class="num">60</span>
<span class="kw">return</span> <span class="str">f"{minuten:02d}:{sekunden:02d}"</span> <span class="cm"># z.B. "03:35"</span></pre>
</div>
<h3>🔍 Groß- und Kleinschreibung beim Suchen ignorieren</h3>
<div class="code-container">
<pre><span class="kw">if</span> <span class="var">song</span>.<span class="attr">kuenstler</span>.<span class="fn">lower</span>() == <span class="var">kuenstler</span>.<span class="fn">lower</span>():
<span class="var">treffer</span>.<span class="fn">append</span>(<span class="var">song</span>)</pre>
</div>
</section>
<!-- 4. Aufgaben Card -->
<section class="card">
<h2>4. 🎯 Deine Aufgaben in <code><a href="aufgabe.py" style="color: inherit; text-decoration: underline;">aufgabe.py</a></code></h2>
<ul class="task-list">
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t5_1">
<label for="t5_1" class="task-label">
<strong>Klasse Song:</strong> <code>__init__(titel, kuenstler, dauer_sekunden)</code>, <code>formatierte_dauer()</code> ("MM:SS") und <code>__str__()</code>.
</label>
</li>
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t5_2">
<label for="t5_2" class="task-label">
<strong>Klasse Playlist:</strong> <code>__init__(name)</code> mit <code>self.songs = []</code>.
</label>
</li>
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t5_3">
<label for="t5_3" class="task-label">
<strong>Playlist Methoden:</strong> <code>song_hinzufuegen</code>, <code>anzahl_songs</code>, <code>gesamtdauer_sekunden</code>.
</label>
</li>
<li class="task-item">
<input type="checkbox" class="task-checkbox" id="t5_4">
<label for="t5_4" class="task-label">
<strong>Playlist Suchen:</strong> <code>finde_songs_von(kuenstler)</code> und <code>laengster_song()</code>.
</label>
</li>
</ul>
<h3>💡 Lösungshinweise (Aufklappen bei Bedarf)</h3>
<details>
<summary>🔍 Tipp zum längsten Song finden</summary>
<div class="details-content">
<div class="code-container">
<pre><span class="kw">def</span> <span class="fn">laengster_song</span>(<span class="var">self</span>):
<span class="kw">if</span> <span class="kw">not</span> <span class="var">self</span>.<span class="attr">songs</span>:
<span class="kw">return</span> <span class="kw">None</span>
<span class="var">bester_song</span> = <span class="var">self</span>.<span class="attr">songs</span>[<span class="num">0</span>]
<span class="kw">for</span> <span class="var">s</span> <span class="kw">in</span> <span class="var">self</span>.<span class="attr">songs</span>:
<span class="kw">if</span> <span class="var">s</span>.<span class="attr">dauer_sekunden</span> > <span class="var">bester_song</span>.<span class="attr">dauer_sekunden</span>:
<span class="var">bester_song</span> = <span class="var">s</span>
<span class="kw">return</span> <span class="var">bester_song</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>05_objekte_kombinieren</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="../04c_git_und_versionskontrolle/index.html" class="btn btn-secondary">&larr; Zurück zu Kapitel 04c: Git</a>
<a href="../06_abschlussprojekt_tamagotchi/index.html" class="btn">Weiter zum Abschlussprojekt &rarr;</a>
</div>
</section>
</main>
</div>
</div>
<button type="button" class="sidebar-mobile-toggle"><span>☰ Menü</span></button>
<div class="sidebar-overlay"></div>
<!-- Scripts -->
<script src="../../assets/gamification_data.js"></script>
<script src="../../assets/gamification.js"></script>
<script src="../../assets/interpreter.js"></script>
<script src="../../assets/certificate.js"></script>
<script src="../../assets/parsons.js"></script>
<script src="../../assets/runner.js"></script>
<script src="../../assets/ui_enhancements.js"></script>
<script src="../../assets/sidebar.js"></script>
</body>
</html>