Musings of a dad with too much time on his hands and not enough to do. Wait. Reverse that.

Month: August 2020

Learning Guitar with Python, Part 1

After many years of just messing around, I’ve started formal guitar lessons this year. A lot of my instruction includes learning the notes on the fret board, the different keys of music, scales, some basic music theory, and so forth. I’ve taken a lot of hand written notes during my instructional sessions and recently started transcribing a lot of those digitally. It occurred to me that Jupyter Notebook and Python might be a fantastic way to depict some of the concepts I’m learning. So, here is Part 1 of some of my guitar notes with the help of Jupyter Notebook and Python.

The 12 Keys

I won’t take the time to explain the notes and basic pattern in music as that information can be found all over the internet. The first idea I wanted to construct was a grid of the 12 keys and the notes within each key. My instructor and I have also talked a lot about the relative minor in each major key, so I wanted my graphic to convey that point, too. I put together this code:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

# make up my list of notes
chromatic_scale_ascending = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
# since I usually start on the low E string, rearrange the notes starting on E
scale_from_e = (chromatic_scale_ascending + chromatic_scale_ascending)[4:16]

# the scale pattern:
# root, whole step, whole step, half step, whole step, whole step, whole step, half step
key_steps = [2, 2, 1, 2, 2, 2]  # on the guitar, a whole step is two frets
major_keys = []
for root in scale_from_e:
    three_octaves = scale_from_e * 3
    steps_from_root = three_octaves.index(root)
    major_scale = [root]
    # construct the unique notes in the scale
    for step in key_steps:
        steps_from_root += step
        major_scale.append(three_octaves[steps_from_root])
        
    # span the scale across 3 octaves
    major_keys.append(major_scale * 2 + [root])
    
df_major_keys = pd.DataFrame(major_keys)
df_major_keys.columns = df_major_keys.columns + 1  # start counting notes at 1 instead of 0

# use this function to highlight the relative minor scales in orange
def highlight_natural_minor(data):
    df = data.copy()
    df.iloc[:,:] = 'font-size:20px;height:30px'
    df.iloc[:,5:13] = 'background-color: lightgray; font-size:20px'
    return df

print('The 12 keys and the notes within them:')
df_major_keys.style.apply(highlight_natural_minor, axis=None)

Which produced this handy graphic:

The 12 keys and their notes

For simplicity, I used sharps in my keys instead of flats. The highlighted part of the table marks the relative minor portion of the major key.

The notes of the fret board

Probably one of the best ways to learn the notes on your guitar’s fret board is to trace out the fret board on a blank piece of paper and start filling in each note by hand. Do that a few hundred times and you’ll probably start remembering the notes. Being lazy, though, I wanted to have my computer do that work for me. Here’s the code I came up with to write out the fret board:

standard_tuned_strings = ['E', 'A', 'D', 'G', 'B', 'E']
chromatic_scale_ascending = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
col_names = ['Low E', 'A', 'D', 'G', 'B', 'High E']
fretboard_notes = []

for string in standard_tuned_strings:
    start_pos = chromatic_scale_ascending.index(string)
    fretboard_notes.append((chromatic_scale_ascending + chromatic_scale_ascending)[start_pos+1:start_pos+13])

df_fretboard = pd.DataFrame(np.array(fretboard_notes).T, index=np.arange(1, 13), columns=col_names)
df_fretboard.index.name = 'fret'

def highlight_select_frets(data):
    fret_markers = [2, 4, 6, 8, 11]
    df = data.copy()
    df.iloc[:,:] = 'font-size:20px'
    df.iloc[fret_markers,:] = 'background-color: lightgray; font-size:20px'
    return df

df_fretboard.style.apply(highlight_select_frets, axis=None)
Notes on the guitar fret board (1st through 12th fret, standard tuning)

More notes to come, so stay tuned! (Puns intended)

Iterating over a date range

I leverage a number of different programming and scripting tools. Recently, I found myself in a situation where I had to write code to loop through a range of dates to do some operations, by month, in not one, not two…but three different languages: Scala, Python, and Bash. The coding principles are the same across the technologies, but the syntax sure is different.

Here are code examples in four technologies–I threw in PowerShell for good measure–for looping through a range of dates. I loop by month, but these could easily be adapted to loop by day or year or whatever increment fits your needs.

Scala

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Date

val start = LocalDate.of(2020, 1, 1) // inclusive in loop
val end = LocalDate.of(2020, 9, 1) // excluded from loop

val template = "This loop is for Year %1$d and Month (zero padded) %2$s \n"

val date_range = Iterator.iterate(start) { _.plusMonths(1) }.takeWhile(_.isBefore(end))
while(date_range.hasNext){
	val d = date_range.next
	val s = template.format(d.getYear, d.format(DateTimeFormatter.ofPattern("MM")))
	print(s)
}

Python

import datetime
import calendar

start = datetime.date(2020, 1, 1)
end = datetime.date(2020, 9, 1)
template = "This loop is for Year {0} and Month (zero padded) {1:%m}"

while start != end:
	s = template.format(start.year, start)
	print(s)
	days_in_month = calendar.monthrange(start.year, start.month)[1]
	start = start + datetime.timedelta(days=days_in_month)
	

Bash

start=2020-1-1
end=2020-9-1

while [ "$start" != "$end" ]; do
	s="`date -d "$start" +"This loop is for Year %Y and Month (zero padded) %m"`"
	echo s
	start=$(date -I -d "$start + 1 month")
done

PowerShell

$start = get-date "2020-1-1"
$end = Get-Date "2020-9-1"

while($start -ne $end){
    "This loop is for Year {0:yyyy} and Month (zero padded) {0:MM}" -f $start
    $start = $start.AddMonths(1)
}

Lessons Learned

Here’s an interesting and astute graduation speech I listened to recently:

“A lesson learned should be a lesson shared.”

Kyle Martin

In the speech, Kyle declares that “a lesson learned should be a lesson shared.” As a dad, I think about this a lot. I want my children to be more successful than me: professionally, personally…across the board. I’m always trying to share lessons I’ve learned with them–most often, mistakes I’ve made that I hope they can avoid.

Of course, a critical component of a learned lesson is the learned part. The fact that you’ve lived enough under certain conditions to have learned a valuable tenet–good or bad–from those conditions and your responses to those conditions. I wonder if a better name for these lessons is lessons lived. As I share my lessons lived with my children, part of me thinks, “will these lessons even resonate with my children if they’ve never lived them in the first place?” Nevertheless, I keep sharing.

Another thought that occurred to me while watching this video was, what must the Salutatorian be thinking? “Heck, if he regrets earning the Valedictorian spot, give it to me!”

© 2024 DadOverflow.com

Theme by Anders NorenUp ↑