Chord

Chord(
    root: TonalVector,
    tones: Iterable[TonalVector],
    bass: TonalVector | None = None,
    name: str | None = None,
    suffix: str | None = None,
)

A concrete realization of a ChordType at a specific root pitch.

Unlike ChordType, a Chord’s root is not necessarily TonalVector(0,0); it is wherever the ChordType was realized (e.g. E(maj) produces a Chord rooted at E).

>>> from openmusickit.systems.wsmn.tonal.symbols import E, maj
>>> chord = E(maj)
>>> chord.root, chord.bass, str(chord)
(TonalVector((2, 4)), TonalVector((2, 4)), 'E')

Attributes

Name Description
tones
root
name_template
name The name template formatted with root.
bass
suffix

Methods

Name Description
__iter__
__len__
__getitem__
__contains__
__repr__
combinations Returns a list of all ToneCollection subsets of k members, in the collection’s order.
all_combinations Returns a list of all ToneCollection subsets of length 2 through len(self)-1.
arpeggiate Returns the chord’s tones as a ToneCollection, rotated so that the
__init__
inversion Returns a Chord with the same tones and root, but a different bass tone.
transform Returns a new Chord made by applying operation to every tone
__str__ Lead-sheet chord symbol: the root’s pitch name followed by the
__truediv__ Returns a Chord with the same tones and root, but a different bass tone.

__iter__

__iter__()

__len__

__len__()

__getitem__

__getitem__(index)

__contains__

__contains__(tone)

__repr__

__repr__()

combinations

combinations(k: int)

Returns a list of all ToneCollection subsets of k members, in the collection’s order.

>>> from openmusickit.systems.wsmn.tonal.symbols import C, E, G
>>> [[format(t) for t in dyad] for dyad in ToneCollection([C, E, G]).combinations(2)]
[['C', 'E'], ['C', 'G'], ['E', 'G']]

all_combinations

all_combinations()

Returns a list of all ToneCollection subsets of length 2 through len(self)-1.

>>> from openmusickit.systems.wsmn.tonal.symbols import C, E, G, B
>>> len(ToneCollection([C, E, G, B]).all_combinations())  # 6 dyads and 4 triads
10

arpeggiate

arpeggiate()

Returns the chord’s tones as a ToneCollection, rotated so that the bass tone comes first and the remaining tones follow in their original (cyclic) order. Root and name are preserved.

>>> from openmusickit.systems.wsmn.tonal.symbols import maj7
>>> def names(tc): return [t.pitch.unicode for t in tc]
>>> names(maj7.arpeggiate())
['C', 'E', 'G', 'B']
>>> names(maj7.inversion(1).arpeggiate())
['E', 'G', 'B', 'C']
>>> names(maj7.inversion(2).arpeggiate())
['G', 'B', 'C', 'E']
>>> names(maj7.inversion(3).arpeggiate())
['B', 'C', 'E', 'G']

__init__

__init__(
    root: TonalVector,
    tones: Iterable[TonalVector],
    bass: TonalVector | None = None,
    name: str | None = None,
    suffix: str | None = None,
)

inversion

inversion(inv: int | TonalVector, name: str | None = None)

Returns a Chord with the same tones and root, but a different bass tone.

>>> from openmusickit.systems.wsmn.tonal.symbols import C, maj
>>> second = C(maj).inversion(2)
>>> str(second), second.root
('C/G', TonalVector((0, 0)))

transform

transform(
    operation: Callable[..., TonalVector],
    *args,
    new_name: str | None = None,
    new_suffix: str | None = None,
    **kwargs,
)

Returns a new Chord made by applying operation to every tone of this chord (root, tones, and bass).

operation is called as operation(tone, *args, **kwargs) for each tone. It is typically a TonalVector method (such as TonalVector.transpose), but any callable that accepts a TonalVector as its first argument and returns a TonalVector will do; if it does not return a TonalVector, a TypeError is raised.

The new chord keeps this chord’s name and suffix unless new_name and/or new_suffix are given.

Examples

>>> from openmusickit.systems.wsmn.tonal.symbols import C, G, min_, maj, M3
>>> from openmusickit.systems.wsmn.tonal.tonal_vector import TonalDirection

Transposition, with the interval passed as the operand:

>>> str(C(min_).transform(TonalVector.transpose, M3))
'Emin'
>>> str(C(min_).transform(TonalVector.transpose, M3, TonalDirection.DOWN))
'A♭min'

The bass is transformed along with the rest of the chord:

>>> str((C(maj) / G).transform(TonalVector.transpose, M3))
'E/B'

A user-defined operation that needs no operand, with a new suffix:

>>> def sharpen(tv):
...     return tv + TonalVector((0, 1))
>>> str(C(maj).transform(sharpen, new_suffix="maj"))
'C♯maj'

An operation that does not produce a TonalVector is rejected:

>>> C(maj).transform(str)
Traceback (most recent call last):
...
TypeError: ...

__str__

__str__()

Lead-sheet chord symbol: the root’s pitch name followed by the suffix, plus “/bass” when the bass is not the root. Falls back to name (with a separating space) when there is no suffix.

Examples

>>> from openmusickit.systems.wsmn.tonal.symbols import C, E, G, Eb, maj, maj7, hdim7

Non-empty suffix, root position and inverted:

>>> str(C(maj7))
'Cmaj7'
>>> str(C(maj7) / E)
'Cmaj7/E'
>>> str(Eb(hdim7).inversion(2))
'E♭ø7/B𝄫'

Empty suffix (the plain major triad) shows just the root:

>>> str(C(maj))
'C'
>>> str(C(maj) / G)
'C/G'

No suffix at all falls back to the name:

>>> str(Chord(C, [C, E, G], name="major"))
'C major'
>>> str(Chord(C, [C, E, G], name="major") / E)
'C major/E'

__truediv__

__truediv__(tv: TonalVector)

Returns a Chord with the same tones and root, but a different bass tone.

This is an overload for the / operator, so a slash chord reads as written:

>>> from openmusickit.systems.wsmn.tonal.symbols import C, E, maj
>>> str(C(maj) / E)
'C/E'