Refactor hello.py to display standard guitar chord charts

This commit is contained in:
2024-11-05 10:38:41 -05:00
parent 3ca8f541c8
commit 08d14b0802
2 changed files with 78 additions and 35 deletions
+52 -14
View File
@@ -1,18 +1,56 @@
from pytheory import Chord, play, Synth, TonedScale
from pytheory import Tone, Fretboard, CHARTS
# Create a C minor scale.
c_minor = TonedScale(tonic="C3")["minor"]
# Create standard tuning (from high E to low E)
standard_tuning = [
Tone.from_string("E4"), # High E
Tone.from_string("B3"), # B
Tone.from_string("G3"), # G
Tone.from_string("D3"), # D
Tone.from_string("A2"), # A
Tone.from_string("E2"), # Low E
]
# Create a C minor chord.
chord = Chord(
[
c_minor[0], # C
c_minor[2], # G
]
)
# Create fretboard with standard tuning
fretboard = Fretboard(tones=standard_tuning)
# Play the chord
print("dissonance", chord.dissonance)
print("harmony", chord.harmony)
# Define flat to sharp note mappings (updated to include all possible flats)
flat_to_sharp = {"Ab": "G#", "Bb": "A#", "Db": "C#", "Eb": "D#", "Gb": "F#"}
play(chord)
# Add sharp to flat mappings
sharp_to_flat = {v: k for k, v in flat_to_sharp.items()}
# Get all available chords from CHARTS
all_chords = sorted(CHARTS["western"].keys())
print("Standard Guitar Chord Charts:")
print("-" * 30)
for chord_name in all_chords:
# Store original chord name for lookup
lookup_name = chord_name
# Convert flat notation to sharp only for display
base_note = chord_name.rstrip("dim7956maj")
if base_note in flat_to_sharp:
# Replace the base note with its sharp equivalent for display only
sharp_base = flat_to_sharp[base_note]
sharp_name = chord_name.replace(base_note, sharp_base)
print(f" Converting {chord_name} to {sharp_name}") # Debug line
display_name = sharp_name
else:
display_name = chord_name
chord = CHARTS["western"][lookup_name] # Use original name for lookup
try:
fingering = chord.fingering(fretboard=fretboard)
print(f"{display_name}: {fingering}")
except Exception as e:
print(f"{display_name}: Unable to calculate fingering - {str(e)}")
# Add more detailed debug information
print(f"Debug - Chord data: {chord}")
print(
f"Debug - Chord tones: {chord.tones if hasattr(chord, 'tones') else 'No tones available'}"
)
print(f"Debug - Fretboard tuning: {[str(t) for t in fretboard.tones]}")
print(f"Debug - Available fretboard tones: {[str(t) for t in fretboard.tones]}")
+26 -21
View File
@@ -3,16 +3,18 @@ import itertools
from .systems import SYSTEMS
from .tones import Tone
QUALITIES = ('', 'maj', 'm', '5', '7', '9', 'dim', 'm6', 'm7', 'm9', 'maj7', 'maj9')
QUALITIES = ("", "maj", "m", "5", "7", "9", "dim", "m6", "m7", "m9", "maj7", "maj9")
MAX_FRET = 7
CHARTS = {}
CHARTS['western'] = []
CHARTS["western"] = []
class NamedChord:
def __init__(self, *, tone_name, quality):
self.tone_name = tone_name
self.quality = quality
self._tone = None
@property
def name(self):
@@ -20,7 +22,11 @@ class NamedChord:
@property
def tone(self):
return Tone(name=self.tone_name)
if self._tone is None:
flat_to_sharp = {"Ab": "G#", "Bb": "A#", "Db": "C#", "Eb": "D#", "Gb": "F#"}
tone_name = flat_to_sharp.get(self.tone_name, self.tone_name)
self._tone = Tone(name=tone_name)
return self._tone
def __repr__(self):
return f"<NamedChord name={self.name!r}>"
@@ -29,41 +35,40 @@ class NamedChord:
def acceptable_tones(self):
acceptable = [self.tone]
# Major third.
if self.quality == 'maj':
if self.quality == "maj":
acceptable += [self.tone.add(3)]
# Minor third.
elif self.quality == 'm':
elif self.quality == "m":
acceptable += [self.tone.add(4)]
# Perfect fifth.
elif self.quality == '5':
elif self.quality == "5":
acceptable += [self.tone.add(5)]
elif self.quality == '7':
elif self.quality == "7":
acceptable += [self.tone.add(7)]
elif self.quality == '9':
elif self.quality == "9":
acceptable += [self.tone.add(9)]
elif self.quality == 'dim':
elif self.quality == "dim":
acceptable += [self.tone.add(4), self.tone.add(8)]
elif self.quality == 'm6':
elif self.quality == "m6":
acceptable += [self.tone.add(4), self.tone.add(6)]
elif self.quality == 'm7':
elif self.quality == "m7":
acceptable += [self.tone.add(4), self.tone.add(7)]
elif self.quality == 'm9':
elif self.quality == "m9":
acceptable += [self.tone.add(4), self.tone.add(9)]
elif self.quality == 'maj7':
elif self.quality == "maj7":
acceptable += [self.tone.add(3), self.tone.add(7)]
elif self.quality == 'maj9':
elif self.quality == "maj9":
acceptable += [self.tone.add(3), self.tone.add(9)]
else:
@@ -142,9 +147,8 @@ class NamedChord:
return tuple([self.fix_fingering(f) for f in best_fingerings])
western_chart = {}
for tone_titles in SYSTEMS['western'].tone_names:
for tone_titles in SYSTEMS["western"].tone_names:
# Take the second tone name, if it's available.
if len(tone_titles) == 2:
tone_name = tone_titles[1]
@@ -155,9 +159,10 @@ for tone_titles in SYSTEMS['western'].tone_names:
named_chord = NamedChord(tone_name=tone_name, quality=quality)
western_chart.update({f"{tone_name}{quality}": named_chord})
CHARTS['western'] = western_chart
CHARTS["western"] = western_chart
def charts_for_fretboard(*, chart=CHARTS['western'], fretboard):
def charts_for_fretboard(*, chart=CHARTS["western"], fretboard):
super_chart = {}
for chord in chart:
super_chart[chord] = chart[chord].fingering(fretboard=fretboard)