update
This commit is contained in:
@@ -18,7 +18,8 @@ import db
|
||||
import guide
|
||||
import ledger
|
||||
import pipeline
|
||||
from config import FRONTEND_DIST, PROJECT_ROOT, topic_name_ok
|
||||
from config import (FRONTEND_DIST, PROJECT_ROOT, PRUEFUNG_PANEL, PRUEFUNG_SCHWELLE,
|
||||
topic_name_ok)
|
||||
from ws import hub
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s %(message)s")
|
||||
@@ -52,6 +53,11 @@ class UebenAntwort(BaseModel):
|
||||
richtig: bool
|
||||
|
||||
|
||||
class PruefungAntwort(BaseModel):
|
||||
ids: list[int] # die 4 Aussagen des Panels
|
||||
angekreuzt: list[int] # die als wahr markierten
|
||||
|
||||
|
||||
class AutoFlag(BaseModel):
|
||||
ebene: str
|
||||
an: bool
|
||||
@@ -252,6 +258,19 @@ async def ebene_entfernen(topic: str, ebene: str):
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@app.post("/api/topics/{topic}/ebene/{ebene}/aktualisieren")
|
||||
async def ebene_aktualisieren(topic: str, ebene: str, tief: bool = False):
|
||||
if not db.one("SELECT name FROM topics WHERE name=?", (topic,)):
|
||||
raise HTTPException(404, "unbekanntes Topic")
|
||||
try:
|
||||
run_id = pipeline.aktualisierung_starten(topic, ebene, tief=tief)
|
||||
except ValueError as e:
|
||||
raise HTTPException(400, str(e))
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(409, str(e))
|
||||
return {"run_id": run_id}
|
||||
|
||||
|
||||
@app.delete("/api/topics/{topic}")
|
||||
async def topic_loeschen(topic: str):
|
||||
if not db.one("SELECT name FROM topics WHERE name=?", (topic,)):
|
||||
@@ -315,6 +334,54 @@ def baustein_fertig(topic: str, baustein_id: int):
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@app.get("/api/topics/{topic}/baustein/{baustein_id}/pruefung")
|
||||
def pruefung_holen(topic: str, baustein_id: int):
|
||||
"""4er-Panels aus verifizierten Aussagen der Baustein-Atome. OHNE Wahrheitswert
|
||||
(Anti-Cheat) und ohne Paar-Partner im selben Panel (verraten sich gegenseitig)."""
|
||||
import random
|
||||
rows = db.query(
|
||||
"SELECT ar.id, ar.inhalt FROM artefakte ar JOIN atome a ON a.id=ar.atom_id"
|
||||
" WHERE a.topic=? AND a.baustein_id=? AND ar.typ='aussage'"
|
||||
" AND ar.status='verifiziert'", (topic, baustein_id))
|
||||
aussagen = [{"id": r["id"], "text": db.uj(r["inhalt"], {}).get("text", ""),
|
||||
"paar": db.uj(r["inhalt"], {}).get("paar", "")} for r in rows]
|
||||
random.shuffle(aussagen)
|
||||
panels: list[list[dict]] = []
|
||||
for a in aussagen: # greedy: erstes Panel ohne Paar-Konflikt mit Platz
|
||||
for p in panels:
|
||||
if len(p) < PRUEFUNG_PANEL and all(x["paar"] != a["paar"] for x in p):
|
||||
p.append(a)
|
||||
break
|
||||
else:
|
||||
panels.append([a])
|
||||
return [{"panel": [{"id": x["id"], "text": x["text"]} for x in p]}
|
||||
for p in panels if len(p) == PRUEFUNG_PANEL]
|
||||
|
||||
|
||||
@app.post("/api/topics/{topic}/pruefung/antwort")
|
||||
def pruefung_antwort(topic: str, a: PruefungAntwort):
|
||||
rows = db.query(f"SELECT ar.id, ar.inhalt, at.baustein_id FROM artefakte ar"
|
||||
f" JOIN atome at ON at.id=ar.atom_id"
|
||||
f" WHERE ar.id IN ({','.join('?' * len(a.ids))})", tuple(a.ids))
|
||||
if len(rows) != len(a.ids):
|
||||
raise HTTPException(404, "unbekannte Aussage")
|
||||
wahre = {r["id"] for r in rows if db.uj(r["inhalt"], {}).get("wahr")}
|
||||
richtig = set(a.angekreuzt) == wahre # exakte Teilmenge, sonst falsch
|
||||
baustein_id = rows[0]["baustein_id"]
|
||||
row = db.one("SELECT xp FROM lernstand WHERE topic=? AND baustein_id=?",
|
||||
(topic, baustein_id))
|
||||
xp = max(0, (row["xp"] if row else 0) + (1 if richtig else -1))
|
||||
status = "fertig" if xp >= PRUEFUNG_SCHWELLE else "aktiv"
|
||||
db.execute("INSERT INTO lernstand(topic, baustein_id, status, xp) VALUES(?,?,?,?)"
|
||||
" ON CONFLICT(topic, baustein_id) DO UPDATE SET xp=excluded.xp,"
|
||||
" status=excluded.status", (topic, baustein_id, status, xp))
|
||||
aufloesung = [{"id": r["id"], "wahr": db.uj(r["inhalt"], {}).get("wahr", False),
|
||||
"erklaerung": db.uj(r["inhalt"], {}).get("erklaerung", "")}
|
||||
for r in rows]
|
||||
return {"richtig": richtig, "aufloesung": aufloesung, "xp": xp,
|
||||
"fertig": xp >= PRUEFUNG_SCHWELLE}
|
||||
|
||||
|
||||
@app.get("/api/runs/{run_id}/kennzahlen")
|
||||
def kennzahlen(run_id: int):
|
||||
return {"zeilen": ledger.kennzahlen(run_id), "verbraucht": ledger.verbraucht(run_id)}
|
||||
|
||||
Reference in New Issue
Block a user