CoolFace
Apppublic

build-small-hackathon/hackathon-advisor

sourceHugging Facemitupdated 3mo agoView on Hugging Face
16likes
scoring.py90 linesDownload Raw Back to hackathon_advisor
1from __future__ import annotations2 3from dataclasses import dataclass4 5from hackathon_advisor.data import ProjectIndex, SearchHit, tokenize6 7 8@dataclass(frozen=True)9class ScoreCard:10    originality: int11    delight: int12    ai_necessity: int13    feasibility: int14    goal_fit: int15    verdict: str16    echoes: tuple[SearchHit, ...]17 18    @property19    def overall(self) -> float:20        return round(21            (22                self.originality * 0.3023                + self.delight * 0.2024                + self.ai_necessity * 0.2025                + self.feasibility * 0.1526                + self.goal_fit * 0.1527            ),28            1,29        )30 31    def to_dict(self) -> dict:32        return {33            "originality": self.originality,34            "delight": self.delight,35            "ai_necessity": self.ai_necessity,36            "feasibility": self.feasibility,37            "goal_fit": self.goal_fit,38            "overall": self.overall,39            "verdict": self.verdict,40            "echoes": [41                {42                    "score": round(hit.score, 3),43                    "page_number": hit.page_number,44                    "matched_terms": list(hit.matched_terms),45                    "project": hit.project.to_public_dict(),46                }47                for hit in self.echoes48            ],49        }50 51 52def score_idea(index: ProjectIndex, title: str, pitch: str, goals: list[str] | None = None) -> ScoreCard:53    text = f"{title} {pitch}".strip()54    hits = index.search(text, limit=4)55    top_overlap = hits[0].score if hits else 0.056    tokens = set(tokenize(text))57    goals = goals or []58 59    originality = clamp_score(10 - round(top_overlap * 18))60    delight = clamp_score(4 + _keyword_count(tokens, {"story", "visual", "game", "ritual", "share", "voice"}) * 2)61    ai_necessity = clamp_score(62        363        + _keyword_count(tokens, {"agent", "model", "embed", "search", "personal", "speech", "local"}) * 264    )65    complexity_penalty = _keyword_count(tokens, {"realtime", "video", "multiplayer", "payments", "social"})66    feasibility = clamp_score(8 - complexity_penalty)67    goal_fit = clamp_score(68        469        + _keyword_count(tokens, {"local", "offline", "small", "llama", "fine", "trace", "gradio"}) * 270        + min(len(goals), 3)71    )72    verdict = "UNWRITTEN" if top_overlap < 0.16 else f"ECHO x{sum(1 for hit in hits if hit.score >= 0.12)}"73    return ScoreCard(74        originality=originality,75        delight=delight,76        ai_necessity=ai_necessity,77        feasibility=feasibility,78        goal_fit=goal_fit,79        verdict=verdict,80        echoes=tuple(hits),81    )82 83 84def clamp_score(value: int) -> int:85    return max(1, min(10, value))86 87 88def _keyword_count(tokens: set[str], keywords: set[str]) -> int:89    return sum(1 for keyword in keywords if any(token.startswith(keyword) for token in tokens))90