Music Theory Implemented

I’m completely new to Python. 20 years ago, I was doing things like this in QBASIC; building waveforms and writing them as WAVE files to be used
in sampling synthesizers. They worked on my TRITON.

Recently, I got a compiler, FreeBASIC, and got some of my old programs to run on this Win10 machine.

I saw that there were people building synths with Raspberry Pi systems, so I decided to go that way. I’m keeping myself in that sandbox, because I’ve seen how an innocent mistake can swamp a system. (Back in the QBASIC days, I always wrote to a floppy. A 200 MB hard drive was huge.)

This site may not be suited to the problems I’m setting for myself. This little program is the beginning of something larger; to ‘add and average’ the interval strings and identify the results of that process; to convert the intervals to notes; and also build waveforms based on these scales.

I’m trying to get used to the Python data types.

‘’’ Octotonic.py

A model of an octotonic system of musical scales. There are 5 out of 8 notes
to make a scale. There are 12 possible scales. These are characterized as a
sequence of integers, the 1st 3 must add to 5, and the last 2 must add to 3,
so that the total is 8; and this is a check sum for the data.

‘’’

OctoStrings = (‘11312’, ‘11321’, ‘12212’, ‘12221’, ‘13112’, ‘13121’,
‘21212’, ‘21221’, ‘22112’, ‘22121’, ‘31112’, ‘31121’)

StringA = ‘’
ListA =

for i in range(12):
StringA = OctoStrings[i]
CheckSum = 0
ListA =
for j in range(5):
ListA = ListA + list(StringA[j])
CheckSum = CheckSum + int(StringA[j])

if (i + 1) < 10:
    print((i+1),'  ', StringA,' ', ListA,' ', CheckSum)
    
if (i + 1) >= 10:
    print((i+1),' ', StringA,' ', ListA,' ', CheckSum)

Python 3.7.3 (/usr/bin/python3)

%Run Octotonic.py
1 11312 [‘1’, ‘1’, ‘3’, ‘1’, ‘2’] 8
2 11321 [‘1’, ‘1’, ‘3’, ‘2’, ‘1’] 8
3 12212 [‘1’, ‘2’, ‘2’, ‘1’, ‘2’] 8
4 12221 [‘1’, ‘2’, ‘2’, ‘2’, ‘1’] 8
5 13112 [‘1’, ‘3’, ‘1’, ‘1’, ‘2’] 8
6 13121 [‘1’, ‘3’, ‘1’, ‘2’, ‘1’] 8
7 21212 [‘2’, ‘1’, ‘2’, ‘1’, ‘2’] 8
8 21221 [‘2’, ‘1’, ‘2’, ‘2’, ‘1’] 8
9 22112 [‘2’, ‘2’, ‘1’, ‘1’, ‘2’] 8
10 22121 [‘2’, ‘2’, ‘1’, ‘2’, ‘1’] 8
11 31112 [‘3’, ‘1’, ‘1’, ‘1’, ‘2’] 8
12 31121 [‘3’, ‘1’, ‘1’, ‘2’, ‘1’] 8

Warnings
May be ignored if you are happy with your program.
Octotonic.py
Line 14 : Need type annotation for ‘ListA’

Was it helpful or confusing?

I’m completely new to Python. 20 years ago, I was doing things like
this in QBASIC; building waveforms and writing them as WAVE files to be
used
in sampling synthesizers. They worked on my TRITON.

Recently, I got a compiler, FreeBASIC, and got some of my old programs to run on this Win10 machine.

I saw that there were people building synths with Raspberry Pi systems, so I decided to go that way. I’m keeping myself in that sandbox, because I’ve seen how an innocent mistake can swamp a system. (Back in the QBASIC days, I always wrote to a floppy. A 200 MB hard drive was huge.)

This site may not be suited to the problems I’m setting for myself. This little program is the beginning of something larger; to ‘add and average’ the interval strings and identify the results of that process; to convert the intervals to notes; and also build waveforms based on these scales.

I’m trying to get used to the Python data types.

Well your programme looks ok to me. Do you have a specific question?

I’ll insert comments inline below:

‘’’ Octotonic.py

A model of an octotonic system of musical scales. There are 5 out of 8 notes
to make a scale. There are 12 possible scales. These are characterized as a
sequence of integers, the 1st 3 must add to 5, and the last 2 must add to 3,
so that the total is 8; and this is a check sum for the data.

‘’’

A module docstring! Very welcome.

OctoStrings = (‘11312’, ‘11321’, ‘12212’, ‘12221’, ‘13112’, ‘13121’,
‘21212’, ‘21221’, ‘22112’, ‘22121’, ‘31112’, ‘31121’)

Stylisticly, we tend to name ordinary variables in lower_case. CamelCase
names tend to be used for class names. It won’t break anything either
way.

StringA = ‘’

I suspect you’re thinking of “declaring” StringA here, since the first
time you use it in the loop below you overwrite it. You don’t need to
declare Python variables.

ListA =

Same remark: this is not needed.

for i in range(12):
StringA = OctoStrings[i]

It seems to me that you want to iterate over the strings in OctoStrings.
The easy way to do this is:

for StringA in OctoStrings:

However, you also use your index “i” in the reporting and some tests.

Python has a useful function called enumerate(), which takes an iterable
such as a tuple or list and yields (i, item) pairs, where “i” takes on
values starting at 0 and “item” takes on each item from the iterable in
turn. So you could rewrite the for-loop like this:

for i, StringA in enumerate(OctoStrings):

to get exactly what you’re doing as:

for i in range(12):
    StringA = OctoStrings[i]

at present.

But wait, there’s more! While list and tuple indices count from zero in
Python, we often want to count from 1 for reporting to humans, just as
you’re doing lower down. And the only place you’re using “i counting
from zero” is the “StringA = OctoStrings[i]” above. Everywhere else
you’re using “i+1”. enumerate() accepts a starting counter. So you can
go:

for i, StringA in enumerate(OctoStrings, 1):

and i will now count from 1. While means all the “i+1” you’re using
lower down can become just “i”. If you like.

CheckSum = 0
ListA =
for j in range(5):
ListA = ListA + list(StringA[j])
CheckSum = CheckSum + int(StringA[j])

You’re just using j to access StringA. So you can make this:

 for ch in StringA:
     ListA = ListA + list(ch)
     CheckSum = CheckSum + int(ch)

to iterate over the characters in StringA. Python doesn’t actually have
a character type, it just uses strings of length 1.

Appending to lists is very common. The “list” type has a .append()
method for adding a single value:

     ListA.append(ch)

if (i + 1) < 10:
print((i+1),’ ‘, StringA,’ ‘, ListA,’ ‘, CheckSum)
if (i + 1) >= 10:
print((i+1),’ ‘, StringA,’ ‘, ListA,’ ', CheckSum)

If you shift to using “enumerate(StringA, 1)” you can replace the “(i +
1)” with just “i” here.

Python 3.7.3 (/usr/bin/python3)

%Run Octotonic.py
1 11312 [‘1’, ‘1’, ‘3’, ‘1’, ‘2’] 8
2 11321 [‘1’, ‘1’, ‘3’, ‘2’, ‘1’] 8
[…]
Warnings
May be ignored if you are happy with your program.
Octotonic.py
Line 14 : Need type annotation for ‘ListA’

Typo annotations are a recent addition to Python, and are totally
optional.

Cheers,
Cameron Simpson cs@cskk.id.au

Thanks, cameron.

I learned early the three rules of coding: documentation, documentation, and documentation. The docstring is one of the best ideas in Python. I can go back to my old BASIC code and still understand what it does.

This 5 of 8 system is a simplified model of the ‘real’ 7 of 12 system. They form groups in the mathematical sense. The 5 of 8 has only 12 members, but the 7 of 12 has 120 members, each one a distinct scale. When I ‘add and average’ two scales, it isn’t normal math. (When I get to that, I’ll upload the new code.) The 5 of 8 system has 12 C 2 = 66 combinations of 2 each. But the 7 of 12 system has 120 C 2 = 7140 combinations. I’ve worked some 2 dozen by hand, but this really needs to be automated.

So, I’ll rewrite this with variable names as: octo_strings, etc. I make the index i + 1 because musicians always start with 1, not 0. There already exists a numbered system of 72 7 of 12 scales, and I don’t want to change that numbering.