first commit
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""Likert scale scoring storage and aggregation."""
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models import Result
|
||||
|
||||
|
||||
def save_likert_score(db: Session, run_id: str, score: int) -> Result:
|
||||
if not 1 <= score <= 5:
|
||||
raise ValueError("Likert score must be between 1 and 5")
|
||||
result = db.query(Result).filter_by(run_id=run_id).first()
|
||||
if not result:
|
||||
raise ValueError(f"Result not found for run {run_id}")
|
||||
result.likert_score = score
|
||||
db.commit()
|
||||
db.refresh(result)
|
||||
return result
|
||||
|
||||
|
||||
def aggregate_likert_by_model_and_level(db: Session) -> Dict[str, Dict[str, Dict[str, float]]]:
|
||||
"""Aggregate Likert scores by model_id and level.
|
||||
|
||||
Returns mean and frequency distribution per (model, level).
|
||||
"""
|
||||
rows = (
|
||||
db.query(Result, ExperimentRun)
|
||||
.join(ExperimentRun, Result.run_id == ExperimentRun.id)
|
||||
.all()
|
||||
)
|
||||
|
||||
grouped: Dict[str, Dict[str, List[int]]] = {}
|
||||
for result, run in rows:
|
||||
if result.likert_score is None:
|
||||
continue
|
||||
key_model = run.model_id
|
||||
key_level = run.template_version.template.level
|
||||
grouped.setdefault(key_model, {}).setdefault(key_level, []).append(result.likert_score)
|
||||
|
||||
output = {}
|
||||
for model, levels in grouped.items():
|
||||
output[model] = {}
|
||||
for level, scores in levels.items():
|
||||
total = len(scores)
|
||||
output[model][level] = {
|
||||
"mean": round(sum(scores) / total, 2) if total else 0.0,
|
||||
"count": total,
|
||||
"distribution": {i: scores.count(i) for i in range(1, 6)},
|
||||
}
|
||||
return output
|
||||
|
||||
|
||||
from app.models import ExperimentRun # noqa: E402
|
||||
Reference in New Issue
Block a user