"""General, independently authored capabilities of the active action search.""" import dataclasses, unittest from fractions import Fraction as F from generator import model, vocabulary from generator.scales import selection, timeline from generator.solo import analysis, construction, harmonic, profiles, types, placement, operators from tests import solo_fixtures as fixtures, rhythm_fixtures, scale_fixtures def builder(symbols=('C7','FM7','Dm7','G7'),seed='independent',count=8): source=fixtures.song(count=count,chords=symbols);a=analysis.analyze(source);ms=source['staves'][0]['measures'] end=sum(model.fraction(m['duration']) for m in ms) cs=selection.select(timeline.read(source['staves'][0]),timeline.Solo(F(),end,'test'),scale_fixtures.library()) return construction.Builder(a,ms,harmonic.Harmony(cs,profiles.Instrument(reference=60)),fixtures.library(),rhythm_fixtures.library(),end,seed) class PhraseConstruction(unittest.TestCase): def test_candidates_include_open_motion_arrivals_and_joint_expression(self): b=builder(count=2);values=b.operators.at(F()) self.assertTrue(any(a.kind=='tone' and a.end==F(1,2) for a in values)) self.assertTrue(any(len(a.notes)==1 and a.end>=2 for a in values)) self.assertTrue(any(a.contracts for a in values)) for a in values: checked=b.harmony.evaluate(a.notes,until=a.end,complete=False,expressions=a.contracts) self.assertTrue(checked.valid,checked.error) evaluation=b.selector.evaluate(a) self.assertEqual(evaluation.total,sum(evaluation.contributions.values())) self.assertTrue(all(a.start<=n.start