1. Chapter One: Getting Started
1.1. Programming basics
Computers are programmable machines that process information by manipulating data. As the data can represent any real world information, and programs can be readily changed, computers are capable of solving many kinds of problems.
Programs are created in a programming language by writing a series of instructions into a text file. The basic unit of a program is called a statement. As the name indicates, a statement is simply a command for the computer. It instructs the computer to do something. For example, the line
1
setTempo(120)
instructs the computer to set the tempo of a song to 120 beats per minute, about the tempo of an average pop song. A collection of statements is called a block. A block can be stored and reused as a function.
The files containing the program (source) code are translated into executable applications or software. Most programs are intended to serve as interactive tools for customers referred to as users. Users interact with programs in many ways including:
-
Text user interfaces using the keyboard and a console.
-
Graphical user interfaces (GUI) using a keyboard, mouse, monitor, touch screen, …
-
Audio user interfaces using speakers and/or a microphone.
-
Combinations of all of the above along with emerging technologies like brain wave interfaces, 3D printers, virtual reality headsets, bio implants, …
1.2. Programming Languages and Environments
There are many different programming languages for programmers to choose from. Each language has its own advantages and disadvantages, and new languages gain popularity while older ones slowly lose ground. In this book, we use the Python 2.7 programming language. It is popular in both academia and industry and was designed with education in mind.
There are many different environments where a programmer may write and test Python. We will utilize a few different environments throughout the semester, but we will start with 2 web-based environments: PythonTutor and EarSketch.
1.3. PythonTutor
PythonTutor is an environment for creating very short and simple Python programs and visualizing their execution. This enables beginners to visually see the data as it gets manipulated by the instructions.
PythonTutor Example 1.1
1.4. Introduction to EarSketch
EarSketch is a DAW (Digital Audio Workstation) that allows users to create music using Python. It has built-in sound clips made by professionals in the music industry for users to mix and combine into novel musical compositions. Instead of providing a GUI interface for users (such as Garageband from Apple), Earsketch provides an IDE (integrated development environment) where users can write Python code to create music. EarSketch runs in a web browser without installing any additional software. Earsketch currently supports Firefox, Chrome, and Safari. (Internet Explorer is not supported.)
Running a script
A typical EarSketch script follows the template below:
1
2
3
4
5
6
7
8
9
10
11
12
# Author: A User
# A simple EarSketch script
from earsketch import *
init()
setTempo(120)
# Your code goes here
insertMedia(ELECTRO_DRUM_MAIN_BEAT_008,1,1)
finish()
Click the link below to open this script in EarSketch.
In EarSketch, press the green "Run" button above the code editor. Then press the green play button to listen to the music produced by the code.
Rhythm and Tempo
“Rhythm describes how the music moves through time as a series of notes of different lengths. These rhythms reference a song’s beat, which is a steady pulse that serves as the basic unit of time in music. If you have ever clapped along to a song, you were probably clapping to the beat. Beats can be divided into sub-beats and they can be grouped into measures.”
So how long does a beat last? The length depends on the overall speed of the song, called the tempo. Tempo is measured in beats per minute (bpm). If we are clapping at 60 bpm, then each beat lasts one second. At 120 bpm, each beat takes half a second. The higher the bpm, the faster the song, the shorter the duration of each beat.
Beats are grouped into measures, with the same number of beats in each measure. In EarSketch, measures always have four beats. You may have noticed above that you can clap along to a song in quite a few ways that seem to fit. For example, if you clap once every 4 beats, you are clapping once every measure.
The EarSketch Workspace
Here are the different sections of the EarSketch workspace:
Accounts (top right): Log in, create an account, or reset your password.
Sound Browser: Browse or search 4000 sound clips to use in your music, made by musicians/producers Young Guru and Richard Devine. You can also record your own sounds or upload sound files from your computer.
Scripts Browser: When you write code in EarSketch, your scripts are automatically saved to the EarSketch server. Go here to find your saved scripts, open them, export them as WAV or MP3 sound files, and share them with others.
Share Browser: When you open an EarSketch script shared with you by someone else, this will show you information about the script and additional options.
API Browser: Information on every EarSketch function.
Digital Audio Workstation (DAW): A timeline view of your current song, showing which sound clips you have added to the song and when they come in. It lets you hear your song, and also visualize its structure.
Code Editor: A text editor with numbered lines. Type your code here, press "Run", and it will turn into music in the DAW.
Console: The console displays important information about your code as it runs, including the location of errors in your code. It is a common and important feature in programming tools.
The DAW in Detail
Take a look at the DAW. The DAW consists of several items:
Playhead: The red line, which represents your playback location in the timeline. The play button will start playback at the playhead’s location.
Transport Controls: The buttons at the top right of the DAW. You’ve probably seen most of these in a media player like iTunes. From left to right, the buttons are:
-
Play/Pause: Press this to hear the music you’ve added. Playback begins at the playhead.
-
Reset: Press to jump the playhead back to the beginning.
-
Loop: When the playhead reaches the end of the timeline, automatically start playing from the beginning again.
Toggle Metronome: Play a click track over your music.
Measure Numbers: At the top of the DAW timeline, there is a horizontal series of numbers. If this were a normal timeline, the numbers would represent minutes and seconds; however, here they represent measure numbers. A measure is a unit of musical time that depends on the speed (a.k.a.tempo) of a song. The tempo has to be specified in every script. For now, think of a measure as a block of time. This is how we tell EarSketch where to place our sound clips. Click on a measure number to move the playhead to it.
Sound Clips: If you have added music to the DAW, the DAW should display some boxes with squiggly lines inside. These are sound clips. They provide a visual representation of the sounds they contain.
Tracks: Every sound clip is placed on a specific track. Tracks are the rows that run across the DAW; they are numbered on the left. Tracks help you organize your sounds by instrument-type: for example, in a recording studio you would record each instrument (vocals, lead guitar, rhythm guitar, bass, drums, etc.) on a separate track. You can only have one sound clip at a given time on each track, so having multiple tracks also means you can overlap them.
Effects Toggle: Show or hide the effects added on each track, if you have any. Note that the effects will still play back; the toggle is just for visuals.
Solo/Mute: Next to each track number, the "S" and "M" stand for solo and mute. Mute turns off playback for that track, and Solo turns off playback for all other tracks.
1.5. EarSketch Chapter Projects
Each Chapter (except this one) will end with an EarSketch project which will allow you to create your own musical composition from scratch. The program will need to use the relevant concepts from the chapter. Peers will provide feedback both on how the music sounds and how the code looks.
2. Chapter Two: Data Types, Variables, and Expressions
2.1. Comments
Program files can contain source code and comments. Comments are not instructions for the computer to follow, but instead notes for programmers to read. Comments in Python start with a pound sign (#). Anything following the pound sign, on the same line, will not be executed. Often, at the very beginning of a program, comments are used to indicate the author and other information. Comments are also used to explain tricky sections of code or disable code from executing.
1
2
3
4
5
6
# This line is not Python code, it is a comment.
setTempo(120) # sets beats per minute.
# The next line of code is disabled because is starts with a #.
# setTempo(480)
2.2. Importing a module
At the beginning of many Python programs, there will be statements which use the import keyword. These statements enable the program to use specific functions contained in a module. For example, all EarSketch programs begin with the line of code below.
1
from earsketch import *
Once this line is executed, the entire application programming interface (API) of EarSketch is enabled. This allows the program to use functions like init()
, setTempo()
, and insertMedia()
. Function calls are covered in more detail in Chapter 3.
2.3. Data Types
Programming is all about information processing. Information is categorized by data types. Three basic data types are int (integer), float, and string. Integers are whole numbers (without a decimal point). Floats are numbers that include decimal places. Strings are text (sequences of characters) including punctuation, symbols, and whitespace. Every value in Python has a corresponding data type. The table below shows examples of ints, floats, and strings.
Data Type | Example Values |
---|---|
int |
2, -2, 0, 834529 |
float |
2.0, -2.235, 0.0, 8329.123782 |
string |
"Hello World!", 'Coconut', "0", '4 + 6' |
Strings and Quotes
Strings are always surrounded by quotes. Python allows either single (') or double(") quotes. Some strings may look like numbers, but as long as they are surrounded by quotes, they are treated like text. |
2.4. Variables
Variables are (virtual) boxes that store values for reuse later. A variable has a name and a current value. Each variable can only hold one value at a time. Variables are assigned a value using the single equal sign (=). As Python executes one line at a time, variables come into existence on the line where they are first assigned.
PythonTutor Asg. 2.1
Variable Names
Variables can have complex names like player1_score. In general, never start a variable name with numbers, and never use spaces. |
EarSketch Example 2.1
EarSketch Asg. 2.1
2.5. Operators and Expressions
Python supports many operators including the standard numeric operators (+ - * /), the remainder operator (%) for integer division, and others. Different operators do different things depending on the data types used. For example, + does addition for ints, but concatenation for strings. Operators, values, and existing variables combine to form expressions. Play with the program below and learn how to predict the return value of expressions. Can you explain how Python divides floats versus integers?
PythonTutor Asg. 2.2
Expression Evaluation
When Python encounters a line with an expression, it always evaluates the expression first.
Python first calculates the return value of the expression by using the standard order of operations and starting inside the parentheses. Then, Python creates the variable and stores the return value (14). The variable only stores the returned value, not the entire expression. |
EarSketch Example 2.2
2.6. Modifying Variables
As you might expect, variables can have their values changed. As a variable can only hold 1 value at a time, the previous value of the variable gets erased when a new value is stored. The single equal sign (=) stores a new value in a variable. The += increments a variable by doing a + operation on the previously stored value.
PythonTutor Asg. 2.3
EarSketch Example 2.3
EarSketch Asg. 2.2
2.7. Constants
Some Python modules come with pre-defined variables that can be used at anytime. These are referred to as constants and should never be modified.
PythonTutor Example 2.1
EarSketch Example 2.4
2.8. Using The EarSketch Sound Library
To find sound clips that work well together in your music, choose them from the same folder. For example, pick all your sounds from DUBSTEP_140_BPM or all of them from Y30_68_BPM_B_MINOR.
To hear a sound clip, click the play button next to its name. To use a sound clip in EarSketch, click the paste button to paste the sound’s constant into your script at the current cursor position. To help you find sound clips, you can search by keyword and you can filter by artist, genre, and instrument.
As you get more comfortable creating music with EarSketch, you may want to experiment some more by combining sound clips from several different folders in the same song and by trying out different tempos. When experimenting, use your musical ear to help you decide what sounds good and what doesn’t, and try a bunch of different possibilities to figure out what you like best.
2.9. Chapter 2 Project
3. Chapter Three: Using Functions
3.1. Function Calls
In the last chapter, we introduced the basic mathematical operators (+ - * /). There are many other operations we might want to perform on data but there are not enough symbols for all of them. Instead, programmers use functions, which have a name and perform some complex operation given the appropriate inputs. Like the addition operation, they take input values, called parameters, and can result in a return value. The following program has two example function calls to the len()
function. The len()
function calculates the length of a string. On the first line, the input parameter value is the string "Mississippi" and the return value is the integer 11. On the second line, the input is "Hi there!" and the return value is 9.
PythonTutor Example 3.1
Function Calls and Parentheses
To call a function, use its name followed by parentheses (). Place all the input parameter values inside the parentheses separated by commas.
Ex: randint(10, 20)
|
3.2. Function Calls in EarSketch
EarSketch includes a special set of functions for making music in Python. To use the EarSketch functions, always import the EarSketch application programming interface (API) at the top of your Python script:
from earsketch import *
We have already used several EarSketch functions, including init()
, setTempo()
, insertMedia()
, and finish()
.
Inserting Clips
The insertMedia()
function is what allows you to place sound clips into the EarSketch DAW. The function takes in 3 parameters:
-
clipName: A string specifying the name of the sound clip to add. Although this is a string, we typically use a string constant from the EarSketch sound library for this parameter.
-
track: An int specifying the track to add the clip to. Track 1 is the first track in the DAW.
-
startMeasure: A float specifying the measure location to place the clip on the track. Measure 1 is the beginning of the song.
Setting Effects
Another useful function is setEffect()
. It allows you to apply audio effects to your tracks to enhance the sound. This function takes in 4 parameters:
-
track: An int specifying the track to add the effect to.
-
effectName: A string (constant) specifying name of the effect (e.g. VOLUME)
-
effectParam: A string (constant) specifying the parameter of the effect to set (e.g. GAIN)
-
paramValue: A float specifying the value of the effect parameter.
There are many effects available in EarSketch such as VOLUME (how loud a track is), PAN (best heard with headphones, this is where the sound lies in stereo from left to right), DELAY (adds echos to the sound), and DISTORTION (makes a sound lofi and noisier). Most effects have multiple parameters which can be adjusted. Below are some of the most common effect parameters and examples of their sound in popular music.
VOLUME
-
GAIN: The amount to change the volume. Ranges from -60.0 decibels to 12.0 decibels with 0.0 being the original volume.
The song “More Than a Feeling” by Boston begins with a volume fade in. A fade in is accomplished by slowly increasing the volume gain.
PAN
-
LEFT_RIGHT: Adjusts where the sound falls between the left and right stereo speakers or headphones. Ranges from -100.0 (all the way left) to 100.0 (all the way right) with 0.0 being in the center.
In Queen’s song “Now I’m Here”, the left-right pan of vocal parts is manipulated.
DELAY
-
DELAY_TIME: Adjusts time between echoes in milliseconds (ms). Ranges from 0.0 (no delay) to 4000 (4 second delay).
-
MIX: Adjusts the volume of the delayed sound verses the original sound without delay. 0.0 is no delayed sound and the full original sound, while 1.0 is full delayed sound and no original sound. 0.5 is equal volumes of both the original and delayed sounds.
The Pink Floyd song “Us and Them” features delay on the vocal part starting around 1:38.
DISTORTION
-
DISTO_GAIN: The amount of distortion applied to the signal. Ranges from 0.0 (no distortion) to 50.0 (maximum distortion).
The song “Revolution” by The Beatles is iconic for its use of heavily distorted guitar.
If you are interested in what other effects and parameters can be used in EarSketch, look in the curriculum panel on the right side of EarSketch under "Every Effect Explained in Detail".
Other EarSketch Functions
There are many more functions included with Earsketch which are all documented in the API browser. To access the browser within EarSketch, click on the API icon on the left side of the EarSketch workspace.
EarSketch Example 3.1
EarSketch Asg. 3.1
3.3. Data Type Conversion Functions
In the last chapter, we introduced the basic data types int, float, _and _string. As you know, different operations (such as +) work different ways on different data types. Therefore, it is very useful to convert data from one type to another. Learn the functions below:
-
str()
- convert any value into a string. -
int()
- convert a string containing digits into an int. -
float()
- convert a string containing digits with a decimal point into a float.
In the following code example, pay special attention to the types of data stored in each variable. Remember, all strings are surrounded in quotes "".
PythonTutor Asg. 3.1
PythonTutor Example 3.2
EarSketch Example 3.2
3.4. Combining Expressions
In the last chapter, we introduced expressions. Generally, an expression is any code that returns a value. Furthermore, anywhere it is legal syntax to use a value, it is legal syntax to use an expression instead. This gives rise to function chaining and complex expressions.
PythonTutor Asg. 3.2
3.5. Random Numbers
The random()
function takes no input parameters and returns a random float greater or equal to 0 and less than 1.
The randint()
function takes 2 integer input parameters and returns a random int somewhere betweeen them (inclusive).
Importing Random Functions
In Chapter 1, we explained how importing modules enables specific functions for a script. The code below uses |
PythonTutor Example 3.3
EarSketch Example 3.3
EarSketch Asg. 3.2
3.6. Console User Interaction
A console, also known as a shell or terminal, is a user interface which allows programs to interact with humans through text. Unlike graphical user interfaces, a console does not allow for images, sound, video, or even mouse input.
The print()
function displays a value to the console user. It does not return a value, so it can not be part of an expression.
The input()
function returns a string typed by a user in the console. It takes 1 input string parameter to display as a question prompt for the user. As input()
always returns a string, we frequently use the data type conversion functions to change the value to an integer or a float.
PythonTutor Asg. 3.3
EarSketch Example 3.4
EarSketch Asg. 3.3
Unpredicatable Values
Some functions like input() and randint() return values that the programmer can not predict in advance. In most textbook examples, it is clear what value a variable will hold, but in most real world examples, programmers only know the data type of a variable, not its value.
|
3.7. Chapter 3 Project
4. Chapter Four: Conditions
4.1. Making Decisions
Computers make decisions that give the illusion of "thinking". For example, a digital thermostat turns on or off the heater depending on the current temperature in the room. IBM’s Big Blue computer decides what chess piece to move next when beating world chess champions. Google’s self-driving car decides when to apply the brakes depending on what is in front of it. All computer decisions are based on conditions built out of a simple logic called Boolean logic.
4.2. Booleans
The boolean data type has just 2 possible values; True and False. This contrasts with the other data types (int, float, string) that have near-infinite possible values. The True and False values always start with a capital letter. The following example assigns the boolean value of False
to the variable a
.
1
a = False
Never put quotes ("False") around a boolean value. Quotes will make Python think it is a string. |
Comparison Operators
The comparison operators are often used to generate boolean values. They can compare 2 ints (or other data types) and return either True or False.
> |
Greater Than |
>= |
Greater Than or Equal |
< |
Less Than |
<= |
Less Than or Equal |
== |
Equals |
!= |
Not Equals |
Equality vs. Storage
Checking if two values are identical (==) is unrelated to storing a value in a variable (=).
|
PythonTutor Asg. 4.1
4.3. Boolean Operators
Just like ints have numeric operators (+ - * /), booleans have their own operators. The 3 boolean operators are and, or, and not.
True and False
The and operator takes 2 boolean inputs and returns True only when both inputs are True, False otherwise.
False or True
The or operator takes 2 boolean inputs and returns True when at least 1 input is True, False otherwise.
not True
The not operator takes 1 boolean input and returns the opposite (negated) boolean.
PythonTutor Asg. 4.2
4.4. If Statements
Boolean logic allows a program to make a decision based on a condition. The if statement executes specific lines of code only when the condition is True
. If the condition is False
, the lines are skipped. The lines of code to be executed are grouped with indentation (tabs or spaces) into a block. Code blocks are always preceded by a colon (:).
PythonTutor Asg. 4.3
EarSketch Example 4.1
EarSketch Asg. 4.1
4.5. If, Elif, Else
As we learned above, if statements will either execute or skip 1 block of code depending on the condition. In some situations, we want to choose between 2 blocks of code depending on the condition. This can be done with the if …else… statement.
PythonTutor Asg. 4.4
EarSketch Asg. 4.2
In some situations, we want to choose to execute 1 block out of 3 or more options. This requires multiple conditions combined with the if…elif…else… statements.
PythonTutor Asg. 4.5
EarSketch Example 4.2
EarSketch Asg. 4.3
4.6. While Loops
As we learned above, the if statement allows us to execute a code block one time if a condition is True. The while statement, on the other hand, allows us to execute a code block repeatedly while a condition is True. This allows our code to loop potentially infinite times. To prevent infinite looping, the code block typically modifies the variable used in the condition. For example, the value of x
is increased with every loop in the code snippet below.
x = 1 while x < 5: x += 1
PythonTutor Asg. 4.6
EarSketch Example 4.3
EarSketch Asg. 4.4
4.7. Input Validation
While loops are often used to validate user input. Users will often enter incorrect data repeatedly (invalid birth month for example). We can use a while loop, along with a condition for invalid data, to repeatedly ask the user for valid input. Notice what happens in the example below when the user inputs numbers like 14, and 112, before entering a valid month.
PythonTutor Asg. 4.7
4.8. Chapter 4 Project
5. Chapter Five: String Indexes and Loops
5.1. More Functions in EarSketch
In this chapter, we will use two new EarSketch functions which will be very useful for the rest of the course, fitMedia()
and makeBeat()
.
At the end of the last chapter, we used while loops with insertMedia()
to repeat clips many times in a row. This is such a useful feature for making music that EarSketch provides a built in function to do this without a loop, the fitMedia()
function.
fitMedia()
takes four arguments:
-
clipName: A string (or constant) specifying the name of the sound clip to add.
-
track: An int specifying the track to add the clip to.
-
startMeasure: A float specifying the measure location to place the clip on the track.
-
endMeasure: A float specifying the measure location to stop the clip.
The ability to specify the end location gives the freedom to play only a short segment of a clip or to automatically repeat it as much as needed such as in the example below.
EarSketch Example 5.1
So far, we’ve been making music using pre-made clips and loops on the measure level, but we can also create custom music on the beat level using an EarSketch function called makeBeat()
.
makeBeat()
takes four arguments:
-
clipName: A string (or constant) specifying the name of the sound clip to add.
-
track: An int specifying the track to add the clip to.
-
startMeasure: A float specifying the measure location to place the clip on the track.
-
beatString: A string which defines the rhythm of the beat.
The beat string is usually 16 characters long (which equals 1 measure) and looks something like this:
myBeat = “0-00-00-0++0+0”
Every character stands for one sixteenth-note sub-beat of a measure.
-
0
starts playing the clip. -
-
is a rest, meaning that there’s nothing being played. -
`` extends the sound clip into the next sixteenth-note sub-beat, so it should always follow either a ``0`` or a ``
.
EarSketch Example 5.2
EarSketch Asg. 5.1
5.2. Indexes
Strings in Python can vary in length from 0 characters to millions of characters (limited by the computer’s memory). As such, we often need to break down strings into shorter fragments or individual characters in order to process them. String processing starts with the concept that each character in a string has a unique index which represents its position in the string. Indexes start with the first chracter at position 0, and end with the last character at position length - 1. The indexes for the string "Hi There" are below. Note that the string is of length 8, and thus has indexes from 0 to 7.
String Characters: |
H |
i |
T |
h |
e |
r |
e |
|
Indexes: |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Individual characters can also be identified with reverse indexes starting with the last character at position -1, and ending with the first character at position -length. The reverse indexes for the string "Mr. Bob" are below. Note that the string is of length 7, and thus has reverse indexes from -1 to -7 right to left.
String: Characters |
M |
r |
. |
B |
o |
b |
|
Indexes: |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
Reverse Indexes: |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
5.3. Accessing Characters
We can access individual characters of a string by using the square bracket ([]) notation along with an index. The code snippet below shows how square bracket notation relates to the characters in a string.
‘a’ == ‘apple’[0] ‘l’ == ‘apple’[3] ‘e’ == ‘apple’[-1]
PythonTutor Asg. 5.1
5.4. Slicing
We can access slices or substrings of a larger string by using the bracket notation and two indexes separated by a colon (:). The first index specifies the starting point of the slice, while the second index specifies the stopping point of the slice + 1. This is known as incluse:exclusive notation.
PythonTutor Asg. 5.2
The Last Index
To get the last letter of a string into a slice, we need the last index + 1. This is identical to the length of the string. If we leave the second index of a slice blank, Python assumes you want the last letter. Thus, in the example below, b and c are equivalent.
|
EarSketch Example 5.3
EarSketch Asg. 5.2
5.5. For Loops
In many situations, we want to access every character of a string one at a time. Although this could be accomplished by using each index from 0..length - 1, it is much more convenient to use the for loop. The for loop creates a new variable, stores the first character of the string in it, and repeatedly executes the attached block. Each time the block is executed, the next character is stored in the new variable.
PythonTutor Asg. 5.3
EarSketch Asg. 5.3
EarSketch Example 5.4
PythonTutor Asg. 5.4
5.6. Chapter 5 Project: Beat Challenge
6. Chapter Six: Lists
6.1. Creating Lists
Lists are collections of values combined into a single entity. They enable a single variable to store multiple values, like a cubbyhole holding different items in each space. Lists can be created manually with brackets ([]), or by using functions like range()
or string.split()
.
The range(a, b) function returns a list of integers from a up to, but not including b. Thus range(2, 5) returns [2, 3, 4].
PythonTutor Asg. 6.1
String Splitting With Numbers
Note that the string.split() function always returns a list of strings, even if they look like numbers. Thus, remember to use the int() or float() functions when working with numbers from string.split() .
|
6.2. Indexes
The indexes of each value in a list are identical to the indexes for each character in a string. They start with the first value at position 0 and end with the last value at position length - 1. The indexes for the list ["Apple", "Plum", "Kiwi"]
are below. Note that the list is of length 3 and thus has indexes from 0 to 2. Reverse indexes are also supported.
List Values: |
"Apple" |
"Plum" |
"Kiwi" |
Indexes: |
0 |
1 |
2 |
Reverse Indexes: |
-3 |
-2 |
-1 |
6.3. Accessing and Modifying List Values
We can access individual values of a list by using the square bracket ([]) notation along with an index. Furthermore, we can modify any value in a list with the same bracket notation and the storage (=) operator.
PythonTutor Asg. 6.2
Swapping Items in a List
Note that since we can access and modify elements in a list, we can also swap them. Can you figure out how to swap the first and last elements of any list?
|
EarSketch Example 6.1
EarSketch Asg. 6.1
EarSketch Example 6.2
EarSketch Asg. 6.2
6.4. List Appending and Slicing
We can append to lists with the concatenation operator (+). We can also slice a list using the bracket notation and two indexes separated by a colon (:). The first index specifies the starting point of the slice while the second index specifies the stopping point of the slice + 1.
PythonTutor Asg. 6.3
6.5. For Loops with Lists
Much like when using strings, we often want to access every element of a list one by one. We can use a for
loop to repeatedly execute the attached block; once for each value of the list.
PythonTutor Asg. 6.4
EarSketch Example 6.3
EarSketch Asg. 6.3
6.6. For Loops with Indexes
Loops over a list of indexes created by the range()
function allow us to do more complex processing like running through two lists at the same time, modifying lists, searching for the index of certain elements, using multiple indexes in the same list, and more. Follow the code below closely.
PythonTutor Asg. 6.5
EarSketch Example 6.4
6.7. Chapter 6 Project: Complete Drummer
7. Chapter Seven: Defining Your Own Functions
7.1. Review: Calling Functions
In Chapter 3, we introduced functions like len()
, print()
, input()
, str()
, int()
, randint()
, range()
, and more. Calling these functions has been fundamental to most of the examples in the book. A function call typically takes 1 or more input parameters. For example, to call the print()
function, we specify 1 string input parameter. This function then displays the string to the console user.
7.2. More Functions in EarSketch
In this chapter, we will use a new version of the setEffect()
EarSketch function which will be very useful for the rest of the course.
EarSketch Example 7.1
7.3. Defining custom functions
Before a function can be called, it must be defined. Every function we have used this semester has been pre-defined for you by other programmers. Here, we introduce how to define your own custom functions. Once defined, you and other programmers will be able to use them like any other function. Thus, by defining your own functions, you are adding new functionality to Python. The fundamental approach to solving large programming problems is breaking them down into small function definitions, and then calling those functions to solve the original complex problem.
As an example, if we are writing a game that needs to print out player names surrounded by star (*) characters, we might want to define our own function called star_print. The function will need an input parameter for the players’s name, and will then print out the name surrounded by * characters. Once defined, the function can be called as many times as needed.
PythonTutor Asg. 7.1
Function Definitions
To define a function, we use the def statment followed by the function name, and 1 variable name per input value required. These input parameter variables are surrounded by parentheses. The attached code block is what is executed when the function is called. Once called, a function comes alive in its own space (called scope). It has its own variables that are separate from variables outside the function. Furthermore, its parameter variables are automatically initialized to the values passed in by the function call. |
EarSketch Example 7.2
EarSketch Asg. 7.1
7.4. Return Statements
Many functions return a value. The return value can then be stored in a variable, or used as part of a complex expression. To make a function return a value, use the return
statement.
As an example, we might want to define a function, called repeat_string, that returns a new string by repeating a simple string multiple times. The function will need two input parameters; one for the string to repeat, and another for the number of times to repeat it. The function will then return the newly created string.
PythonTutor Asg. 7.2
Return Statement Evaluation
When python executes a return statement, it immediately exits the function and replaces the function call with the return value. Thus, code like:
a = repeat_string("*", 4)
gets converted to
a = "****"
during execution.
EarSketch Asg. 7.2
7.5. Combining Functions
Once defined, a function can be called from anywhere, including other function definitions. This allows us to take a complex problem and break it down into smaller problems.
For example, if we want our original star_print() function to print out more stars for longer names, we can call our repeat_string() function from inside the star_print() definition.
PythonTutor Asg. 7.3
7.6. Chapter 7 Project: Structured Song
8. Chapter Eight: File IO
8.1. Getting Data into Programs
In this book, we have covered 3 basic ways of getting data into programs:
-
Hard Coding: Writing data values directly into the code
(age = 27)
is generally referred to as hard coding. It is rarely appropriate for real programs because it does not allow the value to change without editing the source code. -
User Input: Asking the user to input information (ex.
input()
) is the standard way of building interactive user software. It is ideal for programs that do not need lots of data. -
Random Generator: Generating random values (ex.
randint()
) is fundamental to building programs designed for simulations, real world modeling, artificial intelligence (AI), and of course music.
In this chapter, we introduce a fourth way of getting data into programs: text file input. This is a common technique for programs which analyze data intensive systems like stock markets, social media websites, science experiments, etc.
8.2. Review: String.split()
In chapter 6, we introduced the string.split() function, which takes one big string and breaks it up into a list of smaller strings. The function uses a character (specified by the input parameter) to determine how to split the big string. Data text files are typically composed of lines of text separated by the new line character, that like the space character, is invisible white space but important. In Python the newline character is written "\n". Follow the example below to get a refresher on split() and the "\n" character.
PythonTutor Example 8.1
8.3. Reading and Splitting Text Files
Python can open and read the entire contents of a text file with two simple functions: open()
and read()
. The open()
function finds the file on the file system (hard drive). The read()
function loads all of the contents of the file into one string value.
Once a file has been read, we can use the split()
function with the newline ("\n") character to create a list of lines. We can then split any individual line to get a specific item on that line.
Assume you have a text file called mary.txt with the 4 lines below. Notice how there are newline characters between each sentence and space characters between each word.
Mary had a little lamb His fleece was white as snow And everywhere that Mary went The lamb was sure to go.
The following code would read the entire file, grab specific words out of the file, and print them out.
1
2
3
4
5
6
7
8
9
10
f = open("mary.txt")
big_str = f.read()
line_list = big_str.split("\n")
first_line = line_list[0]
last_line = line_list[3]
first_line_word_list = first_line.split(" ")
last_line_word_list = last_line.split(" ")
print(first_line_word_list[3])
print(last_line_word_list[-1])
Testing File I/O
Web Browser Applications like Python Visualizer and EarSketch are not allowed to open files on the local computer. To test the code above, create the text file and the program on your desktop and then run the code inside the shell.One alternative to opening a local file is to simply copy/paste the content with newline characters into the program (used in PythonTutor). Another alternative is to load a file from the web (used in EarSketch). |
PythonTutor Asg. 8.1
EarSketch Asg. 8.1
8.4. Looping Through Files
The most common data file format is called the CSV file. It is composed of lines of comma separated values. Look at the example file for daily high temperatures in US cities. Notice how each line is composed of a city name, a date, and a temperature all separated by commas.
Atlanta,1/1/2012,67 Chicago,1/1/2012,47 Miami,1/1/2012,77 Atlanta,1/2/2012,59 Chicago,1/2/2012,48 Miami,1/2/2012,72 ...
The following example assumes the file has 2 lines and has been read into the variable big_str
. It loops through all contents of the file grabbing each value in a separate variable and converting data types when necessary.
PythonTutor Asg. 8.2
EarSketch Asg. 8.2
8.5. Perceptualizing Data
When working with large data sets, users usually want traditional visualizations such as charts and graphs. There are situations, however, where data can be turned into a more artistic perceptions such as digital paintings or sounds. This section explores how we can use sonification in EarSketch to create auditory perceptions of data.