Music and Coding Part 3

Exploring Trees through Chord Progressions and Harmonic Hierarchies

Introduction

In the previous posts, we looked at linked lists, stacks, and queues with examples from music theory like the C Major scale, chords, and rhythm patterns. Today, we’ll focus on trees, a versatile data structure that branches out much like musical harmonies and chord progressions.

In music, certain notes or chords are central (like the tonic in a key), and other chords and notes relate back to them, creating a hierarchy. Trees are structured similarly, with a root node branching into children nodes. Each child can itself be a root to its own sub-branches, similar to how chords relate to each other within progressions.

Trees: Representing Chord Progressions in a Key

A tree is a structure with a root node (like the “home” chord in a key) and branches that represent relationships. In a chord progression, we can think of the tonic chord as the root, and each branch leads to chords that build the progression in layers, much like how harmonies unfold in a piece of music.

In this post, we’ll create a tree structure representing a chord hierarchy in the key of C Major.


Python Code for a Tree Structure (Chord Progression)

Here’s the code to create a tree structure for a simple chord hierarchy in C Major.

python# Define a Node class to represent each chord
class ChordNode:
    def __init__(self, chord):
        self.chord = chord        # The chord name (e.g., C, G, Am)
        self.children = []        # List of child chords

    def add_child(self, child_node):
        self.children.append(child_node)  # Add a related chord as a child

# Build the tree for a C Major chord progression
class ChordProgressionTree:
    def __init__(self, root_chord):
        self.root = ChordNode(root_chord)  # Start with the tonic chord (root)

    def display_tree(self, node, level=0):
        print("  " * level + f"{node.chord}")
        for child in node.children:
            self.display_tree(child, level + 1)  # Display each child at the next level

# Set up a C Major chord progression tree
chord_tree = ChordProgressionTree("C")   # Root chord (C Major)

# Add child chords (related chords in a typical progression)
g_chord = ChordNode("G")
am_chord = ChordNode("Am")
f_chord = ChordNode("F")

# Build relationships
chord_tree.root.add_child(g_chord)  # C -> G
chord_tree.root.add_child(am_chord) # C -> Am
chord_tree.root.add_child(f_chord)  # C -> F

# Add more layers to the tree
g_chord.add_child(ChordNode("D"))   # G -> D
g_chord.add_child(ChordNode("Em"))  # G -> Em
am_chord.add_child(ChordNode("Dm")) # Am -> Dm

# Display the tree structure
chord_tree.display_tree(chord_tree.root)

Explanation of the Code

  1. ChordNode Class: This class represents a single chord in the tree, with a chord name and a list of children nodes (related chords).
  2. ChordProgressionTree Class: This class sets up a tree structure, beginning with the root chord.
    • display_tree recursively prints each chord and its children in an indented, hierarchical format.

Example Output

Running chord_tree.display_tree(chord_tree.root) would give us something like this:

mathematicaC
  G
    D
    Em
  Am
    Dm
  F

In this tree, the C chord (root) branches into G, Am, and F. The G chord then branches into D and Em, while Am branches into Dm. This structure mirrors the way chord progressions expand and resolve within a key.


Trees and Music Theory

This structure can represent various hierarchical relationships in music:

  • Chord Progressions: The tree captures a primary chord with related chords in a key.
  • Song Structure: Represent verses, choruses, and bridges branching from a central theme.
  • Harmonic Functions: Show dominant, subdominant, and tonic relationships.

Using a tree makes it easy to add new branches, just as composers might add new chords or resolve existing ones in creative ways.


Final Thoughts

Trees give us a flexible way to represent complex hierarchies, and they’re used in programming to manage data that needs organized relationships. In the next post, we’ll dive into Graphs, which go beyond trees by allowing connections between any two nodes—just like connections between notes in jazz improvisation or modulations in key.

Stay tuned for more musical analogies, and try building your own chord progression tree. Happy coding and composing!


Questions for Reflection and Practice

  1. How might you modify this tree to allow more complex relationships, such as including seventh chords or modulations to other keys?
  2. Could this tree structure represent other hierarchical concepts in music, like scales or modes within different keys?
  3. What would happen if you allowed each chord to link back to any other chord? How might this change the way you navigate or display the structure?
  4. How could you expand the display function to visually show each level’s harmonic function, like tonic, dominant, or subdominant?
Lydia Bandy Avatar

Published by Lydia Bandy

Harpist, Pianist, Award Winning Music Teacher, and Software Engineer🎼👨‍💻 Bridging music and technology with 25 years experience as a harpist, pianist, and award-winning instructor! Having 3-4 years as a software engineer and web developer, my goal is to teach coding and music theory to the world🌎🎵 Facebook/Instagram/YouTube: @LydiasPianoStudio

Leave a comment