TriuneCadence/composer_ans/classical_rules.py

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)