mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-06-05 14:50:18 +00:00
v0.7.0: Add Fretboard.chord() method for named chord lookups
New `fb.chord("G")` API lets you look up fingerings by chord name
instead of knowing fret positions upfront. Updates all docs to use
REPL-style examples with verified output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+29
-29
@@ -185,46 +185,46 @@ on any instrument. It scores each possibility by:
|
||||
2. Preferring **ascending** fret patterns — easier hand position
|
||||
3. Minimizing the number of **fingers needed**
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
from pytheory import Fretboard, CHARTS
|
||||
>>> from pytheory import Fretboard, CHARTS
|
||||
|
||||
fb = Fretboard.guitar()
|
||||
c = CHARTS["western"]["C"]
|
||||
>>> fb = Fretboard.guitar()
|
||||
>>> f = fb.chord("C")
|
||||
>>> f
|
||||
Fingering(e=0, B=1, G=0, D=2, A=3, E=0)
|
||||
|
||||
# Fingerings return a Fingering object with labeled strings
|
||||
f = c.fingering(fretboard=fb)
|
||||
print(f)
|
||||
# Fingering(e=0, B=1, G=0, D=2, A=3, E=0)
|
||||
>>> f['A']
|
||||
3
|
||||
>>> f[1]
|
||||
1
|
||||
|
||||
# Access by string name or index
|
||||
f['A'] # 3
|
||||
f[1] # 1 (B string)
|
||||
>>> f.identify()
|
||||
'C major'
|
||||
|
||||
# Identify the chord directly from a fingering
|
||||
f.identify() # 'C major'
|
||||
>>> chord = f.to_chord()
|
||||
>>> chord.identify()
|
||||
'C major'
|
||||
|
||||
# Convert to a Chord for further analysis
|
||||
chord = f.to_chord()
|
||||
chord.harmony # consonance score
|
||||
chord.intervals # [4, 3] — major triad
|
||||
>>> # All equally-scored fingerings via CHARTS
|
||||
>>> CHARTS["western"]["C"].fingering(fretboard=fb, multiple=True)
|
||||
[...]
|
||||
|
||||
# All equally-scored fingerings
|
||||
all_c = c.fingering(fretboard=fb, multiple=True)
|
||||
|
||||
# Muted strings appear as None
|
||||
f = CHARTS["western"]["F"]
|
||||
print(f.fingering(fretboard=fb))
|
||||
>>> # Muted strings appear as None
|
||||
>>> CHARTS["western"]["F"].fingering(fretboard=fb)
|
||||
...
|
||||
|
||||
You can also go from fret positions to chord identification:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
# "What chord am I playing?"
|
||||
fb = Fretboard.guitar()
|
||||
f = fb.fingering(0, 0, 0, 2, 2, 0)
|
||||
print(f) # Fingering(e=0, B=0, G=0, D=2, A=2, E=0)
|
||||
print(f.identify()) # E minor
|
||||
>>> # "What chord am I playing?"
|
||||
>>> fb = Fretboard.guitar()
|
||||
>>> f = fb.fingering(0, 0, 0, 2, 2, 0)
|
||||
>>> f
|
||||
Fingering(e=0, B=0, G=0, D=2, A=2, E=0)
|
||||
>>> f.identify()
|
||||
'E minor'
|
||||
|
||||
Reading Fingerings
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
+19
-18
@@ -117,29 +117,30 @@ Build chords directly:
|
||||
Guitar Fingerings
|
||||
-----------------
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
from pytheory import Fretboard, CHARTS
|
||||
>>> from pytheory import Fretboard
|
||||
|
||||
fb = Fretboard.guitar()
|
||||
>>> fb = Fretboard.guitar()
|
||||
|
||||
# Get a labeled fingering from the chord chart
|
||||
f = CHARTS["western"]["C"].fingering(fretboard=fb)
|
||||
f # Fingering(e=0, B=1, G=0, D=2, A=3, E=0)
|
||||
f['A'] # 3
|
||||
>>> fb.chord("C")
|
||||
Fingering(e=0, B=1, G=0, D=2, A=3, E=0)
|
||||
|
||||
# Identify a chord from fret positions
|
||||
fb.fingering(0, 0, 0, 2, 2, 0).identify() # 'E minor'
|
||||
>>> fb.chord("C")['A']
|
||||
3
|
||||
|
||||
# ASCII tablature
|
||||
print(CHARTS["western"]["Am"].tab(fretboard=fb))
|
||||
# Am
|
||||
# E|--0--
|
||||
# B|--1--
|
||||
# G|--2--
|
||||
# D|--2--
|
||||
# A|--0--
|
||||
# E|--0--
|
||||
>>> fb.fingering(0, 0, 0, 2, 2, 0).identify()
|
||||
'E minor'
|
||||
|
||||
>>> from pytheory import CHARTS
|
||||
>>> print(CHARTS["western"]["Am"].tab(fretboard=fb))
|
||||
Am
|
||||
E|--0--
|
||||
B|--1--
|
||||
G|--2--
|
||||
D|--2--
|
||||
A|--0--
|
||||
E|--0--
|
||||
|
||||
Audio Playback
|
||||
--------------
|
||||
|
||||
+2
-2
@@ -29,8 +29,8 @@ instruments using a clean, Pythonic API.
|
||||
'perfect 5th'
|
||||
|
||||
>>> fb = Fretboard.guitar()
|
||||
>>> fb.fingering(0, 1, 0, 2, 3, 0)
|
||||
Fingering(e=0, B=1, G=0, D=2, A=3, E=0)
|
||||
>>> fb.chord("G")
|
||||
Fingering(e=3, B=0, G=0, D=0, A=2, E=3)
|
||||
|
||||
It also works from the command line::
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "pytheory"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
description = "Music Theory for Humans"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""PyTheory: Music Theory for Humans."""
|
||||
|
||||
__version__ = "0.6.1"
|
||||
__version__ = "0.7.0"
|
||||
|
||||
from .tones import Tone, Interval
|
||||
from .systems import System, SYSTEMS
|
||||
|
||||
@@ -1251,6 +1251,25 @@ class Fretboard:
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
def chord(self, name: str, *, system: str = "western") -> "Fingering":
|
||||
"""Look up a chord by name and return its best fingering.
|
||||
|
||||
Args:
|
||||
name: Chord name like ``"G"``, ``"Am7"``, ``"Bb"``, ``"Dm"``.
|
||||
system: Tonal system to use (default ``"western"``).
|
||||
|
||||
Returns:
|
||||
A :class:`Fingering` for that chord on this fretboard.
|
||||
|
||||
Example::
|
||||
|
||||
>>> fb = Fretboard.guitar()
|
||||
>>> fb.chord("G")
|
||||
Fingering(e=3, B=0, G=0, D=0, A=2, E=3)
|
||||
"""
|
||||
from .charts import CHARTS
|
||||
return CHARTS[system][name].fingering(fretboard=self)
|
||||
|
||||
def fingering(self, *positions: int) -> "Fingering":
|
||||
"""Apply fret positions to each string, returning a Fingering.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user