import pytest from chordparser.analysers.chords_analyser import ChordAnalyser from chordparser.editors.chords_editor import ChordEditor from chordparser.editors.keys_editor import KeyEditor from chordparser.editors.notes_editor import NoteEditor from chordparser.editors.scales_editor import ScaleEditor NE = NoteEditor() KE = KeyEditor() SE = ScaleEditor() CE = ChordEditor() CA = ChordAnalyser() @pytest.mark.parametrize( "chord, mode, incl_submodes, result", [ ("C", "major", True, [('I', 'major', None)]), ("C7", "major", False, [('I7', 'major', None)]), ("Cm", "minor", False, [('i', 'minor', 'natural')]), ("Cm", "minor", True, [('i', 'minor', 'natural'), ('i', 'minor', 'harmonic'), ('i', 'minor', 'melodic')]), ] ) def test_diatonic(chord, mode, incl_submodes, result): c = CE.create_chord(chord) s = SE.create_scale("C", mode) assert CA.analyse_diatonic(c, s, incl_submodes) == result @pytest.mark.parametrize(
class ScaleEditor: """A `Scale` editor that can create and change `Scales`. The `ScaleEditor` class can create a `Scale` from a `Key` or a `Key`'s notation. It can change the `Scale` by specifying a different `Key` it is based on. """ _KE = KeyEditor() def create_scale(self, value, *args, **kwargs): """Create a `Scale`. Specify either a `Key` or the parameters necessary to create a `Key`. Parameters ---------- value Either a `Key` or the first parameter for creating a `Key` (i.e. the `root`). *args : iterable The parameters for creating a `Key`. **kwargs : dict The keyword parameters for creating a `Key`. Returns ------- Scale The created `Scale`. See Also -------- chordparser.KeyEditor.create_key : See the necessary parameters for creating a `Key`. Examples -------- >>> SE = ScaleEditor() >>> KE = KeyEditor() >>> c_key = KE.create_key("C", "minor") >>> SE.create_scale(c_key) C natural minor scale >>> SE.create_scale("C", "major") C major scale """ if not isinstance(value, Key): key = self._KE.create_key(value, *args, **kwargs) else: key = value return Scale(key) def change_scale(self, scale, *args, inplace=True, **kwargs): """Change a `Scale` based on its `Key`. The parameters accepted are the same parameters accepted for changing a `Key`: the `root`, `mode` and `submode`. The `root` must be a valid `Note` notation if type `str`. The `submode` refers to the different types of 'minor'/ 'aeolian' mode, i.e. 'natural', 'harmonic' and 'melodic'. Hence, other than the 'minor'/ 'aeolian' `mode`, the `submode` must be None. Parameters ---------- scale : Scale The `Scale` which key you want to change. *args : iterable The parameters for changing the `Scale`'s `Key`. inplace : boolean, Optional Selector to change the current `Scale` or to return a new `Scale`. Default True when optional. **kwargs : dict The keyword parameters for changing the `Scale`'s `Key`. Returns ------- Scale The `Scale` with the new `Key`. Examples -------- >>> SE = ScaleEditor() >>> c = SE.create_scale("C", "major") >>> SE.change_scale(c, "D", "lydian") D lydian scale >>> SE.change_scale(c, "E", "dorian", inplace=False) E dorian scale >>> c D lydian scale """ if not inplace: scale = self.create_scale(scale.key) self._KE.change_key(scale.key, *args, **kwargs) scale.build() return scale