update
This commit is contained in:
@@ -21,12 +21,40 @@ from textkit import _norm_titel
|
||||
|
||||
log = logging.getLogger("creator.lernen")
|
||||
|
||||
# Meilensteine je Baustein (Score 0–30). Form ergibt sich aus dem Score-Band:
|
||||
# 0–6 Quiz, 7–12 Lückentext, 13–18 Erklären, 19–30 frei.
|
||||
NOETIG = 6 # MiniGuide-Meilenstein → „absolviert" (Quiz-Band durch)
|
||||
MASTERY = 12 # Guide-Meilenstein → „verstanden" (Lückentext-Band durch)
|
||||
MEISTERN = 18 # ProGuide-Meilenstein → „gemeistert" (Erklären-Band durch, Thema fertig)
|
||||
MAX_VOLL = 30 # FullGuide-Maximum (freie Formwahl ab 18)
|
||||
# Lernstufen je Baustein — relativ zum cap (Floor in % des Maximal-Scores):
|
||||
# grün=Anfänger 20% · blau=Fortgeschritten 40% · lila=Experte 60% · gold=Meister 100%.
|
||||
# Prüfungsform ist immer zufällig (5 Formen); der cap skaliert mit der Stoffmenge.
|
||||
STUFEN = (("anfaenger", 0.2), ("fortgeschritten", 0.4), ("experte", 0.6), ("meister", 1.0))
|
||||
|
||||
|
||||
def cap_fuer(n_subs: int) -> int:
|
||||
"""Maximal-Score eines Bausteins: 2 Punkte je relevantem Subbaustein, gedeckelt [10, 50]."""
|
||||
return max(10, min(50, 2 * n_subs))
|
||||
|
||||
|
||||
def _schwelle(p: float, cap: int) -> int:
|
||||
return round(p * cap)
|
||||
|
||||
|
||||
def stufe_aus_score(score: int, cap: int) -> str | None:
|
||||
"""Höchste erreichte Stufe (None unter 20 %)."""
|
||||
erreicht = None
|
||||
for key, p in STUFEN:
|
||||
if score >= _schwelle(p, cap):
|
||||
erreicht = key
|
||||
return erreicht
|
||||
|
||||
|
||||
def progressiver_malus(basis: int, cap: int) -> int:
|
||||
"""Fehler-Strafe nach Fortschritt: 0–20 %→0 · 21–40 %→−1 · 41–60 %→−2 · 61–100 %→−3."""
|
||||
pct = (basis / cap) if cap else 0.0
|
||||
if pct <= 0.2:
|
||||
return 0
|
||||
if pct <= 0.4:
|
||||
return -1
|
||||
if pct <= 0.6:
|
||||
return -2
|
||||
return -3
|
||||
CHAT_TIMEOUT = 240
|
||||
PRUEFUNG_TIMEOUT = 120 # kurze JSON-Turns; deckelt die Serien-Latenz pro Prüfungs-Schritt
|
||||
GRUENDLICH_TIMEOUT = 600 # „Gründlich prüfen": starkes Modell (role guide) braucht länger
|
||||
@@ -54,30 +82,22 @@ NIVEAUS = {
|
||||
|
||||
def score_berechnen(basis: int, delta: int, floor: int, cap: int) -> int:
|
||||
"""Neuer Score · driftfrei aus der Basis. `delta` liefert die Route je Prüfungsform
|
||||
(Quiz +1/+3, Lückentext +1/+3, Erklären −1…+3; falsch −1). Auf [floor, cap] geklemmt.
|
||||
floor = höchster erreichter Meilenstein (6/12/18); cap = Max des höchsten Formats.
|
||||
Am Format-Deckel (basis ≥ cap) eingefroren: „Max" — weder + noch −, bis das nächste
|
||||
Format freischaltet. Bei cap 30 (FullGuide) bleibt 30 endgültig."""
|
||||
(Quiz +1/+3, Lückentext +1/+3, Erklären −1…+3; falsch = progressiver_malus). Auf
|
||||
[floor, cap] geklemmt. floor = höchste erreichte Stufenschwelle (kein Rückfall);
|
||||
cap = 2× relevante Subbausteine [10, 50]. Am Deckel (basis ≥ cap) eingefroren („Max")."""
|
||||
if basis >= cap:
|
||||
return basis
|
||||
return max(floor, min(cap, basis + delta))
|
||||
|
||||
|
||||
def _zufall_malus(basis: int, delta: int) -> int:
|
||||
"""Im Zufallband (Score ≥ MEISTERN=18, FullGuide) kostet jeder Fehler −3 statt −1 —
|
||||
die 30 erreicht man nur mit Sicherheit. Richtige Antworten bleiben unverändert."""
|
||||
return -3 if (basis >= MEISTERN and delta < 0) else delta
|
||||
|
||||
|
||||
def floor_aus_meilensteinen(absolviert: bool, verstanden: bool, gemeistert: bool) -> int:
|
||||
"""Untergrenze des Scores: ein erreichter Meilenstein hält (kein Rückfall ins Band davor)."""
|
||||
if gemeistert:
|
||||
return MEISTERN
|
||||
if verstanden:
|
||||
return MASTERY
|
||||
if absolviert:
|
||||
return NOETIG
|
||||
return 0
|
||||
def floor_aus_score(basis: int, cap: int) -> int:
|
||||
"""Untergrenze: höchste erreichte Stufenschwelle — kein Rückfall unter die Stufe."""
|
||||
floor = 0
|
||||
for _, p in STUFEN:
|
||||
s = _schwelle(p, cap)
|
||||
if basis >= s:
|
||||
floor = s
|
||||
return floor
|
||||
|
||||
|
||||
def _transcript(messages: list[dict]) -> str:
|
||||
|
||||
Reference in New Issue
Block a user