app/app.py aktualisiert

This commit is contained in:
sascha 2026-01-28 21:39:21 +00:00
parent 8ce68eddd2
commit d4e3dd4a92

View File

@ -34,10 +34,9 @@ def init_db():
cur.close()
conn.close()
# Start-Initialisierung
init_db()
# --- HELPER FUNKTIONEN ---
# --- HELPER ---
def is_middle_relevant(text):
if not text: return False
@ -50,13 +49,14 @@ def is_middle_relevant(text):
return True
def clean_german_answers(text):
# Alles in Klammern entfernen und splitten
text = re.sub(r'\(.*?\)', '', text)
text = re.sub(r'\[.*?\]', '', text)
parts = re.split(r'[;,]', text)
return [p.strip() for p in parts if p.strip()]
def check_middle_logic(user_in, correct):
"""Prüft auf Unvollständigkeit (Komma-Trennung)"""
"""Prüft Grammatik (erlaubt unvollständige Eingaben)"""
u = user_in.strip().lower()
c = correct.strip().lower()
@ -69,27 +69,34 @@ def check_middle_logic(user_in, correct):
if not u_parts: return 'wrong'
# Sind alle eingegebenen Teile in der Lösung vorhanden?
all_user_parts_correct = all(p in c_parts for p in u_parts)
if all_user_parts_correct:
# Wenn weniger Teile als nötig -> unvollständig
if len(u_parts) < len(c_parts):
return 'incomplete'
return 'correct'
# Tippfehler-Check
ratio = SequenceMatcher(None, u, c).ratio()
if ratio > 0.85: return 'typo'
return 'wrong'
def check_string_match(user_in, correct):
"""Standard String Vergleich"""
u = user_in.strip().lower()
c = correct.strip().lower()
if not u: return 'wrong'
if u == c: return 'correct'
ratio = SequenceMatcher(None, u, c).ratio()
if ratio > 0.85: return 'typo'
return 'wrong'
# --- ROUTEN ---
# --- ROUTES ---
@app.route('/')
def index():
@ -103,15 +110,11 @@ def get_lessons():
rows = cur.fetchall()
cur.close()
conn.close()
lessons = [r[0] for r in rows]
# Sortierung: Erst Zahlen, dann Strings, "Original" ganz hinten
def sort_key(val):
if val.isdigit(): return (0, int(val))
if val.startswith("Original"): return (2, val)
return (1, val)
lessons.sort(key=sort_key)
return jsonify(lessons)
@ -158,34 +161,69 @@ def check():
inputs = data.get('inputs', [])
attempt_num = data.get('attempt', 1)
results = []
total_items = len(inputs)
# Wir initialisieren die Ergebnis-Liste mit "falsch", damit wir sie später füllen können
results = [None] * len(inputs)
correct_items = 0
total_items = len(inputs)
has_incomplete = False
for inp in inputs:
user_val = inp.get('value', '')
correct_val = inp.get('correct', '')
field_type = inp.get('type', 'german')
# 1. GRAMMATIK (Mitte) direkt prüfen (feste Position)
for i, inp in enumerate(inputs):
if inp.get('type') == 'middle':
status = check_middle_logic(inp.get('value', ''), inp.get('correct', ''))
msg = 'Unvollständig! Da fehlt noch etwas.' if status == 'incomplete' else ''
if status == 'incomplete': has_incomplete = True
status = 'wrong'
results[i] = {'status': status, 'correct': inp.get('correct', ''), 'msg': msg}
if status in ['correct', 'typo']: correct_items += 1
if field_type == 'middle':
status = check_middle_logic(user_val, correct_val)
else:
status = check_string_match(user_val, correct_val)
# 2. DEUTSCH (German) - Pool-Logik für Reihenfolge-Unabhängigkeit
res_entry = {'status': status, 'correct': correct_val}
# Sammle alle deutschen User-Eingaben und ihre Indizes
german_user_inputs = [] # Liste von {'index': 1, 'value': '...'}
# Sammle alle korrekten deutschen Lösungen (Pool)
german_correct_pool = []
if status == 'incomplete':
res_entry['msg'] = 'Unvollständig! Da fehlt noch etwas.'
has_incomplete = True
for i, inp in enumerate(inputs):
if inp.get('type') == 'german' or inp.get('type') is None:
german_user_inputs.append({'index': i, 'value': inp.get('value', '')})
german_correct_pool.append(inp.get('correct', ''))
results.append(res_entry)
# Welche Pool-Einträge wurden schon "verbraucht"?
used_pool_indices = set()
# Jetzt prüfen wir jede User-Eingabe gegen den GANZEN Pool
for u_item in german_user_inputs:
idx = u_item['index']
val = u_item['value']
found_match = False
matched_correct_val = ""
# Suche im Pool nach einem Match, der noch nicht benutzt wurde
for pool_i, pool_val in enumerate(german_correct_pool):
if pool_i in used_pool_indices:
continue
# Standard Prüfung für Deutsch
status = check_string_match(val, pool_val)
if status in ['correct', 'typo']:
# Treffer!
results[idx] = {'status': status, 'correct': pool_val}
used_pool_indices.add(pool_i) # Lösung als "benutzt" markieren
correct_items += 1
found_match = True
break
# Wenn KEIN Match im Pool gefunden wurde
if not found_match:
# Wir zeigen als Lösung einfach die an, die ursprünglich an dieser Position stand
# (auch wenn die Position eigentlich egal ist, irgendwas müssen wir anzeigen)
original_correct = inputs[idx].get('correct', '')
results[idx] = {'status': 'wrong', 'correct': original_correct}
# Punkteberechnung
score_fraction = 0
if total_items > 0:
base_score = correct_items / total_items
@ -203,4 +241,5 @@ def check():
})
if __name__ == '__main__':
# Production settings
app.run(host='0.0.0.0', port=5000)