Scales¶
- class pytheory.scales.Scale(*, tones: tuple[Tone, ...], degrees: tuple[str, ...] | None = None, system: str | System = 'western')[source]¶
Bases:
object- __init__(*, tones: tuple[Tone, ...], degrees: tuple[str, ...] | None = None, system: str | System = 'western') None[source]¶
Initialize a Scale from a sequence of Tones.
- Parameters:
tones – The tones that make up the scale.
degrees – Optional names for each scale degree (must match length of tones).
system – A tone system name or
Systeminstance.
- Raises:
ValueError – If degrees is provided but its length differs from tones.
- property system: System | None¶
Return the tone system for this scale.
Resolves a system name to a
Systemobject on first access.
- __contains__(item: str | Tone) bool[source]¶
Check whether a tone or note name belongs to this scale.
- chord(*degrees: int) Chord[source]¶
Build a Chord from scale degrees (0-indexed).
Wraps around if degrees exceed the scale length, transposing up by an octave as needed.
Example: scale.chord(0, 2, 4) builds a triad from the 1st, 3rd, 5th.
- transpose(semitones: int) Scale[source]¶
Return a new Scale transposed by the given number of semitones.
Every tone is shifted by the same interval, preserving the scale’s interval pattern.
Example:
>>> c_major = TonedScale(tonic="C4")["major"] >>> d_major = c_major.transpose(2) >>> d_major.note_names ['D', 'E', 'F#', 'G', 'A', 'B', 'C#', 'D']
- triad(root: int = 0) Chord[source]¶
Build a triad starting from the given scale degree (0-indexed).
Returns a chord with the root, 3rd, and 5th above it.
- seventh(root: int = 0) Chord[source]¶
Build a seventh chord from the given scale degree (0-indexed).
Returns a chord with the root, 3rd, 5th, and 7th.
- progression(*numerals: str) list[Chord][source]¶
Build a chord progression from Roman numeral strings.
Accepts Roman numerals like
"I","IV","V","ii","vi". Lowercase = minor triad, uppercase = major triad. Add"7"suffix for seventh chords.Example:
>>> scale.progression("I", "IV", "V", "I") [<Chord (C,E,G)>, <Chord (F,A,C)>, <Chord (G,B,D)>, <Chord (C,E,G)>]
- nashville(*numbers: int | str) list[Chord][source]¶
Build a chord progression using Nashville number system.
The Nashville number system uses Arabic numerals instead of Roman numerals. It’s the standard chart system in Nashville recording studios.
Numbers 1-7 build diatonic triads. Suffix
"7"for seventh chords,"m"to force minor.Example:
>>> scale.nashville(1, 4, 5, 1) [<Chord C major>, <Chord F major>, <Chord G major>, <Chord C major>]
- static detect(*note_names: str) tuple[str, str, int] | None[source]¶
Detect the most likely scale from a set of note names.
Tries all scales in the Western system and returns the best match as a
(tonic, scale_name, match_count)tuple.Example:
>>> Scale.detect("C", "D", "E", "F", "G", "A", "B") ('C', 'major', 7) >>> Scale.detect("C", "D", "Eb", "F", "G", "Ab", "Bb") ('C', 'minor', 7)
- harmonize() list[Chord][source]¶
Build diatonic triads on every scale degree.
Returns a list of Chords — one triad for each degree of the scale. In a major scale this produces: I, ii, iii, IV, V, vi, vii°.
Example:
>>> [c.identify() for c in TonedScale(tonic="C4")["major"].harmonize()] ['C major', 'D minor', 'E minor', 'F major', 'G major', 'A minor', 'B diminished']
- pytheory.scales.PROGRESSIONS = {'12-bar blues': ('I', 'I', 'I', 'I', 'IV', 'IV', 'I', 'I', 'V', 'IV', 'I', 'V'), 'Andalusian': ('i', 'VII', 'VI', 'V'), 'Dorian vamp': ('i', 'IV'), 'I-IV-V-I': ('I', 'IV', 'V', 'I'), 'I-IV-vi-V': ('I', 'IV', 'vi', 'V'), 'I-V-vi-IV': ('I', 'V', 'vi', 'IV'), 'I-vi-IV-V': ('I', 'vi', 'IV', 'V'), 'I-vi-ii-V': ('I', 'vi', 'ii', 'V'), 'Mixolydian vamp': ('I', 'VII'), 'Pachelbel': ('I', 'V', 'vi', 'iii', 'IV', 'I', 'IV', 'V'), 'i-bVI-bIII-bVII': ('i', 'VI', 'III', 'VII'), 'ii-V-I': ('ii', 'V7', 'I'), 'iii-vi-ii-V': ('iii', 'vi', 'ii', 'V'), 'vi-IV-I-V': ('vi', 'IV', 'I', 'V')}¶
Common chord progressions as Roman numeral tuples.
Use with
Scale.progression()orKey.progression():Key("C", "major").progression(*PROGRESSIONS["I-V-vi-IV"])
- class pytheory.scales.Key(tonic: str, mode: str = 'major', system: str | System | None = None)[source]¶
Bases:
objectA musical key — a convenient entry point for scales and harmony.
A Key represents a tonic note and a mode. It provides quick access to the scale, diatonic chords, and common progressions.
Example:
>>> key = Key("C", "major") >>> key.scale.note_names ['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C'] >>> key.chords ['C major', 'D minor', 'E minor', 'F major', ...] >>> key.progression("I", "V", "vi", "IV") [<Chord (C,E,G)>, <Chord (G,B,D)>, ...]
- classmethod detect(*note_names: str) Key | None[source]¶
Detect the most likely key from a set of note names.
Tries every possible major and minor key and returns the one whose scale contains the most of the given notes.
Example:
>>> Key.detect("C", "D", "E", "F", "G", "A", "B") <Key C major> >>> Key.detect("A", "B", "C", "D", "E", "F", "G") <Key C major> >>> Key.detect("A", "C", "E") <Key C major>
- Returns:
The best-matching Key, or None if no notes given.
- progression(*numerals: str) list[Chord][source]¶
Build a chord progression from Roman numerals.
Example:
>>> Key("G", "major").progression("I", "IV", "V7", "I")
- nashville(*numbers: int | str) list[Chord][source]¶
Build a chord progression using Nashville numbers.
Example:
>>> Key("G", "major").nashville(1, 4, 5, 1)
- secondary_dominant(degree: int) Chord[source]¶
Build a secondary dominant (V/x) for the given scale degree.
A secondary dominant is the dominant chord of a non-tonic degree. For example, in C major, V/V is D major (the V chord of G). Secondary dominants create momentary tonicizations that add color and forward motion.
Common secondary dominants:
V/V (e.g. D7 in C major) — approaches the dominant
V/ii (e.g. A7 in C major) — approaches the supertonic
V/vi (e.g. E7 in C major) — approaches the relative minor
- Parameters:
degree – Scale degree to target (1-indexed).
5means “build the V of the 5th degree.”- Returns:
A dominant 7th Chord that resolves to the given degree.
Example:
>>> Key("C", "major").secondary_dominant(5) # V/V = D7 <Chord D dominant 7th>
- classmethod all_keys() list[Key][source]¶
Return all 24 major and minor keys.
- Returns:
A list of Key objects for all 12 major and 12 minor keys.
Example:
>>> for k in Key.all_keys(): ... print(k)
- property signature: dict¶
The key signature — number and names of sharps or flats.
In Western music, each key has a unique key signature that tells you which notes are sharped or flatted throughout a piece.
- Returns:
sharps(int): number of sharps (0 if flat key)flats(int): number of flats (0 if sharp key)accidentals(list[str]): the sharped/flatted note names
- Return type:
A dict with
Example:
>>> Key("G", "major").signature {'sharps': 1, 'flats': 0, 'accidentals': ['F#']} >>> Key("F", "major").signature {'sharps': 0, 'flats': 1, 'accidentals': ['Bb']} >>> Key("C", "major").signature {'sharps': 0, 'flats': 0, 'accidentals': []}
- property borrowed_chords: list[str]¶
Chords borrowed from the parallel key.
Modal interchange (or modal mixture) borrows chords from the parallel major or minor key. In C major, the parallel minor is C minor, which provides chords like Ab major, Bb major, and Eb major — commonly heard in rock, film, and pop music.
- Returns:
A list of chord names from the parallel key that are NOT in the current key’s diatonic chords.
Example:
>>> Key("C", "major").borrowed_chords ['C minor', 'D diminished', 'D# major', ...]
- random_progression(length: int = 4) list[source]¶
Generate a random diatonic chord progression.
Uses weighted probabilities based on common chord function: I and vi are most common, IV and V are very common, ii is common, iii and viidim are rare. Always starts on I and ends on I or V.
- Parameters:
length – Number of chords (default 4).
- Returns:
A list of Chord objects.
Example:
>>> Key("C", "major").random_progression(4) [<Chord C major>, <Chord F major>, <Chord G major>, <Chord C major>]
- class pytheory.scales.TonedScale(*, system: str | System = <System semitones=12>, tonic: str | Tone)[source]¶
Bases:
object- __init__(*, system: str | System = <System semitones=12>, tonic: str | Tone) None[source]¶
Initialize a TonedScale with a tonic note and tone system.
- Parameters:
system – A tone system name or
Systeminstance.tonic – The tonic note as a string (e.g.
"C4") orTone.