40 lines
954 B
Python
40 lines
954 B
Python
from dataclasses import dataclass
|
|
from typing import Tuple
|
|
|
|
from serato_doctor.models.reference import TrackReference
|
|
from serato_doctor.models.track import DiskTrack
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MatchEvidence:
|
|
"""One explainable scoring decision for a candidate track."""
|
|
|
|
field: str
|
|
matched: bool
|
|
points: int
|
|
max_points: int
|
|
explanation: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TrackMatch:
|
|
"""A ranked candidate backed by explicit, inspectable evidence."""
|
|
|
|
reference: TrackReference
|
|
track: DiskTrack
|
|
evidence: Tuple[MatchEvidence, ...]
|
|
|
|
@property
|
|
def score(self) -> int:
|
|
return sum(item.points for item in self.evidence)
|
|
|
|
@property
|
|
def max_score(self) -> int:
|
|
return sum(item.max_points for item in self.evidence)
|
|
|
|
@property
|
|
def score_percent(self) -> float:
|
|
if not self.max_score:
|
|
return 0.0
|
|
return round(self.score / self.max_score * 100, 1)
|