Skip to content

Commit

Permalink
Dev (#180)
Browse files Browse the repository at this point in the history
* add chromatic rotations for compatability

* add empty intervalset

* wip

* Scale(name='empty') validation

* add row and col data to svg polygons for isomporphic keyboard
  • Loading branch information
tandav authored Sep 12, 2024
1 parent 9bd37f9 commit f71f34c
Show file tree
Hide file tree
Showing 31 changed files with 54 additions and 13 deletions.
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ repos:
- id: add-trailing-comma

- repo: https://github.com/asottile/pyupgrade
rev: v3.15.2
rev: v3.17.0
hooks:
- id: pyupgrade

Expand All @@ -42,26 +42,26 @@ repos:
- id: autoflake

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.4.7
rev: v0.6.4
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
rev: 7.1.1
hooks:
- id: flake8
additional_dependencies: [Flake8-pyproject, flake8-functions-names]

- repo: https://github.com/PyCQA/pylint
rev: v3.0.3
rev: v3.2.7
hooks:
- id: pylint
# additional_dependencies: ["pylint-per-file-ignores"]
# https://github.com/christopherpickering/pylint-per-file-ignores/issues/76

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
rev: v1.11.2
hooks:
- id: mypy
additional_dependencies:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ ignore = [
"PT011",
"PT023",
"N806",
"ICN001",
]

[tool.ruff.lint.isort]
Expand Down
5 changes: 2 additions & 3 deletions src/musiclib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@


name_to_intervals_kind_grouped = {
'chromatic_kind': {
'chromatic': {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
},
'chromatic': named_intervals_rotations({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 'chromatic'),
'emtykind': {'empty': set()},
'natural': {
'major': {0, 2, 4, 5, 7, 9, 11},
'dorian': {0, 2, 3, 5, 7, 9, 10},
Expand Down
2 changes: 1 addition & 1 deletion src/musiclib/midi/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def append_bar(noteset: SpecificNoteSet | None) -> None:
nonlocal t
for is_play in rhythm.notes:
if is_play:
notes = [note__.i] if noteset is None else [note.i for note in noteset.notes]
notes = [note__.i] if noteset is None else [note.i for note in noteset.notes] # pylint: disable=possibly-used-before-assignment
for i, note in enumerate(notes):
track.append(mido.Message('note_on', note=note, velocity=100, time=t if i == 0 else 0))
for i, note in enumerate(notes):
Expand Down
2 changes: 1 addition & 1 deletion src/musiclib/progression.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def transpose_unique_key(self, *, origin_name: bool = True) -> tuple[frozenset[i
origin = self[0][0] # pylint: disable=unsubscriptable-object
key = tuple(frozenset(note - origin for note in chord.notes) for chord in self)
if origin_name:
return origin.abstract.i, key
return origin.abstract.i, key # pylint: disable=no-member
return key

def __add__(self, other: int) -> Progression:
Expand Down
2 changes: 2 additions & 0 deletions src/musiclib/scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def __init__(self, root: Note, intervalset: IntervalSet) -> None:

@classmethod
def from_name(cls: type[Self], root: str | Note, name: str) -> Self:
if name == 'empty':
raise ValueError("name 'empty' is not allowed for Scale, because Scale should have at least 1 note (root note)")
if isinstance(root, str):
root = Note(root)
elif not isinstance(root, Note):
Expand Down
4 changes: 4 additions & 0 deletions src/musiclib/svg/isomorphic/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def add_key(self, row: float, col: float) -> None:
polygon.interval = interval # type: ignore[attr-defined]
polygon.abstract_interval = abstract_interval.interval # type: ignore[attr-defined]
polygon.abstract_interval_base12 = abstract_interval # type: ignore[attr-defined]
polygon.row = row # type: ignore[attr-defined]
polygon.col = col # type: ignore[attr-defined]
self.elements.append(polygon)

if self.n_parts is not None:
Expand All @@ -262,6 +264,8 @@ def add_key(self, row: float, col: float) -> None:
polygon.interval = interval # type: ignore[attr-defined]
polygon.abstract_interval = abstract_interval.interval # type: ignore[attr-defined]
polygon.abstract_interval_base12 = abstract_interval # type: ignore[attr-defined]
polygon.row = row # type: ignore[attr-defined]
polygon.col = col # type: ignore[attr-defined]
self.elements.append(polygon)

@abc.abstractmethod
Expand Down
2 changes: 1 addition & 1 deletion src/musiclib/svg/pianoroll.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(
self.piano = IsoPiano(
n_cols=len(self.sns),
interval_colors=dict.fromkeys(self.sns.intervals, config.WHITE_PALE),
interval_strokes=dict.fromkeys(self.sns.intervals, {'stroke': config.BLACK_PALE, 'stroke_width': 0.5}),
interval_strokes={i: {'stroke': config.BLACK_PALE, 'stroke_width': 0.5} for i in self.sns.intervals},
interval_text=FromIntervalDict({i: str(n) for i, n in zip(self.sns.intervals, self.sns.notes_ascending, strict=True)}),
radius=key_width // 2,
radius1=key_height // 2,
Expand Down
12 changes: 10 additions & 2 deletions src/musiclib/voice_leading/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,22 @@ def is_make_major_scale_leading_tone_resolving_semitone_up(
return tonic - leading_tone == 1


def is_large_spacing(c: SpecificNoteSet, max_interval: int = 12, /) -> bool:
def is_large_spacing_intervals(c: tuple[int, ...], max_interval: int = 12, /) -> bool:
return any(b - a > max_interval for a, b in itertools.pairwise(c))


def is_small_spacing(c: SpecificNoteSet, min_interval: int = 3, /) -> bool:
def is_small_spacing_intervals(c: tuple[int, ...], min_interval: int = 3, /) -> bool:
return any(b - a < min_interval for a, b in itertools.pairwise(c))


def is_large_spacing(c: SpecificNoteSet, max_interval: int = 12, /) -> bool:
return is_large_spacing_intervals(c.intervals, max_interval)


def is_small_spacing(c: SpecificNoteSet, min_interval: int = 3, /) -> bool:
return is_small_spacing_intervals(c.intervals, min_interval)


def find_paused_voices(a: SpecificNoteSet, b: SpecificNoteSet, n_notes: int) -> tuple[int, ...] | tuple[()]:
if n_notes == 0 or len(a) == len(b) == 0:
return ()
Expand Down
1 change: 1 addition & 0 deletions tests/cache_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import operator

import pytest

from musiclib.interval import AbstractInterval
from musiclib.intervalset import IntervalSet
from musiclib.note import Note
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import mido
import pytest

from musiclib.midi.parse import Midi
from musiclib.midi.parse import MidiNote
from musiclib.midi.parse import MidiPitch
Expand Down
1 change: 1 addition & 0 deletions tests/interval_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.interval import AbstractInterval


Expand Down
1 change: 1 addition & 0 deletions tests/intervalset_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.interval import AbstractInterval
from musiclib.intervalset import IntervalSet

Expand Down
1 change: 1 addition & 0 deletions tests/midi/parse_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import mido
import pytest

from musiclib.midi import parse
from musiclib.note import SpecificNote
from musiclib.noteset import SpecificNoteSet
Expand Down
1 change: 1 addition & 0 deletions tests/midi/pitchbend_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.midi import pitchbend
from musiclib.midi.parse import Midi
from musiclib.midi.parse import MidiNote
Expand Down
1 change: 1 addition & 0 deletions tests/midi/player_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.midi.player import Player
from musiclib.note import SpecificNote
from musiclib.noteset import SpecificNoteSet
Expand Down
1 change: 1 addition & 0 deletions tests/note_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import hypothesis.strategies as st
import pytest
from hypothesis import given

from musiclib.interval import AbstractInterval
from musiclib.note import Note
from musiclib.note import SpecificNote
Expand Down
1 change: 1 addition & 0 deletions tests/noteset_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from collections.abc import Sequence

import pytest

from musiclib import config
from musiclib.interval import AbstractInterval
from musiclib.note import Note
Expand Down
1 change: 1 addition & 0 deletions tests/pickle_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pickle

import pytest

from musiclib.interval import AbstractInterval
from musiclib.intervalset import IntervalSet
from musiclib.note import Note
Expand Down
1 change: 1 addition & 0 deletions tests/pitch_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.note import SpecificNote
from musiclib.pitch import Pitch

Expand Down
1 change: 1 addition & 0 deletions tests/progression_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections.abc import Sequence

import pytest

from musiclib.noteset import SpecificNoteSet
from musiclib.progression import Progression

Expand Down
1 change: 1 addition & 0 deletions tests/rhythm_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections import deque

import pytest

from musiclib.rhythm import Rhythm


Expand Down
6 changes: 6 additions & 0 deletions tests/scale_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import operator

import pytest

from musiclib import config
from musiclib.interval import AbstractInterval
from musiclib.intervalset import IntervalSet
Expand Down Expand Up @@ -82,6 +83,11 @@ def test_from_name(root, name, expected):
assert Scale.from_name(root, name) == expected


def test_empty_validation():
with pytest.raises(ValueError):
Scale.from_name(Note('C'), 'empty')


@pytest.mark.parametrize(
('scale', 'note_to_interval'), [
(Scale.from_str('CDE/C'), {Note('C'): AbstractInterval(0), Note('D'): AbstractInterval(2), Note('E'): AbstractInterval(4)}),
Expand Down
1 change: 1 addition & 0 deletions tests/specificnoteset_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections.abc import Sequence

import pytest

from musiclib import config
from musiclib.note import SpecificNote
from musiclib.noteset import NoteSet
Expand Down
1 change: 1 addition & 0 deletions tests/svg/isomorphic_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.svg.isomorphic.hexagonal import Hexagonal
from musiclib.svg.isomorphic.squared import Squared

Expand Down
1 change: 1 addition & 0 deletions tests/svg/piano_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import pytest
from colortool import Color

from musiclib import config
from musiclib.note import Note
from musiclib.note import SpecificNote
Expand Down
1 change: 1 addition & 0 deletions tests/svg/repr_svg_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from colortool import Color

from musiclib import config
from musiclib.noteset import NoteSet
from musiclib.noteset import SpecificNoteSet
Expand Down
1 change: 1 addition & 0 deletions tests/tempo_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import typing as tp

import pytest

from musiclib.tempo import Tempo


Expand Down
1 change: 1 addition & 0 deletions tests/util/etc_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.util import etc


Expand Down
1 change: 1 addition & 0 deletions tests/voice_leading/checks_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from musiclib.noteset import SpecificNoteSet
from musiclib.voice_leading import checks

Expand Down
1 change: 1 addition & 0 deletions tests/voice_leading/transition_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import itertools

import pytest

from musiclib.note import SpecificNote
from musiclib.noteset import NoteSet
from musiclib.noteset import SpecificNoteSet
Expand Down

0 comments on commit f71f34c

Please sign in to comment.