Python Organizer
Desktop-Anwendung zur Verwaltung von Lerninhalten
Eine Desktop-Anwendung basierend auf Python & PyQt6 zum Sortieren, Üben und Verwalten von Lerninhalten. Ursprünglich als kleines Projekt zur automatischen Sortierung von Unterlagen gestartet, wuchs die App schnell zu einem umfangreichen Toolset mit Karteikarten, Quiz-Funktionen und nützlichen Entwickler-Werkzeugen an.
Ursprung & Idee
Ursprünglich als erstes kleines Python-Projekt gestartet, war das Ziel die automatische Sortierung meiner Unterlagen für die verschiedenen Lernfelder. Als grafische Oberfläche kam PyQt6 zum Einsatz.
Erweiterte Funktionen
Das Projekt wuchs schnell: Es kamen Funktionen hinzu, um eigene Ordnerstrukturen und Kategorien flexibel anzulegen und zu verwalten.
Integrierte Tools
Speichergrößen-Rechner
Ein integriertes Tool zur schnellen Umrechnung verschiedener digitaler Speichereinheiten (Bit, Byte, KB, MB, etc.).
Zahlensystem-Konverter
Funktion zum direkten Umrechnen zwischen den gängigen Zahlensystemen der Informatik: Binär ↔ Dezimal ↔ Hexadezimal
Lernen & Üben
Quiz & Highscores
Eine interaktive Lernfunktion ermöglicht das Üben einzelner Lernfelder mittels Multiple-Choice-Fragen. Ein Highscore-System speichert die besten 3 Ergebnisse inkl. Zeitstempel. Die Fragen werden aus einer SQLite-Datenbank geladen.
Digitaler Karteikasten
Ebenfalls integriert ist ein Karteikarten-System. Karten können erstellt und spezifischen Lernfeldern zugewiesen werden. Die Speicherung erfolgt – wie auch beim Quiz – in einer lokalen Datenbank-Datei.
Extras & Anpassung
Ressourcen & KI
Ein editierbares Verzeichnis für hilfreiche Web-Links und Ressourcen, die den Lernprozess unterstützen.
Design & Theming
Da Qt6 Systemfarben nutzt, habe ich Möglichkeiten zur Personalisierung geschaffen: Fensterfarben, Schriftarten und Akzente können direkt in der App angepasst werden.
Einblicke in den Code
1. Intelligente Dateizuordnung
Der Organizer hilft beim Sortieren neuer Dateien. Mittels difflib wird der Dateiname analysiert und automatisch dem ähnlichsten Lernfeld-Ordner zugeordnet ("Fuzzy Matching"), falls kein exakter Treffer existiert.
def dateien_hinzufuegen(self):
dateien, _ = QFileDialog.getOpenFileNames(self, "Dateien auswählen")
# ...
for dateipfad in dateien:
dateiname = os.path.basename(dateipfad)
name_ohne_ext = os.path.splitext(dateiname)[0].lower()
# Fuzzy Matching: Finde den ähnlichsten Ordnernamen
treffer = difflib.get_close_matches(
name_ohne_ext,
[lf.lower() for lf in lernfelder],
n=1, cutoff=0.3
)
if treffer:
# Ordner basierend auf Treffer wählen
ziel = next(lf for lf in lernfelder if lf.lower() == treffer[0])
zielordner = os.path.join(BASIS_ORDNER, ziel)
else:
zielordner = os.path.join(BASIS_ORDNER, "Sonstiges")
shutil.copy(dateipfad, os.path.join(zielordner, dateiname))
2. Import & Parsing (Datenbank)
Fragenkataloge können als Textdateien importiert werden. Ein Parser zerlegt die Blöcke in Frage und Antworten und speichert sie via SQL in der Datenbank.
def fragen_aus_datei_importieren(pfad_zur_datei, lernfeld):
conn = sqlite3.connect(FRAGEN_DB)
cursor = conn.cursor()
# ... Datei wird eingelesen ...
fragen_blocks = inhalt.strip().split("\n\n")
for block in fragen_blocks:
# Zeilenweises Parsen für "Frage:", "A:", "B:", etc.
# ... (Parsing-Logik) ...
if frage and a and b and c and d:
cursor.execute("""
INSERT INTO fragen
(frage, antwort_a, antwort_b, antwort_c, antwort_d, richtige_antwort, lernfeld)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (frage, a, b, c, d, richtige_antwort, lernfeld))
conn.commit()
conn.close()
3. GUI-Aufbau (PyQt6)
Das Layout der Anwendung wird dynamisch im Code erstellt (QHBoxLayout, QVBoxLayout), ohne externe UI-Dateien. Dies ermöglicht eine flexible Anpassung der Oberfläche.
class UmschulungsOrganizer(QWidget):
def __init__(self):
super().__init__()
# ...
self.layout = QHBoxLayout()
self.linke_seite = QVBoxLayout()
self.rechte_seite = QVBoxLayout()
# Widgets instanziieren und hinzufügen
self.btn_karteikarten = QPushButton("Karteikarten")
self.linke_seite.addWidget(self.lernfeld_list)
self.linke_seite.addWidget(self.btn_karteikarten)
self.rechte_seite.addWidget(self.suchfeld)
self.rechte_seite.addWidget(self.datei_list)
# Layout-Verhältnis 1:3 setzen
self.layout.addLayout(self.linke_seite, 1)
self.layout.addLayout(self.rechte_seite, 3)
self.setLayout(self.layout)