from __future__ import annotations from dataclasses import dataclass from pathlib import Path from .encoding import encode_note_sequence from .types import NoteSequence @dataclass(frozen=True) class ClassicalInstructor: sequences: tuple[str, ...] @classmethod def from_sequence_file(cls, path: str | Path) -> "ClassicalInstructor": sequence_path = Path(path) sequences = tuple( line.strip().rstrip("\x1a") for line in sequence_path.read_text(encoding="ascii").splitlines() if line.strip().rstrip("\x1a") ) return cls(sequences=sequences) def classify(self, notes: list[int] | tuple[int, ...]) -> int: target = "".join(str(note) for note in encode_note_sequence(notes)) for candidate in self.sequences: candidate_len = len(candidate) if target[-candidate_len:] == candidate: return 1 return 0 def __call__(self, notes: list[int] | tuple[int, ...]) -> int: return self.classify(notes)