This task is part of project10 which is due at 23:00 EST on 2024-11-19.
You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.
You can download the starter code for this task using this link.
You can submit this task using this link.
Put all of your work for this task into the file
recursiveScales.py
(you will create this file from scratch)
This task and the recursiveCircles task are very
similar. This task is based on audio using the wavesynth
library, while
the recursive circles task is based on turtle
graphics instead. You
may choose to do either task, but you do not need to do both.
In this task, you will create a file named recursiveScales.py
and write
functions scale
, unevenScale
, and rungsListMelody
within it, the
first two of which which are similar to the functions with the same names
from the earlier "scales" task. However, for this task, you
are not allowed to use any loops, and must use recursion instead.
If you didn't do the scale task before, you should review
that material before starting this task, and you may need to familiarize
yourself with the wavesynth
library.
It may be easier to do the recursiveCircles task
instead of this one in that case.
scale
This function works like the scale
function from the earlier task of the same name, and takes equivalent
parameters:
scaleDuration
determines the duration of the entire scale.notesUp
determines the number of notes in the scale.It should behave exactly like scale
from the earlier task: it must add
a number of notes to the current track, each one step above the
last. climbUp
must be used to increase the
pitch. The number of notes added
is determined by the second parameter, and the duration of each note is
the same, so the total scale duration is split evenly between the notes.
For example, if there are 4 notes and the total duration is 1 second,
each note will be 1/4 second long.
Whereas in the previous task this problem was solved using a loop, in
this task, you may not use any loops
and you must use recursion. As an extra goal, you should only include a single call to
addNote
and you
should only include a single recursive
call.
Hint: Each recursive function call frame needs to add just one note.
These scale
examples demonstrate what it should print
and what the results should sound like.
unevenScale
This function works exactly like
unevenScale
from the non-recursive scale task, taking equivalent
parameters:
notesUp
determines the number of notes in the scale.startLength
determines the length of the first note in the scale, and
every odd-numbered note after that.otherLength
determines the length of the even-numbered notes in the
scale (every other note starting from the second one).As before, notes are added stepping up one step at a
time using
climbUp
, but now every
other note has a different duration.
Just like in the previous function, you may not use any
loops and you must use
recursion. Also as
above, as extra goals, you should use addNote
in only one
place, and you should
also only include a single recursive
call.
These unevenScale
examples demonstrate what the
printed output and audio should be.
rungsListMelody
This function is a new function:
given a total duration and a list of rung values, it must add notes to
the current track which follow the pattern of climbing up and/or down
that is provided. Specifically, it
will add one note at the current pitch, even if the rungs list is empty.
If the rungs list is not empty, it will contain positive and negative
integers, and subsequent notes should be added climbing up or down that
many rungs in pitch. Note that it must use the climbUp
function, which can
accept an argument to specify how many steps to take, and negative values
will cause it to climb down, so you can simply pass the numbers from the
rungs list directly to the climbUp
function. As a concrete example, if
the rungs list is [3, -2, 1] then the notes added would be:
Just like turtle keeps track of the current drawing position, wavesynth
keeps track of the "current pitch" which is what climbUp
changes and
what addNote
uses to determine the pitch of the note it creates.
As with the other functions in this task, you may not use
loops and you must use
recursion.
Also as before, as extra goals, you should call addNote
in only one
place and you
should include only one recursive
call.
Hint: The total number of notes in the melody is always one more than the number of intervals in the rungs list, because the rungs represent pitch changes in between notes.
These rungsListMelody
examples demonstrate
what the printed output and audio should be.
scale
examples
These examples demonstrate what the printed output and audio results of
the scale
function should be. Note that you must call saveTrack
and
then open the specified file with an audio player to hear the notes
added, and if you call multiple functions that add notes without calling
eraseTrack
in between, the notes will all pile into the same track.
You can also call playTrack
to have Python play the sound directly,
but you will need to use the package manager to install the
simpleaudio
package for that to work. Note that each example below
uses setPitch
before calling scale
, since scale
starts from
whatever the current pitch happens to be.
In []:PrintssetPitch(C4) scale(2, 8) printTrack()
a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at D4 (60% vol) and a 0.25s keyboard note at E4 (60% vol) and a 0.25s keyboard note at F4 (60% vol) and a 0.25s keyboard note at G4 (60% vol) and a 0.25s keyboard note at A4 (60% vol) and a 0.25s keyboard note at B4 (60% vol) and a 0.25s keyboard note at C5 (60% vol)Audio In []:PrintssetPitch(C4) scale(1.2, 5) printTrack()
a 0.24s keyboard note at C4 (60% vol) and a 0.24s keyboard note at D4 (60% vol) and a 0.24s keyboard note at E4 (60% vol) and a 0.24s keyboard note at F4 (60% vol) and a 0.24s keyboard note at G4 (60% vol)Audio In []:PrintssetPitch(A3) scale(1.6, 4) printTrack()
a 0.4s keyboard note at A3 (60% vol) and a 0.4s keyboard note at B3 (60% vol) and a 0.4s keyboard note at C4 (60% vol) and a 0.4s keyboard note at D4 (60% vol)Audio
unevenScale
examples
These examples demonstrate what the printed output and audio results of
unevenScale
should be. Once again, setPitch
is used beforehand to
determine the starting pitch.
In []:PrintssetPitch(C4) unevenScale(5, 0.3, 0.15) printTrack()
a 0.3s keyboard note at C4 (60% vol) and a 0.15s keyboard note at D4 (60% vol) and a 0.3s keyboard note at E4 (60% vol) and a 0.15s keyboard note at F4 (60% vol) and a 0.3s keyboard note at G4 (60% vol)Audio In []:PrintssetPitch(C4) unevenScale(6, 0.4, 0.3) printTrack()
a 0.4s keyboard note at C4 (60% vol) and a 0.3s keyboard note at D4 (60% vol) and a 0.4s keyboard note at E4 (60% vol) and a 0.3s keyboard note at F4 (60% vol) and a 0.4s keyboard note at G4 (60% vol) and a 0.3s keyboard note at A4 (60% vol)Audio In []:PrintssetPitch(A3) unevenScale(8, 0.2, 0.36) printTrack()
a 0.2s keyboard note at A3 (60% vol) and a 0.36s keyboard note at B3 (60% vol) and a 0.2s keyboard note at C4 (60% vol) and a 0.36s keyboard note at D4 (60% vol) and a 0.2s keyboard note at E4 (60% vol) and a 0.36s keyboard note at F4 (60% vol) and a 0.2s keyboard note at G4 (60% vol) and a 0.36s keyboard note at A4 (60% vol)Audio
rungsListMelody
examples
These examples demonstrate what the printed output and audio results of
rungsListMelody
should be. Note that even when the list of steps is
empty, a single note is added to the track, taking up the full specified
total duration.
In []:PrintssetPitch(C4) rungsListMelody(0.5, []) printTrack()
a 0.5s keyboard note at C4 (60% vol)Audio In []:PrintssetPitch(C4) rungsListMelody(1, [3, -2, 1]) printTrack()
a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at F4 (60% vol) and a 0.25s keyboard note at D4 (60% vol) and a 0.25s keyboard note at E4 (60% vol)Audio In []:PrintssetPitch(C4) rungsListMelody(2, [3, -2, 1, -2, 3, -2, 1]) printTrack()
a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at F4 (60% vol) and a 0.25s keyboard note at D4 (60% vol) and a 0.25s keyboard note at E4 (60% vol) and a 0.25s keyboard note at C4 (60% vol) and a 0.25s keyboard note at F4 (60% vol) and a 0.25s keyboard note at D4 (60% vol) and a 0.25s keyboard note at E4 (60% vol)Audio In []:PrintssetPitch(C4) rungsListMelody(3, [2, 2, 1, 2, 2, 1, -3, 2, -3, 1]) printTrack()
a 0.273s keyboard note at C4 (60% vol) and a 0.273s keyboard note at E4 (60% vol) and a 0.273s keyboard note at G4 (60% vol) and a 0.273s keyboard note at A4 (60% vol) and a 0.273s keyboard note at C5 (60% vol) and a 0.273s keyboard note at E5 (60% vol) and a 0.273s keyboard note at F5 (60% vol) and a 0.273s keyboard note at C5 (60% vol) and a 0.273s keyboard note at E5 (60% vol) and a 0.273s keyboard note at B4 (60% vol) and a 0.273s keyboard note at C5 (60% vol)Audio
=
or by defining a parameter for a function) you must also later use that variable as part of another expression. If you need to create a variable that you won't use, it must have the name _
, but you should only do this if absolutely necessary.scale
must produce the correct note sequence
scale
is called must match the solution notes in terms of timing, instruments, pitches, and volumes.unevenScale
must produce the correct note sequence
unevenScale
is called must match the solution notes in terms of timing, instruments, pitches, and volumes.rungsListMelody
must produce the correct note sequence
rungsListMelody
is called must match the solution notes in terms of timing, instruments, pitches, and volumes.scale
must produce the correct note sequence
scale
is called must match the solution notes in terms of timing, instruments, pitches, and volumes.unevenScale
must produce the correct note sequence
unevenScale
is called must match the solution notes in terms of timing, instruments, pitches, and volumes.rungsListMelody
must produce the correct note sequence
rungsListMelody
is called must match the solution notes in terms of timing, instruments, pitches, and volumes.scale
with 2 parameters
def
to define scale
with 2 parametersscale
with 2 parameters, do not use any kind of loop.scale
with 2 parameters, use an if
statement (possibly accompanied by an elif
or else
block) in at least one place.climbUp
scale
with 2 parameters, call climbUp
in at least one place.scale
scale
with 2 parameters, call scale
in at least one place.scale
with 2 parameters
def
to define scale
with 2 parametersscale
scale
with 2 parameters, call scale
in exactly one place.addNote
scale
with 2 parameters, call addNote
in exactly one place.unevenScale
with 3 parameters
def
to define unevenScale
with 3 parametersunevenScale
with 3 parameters, do not use any kind of loop.unevenScale
with 3 parameters, use an if
statement (possibly accompanied by an elif
or else
block) in at least one place.climbUp
unevenScale
with 3 parameters, call climbUp
in at least one place.unevenScale
unevenScale
with 3 parameters, call unevenScale
in at least one place.unevenScale
with 3 parameters
def
to define unevenScale
with 3 parametersunevenScale
unevenScale
with 3 parameters, call unevenScale
in exactly one place.addNote
unevenScale
with 3 parameters, call addNote
in exactly one place.rungsListMelody
with 2 parameters
def
to define rungsListMelody
with 2 parametersrungsListMelody
with 2 parameters, do not use any kind of loop.rungsListMelody
with 2 parameters, use an if
statement (possibly accompanied by an elif
or else
block) in at least one place.climbUp
rungsListMelody
with 2 parameters, call climbUp
in at least one place.rungsListMelody
rungsListMelody
with 2 parameters, call rungsListMelody
in at least one place.rungsListMelody
with 2 parameters
def
to define rungsListMelody
with 2 parametersrungsListMelody
rungsListMelody
with 2 parameters, call rungsListMelody
in exactly one place.addNote
rungsListMelody
with 2 parameters, call addNote
in exactly one place.