"""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