Download src/analysis/difficulty_analyzer.py from InternsProgressUpdate/Venket: direct link, hf CLI and curl.
- Browser
- Download file 2.52 kB
-
https://huggingface.co/InternsProgressUpdate/Venket/resolve/main/src/analysis/difficulty_analyzer.py
- Command line
-
hf download hf://InternsProgressUpdate/Venket/src/analysis/difficulty_analyzer.py
-
curl -L -o difficulty_analyzer.py https://huggingface.co/InternsProgressUpdate/Venket/resolve/main/src/analysis/difficulty_analyzer.py
2.52 kB
| """Computes the deterministic difficulty score from post-render geometry metrics. | |
| Pure function of :class:`~src.analysis.geometry_analyzer.GeometryResult` and | |
| the configured weights -- no randomness is involved, so the score is | |
| trivially reproducible given identical geometry inputs. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| import numpy as np | |
| from src.analysis.geometry_analyzer import GeometryResult | |
| from src.config.schema import DifficultyWeights | |
| from src.utils.geometry_utils import clamp01 | |
| class DifficultyResult: | |
| """The five difficulty components, the weighted score, and its tier.""" | |
| misplacement: float | |
| whitespace: float | |
| faintness: float | |
| smallness: float | |
| low_texture: float | |
| score: float | |
| tier: str | |
| class DifficultyAnalyzer: | |
| """Computes the exact spec-defined difficulty score and tier. | |
| ``score = 0.35*misplacement + 0.20*whitespace + 0.20*faintness + 0.15*smallness + 0.10*low_texture`` | |
| Example: | |
| >>> analyzer = DifficultyAnalyzer(cfg.difficulty) | |
| >>> result = analyzer.analyze(geometry_result) | |
| """ | |
| def __init__(self, weights: DifficultyWeights) -> None: | |
| self.weights = weights | |
| def analyze(self, geometry: GeometryResult) -> DifficultyResult: | |
| """Compute the difficulty components, weighted score, and tier for one sample.""" | |
| w = self.weights | |
| misplacement = clamp01(1.0 - geometry.polygon_overlap_proxy) | |
| whitespace = clamp01(geometry.whitespace_ratio) | |
| faintness = clamp01((geometry.mean_dark_intensity - 90.0) / 120.0) | |
| smallness = clamp01(1.0 - geometry.signature_area_ratio / 0.04) | |
| low_texture = clamp01(1.0 - geometry.gray_stddev / 60.0) | |
| score = ( | |
| w.misplacement * misplacement | |
| + w.whitespace * whitespace | |
| + w.faintness * faintness | |
| + w.smallness * smallness | |
| + w.low_texture * low_texture | |
| ) | |
| score = float(np.clip(score, 0.0, 1.0)) | |
| if score < w.easy_threshold: | |
| tier = "easy" | |
| elif score < w.hard_threshold: | |
| tier = "medium" | |
| else: | |
| tier = "hard" | |
| return DifficultyResult( | |
| misplacement=round(misplacement, 4), | |
| whitespace=round(whitespace, 4), | |
| faintness=round(faintness, 4), | |
| smallness=round(smallness, 4), | |
| low_texture=round(low_texture, 4), | |
| score=round(score, 4), | |
| tier=tier, | |
| ) | |