34 lines
1.0 KiB
Python
34 lines
1.0 KiB
Python
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)
|