Source code for pychord.progression

from typing import Any

from .chord import Chord


[docs] class ChordProgression: """ A chord progression, which is a sequence of :class:`Chord` instances. :param initial_chords: Initial chord or chords of the chord progression. """ def __init__( self, initial_chords: str | Chord | list[str] | list[Chord] = [] ) -> None: if isinstance(initial_chords, Chord): chords = [initial_chords] elif isinstance(initial_chords, str): chords = [self._as_chord(initial_chords)] elif isinstance(initial_chords, list): chords = [self._as_chord(chord) for chord in initial_chords] else: raise TypeError( f"Cannot initialize ChordProgression with argument of {type(initial_chords)} type" ) self._chords: list[Chord] = chords def __str__(self) -> str: return " | ".join([chord.chord for chord in self._chords]) def __repr__(self) -> str: return f"<ChordProgression: {self}>" def __add__(self, other: "ChordProgression") -> "ChordProgression": return ChordProgression(self._chords + other._chords) def __len__(self) -> int: return len(self._chords) def __getitem__(self, key: int) -> Chord: return self._chords[key] def __setitem__(self, key: int, value: Chord) -> None: self._chords[key] = value def __eq__(self, other: Any) -> bool: if not isinstance(other, ChordProgression): raise TypeError( f"Cannot compare ChordProgression object with {type(other)} object" ) return self._chords == other._chords @property def chords(self) -> list[Chord]: """ The component chords of the chord progression. """ return self._chords
[docs] def append(self, chord: str | Chord) -> None: """ Append a chord to the chord progression. :param chord: A chord to append. """ self._chords.append(self._as_chord(chord))
[docs] def insert(self, index: int, chord: str | Chord) -> None: """ Insert a chord into the chord progression. :param index: Index to insert a chord. :param chord: A chord to insert. """ self._chords.insert(index, self._as_chord(chord))
[docs] def pop(self, index: int = -1) -> Chord: """ Pop a chord from the chord progression. :param index: Index of the chord to pop (default: -1). """ return self._chords.pop(index)
[docs] def transpose(self, trans: int) -> None: """ Transpose the whole chord progression. :param trans: The number of semitones. """ for chord in self._chords: chord.transpose(trans)
@staticmethod def _as_chord(chord: str | Chord) -> Chord: """Convert from str to Chord instance if input is str. :param chord: Chord name or :class:`Chord` instance. """ if isinstance(chord, Chord): return chord elif isinstance(chord, str): return Chord(chord) else: raise TypeError("input type should be str or Chord instance.")