it-praxisportal/13_persistenz_json_und_csv/aufgabe.py

194 lines
6.5 KiB
Python

"""
Kapitel 13: Datei-Persistenz (JSON & CSV) 💾📁
==============================================
Schulabgleich: 14.0 CSV & Dateien / Savegame-Persistenz
Aufgabe:
Implementiere ein modulares Savegame- und Highscore-System:
1. Klasse 'Spieler': mit Serialisierung (to_dict, from_dict).
2. Klasse 'Spielstand': mit JSON-Speichern/Laden und CSV-Tabellen-Export.
"""
import json
import csv
from pathlib import Path
from typing import List, Optional, Dict, Any
# ==============================================================================
# TODO 1: Klasse Spieler mit Serialisierung
# ==============================================================================
class Spieler:
def __init__(self, name: str, level: int, punkte: int, inventar: Optional[List[str]] = None):
"""
Initialisiert einen Spieler.
Attribute:
- self.name: str = name
- self.level: int = int(level)
- self.punkte: int = int(punkte)
- self.inventar: list[str] = inventar (oder [] falls None)
"""
# TODO: Implementieren
pass
def to_dict(self) -> Dict[str, Any]:
"""
Wandelt das Spieler-Objekt in ein Dictionary um, damit es als JSON
gespeichert werden kann.
Rückgabe-Format:
{
"name": self.name,
"level": self.level,
"punkte": self.punkte,
"inventar": self.inventar
}
"""
# TODO: Implementieren
pass
@classmethod
def from_dict(cls, daten: Dict[str, Any]) -> "Spieler":
"""
Erstellt ein neues Spieler-Objekt aus einem Dictionary.
Beispiel: Spieler.from_dict({"name": "Alex", "level": 5, "punkte": 1200, "inventar": ["Schwert"]})
"""
# TODO: Implementieren
pass
def __repr__(self) -> str:
return f"Spieler(name='{self.name}', level={self.level}, punkte={self.punkte}, inventar={self.inventar})"
def __eq__(self, other: object) -> bool:
if not isinstance(other, Spieler):
return False
return (
self.name == other.name
and self.level == other.level
and self.punkte == other.punkte
and self.inventar == other.inventar
)
# ==============================================================================
# TODO 2: Klasse Spielstand mit JSON- und CSV-Persistenz
# ==============================================================================
class Spielstand:
def __init__(self, titel: str = "Neuer Spielstand"):
"""
Initialisiert einen Spielstand.
Attribute:
- self.titel: str = titel
- self.spieler_liste: list[Spieler] = []
"""
# TODO: Implementieren
pass
def spieler_hinzufuegen(self, spieler: Spieler) -> None:
"""Fügt ein Spieler-Objekt zur internen Spieler-Liste hinzu."""
# TODO: Implementieren
pass
def spieler_suchen(self, name: str) -> Optional[Spieler]:
"""
Sucht einen Spieler nach Name.
Gibt das gefundene Spieler-Objekt zurück oder None, wenn nicht vorhanden.
"""
# TODO: Implementieren
pass
def bester_spieler(self) -> Optional[Spieler]:
"""
Gibt den Spieler mit den meisten Punkten zurück.
Gibt None zurück, wenn die Liste leer ist.
"""
# TODO: Implementieren
pass
def speichern_als_json(self, dateipfad: str | Path) -> None:
"""
Speichert den gesamten Spielstand als formatierte JSON-Datei ab.
Struktur der JSON-Datei:
{
"titel": self.titel,
"spieler": [
{ "name": ..., "level": ..., "punkte": ..., "inventar": [...] },
...
]
}
WICHTIG:
- Nutze 'with open(dateipfad, "w", encoding="utf-8") as f:'
- Nutze 'json.dump(daten, f, indent=4, ensure_ascii=False)'
"""
# TODO: Implementieren
pass
def laden_aus_json(self, dateipfad: str | Path) -> None:
"""
Lädt den Spielstand aus einer JSON-Datei und stellt alle Spieler wieder her.
Ablauf:
1. Öffne die Datei mit 'with open(dateipfad, "r", encoding="utf-8") as f:'
2. Lade die Daten mit 'json.load(f)'
3. Setze self.titel auf den geladenen Titel
4. Erstelle für jeden Eintrag in der Spieler-Liste ein neues Spieler-Objekt
mittels 'Spieler.from_dict(d)' und weise die neue Liste 'self.spieler_liste' zu.
"""
# TODO: Implementieren
pass
def exportiere_als_csv(self, dateipfad: str | Path) -> None:
"""
Exportiert eine Tabellen-Übersicht aller Spieler als CSV-Datei.
Spalten (Header):
["name", "level", "punkte", "inventar_anzahl"]
WICHTIG:
- Nutze 'with open(dateipfad, "w", newline="", encoding="utf-8") as f:'
- Nutze 'csv.DictWriter(f, fieldnames=...)'
- Schreibe zuerst den Header mit 'writer.writeheader()'
- Schreibe dann für jeden Spieler eine Zeile (inventar_anzahl = len(s.inventar))
"""
# TODO: Implementieren
pass
def importiere_aus_csv(self, dateipfad: str | Path) -> int:
"""
Liest Spieler aus einer CSV-Datei ein und fügt sie zur spieler_liste hinzu.
(Hinweis: Das Inventar wird beim einfachen CSV-Import als leere Liste [] initialisiert).
Gibt die Anzahl der neu importierten Spieler zurück.
"""
# TODO: Implementieren
pass
# ==============================================================================
# Kleiner Test zum Ausprobieren im Terminal:
# (python3 aufgabe.py)
# ==============================================================================
if __name__ == "__main__":
spielstand = Spielstand("Highscore-Tabelle RPG")
p1 = Spieler("Arthur", 12, 4500, ["Excalibur", "Heiltrank"])
p2 = Spieler("Morgana", 15, 6200, ["Zauberstab", "Manatrank", "Schriftrolle"])
p3 = Spieler("Lancelot", 10, 3800, ["Schild"])
spielstand.spieler_hinzufuegen(p1)
spielstand.spieler_hinzufuegen(p2)
spielstand.spieler_hinzufuegen(p3)
print("Bester Spieler:", spielstand.bester_spieler())
# JSON Test
json_pfad = Path("test_savegame.json")
spielstand.speichern_als_json(json_pfad)
print(f"Gespeichert in {json_pfad}!")
# CSV Test
csv_pfad = Path("test_export.csv")
spielstand.exportiere_als_csv(csv_pfad)
print(f"Exportiert nach {csv_pfad}!")