Teach your child to code the Sonic Pi

A parent friendly guide to teaching your child basic coding skills while having fun creating music. Together with your children you’ll learn how to create and compose music using the Sonic Pi software, which was originally designed to support computing lessons within schools. This guide is aimed at anyone over the age of 9 years.


Chapters

  1. Getting Started
  2. Creating Your First Tune
  3. Saving & Opening Files
  4. Attack, Release, Sustain & Amplitude
  5. Samples & Special Effects
  6. Creating a Drum Machine
  7. Drum Morse Code
  8. Composing a Ring Tone
  9. Coding Star Wars
  10. Coding Match of The Day
  11. Coding Super Trouper
  12. Supporting This Guide
  13. Index
  14. Copyright

Chapter 1
Getting Started

What is Sonic Pi

The primary school curriculum in the UK changed in 2015, putting a greater emphasis on children learning how to code and program computers.

The Sonic Pi software was originally designed to support computing and music lessons within schools. Developed by a team at Cambridge University the software is a free live coding synth which has been designed to be easy to learn and use.

Music is a great way to learn the concepts of computer programming. Many songs that children learn in school use structures which are commonly found in computer programming.

These songs typically use repeated sections or rhythms which can be easily coded using loops, a key concept in programming. By its nature music gives you instant audible feedback so it’s easy to listen to how the code you are writing is affecting the outcome.

The Sonic Pi software is freely available from their web site and there are versions built for Windows, Mac OSX and the Raspberry Pi.

A Raspberry Pi is a low cost, credit card sized computer which plugs into existing monitors and keyboards and is ideally suited to running the Sonic Pi software. You can get a Raspberry Pi from Amazon for under £30.

What you will learn

You will learn the commands to code the Sonic Pi synth to play notes, chords and drum beats. By the end of the second chapter you and your child will have created a popular tune which every child should recognise from school. The piano keyboard layout is explained showing how the notes on the keyboard relate to the note values entered into the various Sonic Pi commands.

Don’t worry if you don’t already read music. The musical notation required to understand the exercises are explained in detail. Hopefully by the end of the book you will have learnt how to read basic musical scores as well as learning how to code.

The Sonic Pi software comes with a selection of pre-defined samples and special effects. Your child will experiment with these to make up their own sound effects and create a drum machine. There is an exercise on coding a rhythmic machine which will play your child’s name using Morse code.

By chapter eight, your child will be confidant enough to code a simple mobile phone ring tone. In this exercise we’ll cover how to record your creations and convert the files to an MP3 file so that you can install the ring tone onto your smart phone.

Computers are very good at creating random numbers. We’ll look at how we can use random numbers to get the computer to generate its own music.

The last couple of chapters cover techniques for coding some popular music. In these chapters you will be introduced to reading musical scores and how to transpose these scores into computer code. We’ll discuss how to set up different variables for each musical note like the crotchet and the quaver. You’ll cover how to play chords and play multiple instruments together at the same time.

Encourage your child

Let your child sit at the computer and do all the typing. It’s the best way for them to learn. Above all make it fun. Laugh when things go wrong or the sound is funny and not what you expected. When your child does get it right be amazed and give lots of praise.

Throughout the book there are questions for you to ask your child. Prompting your child to think about the different problems and issues being covered will help them pick up the concepts quicker. Encourage them to think and talk about possible answers and then try and code the solutions themselves before looking at the solutions. The solutions are included with each exercise.

After teaching this material to hundreds of primary school children I have learnt to let them experiment. The results always amaze me. After each chapter encourage your child to experiment with the concepts learned.

About the author

Paul Bradley is a full time software developer working for the NHS. He started teaching primary school children computer programming as part of an after school code club. For the last two years he has been teaching children at two schools in Cumbria and towards the end of June 2015 started teaching them the Sonic Pi.

He wrote and developed the material that became this short book while working with children between the ages of 9 and 11. He shared the weekly course material with colleagues volunteering in schools around the Manchester area. The exercises were refined and have been delivered to hundreds of children. The feedback from these children was that Sonic Pi is a fun way to learn both coding and music.

Coding the Star Wars theme tune

Coding the Star Wars theme tune in Sonic Pi

Children who wouldn’t dream of playing a traditional instrument were enjoying creating and composing their own music.

After just six one hour sessions, several children created pieces of music that were included in the schools end of year concert. It was the first time that electronic music had been incorporated into the schools summer concert.

Installing Sonic Pi

The latest release of Sonic Pi is version 2.10.0, visit the projects website and download the relevant package for your system.

The installation process for Windows and MAC OSX is relatively straight forward and if you’re used to installing software on your system then you shouldn’t have any problems.

The Sonic Pi screen

The Sonic Pi screen

This is the main Sonic Pi screen; it has three main windows. The largest one is for writing your code, and we call it the “Programming Panel”. There is also an output panel which displays information about your program as it runs.

When you click on the help button at the top of the window, the third panel appears along the bottom displaying the help documentation. This help system contains extensive information about all the commands available in Sonic Pi. It lists all the different parameters you can pass into each command to change the music.

Along the bottom of the “Programming Panel” you’ll find ten buttons labelled “Buffer 0” through to “Buffer 9”. These are tabs or documents which allow you to work on upto ten songs at once.

Along the top top of the Sonic Pi screen there are ten buttons in a toolbar. Working from left to right these are:-

Sonic Pi Toolbar

Run plays the tune for the code within the current buffer document
Stop stops any playing code, useful for stopping long looping tunes
Save saves the code in the current buffer to a file on disk
Rec records the tune as it plays and saves the file as a WAV file
Size - decrease the size of the font used within the programming panel. Useful if you have a long program and want to display the whole program on the screen
Size + increase the size of the font used within the programming panel
Align aligns and indents your code. Makes it easier to read your code when using loops within loops
Info displays information and the version number of your current copy of Sonic Pi
Help displays the help panel
Prefs shows or hides the preferences panel which allows you to change certain settings within the programming panel. For example you can toggle the displaying of line numbers to be either on or off

Creating your first sounds

Select the “Buffer 0” tab and type in the following play command:

play 60

Click on the Run button at the top of the screen. You should hear a beep at a particular tone. This tone represents the note with a value of 60. We’ll discover how these numbers relate to the piano keyboard in chapter two. The beep sound is generated because that is the default synth within the Sonic Pi software. We’ll learn how to change the synth sound later in this chapter.

What happens if you miss-type a command

What happens if you type a Sonic Pi command incorrectly. Let’s try it, change the word play to pley so it looks like this:

pley 60

Click on the Run button, and what happens?

Well no sound should be produced as the synth didn’t understand your instructions. You have to be very specific or the synth won’t be able to produce your music.

Sonic Pi Error

A red arrow will be placed next to the line which contains the instructions the synth didn’t understand. A window should also appear under the Programming Panel which contains red text telling us it has encountered an error within our code. This usually happens when Sonic Pi encounters commands it doesn’t recognise.

Sonic Pi Error

This is an example of a bug in your code. In later activities, if the error panel displays text you will know that you have a bug that you need to fix. It could be that you have misspelled a command, missed a vital comma or entered invalid values for certain commands. Some of the error messages can be quite cryptic, however when read in context with looking at the line were the red arrow is pointing, you can usually work out what the problem is.

Don’t panic, finding and correcting your mistakes is all part of being a good computer programmer. Few professional programmers can write perfect code in the first try. It’s fine to make mistake.

Issuing multiple play commands

Now let’s see what happens when you enter more than one play command.

play 60
play 67
play 69

Ask your child what they think will happen when they press the Run button. Then compare their guess with what actually happens.

The computer is playing each note in sequence one after the other. The computer is playing them so fast that to our ears they sound like they are being played at the same time. We need to tell the computer to pause between each musical note. Most computer programming languages have a command which instructs the program to pause for a specified amount of time. In Sonic Pi this command is called sleep

sleep 1

The sleep command accepts one value which represents the time to sleep in seconds. Using the value 1 represents one second. Change your code so that it looks like the example shown below with a sleep command between each play command.

play 60
sleep 1

play 67
sleep 1

play 69
sleep 1

What would you type for half a second?. Well the sleep command can accept real numbers with decimal digits. So half a second would be 0.5 and a quarter of a second would be 0.25

Below is an example were the notes get quicker as the value of the sleep command is reduced.

play 60
sleep 1

play 67
sleep 0.5

play 69
sleep 0.2

play 60
sleep 0.1

Try testing different sleep values between each note. What value or values do you think works best?

Variables

You could continue to write the value for the sleep command after each note in this manner. However, if we later decided to increase or decrease the speed of our tune, we would have to change every value on each line by hand. This would be very time consuming and boring.

Enter variables, the first programming concept we will cover. A variable is a named location in computer memory that can hold a value that we assign to it. The value of the variable can then be read and used by our program at any point. To define a variable we give it a name and assign an initial value to it using the equals sign.

t = 0.5

play 60
sleep t

play 62
sleep t

play 64
sleep t

play 60
sleep t

In the example above we have created a variable called t which we have set to half a second. Now each sleep command will pause the program by that amount. If we want to slow the music down, we just change the value of t once at the top of our code.

Try changing the value of your variable and test if it changes the speed the notes are played.

It is important to realise that our computer programs can change the value of any variable as the program progresses thus changing how the program runs. As the value of the sleep command accepts numbers, we can use all the arithmetic functions to assign new values to the variable.

Let’s say we start with the value of t equalling one second. We could just assign a new value like:

t = 1

' ... various play commands

t = 0.5

We could also add or take away a set amount from the original value as the program progresses. The example below shows three assignments to the variable t. It starts off as being one second, we then add a quarter of a second to the original value so that the value of t now becomes 1.25 seconds. We finally take off half a second from the current value of t so that the new value of t going forward is 0.75 seconds.

t = 1

' ... various play commands

t = t+0.25

' ... various play commands

t = t-0.5

Likewise we can use the division and multiply operators to change the value of a variable holding a numeric value. In the example below we again start with t being equal to one second. We then times the value of t by 2, so that t has a new value of two seconds. Finally we divide the current value of t by four. Two divided by four gives us a value of 0.5, meaning the new value of t will be half a second.

t = 1

' ... various play commands

t = t*2

' ... various play commands

t = t/4

These are just examples, yet demonstrate how you can affect the way a program runs by changing the values of a variable you have defined. Let’s look at putting this into a practical example. At the end of the chapter there is a challenge to write a short program that plays a single note which speeds up over time. But first let’s introduce you to loops.

Looping

Computers are very good at repetition and we can use loop statements within our code to get the computer to repeat all the commands within the loop block. There are two main types of loops. The first is were you specify the number of times the code within it should be repeated. The second being a forever loop, which will just continuing performing the commands until you hit the Stop button.

We’ll look at both types starting with the forever loop. Select a different buffer tab so that you have a new blank document to work with. Then type in the following code and press the Run button.

t = 0.5

loop do
    play 60
    sleep t
end

The synthesizer will play a single note continuously with a half second gap between each note. You will have to press the Stop button otherwise the music will continue forever.

Loops are quite easy to understand, they just repeat all the commands between the do keyword and the end keyword. Notice how the play & sleep commands are indented in from the left margin. They don’t have to be indented for the code to still work but it makes it easier to see which commands are inside the loop. This is especially true if you start putting loops within loops.

To indent your code you can either use spaces or hit the Tab key on your keyboard. You can also use the Align button on the toolbar to automatically indent the code for you if you haven’t done it yourself.

So let’s try it. We’ll put a loop inside the forever loop which only loops for a specific number of times. The command for this is x.times where x is the number of times you want to repeat the code between the do & end keywords. Modify the code you already have so it looks like this:

t = 0.5

loop do
    play 60
    sleep t

    2.times do
        play 70
        sleep t/2
    end
end

When you Run this code you should get a constant low note followed by two quicker higher notes. Try changing the number of times the second loop is repeated and maybe experiment with different values for the play command within that second loop.

Change the sound / synthesizer

It’s time to make the sounds more interesting! We can do this by changing the synthesizer sound that Sonic Pi uses. To use a different synth, from the default beep, you need to add the code use_synth :name of synth right at the top of your code. Where :name of synth is one of the valid synth’s Sonic Pi can use.

For example, to make the sound emulate a piano you would add the code highlighted below to the top of your program.

use_synth :piano

t = 0.5

loop do
    play 60
    sleep t

    2.times do
        play 70
        sleep t/2
    end
end

Sonic Pi has quite a few different synth’s you can use. Try changing the value :piano to each of these different synth’s and Run the code to listen to how the synth affects the music generated.

TODO: explain with screen shot how to get the list of all possible synth names.

Try using some of the other synth values and make a list of which ones you like for later use.

You don’t have to stick to playing the whole music with just one synth. You can mix it up and you should encourage your child to experiment. As an example let’s play the two higher notes in a different synth. Take a look at the code below. You can see that we have added a pretty bell synth for the notes played within the 2.times loop command.

You’ll also notice that we have had to move the piano synth command into the main loop. If we didn’t the synth would have changed to the pretty bell on the first iteration of the second loop. So every time we go around the loop we need to set the synth back to the piano so that it can play that first note using the piano synth.

Give it a go and experiment.

t = 0.5

loop do
    use_synth :piano
    play 60
    sleep t

    2.times do
        use_synth :pretty_bell
        play 70
        sleep t/2
    end
end

Challenge

Now we have explored variables and loops let’s try writing that short program which plays a single note and speeds up over time. Ask your child to think about how they could use a forever loop and use a variable to set the initial sleep value. Ask them to start with an initial sleep value of 3, and see if they understand how to reduce the value by a quarter of a second each time around the loop.

You should end up with something that looks like this code:

t = 3

loop do
    play 60
    sleep t

    t = t-0.25
end

Now if you run this code the value of t will eventually reduce to zero and then go into negative values as you keep taking 0.25 seconds off the last value. As you can’t really sleep for negative seconds Sonic Pi will complain and eventually stop running generating an error.

We can fix this using a conditional statement.

Conditional statements

A conditional statement allows programmers to check if a given value or condition is true and if it is then and only then execute the commands desired. We can use a conditional statement to check to see if the current value of t is still greater than 0.25 and if it is only then take away another 0.25 seconds. This will ensure that the value of t never goes below zero.

To check a conditional statement you use the if keyword followed by the statement you want to test. In this case we are checking if t is greater than > 0.25 and if it is then execute all the commands before the end keyword.

The end result should look something like:

t = 3

loop do
    play 60
    sleep t

    if t > 0.25
        t = t-0.25
    end
end

We’ll revisit conditional statements later in the book when we compose our own ring tones. We’ll use them to control the volume, increasing it the longer the ring tone plays.

See if your child can work out what needs to change to make the program work in the opposite way. Starting off quick and getting slower the longer it progresses. The necessary changes required are highlighted below for you.

t = 0.25

loop do
    play 60
    sleep t

    if t < 5
        t = t+0.25
    end
end

Start by changing the initial value of the t variable to 0.25, then change the greater than sign to the less sign in the conditional statement. Finally, change the minus sign to an addition sign so that the value of t increases.


Chapter 2
Creating Your First Tune

MIDI

The values that we have been typing after the play command represent actual notes on a musical scale. MIDI, short for Musical Instrument Digital Interface is a standard which maps every note on the scale to a given number and each note has it’s own unique number. For example, the number 60 is the MIDI value for the middle C on a piano keyboard. Using these values we can translate any song played on a piano into Sonic Pi code.

The diagram below represents one octave on the piano keyboard. A typical piano will have seven octaves comprising 52 white keys and 36 black keys. The octave shown goes from middle C, also know as C4, which has a MIDI value of 60 through to C5 which has a MIDI value of 72. It shows each note letter and the corresponding MIDI numeric value.

     61   62        66   68   70
     C#   D#        F#   G#   A#
 _________________________________________
|   |█|  |█|   |   |█|  |█|  |█|   |   |█|
|   |█|  |█|   |   |█|  |█|  |█|   |   |█|
|   |█|  |█|   |   |█|  |█|  |█|   |   |█|
|    |    |    |    |    |    |    |    |
| C  | D  | E  | F  | G  | A  | B  | C  |
| 60 | 62 | 64 | 65 | 67 | 69 | 71 | 72 |
|____|____|____|____|____|____|____|____|

Find the range of MIDI numbers

Ask your child to use the play command to see if they can find the range of MIDI numbers that Sonic Pi supports. See if they can find the lowest and highest audible values and make a note of them. This will come in handy when composing their own tunes.

Performing a scale

When learning any musical instrument one of the things you need to practice are your scales. This is simply playing every note between a start and end point. See if your child can think how they might create a program to play every note from middle C (which has a value of 60) to the next C on the piano keyboard (which has a value of 72)

Tip: It can be done in 8 lines!

As there are 12 notes in the scale and you would need a sleep command between each note, you can’t simply use a play command for each note. Think about how we used variables and loops in chapter 1. As the play command accepts numbers for the note value we can create a variable for the note to be played and then increment this variable every time we go around the loop.

Create a new variable called n short for note and set it’s initial value equal to 60. Each time around the loop we increase the value of n by 1. The solution is shown below.

use_synth :piano
t = 0.5
n = 60
13.times do
    play n
    sleep t
    n = n+1
end

See if your child can modify the code to include another another loop which comes back down the scale. So that the final result is a piano scale that is played up and then down again.

If you need help the final solution should look like:

use_synth :piano
t = 0.5
n = 60
13.times do
    play n
    sleep t
    n = n+1
end

13.times do
    play n
    sleep t
    n = n-1
end

Creating our first tune

Below are six lines of music for a popular tune your child should recognise when coded. Ask you child to use the diagram of the piano octave to look up the MIDI values for each of the notes and write them down.

Ask your child to then examine the sequence of notes and see if they can spot any repeating patterns as this will save them a lot of typing if they can make use of the loop commands we have already learned in chapter one.

Each line has 3 repeating note patterns, followed by a single note on its own. So each of these groups of notes can be put into a 2.times loop. Also, if you look closely at lines 3 and 4 they are also repeated, so you could just code line 3 once and then enclose it within a 2.times loop.

C  C    G  G    A  A    G

F  F    E  E    D  D    C

G  G    F  F    E  E    D

G  G    F  F    E  E    D

C  C    G  G    A  A    G

F  F    E  E    D  D    C

Have a go at coding the first line. Select a new buffer tab so that you can start coding on an empty document.

Can you name the tune? It’s Twinkle Twinkle Little Star and this is what it should sound like:

After coding the first line of notes your program should look something like:

use_synth :piano

t = 0.5

# play line one
2.times do
    play 60
    sleep t
end

2.times do
    play 67
    sleep t
end

2.times do
    play 69
    sleep t
end

play 67
sleep t

What’s the hash tag?

You might have noticed the line starting with a # character. The one that says # play line one. Any line starting with the # character is a code comment meant for the programmer to read & remind them what the code that follows is meant to do. The Sonic Pi software just reads the comments and doesn’t do anything specific with them. They are meant as an aid to the programmer.

This becomes especially useful when you start writing longer pieces of music as you can put markers in the code so you know where each bar / section begins. It’s also helpful when you return to working on a piece of code that you have not looked at in a while as it reminds you what you were trying to achieve.

Programmers also use code comments at the top of the file to name their programs and sign their name as the author of the code. Encourage your child to be proud of the code they write and sign their work. You can add a title at the top of your code like:

# Twinkle Twinkle Little Star
# by Paul Bradley

use_synth :piano

t = 0.5

...

Let’s create a code comment for the start of line two and begin adding the commands to the end of what we have already coded.

# play line two
2.times do
    play 65
    sleep t
end

2.times do
    play 64
    sleep t
end

2.times do
    play 62
    sleep t
end

play 60
sleep t

Chapter 3
Saving & Opening Files

A short chapter on how to save your work to a file and then reload it into Sonic Pi will follow shorty. However, in the meantime anything you enter into a buffer tab will be saved & reloaded when Sonic Pi is restarted.

Being able to save your work to an external file only becomes necessary when you are working on and experimenting with more than ten bits of code that the ten buffer tabs can hold.


Chapter 4
Attack, Release, Sustain & Amplitude

Most musical instruments allow you to control how a given note is actually performed. Consider the humble recorder. You can control how long a note is played by blowing through the instrument for a longer time. You’re only really limited by how long you can control your breath before needing to take in more air.

Likewise you can control the volume of a note by either blowing gently to produce a quieter sound or by blowing forcefully to increase the volume. You can also add expression to your playing by starting the note quietly and progressively getting louder over time. You can also fade the note out over time by gradually getting quieter.

Sonic Pi can replicate this behaviour by using one or more parameters after the play command. We have already looked at using the sustain parameter in chapter 2. We used it to make the last note of each line of Twinkle Twinkle little star play for longer.

So let’s look at each of these parameters in turn and listen to the affect they have on a note when it’s played.

Sustain

Sustain is used to give the note duration. This parameter expects a numeric value which indicates the duration in beats for the sound to stay at full volume. So let’s start by playing a low piano note for two seconds. Select a new buffer tab which is empty and type in the following code:

use_synth :piano

play 40, sustain: 2

To instruct the play command that we want to use parameters we need to put a comma character after the MIDI note number. See how the word sustain is also followed by the colon character. The colon is important, if you miss it out Sonic Pi will generate an error.

Try changing the value 2 to make the note play for different lengths of time. It’s worth noting that the sustain parameter can also accept numbers with decimal points. For example, you can hold a note for five and a half seconds by using 5.5 as the sustain value.

Amplitude

Amplitude controls the volume of the note. This will become useful when we start coding multiple instruments playing at the same time. It allows us to control which instruments should be the loudest and which should be just backing accompaniment.

Modify the code so that we now add the amp (short for amplitude) parameter with a value of one. Notice how we have had to add a comma character after the number two for the sustain parameter. This is because we have to separate each parameter of the play command with the comma character so that the Sonic Pi software can correctly distinguish each individual parameter values.

use_synth :piano

play 40, sustain: 2, amp: 1

When you Run this code, it shouldn’t sound too different to the last example. This is because the default value of amplitude is one. Try changing the value to 0.2 and re-running the code and you should hear that the note is played much quieter.

Attack

The attack parameter allows you set the duration for the note to reach maximum volume. You can choose short values for percussive sounds and longer durations for a fade-in effect.

Let’s try a fade-in effect by changing both the sustain & amplitude values to five. Then add an attack parameter for one second. This will fade the note in for one second and hold at full volume for five seconds.

use_synth :piano

play 40, sustain: 5, amp: 5, attack: 1

Release

The release parameter works in the opposite way to attack. It allows you set the duration for the note to fade out. So by adding a release value to the end of the code we already have written, the final result should be a note which fades in for one second, is held and then fades out over a second.

use_synth :piano

play 40, sustain: 5, amp: 5, attack: 1, release: 1

Get the computer to compose a haunting melody

Computers are very good at automating tasks and particularly good at generating random numbers. We can use this characteristic to write a program which instructs the computer to compose a different melody every time the code is run.

To achieve this we will use a new Sonic Pi command to generate a set of random numbers. These random numbers will be used for each of the different parameters we have just covered. The command to generate random numbers is called rrand which takes two numbers, a minimum and a maximum, and generates a random number between those two values.

For example, to play a random MIDI note between forty and seventy you would use the output from the rrand command as input into the play command like:

    play rrand(40, 70)

To make our haunting melody we are going start by using the :hollow synthesizer, which produces a breathy sound constructed from random noise. We want the computer to just keep on composing music, so we’ll use a continuous loop by using the loop do / end keywords.

Next we’ll create variables for the note as well as each of the parameters the play command accepts. Using the rrand command we can set the values of each variable to a random value within a meaningful range. Each time around the loop all our variables will get assigned new random values which is what makes the composition different every time.

use_synth :hollow

loop do
    note = rrand(50, 70)
    sus  = rrand(0.1, 3)
    vol  = rrand(0.2, 2)
    att  = rrand(0.2, 1)
    rel  = rrand(0.2, 1)

    play note, sustain: sus, amp: vol, attack: att, release: rel
    sleep sus+att+rel
end

You can see from the finished code example above we use the variables in the play command to pass in the random numbers generated.

As we are using all three parameters which affect the duration a note is played, we need the sleep command to sleep for the correction duration. We can do this by adding the values of the three variables for sustain, attack and release together.

Try changing the value of the sleep command to just use the value of the sustain variable. This might actually make the music sound more haunting as new notes start playing as others are still fading out.

Try experimenting with different synthesizers to see how it affects the music.

Here is an example of how it might sound:


Supporting this guide

If you have enjoyed working through these first couple of chapters, please consider supporting the creation of new sections and exercises. This guide is provided through a pay-what-you-like model, anything from $1 upward. By supporting my writing you’ll get updates about changes, additions and access to exclusive videos.

Upcoming chapters will cover creating drum machines and composing your own mobile phone ringtone. Listen to an example created in one of my classes by a student.

So if you’d like to learn to read music and be able to code classics like the example below then please support this resource. Thanks.

Moonlight Sonata by Ludwig van Beethoven


Index

© 2016 Paul Bradley
All rights reserved. This book or any portion thereof may not be reproduced or used in any manner whatsoever without the express written permission of the publisher except for the use of brief quotations in a book review.