{"id":41351124,"url":"https://github.com/kqc-real/streamlit","last_synced_at":"2026-01-23T07:19:36.217Z","repository":{"id":316709918,"uuid":"1064238894","full_name":"kqc-real/streamlit","owner":"kqc-real","description":"MC-Tests in deutscher Sprache","archived":false,"fork":false,"pushed_at":"2026-01-15T16:00:10.000Z","size":472521,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-15T19:30:36.707Z","etag":null,"topics":["agiles-projektmanagement","data-science","deep-learning","mathematische-grundlagen"],"latest_commit_sha":null,"homepage":"https://mc-test.streamlit.app/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kqc-real.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit_log.py","citation":null,"codeowners":null,"security":"SECURITY_ANALYSIS_ADMIN_AUTH.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-09-25T18:35:43.000Z","updated_at":"2026-01-15T16:00:16.000Z","dependencies_parsed_at":"2026-01-15T18:02:46.189Z","dependency_job_id":null,"html_url":"https://github.com/kqc-real/streamlit","commit_stats":null,"previous_names":["kqc-real/streamlit"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/kqc-real/streamlit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kqc-real%2Fstreamlit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kqc-real%2Fstreamlit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kqc-real%2Fstreamlit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kqc-real%2Fstreamlit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kqc-real","download_url":"https://codeload.github.com/kqc-real/streamlit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kqc-real%2Fstreamlit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28682860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T05:48:07.525Z","status":"ssl_error","status_checked_at":"2026-01-23T05:48:07.129Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agiles-projektmanagement","data-science","deep-learning","mathematische-grundlagen"],"created_at":"2026-01-23T07:19:35.524Z","updated_at":"2026-01-23T07:19:36.207Z","avatar_url":"https://github.com/kqc-real.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📝 MC-Test Streamlit App\n\n[![CI](https://github.com/kqc-real/streamlit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/kqc-real/streamlit/actions/workflows/ci.yml)\n\nInteraktive Multiple-Choice-App mit schnellem Feedback, Pseudonym-Login, Itemanalyse und PDF-Exports. 40+ Fragensets (JSON + Learning-Objectives) sind enthalten; weitere lassen sich hochladen oder per KI-Generator erstellen.\n\n## Inhalt\n- [Schnellstart](#-schnellstart)\n- [Übersicht](#-übersicht)\n- [Hauptfunktionen](#-hauptfunktionen-stand-2026-01)\n- [Fragenset-Schema](#-fragenset-schema)\n- [Sicherheitsfeatures](#-security-features)\n- [Voraussetzungen](#-voraussetzungen)\n- [Installation \u0026 Start](#-installation-und-start)\n- [Konfiguration](#-konfiguration)\n\n---\n\n## 🚀 Schnellstart\n\nInstallationsguides: [Mac](INSTALLATION_MAC_ANLEITUNG.md) · [Windows](INSTALLATION_WINDOWS_ANLEITUNG.md) · [VS Code SSH](INSTALLATION_VS-CODE_SSH-AUTHENTIFIZIERUNG.md)  \nAdmin-Panel testen: [🔐 Anleitung](ADMIN_PANEL_ANLEITUNG.md)\n\n---\n\n## 🚀 Übersicht\n\n- Pseudonym-Login, zufällige Fragenreihenfolge, Gewichtung pro Frage.\n- Schnellsuche (Titel/Slug/Meta), Sprachenhinweis aus `meta.language`, 40+ Fragensets + Upload temporärer User-Sets.\n- Scoring: Nur-Plus oder Plus/Minus; Zeitlimit optional pro Set oder via `MC_TEST_DURATION_MINUTES` (Default 60, leer/0 = kein Limit).\n- Navigation: Markieren, Überspringen, Seitenleiste; Panic Mode schaltet alle Cooldowns sofort ab.\n- Feedback/Erklärungen, Mini-Glossare, erweiterte Erklärungen; Item- \u0026 Distraktor-Analyse, Leaderboard.\n- Exporte: PDF (LaTeX, Glossar, Bookmarks), CSV aller Antworten, DB-Dump; Admin-Panel für Analytics, Feedback, KI-Generator.\n\n## ❓ Fragenset-Schema\n\nDie App lädt Fragensets aus JSON-Dateien im `data/questions_*.json`-Format. Erwartet wird ein Objekt mit:\n\n- `questions`: Liste von Fragen\n- `meta`: Objekt mit Basis-Metadaten (erforderlich, mindestens `language`)\n\n### Pflichtfelder je Frage\n\n- `question`: String (nicht leer)\n- `options`: Liste mit **3–5** Strings\n- `answer`: Ganzzahl, 0-basierter Index in `options`\n- `explanation`: String (nicht leer)\n- `topic`: String (nicht leer)\n- `weight`: Ganzzahl 1, 2 oder 3 (empfohlen, abweichende Werte erzeugen Warnungen)\n\n### Optionale Felder je Frage\n\n- `concept`: String (klares Lernziel/Konzept)\n- `cognitive_level`: String (z. B. „Reproduction“, „Application“, „Analysis“)\n- `mini_glossary`: Objekt oder Liste mit Begriff/Definition; empfohlen **2–6** Einträge, max. 10 (App-Features nutzen das Glossar intensiv)\n- `extended_explanation`: erlaubt; Schema siehe `KI_PROMPT.md` und `GLOSSARY_SCHEMA.md`\n\n### Meta (erforderlich)\n\n- `language` (ISO-639-1, z. B. `de`) – Pflicht\n- Empfohlen: `title`, `question_count` (wird auf Konsistenz geprüft), `difficulty_profile` (easy/medium/hard), `test_duration_minutes`, `time_per_weight_minutes`, `additional_buffer_minutes`, `created`/`modified`\n\n### Minimales Beispiel\n\n```json\n{\n  \"meta\": {\n    \"language\": \"de\",\n    \"question_count\": 1,\n    \"difficulty_profile\": {\"easy\": 0, \"medium\": 1, \"hard\": 0}\n  },\n  \"questions\": [\n    {\n      \"question\": \"1. Was ist die BFS-Besuchreihenfolge ab Knoten A?\",\n      \"options\": [\"A B C D\", \"A C B D\", \"A D B C\"],\n      \"answer\": 0,\n      \"explanation\": \"BFS besucht erst alle direkten Nachbarn in Einfügereihenfolge.\",\n      \"weight\": 2,\n      \"topic\": \"Graph Traversal\",\n      \"concept\": \"BFS visitation order\"\n    }\n  ]\n}\n```\n\n### Empfehlungen für Contributors/Admins\n\n1. **Konsistente Terminologie** für `topic`/`concept`/`cognitive_level`, damit Exporte und Analytics sauber gruppieren.\n2. **Meta pflegen:** `language` ist Pflicht; `question_count`/`difficulty_profile` sollten mit der tatsächlichen Anzahl/Verteilung übereinstimmen.\n3. **Plausible Distraktoren:** 3–5 Optionen ähnlicher Länge; kein „Alle/Keine der oben genannten“.\n4. **Mini-Glossar pflegen:** 2–6 relevante Begriffe pro Frage, keine Füllwörter.\n5. **Validierung:** `python validate_sets.py` ausführen, bevor ein Fragenset committet wird; prüft Pflichtfelder, Optionslänge, Answer-Index, Glossargröße, Gewichtungen u. a.\n6. **LaTeX/Markdown:** Keine LaTeX-Ausdrücke in Backticks; bei Bedarf korrekt escapen (`\\\\`).\n\nHinweis: Ältere Fragensets können unvollständige Meta-Daten haben (z. B. kein Datum) und erscheinen dann ohne Datum im Auswahlmenü. Neue Fragensets sollten alle Meta-Felder sauber pflegen (`language`, `question_count`, `difficulty_profile`, ggf. `created`/`modified`), damit UI und Exporte korrekt funktionieren.\n\n### Aktuelle Ergänzungen\n\n- Musterlösung (PDF) inkl. Mini-Glossar, Hervorhebung korrekter Optionen, LaTeX-Rendering mit Parallelisierung/Timeouts.\n- Schnellsuche auf der Startseite (Titel/Slug/Meta) inkl. Sprachenhinweis; temporäre User-Fragensets werden beim Laden bereinigt (Cleanup konfigurierbar).\n- Panic Mode: Sobald verbleibende Zeit \u003c Fragen * Schwellenwert, sind Cooldowns für Antworten/Nächste-Frage deaktiviert.\n- KI-Generator/Prompts im Admin-Panel; Upload/JSON-Paste für eigene Fragensets mit Validierung und Zeitlimit-Cleanup.\n\n### Formel-Cache (Disk) \u0026 automatische Eviction\n\nDie App cached gerenderte LaTeX-Formel-Bilder als PNG-Dateien auf der lokalen Festplatte, um Netzwerkaufrufe zur Remote-Render-API zu reduzieren und Exporte zu beschleunigen. Damit der Cache auf Hosts mit begrenztem oder ephemerem Speicher (z. B. Streamlit Community Cloud) nicht unkontrolliert wächst, gibt es automatische Eviction-Mechanismen.\n\nKonfigurierbare Umgebungsvariablen:\n\n- FORMULA_CACHE_DIR: Pfad zum Cache-Verzeichnis (Standard: ./var/formula_cache)\n- FORMULA_RENDER_PARALLEL: Anzahl paralleler Render-Jobs für Formeln (Standard: 6)\n- FORMULA_CACHE_MAX_FILES: Maximale Anzahl Dateien im Cache (Standard: 100)\n- FORMULA_CACHE_MAX_MB: Maximale Gesamtgröße des Caches in MiB (Standard: 50)\n- FORMULA_CACHE_TTL_DAYS: Lebensdauer von Cache-Dateien in Tagen (Standard: 7)\n\nVerhalten:\n\n- Vor jedem Schreiben einer neuen Formeldatei wird die Eviction-Routine ausgeführt: Dateien älter als TTL werden zuerst entfernt; danach werden die ältesten Dateien gelöscht, bis sowohl Dateianzahl als auch Gesamtgröße innerhalb der Grenzwerte liegen.\n- Auf schreibgeschützten oder nicht verfügbaren Dateisystemen werden Schreibfehler ignoriert und die In-Memory-Fallback-Strategie verwendet. Das verhindert Abstürze auf restriktiven Plattformen.\n\nEmpfehlung: Setze konservative Limits für Cloud-Deploys (z. B. FORMULA_CACHE_MAX_MB=50, FORMULA_CACHE_MAX_FILES=100) und überwache die Nutzung in Logs.\n\n\n---\n\n## 🔐 Security Features\n\nDie MC-Test-App setzt auf folgende Sicherheitsmaßnahmen (Versionen werden hier bewusst nicht aufgelistet):\n\n- Kryptographische Session-Tokens (`secrets.token_urlsafe(32)`) mit serverseitigem SHA-256-Hashing (user_id + admin_key + token) statt Klartext im Session-State; Re-Auth vor kritischen Aktionen.\n- Session-Handling mit Inaktivitäts-Timeout (2 Stunden) und Threading-Locks für sicheren Concurrent Access.\n- Rate-Limiting für Login/Wiederherstellung (z. B. 3 Fehlversuche → temporäre Sperre, Reset nach Erfolg).\n- SQLite-basiertes Audit-Logging aller Admin-Aktionen inkl. Erfolg/Fehlschlag, CSV-Export und Dashboard-Statistiken.\n- DSGVO-orientierte Aufbewahrung via Cleanup-Tool (empfohlen: 90 Tage) und optionales Client-IP-Tracking.\n- Warnungen bei leerem/unsicherem Admin-Key.\n\n**Security Level:** 🛡️ **VERY HIGH (Enterprise-Grade)**\n\n**Dokumentation:**\n- 📘 [SECURITY_PHASE3_SUMMARY.md](SECURITY_PHASE3_SUMMARY.md) - Technische Details\n- 📋 [CHANGELOG_SECURITY_PHASE3.md](CHANGELOG_SECURITY_PHASE3.md) - Vollständiger Changelog\n- 📄 [PHASE3_ABSCHLUSS.md](PHASE3_ABSCHLUSS.md) - User-Guide\n\n---\n\n## 📋 Voraussetzungen\n\n- **Python:** 3.10–3.12 (empfohlen 3.12).\n- **Abhängigkeiten:** Installiere via `pip install -r requirements.txt`.\n\n---\n\n## 🛠️ Installation und Start\n\n### Lokaler Start\n\n1.  Klone das Repository.\n2.  Installiere die Abhängigkeiten:\n    ```bash\n    pip install -r requirements.txt\n    ```\n3.  Starte die App:\n    ```bash\n    streamlit run app.py\n    ```\n4.  Öffne [http://localhost:8501](http://localhost:8501) im Browser.\n\n### Deployment (z. B. Streamlit Cloud)\n\n1.  Verbinde dein GitHub-Repository mit deinem Streamlit-Cloud-Konto.\n2.  Deploye die App.\n3.  Konfiguriere die Secrets (siehe nächster Abschnitt) im Dashboard deiner Streamlit-Cloud-App.\n\n---\n\n## ⚙️ Konfiguration\n\n### Umgebungsvariablen / Secrets\n\nDie App wird über Umgebungsvariablen (für sensible Daten) und eine Konfigurationsdatei (für nicht-sensible Daten) konfiguriert.\n\nFür die lokale Entwicklung kannst du eine `.env`-Datei erstellen. Für das Deployment auf Streamlit Cloud müssen diese Variablen als \"Secrets\" im Dashboard der App hinterlegt werden.\n\n```env\n# Beispiel für .env oder Streamlit Cloud Secrets\nMC_TEST_ADMIN_USER=\"dein_admin_user\"\nMC_TEST_ADMIN_KEY=\"dein_geheimes_passwort\"\nAPP_URL=\"https://ihre-streamlit-app.streamlit.app\"\n```\n\n\n- **`MC_TEST_ADMIN_USER`**: Benutzername für den Admin-Login.\n- **`MC_TEST_ADMIN_KEY`**: Passwort für den Admin-Login.\n- **`MC_NEXT_COOLDOWN_NORMALIZATION_FACTOR`**: Optionaler Skalierungsfaktor für die Wartezeit beim Klick auf „Nächste Frage“ nach dem Lesen von Erklärungen. Standard: `0.3` (reduziert die Extras); Werte \u003c 1.0 verkürzen die Cooldowns weiter.\n- **`APP_URL`**: URL der Streamlit-App für den QR-Code im PDF-Export. (Default: `https://mc-test-amalea.streamlit.app`)\n\nZusätzliche Secrets / Umgebungsvariablen (kurz erklärt):\n\n- **`MC_TEST_DURATION_MINUTES`**: Optionaler Default für die Testdauer (in Minuten) wenn nicht im Fragenset-Meta angegeben. (Default: `60`; leer/0 = kein Zeitlimit)\n- **`MC_USER_QSET_CLEANUP_HOURS`**: Wie viele Stunden temporäre, von Nutzern hochgeladene Fragensets als \"stale\" gelten und automatisch beim Laden der Startseite entfernt werden können. (Default: `24`)\n- **`MC_USER_QSET_RESERVED_RETENTION_DAYS`**: Aufbewahrungsdauer (Tage) für temporäre Sets reservierter Pseudonyme. (Default: `14`)\n- **`MC_AUTO_RELEASE_PSEUDONYMS`**: Bei `1/true` werden unreservierte Pseudonyme nach Inaktivität automatisch freigegeben. (Default: aktiviert)\n- **`MC_RATE_LIMIT_ATTEMPTS`**: Anzahl erlaubter fehlgeschlagener Login-/Wiederherstellungs-Versuche bevor Rate-Limiting greift. (Default: `3`)\n- **`MC_RATE_LIMIT_WINDOW_MINUTES`**: Fenstergröße in Minuten für das Rate-Limit. (Default: `5`)\n- **`MC_RECOVERY_MIN_LENGTH`**: Minimale Länge für ein Wiederherstellungs-Geheimwort (Default: `6`).\n- **`MC_RECOVERY_ALLOW_SHORT`**: Falls gesetzt auf `1`/`true`, werden kürzere Wiederherstellungs-Geheimwörter erlaubt.\n- **`EXPORT_COOLDOWN_SECONDS`**: Wartezeit nach einem Export im Admin-Panel (Default: `300` Sekunden).\n- **`EXPORT_JOB_WORKERS`**: Anzahl paralleler Export-Worker im Export-Job-Skript (Default: `2`).\n- **`EXPORTS_DIR`**: Zielverzeichnis für Exporte im Export-Job-Skript (Default: `./exports`).\n- **`ARSNOVA_MAX_OPTION_LENGTH`**: Max. Antwortlänge für ARSnova-Export (Default: `120` Zeichen).\n- **`BENCH_EXPORTS_N`**: Anzahl PDF-Exporte im Benchmark-Skript (Default: `5`).\n\nHinweis: Du kannst diese Werte lokal in einer `.env` Datei setzen (z.B. für die Entwicklung) oder als Secrets in deiner Deployment-Umgebung (z. B. Streamlit Cloud). Die App liest zuerst Streamlit-Secrets, dann Umgebungsvariablen und schließlich die lokale JSON-Konfiguration `mc_test_config.json`.\n\n`mc_test_config.json` (nicht-sensitiv, wird zuletzt ausgewertet) kann u. a. folgende Felder enthalten: `scoring_mode`, `show_top5_public`, `test_duration_minutes`, `recovery_min_length`, `recovery_allow_short`, `rate_limit_attempts`, `rate_limit_window_minutes`, `next_cooldown_normalization_factor`, `user_qset_cleanup_hours`, `user_qset_reserved_retention_days`.\n\n### 🌐 Sprache / Locale\n\n- Die App liest die Sprache nicht aus URL-Query-Parametern (z. B. `?lang=de`).\n- Sprache wird ausschließlich über den UI-Sprachselektor gesteuert und in der Session gespeichert.\n- Möchtest du das Standardverhalten ändern, passe den Default in `i18n/__init__.py` (`_DEFAULT_LOCALE`) an.\n\n\nKurzes Beispiel: Setzen des Cleanup-Timeouts\n\nLokale Shell (temporär für die laufende Shell):\n\n```bash\nexport MC_USER_QSET_CLEANUP_HOURS=1  # Temporäre Fragensets älter als 1 Stunde gelten als stale\nstreamlit run app.py\n```\n\nBeispiel: Setzen des Normalisierungsfaktors in der Shell (temporär):\n\n```bash\nexport MC_NEXT_COOLDOWN_NORMALIZATION_FACTOR=0.5\nstreamlit run app.py\n```\n\nAls Streamlit-Cloud-Secret (im Secrets-Editor):\n\n```yaml\n# Im Secrets-Editor der Streamlit-App hinzufügen\nMC_NEXT_COOLDOWN_NORMALIZATION_FACTOR: \"0.5\"\n```\n\nAls Streamlit-Cloud-Secret (YAML / UI):\n\n```yaml\n# Im Secrets-Editor der Streamlit-App hinzufügen\nMC_USER_QSET_CLEANUP_HOURS: \"1\"\n```\n\nHinweis: Die App priorisiert Werte in dieser Reihenfolge: Streamlit-Secrets → Umgebungsvariablen → `mc_test_config.json`.\n\n---\n\n## 📁 Projektstruktur\n\n```\n.\n├── .github/                 # CI/CD Workflows\n├── .streamlit/              # Streamlit-Themes/Config\n├── artifacts/               # Export-Artefakte \u0026 Beispiel-SVGs\n├── data/                    # Fragensets (JSON), Pseudonyme, Glossare\n├── data-user/               # Temporäre User-Uploads (bereinigbar)\n├── db/                      # SQLite-Datenbank(en) + Test-WALs\n├── docs/                    # Slides, Handouts, Feasibility-Studien\n├── examples/                # Beispiel-Configs/Prompts\n├── exporters/               # Export-Logik (Anki, CSV, PDF-Helfer)\n├── helpers/                 # Hilfsfunktionen (PDF, Caching, Validierung)\n├── i18n/                    # Sprachdateien und Defaults\n├── orga/                    # Orga-Dokumente \u0026 KI-Nutzungsguides\n├── scripts/                 # Build/CI-Helper (z.B. Key-Extraktion)\n├── teams/                   # Team-/Stakeholder-Material\n├── tests/                   # Pytest-Suite\n├── tools/                   # Lokale Dev-Skripte (Bench, Cache, Export)\n├── var/                     # Cache-Verzeichnisse (z.B. Formel-Cache)\n├── .env.example             # Beispiel-Env (nicht eingecheckter .env)\n├── mc_test_config.json      # Nicht-sensitive Default-Konfiguration\n├── anki_serif.apkg          # Beispiel-Anki-Deck\n├── logo.jpg                 # Logo der App\n├── admin_panel.py           # Admin-Panel inkl. Audit/Ratelimit\n├── app.py                   # Streamlit-Einstiegspunkt\n├── auth.py                  # Authentifizierung \u0026 Session-Management\n├── components.py            # Wiederverwendbare UI-Komponenten\n├── config.py                # Laden der Konfiguration und Fragensets\n├── database.py              # SQLite-Interaktionen\n├── logic.py                 # Kernlogik (Scoring, Navigation, Status)\n├── main_view.py             # UI-Logik für die Hauptansichten\n├── pdf_export.py            # PDF-Report-Generierung mit LaTeX \u0026 Glossar\n├── pacing_helper.py         # Pace-/Cooldown-Helfer\n├── session_manager.py       # Session-State-Verwaltung\n├── question_set_validation.py# Validierung von Fragensets\n├── validate_sets.py         # CLI-Validator für Fragensets\n├── requirements.txt         # Python-Abhängigkeiten\n├── AI_QUESTION_GENERATOR_PLAN.md   # Plan für KI-basierte Fragenset-Generierung\n├── DEPLOYMENT_FEASIBILITY_STUDY.md # Infrastruktur \u0026 Kostenanalyse\n├── GLOSSARY_SCHEMA.md              # Mini-Glossar-Schema\n├── VISION_RELEASE_2.0.md           # Strategische Vision \u0026 Roadmap\n└── README.md                       # Diese Dokumentation\n```\n\n---\n\n## 📊 Repository-Größe \u0026 Statistiken\n\n**Wie groß ist dieses Repository?**\n\n| Metrik                    | Wert                |\n|---------------------------|---------------------|\n| 📦 Gesamtgröße            | ~535 MB             |\n| 📂 Git-Historie           | ~513 MB             |\n| 📄 Dateien gesamt         | 313 Dateien         |\n| 🐍 Python-Dateien         | 100 Dateien         |\n| 📝 Markdown-Dokumentation | 107 Dateien         |\n| 🗂️ JSON-Dateien           | 60 Dateien          |\n| 💻 Python-Codezeilen      | ~33 200 Zeilen      |\n| 📁 Hauptverzeichnisse     | 17 Verzeichnisse    |\n\n**Hinweis:** Messung: tracked Dateien (~21 MB) plus `.git` (~513 MB) → ~535 MB Gesamtgröße; lokale `.venv`-/Cache-Ordner sind nicht berücksichtigt. Die Statistiken können sich mit der Weiterentwicklung des Projekts ändern.\n\n---\n\n## 🧰 Developer tools (local)\n\nEs gibt kleine Hilfs-Skripte zum Testen und Benchmarking im Ordner `tools/`:\n\n- `tools/test_evict.py` — Erzeugt Dummy-Dateien im Cache (`var/formula_cache`) und testet die Eviction-Routine.\n- `tools/run_export_test.py` — Führt einen einzelnen Musterlösungs-Export durch und schreibt das PDF nach `exports/`.\n- `tools/benchmark_exports.py` — Führe N Exporte hintereinander aus (Standard N=5) und schreibe eine `exports/benchmark_summary.txt`.\n- `tools/check_export_stems.py` — Prüft die Dateinamen-Generierung für Exporte (Slug-Logik wie in der App).\n- `tools/print_cooldowns.py` — Druckt alle Cooldown-Varianten pro Gewichtung/Tempo mit aktuellem Normalisierungsfaktor.\n\nBeispiele:\n\n```bash\n# Eviction smoke test\nPYTHONPATH=. python3 tools/test_evict.py\n\n# Single export (shows progress)\nPYTHONPATH=. python3 tools/run_export_test.py\n\n# Benchmark with 5 runs\nBENCH_EXPORTS_N=5 PYTHONPATH=. python3 tools/benchmark_exports.py\n\n# Check export filename stems (slug logic)\nPYTHONPATH=. python3 tools/check_export_stems.py\n\n# Inspect cooldown table with current normalization\nPYTHONPATH=. python3 tools/print_cooldowns.py\n```\n\n---\n\n## 🧭 Hinweise zum Prompting (für AI / Text‑Generierung)\n\n- Folge strikt dem 5‑Schritte-Konfig-Flow aus `KI_PROMPT.md`: 1) Thema, 2) Zielgruppe, 3) Fragenanzahl + Verteilung Gewichte 1–3, 4) Optionsanzahl (A/B/C), 5) Kontextmaterial. Immer nur eine Frage stellen, Unklarheiten zuerst klären.\n- Vor der Generierung: Zusammenfassung der 5 Konfigs in Nutzersprache anzeigen und explizit Bestätigung abwarten („ja/yes“). Keinen JSON ausgeben, bevor bestätigt wurde.\n- Sprache: Nutzer*innen-Sprache für Inhalte, JSON-Schlüssel bleiben Englisch. Gewichte → kognitive Stufen zwingend: 1=Reproduction, 2=Application, 3=Analysis; `answer` ist 0-basiert.\n- Blueprinting vor JSON: `\u003cscratchpad\u003e` mit Planung (Verteilung, Themen, Optionenzahl bei C, Dauerberechnung). Danach genau ein ```json```-Block, kein weiterer Text.\n- Schema-Pflicht: Fragen mit führender Nummer `\"1. \"`, Optionsanzahl gemäß A/B/C, `difficulty_profile` = Summe der Gewichte, `test_duration_minutes` aus `time_per_weight_minutes` (Standard: 0.5/0.75/1.0) + Buffer 5.\n- Qualitätsregeln: Distraktoren plausibel und ähnlich lang, kein „All/None of the above“. Mini-Glossar pro Frage (6–10 sinnvolle Terme). `extended_explanation`: `null` bei Gewicht 1, Objekt mit 2–6 Schritten bei Gewicht 2/3.\n- Code/LaTeX: Code immer mit ```lang``` und Zeilennummern innerhalb des JSON-Strings (`\\n` nutzen); LaTeX doppelt escapen (`\\\\det`), Inline-Math `$...$`. Echte Leerzeilen statt des Literal-Strings `\"\\\\n\"`.\n- Artefakte landen in `exports/` und sind `.gitignore`-geschützt.\n\n---\n\n## 🛠️ Administration \u0026 Wartung\n\n### Admin-Bereich\n\n- **Zugang:**\n    1. Wähle auf der Startseite das in den Secrets (`MC_TEST_ADMIN_USER`) definierte Admin-Pseudonym aus.\n    2. Nach dem Start des Tests erscheint in der Seitenleiste der Bereich \"🔐 Admin Panel\".\n    3. Gib dort das Admin-Passwort (`MC_TEST_ADMIN_KEY`) ein, um vollen Zugriff zu erhalten.\n- **Funktionen:** Das Panel bietet detaillierte Analysen (Item- \u0026 Distraktoranalyse), eine Übersicht und Verwaltung für gemeldetes Feedback, Datenexport (CSV, SQL-Dump, **PDF-Export**) und Systemeinstellungen (Scoring-Modus, Zurücksetzen der Testdaten).\n\n### Tests ausführen\n\n```bash\npip install -r requirements.txt\nPYTHONPATH=. pytest\n```\n\n---\n\n## 🐛 Troubleshooting\n\n-   **App startet nicht:** Stelle sicher, dass alle Abhängigkeiten aus `requirements.txt` installiert sind.\n\n---\n\n## 🤝 Contributing\n\n\nBeiträge sind willkommen! Forke das Repository, erstelle einen Branch und öffne einen Pull Request.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkqc-real%2Fstreamlit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkqc-real%2Fstreamlit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkqc-real%2Fstreamlit/lists"}