# Playing Scales

scale.py: 16 points

A scale is a sequence of notes, defined by the intervals between them. For example, the major scale is defined by the 7 intervals (and hence 8 notes) (2,2,1,2,2,2,1), that is, there are 2 half tones between the first and second notes, between the second and third notes, but a single half tone between the third and fourth notes, and so on. The “C Major Scale” is the sequence of notes starting at C and continuing to D, E, F, G, A, B, C as determined by the major scale intervals. The D major scale is the major scale starting at D and continuing to E, F#, G, A, B, C#, and D. The A major scale is the sequence of notes A, B, C#, D, E, F#, G#, A.

There are many other interesting scales, such as the minor scale, defined by the intervals (2,1,2,2,1,2,2), and the blues scale, defined by the intervals (3,2,1,1,3,2) (the scale only contains 7 notes).

### Scales on the Command Line

For this part of the lab, you should write a program `scale.py` that will create a WAV file with a scale specified by command-line arguments. In particular, we’d like to be able to run:

``````python scale.py -3 M
``````

to create an A major scale,

``````python scale.py 0 N
``````

to create a C minor scale, or

``````python scale.py 4 B
``````

to create a blues scale in E.

In particular, you will pass as command-line arguments the tonic note (in its half-tone offset from middle C) and which scale to play (as a character: `M` for major, `N` for minor, and `B` for blues).

How can your program make use of the arguments you add after the program name? If you add:

``````import sys
``````

at the beginning of your program, you’ll get access to the variable `sys.argv`, which is a list of the arguments passed to Python from the shell. The first of these is always the name of the program itself. But if you were to run:

``````python scale.py 4 B
``````

and that program included the statement `print(sys.argv)`, we’d get as output:

``````['scale.py', '4', 'B']
``````

Given this (and possibly judicious use of the `int()` function), you should be able to get all the input you need from command-line arguments.

#### Program Requirements

To make use of your `SoundWave` class, include:

``````import soundwave
``````

at the top of your file.

The bulk of this file should be a `main()` function which will first gracefully handle invalid input from the user by catching exceptions, reporting the error, and quitting the program.

Closing a Program

Previously, when you’ve wanted to quit a program due to faulty user input, you might have wrapped your code in an `if` statement or used an empty `return` within your `main()` function. Now that we know about the `sys` module, we can instead use the command `exit` as follows, which will quit the program entirely.

``````sys.exit(-1)
``````

You should then also declare a dictionary `intervals`, similar to that below:

``````intervals = {'M':[2,2,1,2,2,2,1],
'N':[2,1,2,2,1,2,2],
'B':[3,2,1,1,3,2]}
``````

Each value list corresponds to the number of half tones between successive notes in the Major, Minor, and Blues scales respectively. This should make building scales cleaner.

Next, you should create a new `SoundWave` object at the half tone chosen by the user in the command-line arguments. Then, use a `for` loop to create another `SoundWave` for the next note in the scale (using the intervals corresponding to the type of scale the user desires) and call `extend()` to add this new note to the first one you created. By the end of the `for` loop, you should have the entire scale in a single `SoundWave` object. Finally, call the save method on that `SoundWave` object and pass in “scale.wav” as the name of the WAV file to be created.

After running your `scale.py` program, you should be able to click on the `scale.wav` file and play it to hear the scale you created (similar to the other parts of the lab). If you encounter a 0 second long scale, remind yourself about the `duration` parameter to the constructor for `SoundWave`.