35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import asdict
|
|
import json
|
|
|
|
from .analysis import CompositionAnalysis, analyze_composition
|
|
from .types import CompositionRecord, CompositionRunReport
|
|
|
|
|
|
def build_run_report(
|
|
record: CompositionRecord,
|
|
*,
|
|
alphabet_size: int = 8,
|
|
parameters: dict[str, object] | None = None,
|
|
) -> CompositionRunReport:
|
|
analysis = analyze_composition(record.notes, alphabet_size=alphabet_size)
|
|
return CompositionRunReport(
|
|
notes=record.notes,
|
|
per_note_seconds=record.per_note_seconds,
|
|
total_seconds=record.total_seconds,
|
|
parameters=parameters or {},
|
|
note_count=analysis.note_count,
|
|
alphabet_size=analysis.alphabet_size,
|
|
unigram_entropy_bits=analysis.unigram_entropy_bits,
|
|
conditional_entropy_bits=analysis.conditional_entropy_bits,
|
|
normalized_entropy=analysis.normalized_entropy,
|
|
predictability=analysis.predictability,
|
|
redundancy=analysis.redundancy,
|
|
)
|
|
|
|
|
|
def save_run_report_json(report: CompositionRunReport, path: str) -> None:
|
|
with open(path, "w", encoding="utf-8") as handle:
|
|
json.dump(asdict(report), handle, indent=2)
|