43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
"""Einfacher Qualitaets-Score (0-100) fuer ein Wissensdokument.
|
|
|
|
Heuristik (bewusst simpel, erweiterbar): Laenge, Wortanzahl, Struktur
|
|
(Ueberschriften/Listen/Tabellen). Dient als Orientierung auf der Pages-Seite;
|
|
spaeter optional als Gate-Schwelle (niedrig -> pending) nutzbar.
|
|
|
|
`quality_breakdown` liefert die Einzelpunkte transparent (fuer die Anzeige),
|
|
`quality_score` den gerundeten Gesamtwert.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
# Maximalpunkte je Kriterium (Summe = 100) - zentrale, transparente Definition.
|
|
WEIGHTS = {
|
|
"laenge": 45, # bis 1000 Zeichen
|
|
"woerter": 20, # bis 80 Woerter
|
|
"headings": 15, # mind. eine Ueberschrift (#)
|
|
"listen": 10, # mind. eine Liste (-/*/Nummer)
|
|
"tabellen": 10, # mind. eine Tabelle (|)
|
|
}
|
|
|
|
|
|
def quality_breakdown(text: str) -> dict:
|
|
"""Punkte je Kriterium + Gesamt (0-100), transparent nachvollziehbar."""
|
|
t = (text or "").strip()
|
|
if not t:
|
|
return {**{k: 0 for k in WEIGHTS}, "total": 0}
|
|
lines = t.splitlines()
|
|
parts = {
|
|
"laenge": round(min(len(t) / 1000.0, 1.0) * WEIGHTS["laenge"]),
|
|
"woerter": round(min(len(t.split()) / 80.0, 1.0) * WEIGHTS["woerter"]),
|
|
"headings": WEIGHTS["headings"] if any(ln.lstrip().startswith("#") for ln in lines) else 0,
|
|
"listen": WEIGHTS["listen"] if any(
|
|
ln.lstrip().startswith(("-", "*")) or ln.lstrip()[:2].isdigit() for ln in lines
|
|
) else 0,
|
|
"tabellen": WEIGHTS["tabellen"] if "|" in t else 0,
|
|
}
|
|
parts["total"] = int(min(sum(parts.values()), 100))
|
|
return parts
|
|
|
|
|
|
def quality_score(text: str) -> int:
|
|
return quality_breakdown(text)["total"]
|