Get rid of Magic Numbers from your code

Last November I got really perplexed.

I was looking at some code for the Pimoroni Explorer Base. I love that hardware. It comes with lots of useful peripherals and plenty of sample code to show you how to control them.

One of the examples is called noise. It plays a simple tune on the Explorer Base Piezo buzzer, and shows the rise and fall of the notes on the built-in display.

You tell the program what notes to play by creating a list like this:

tones = ["AS6", "A6", "AS6", "P", "AS5", "P", "AS5", "P", "F6", "DS6", "D6", "F6", "AS6",]

The code is easy to follow, but one thing really puzzled me.

The program turns each note into a frequency by looking up the name of the note in tones, a massive dictionary with names as keys and integer frequencies as values.

I could read the code, but I was still puzzled.

Where did all those frequencies come from?

Each frequency is a magic number: a value that a program uses without explaining its origin. Magic numbers bother me, and in this case they make up most of the code!

I had a dim memory of the chromatic scale from music lessons long ago. After a little research I started to understand what was going on.

The chromatic scale

The names of the notes are based on the chromatic scale. That’s a series of twelve named tones that make up an octave. Since the tune in the code extends beyond a single octave, each note needs to specify the note name and the number of the octave it’s part of.

For example ‘A4’ is the note ‘A’ in octave number 4.

How do you convert a note to a frequency?

In the chromatic scale the frequency of each tone has a fixed relation to the semitones above and below it.

An octave represents a doubling in frequency, so the ratio between semitones is the twelfth root of 2. That’s approximately 1.0595.

Now you know the relationships between notes, but what’s the anchor - the frequency to which the other notes relate?

A440 pitch

The notes in the code are based on the A440 pitch standard. That standard specifies that the frequency of the note A4 is 440 Hertz (cycles/second).

Now I had enough information to work out the relationship between note names and their frequencies. I wrote a Python module to do that, and I also fixed a couple of other minor niggles.

Take a look at the new code

You can see the code here. Comments in the code explain where all the numbers come from.

Get rid of Magic Numbers!

The time you spend in getting rid of magic numbers will be time well spent.

The code will express intent more clearly, and you may even learn something useful!


Popular posts from this blog

Controlling a Raspberry Pi Pico remotely using PySerial

Five steps to connect Jetson Nano and Arduino

Raspberry Pi Pico project 2 - MCP3008