An Introduction to Python and JES

This guide is for for students in CS101 at Boston University and covers the Python, Jython, and JES features that you'll use in CS101.

To find a specific topic in this guide, use ctrl+F (command+F on a Mac) to search for a keyword, or find the relevant section in the table of contents below.

Python

For most CS101 students, Python marks some of the most technical and computer-science-y stuff they’ve ever worked on. Like HTML, it’s a new language to learn, but unlike HTML, it’s very mathematical and gets far more advanced than the topics covered in this class. The goal of this tutorial is to explain how Python is laid out, what key words you’ll need to know, and how to approach writing a Python program.

Python is a programming language that was created to be easy to understand, and once you get familiar with the small group of concepts that power it, it’s very simple to write code. CS101 uses JES (Jython Environment for Students), which is basically like a text editor (think Microsoft Word) for a variant of Python called “Jython”. It comes with a bunch of built-in stuff that you can use to work on images and sound files by writing small chunks of code.

Some Python Vocab

You’ll need to be familiar with most of these for quizzes, but knowing what to call the thing you’re talking about is also useful.

  • Program – A larger file of code that may contain one or more functions.
  • Comments – These are notes, just like in HTML, that are ignored by the computer. In Python, comments start with a hash mark (#) and end at the end of the line.
  • Variable – Just like in algebra, these are names (in Python, often relevant words) that you can assign values to, allowing you to reuse them later on.
  • Operators – Mathematical symbols, like +, -, *, and /, but also ** (“to the power of”, for exponents).
  • Keyword – Words that have already been giving some meaning/purpose in Python. Examples include “and”, “print”, and “if”.
  • Function – A chunk of code that performs an action. Functions are given names and are reusable. There are two kinds of functions: built-in ones, and “user-defined” ones (functions that you create).
  • Expression – Statements that produce values. Examples include 3 + 5, "Hello world!", and (a variable called) name.
  • Error – When your program has a problem, the command area will provide an error message that attempts to tell you where the error is. JES will often also highlight the problem line in yellow.

The JES Window

Once you install JES and fire it up, you’ll see something like this:

JES Window

(Note that this is on a Mac, so it might look a little different for you Windows users…)

If you’ve never used a program to write code before, this window probably doesn’t make a whole lot of sense to you, so here’s what all that is:

The top part (the white window with the tiny number 1, which tells you that that’s line number 1), or the “program area”, works like any text editor would, where you can type stuff and save it under some file name so you can close it and pull it back up later. The bottom part (in black), the “command area”, is the brains of the operation. Consider writing Python code to be like giving your computer some orders, which it will take and give you some kind of response. Typing in the command area means every time you hit enter, you immediately send your instruction to the computer; it’s kind of like talking to it. Writing in the program area, and saving your work, is more like writing it a to-do list or a recipe that you can take your time with and give to it later.

This means that for most of the assignments in Python that you do for CS101, which will have multiple steps, you’ll write them in the program area and save them as *.py files, which you can submit to WebSubmit. However, if you want to quickly check if something small works the way you want it to, using the command area will give you immediate feedback.

There are a couple of buttons and menu options to get familiar with as well. The “Load Program” button takes a saved program from the top, and submits it to be run on the bottom half. The “Explain <click>” button, which will change name when you click on a function it recognizes, will explain how to use the special built-in functions that come with JES. These functions are also accessible from the “JES Functions” menu, and help with everything from requesting information or a file to working on pictures and sounds. The explain button opens up an information pane that tells you how to use that function. The “Stop” button, which is grayed out if nothing is happening, is useful if you load a program that’s taking forever or repeating endlessly and you want to cancel loading it. The three greater-than signs (“>>>”) in the command area just tell you that JES is ready to take a command.

The File and Edit menus are pretty standard stuff; they have all the usual New, Open, Save, Copy, and Paste options that you’d expect.

Starting to Write Code

Using combinations of functions, keywords, operators, and variables, you can write Python instructions to do lots of different things.

Header Comments

Writing a program involves combining a bunch of the techniques explained below, depending on your goal for the program. At minimum, your program file should contain a header with some basic information, and the description of your program. Headers are written using comments, and should include information like the file name, author, and a description of what the program does. It can have other information as well. A good example of a header:

# file name: tri.py
# author: John Doe (jdoe@bu.edu)
# description: a program to calculate the area of a right triangle
You can also include the course name, date, and assignment number (e.g., hw1, lab3, etc.)

Defining Functions

When you’re writing your code, the simplest thing to do would be to write a program with a list of instructions, each of which would immediately be executed when you hit the “Load Program” button.

This has two major problems: first, sometimes you don’t want to execute all the instructions right away, and secondly, once they’ve been executed, the only way to get them to execute again is to reload the program. Because of this, in CS101 you’ll put your instructions in the definition of a function. This means that you can call the function whenever you want, and however many times you’d like, without reloading the program. Being able to define separate functions of different tasks can also make complex programs easier to read.

Sometimes, you’ll have a clear purpose for the function, in which case you can name the function accordingly, like “triArea()” or “reverseText()”, but for experimenting or other general purposes, you can call it “main()”, as in “main function”.

To define a function, which you’ll do so that it can be used later on, you’ll list each step. For example:

def main():
  print "Hello world!"
This is a function, which we’ve called “main()”, that will print (output) the phrase ‘Hello world!’ when it’s called.

At this point, you’re probably wondering what the deal is with the set of parentheses after each function name. The explanation can get a tiny bit technical, but in some (more advanced) functions, you’ll want to perform the set of instructions to a particular thing, which will then get put in the parentheses (these are called parameters). In most of the functions you’ll deal with, however, the function isn’t operating on anything, so there’s nothing between the parentheses. So all functions have parentheses after them, the only difference is that some have an empty set, and some contain a variable (or multiple) that gets referenced in the instructions.

Notice also that the print statement is indented. In Python, indenting specifies the “scope” of different chunks of your code. Consider it this way: everything indented after a first, unindented (or less indented) line ‘belongs’ to that line. So above, the print statement belongs to the definition of the function called ‘main()’. If you wanted ‘main()’ to accomplish multiple things, they’d all have the same amount of indent as the print statement. Any lines that started at the far left (i.e., lined up with the ‘def’ line) would be the start of something else, and not read if the program were to run the ‘main()’ function.

Calling Functions

Calling a function means telling the computer to go find and execute the instructions in the function’s definition. To do so, you must know the name of the function (which is case-sensitive), and whether you should put value(s) between the function’s parentheses (see above). For instance, calling the function defined above:

main()
will give the output
Hello world!
Note: many people get tripped up by the fact that in the definition of the function, there is a colon (:) after the function name. You should not use a colon when calling the function, as it’s part of “def”, and not part of the function name.

Output: Specifically, print

The most basic is to tell a computer to give output, which means to display a particular piece of information. To do this, you can use the print statement. For example,

print "Hello world!"
will give the output
Hello world!
Try typing this in the command area (bottom half) of the JES window. Typing ‘print Hello world!’ without the quotes around “Hello world!” causes an error message. This is because chunks of text that aren’t part of the instruction are called strings, and need to be isolated in quotes so JES doesn’t accidentally try to read them as instructions.

There are a couple ways of formatting tricks for print. First, you can use commas to separate things you want printed together on a line.

print "Hello", "world", "!"
will give the output
Hello world !
Notice that each string that was separated by a comma in the print statement is separated by a space in the returned text.

You can also do this with variables you’ve defined:

x = 42
print "The value of x is", x, "."
will give the output
The value of x is 42 .

Notice also that Python will return an error message if you try to print multiple things without using the comma separator:

print "The value of x is" x
causes an error.

Sometimes things should print out without spaces between them (which commas add automatically). This is a tiny bit trickier than using commas, but involves using the plus sign (+) instead of a comma. Plus signs can only combine two things that the computer believes are text, so:

print "Hello" + "world" + "!"
will give the output
Helloworld!

However, combining text/symbols with a number takes one extra step. Notice that simply using a plus sign doesn’t work:

x = 42
print "$" + x

causes an error.

We need to tell the computer to treat the number(s) as text. To do this, we use a function called str(). The str() function takes any type of input (between the parentheses), and formats the output as plain, non-numeric text:

x = 42
print "$" + str(x)
will give the output
$42

One last trick for formatting things you’re printing is another use of the comma. In your average print statement, the computer will print everything it’s told, and upon reaching the end of the print statement will also start a new line (which basically means it hits “enter” at the end of each print statement). This is usually helpful. Here’s an example:

print "Hello"
print "world"
print "!"
will give the output
Hello
world
!

Sometimes, though, you want things to print out on one line, even if they’re coming from separate print statements. (This will become more important when you learn about for loops, which are discussed below.) In these cases, putting a comma at the end of the print statement tells the computer not to start a new line, but to just end with a space. So:

print "Hello",
print "world",
print "!"
will give the output
Hello world !

Defining Variables

If you read the section above on output, you might notice that in some of the examples, there was a line “x = 42”. For anyone who’s taken algebra, this probably looks pretty familiar. You can have an equation with a variable (like ‘x’), assign a value (like 42) to the variable, and then run through the equation, replacing the variable, to get an answer. Python works the same way, although unlike in algebra, Python variables can be words or other spaceless names.

Rules for naming variables:

  • Have to start with a letter or underscore (_)
  • Can contain letters, numbers, and underscores
  • Can’t contain spaces, punctuation, etc.
  • Can’t be Python keywords
  • Are case sensitive

Things that aren’t rules, but are worth considering:

  • You should give your variables sensible names (“price”, “pixelColor, or “samplingRate” instead of “x”) so it’ll make more sense when you use them and so you won’t forget them.
  • Just because you technically can start your variable names with underscores doesn’t mean you should. Professor Stevens says “don’t do it.” In fact, having underscores anywhere in your variable names will most likely just make them harder to read.
  • Since you can’t use spaces, if you’d like to use multi-word variable names, you have two options: start capitalizing each word after the first, or separate them with underscores. Most people use capitalization. For instance, a variable for “dollars and cents” could be “dollarsAndCents”.
  • Abbreviating is common for longer words, as long as the abbreviation is still clear. So, a variable for “average price” could be “avgPrice” or even “avg”.

Variables can hold all kinds of values, including strings, different types of numbers, and user input. The simplest is numbers:

price = 4
tax = 0.50

From here, you can perform arithmetic and print variables as shown above:

print "Total: ", price+tax
will give the output
Total: 4.5

You can also assign variables a value that is the product of an equation:

price = 5 + 5
total = price + 1
print total
will give the output
11

To assign a string value (non-numeric values, or numbers you won’t perform arithmetic on) to a variable, you have to wrap the string in quotes (like usual).

firstName = "John"
lastName = "Doe"
mathProblem = "5 + 5"
print lastName, ",", firstName, ";", mathProblem
will give the output
Doe , John ; 5 + 5

Variables can also be assigned new values that are relative to their old values. For example:

total = 10
print "Original total:", total
total = total + 4
print "New total:", total
will give the output
Original total: 10
New total: 14

The only thing you have to remember when doing this is that the variable has to have been defined on a previous line before it can be used on the right-hand side of an equation, so:

total = total + 4
print "Total:", total

causes an error, since there was no mention of the value of “total” before the line trying to redefine it.

Working with Your Data

The next couple sections deal with tools you’ll be using in CS101 to manipulate data, whether its written into the code or user-defined.

Arithmetic

The good news is that doing arithmetic in Python is just like the arithmetic you’re used to, with the same symbols (except exponents) and the same general order of operations: PEMDAS. As a refresher, this means that Python will do arithmetic on a given line in this order:

  1. Parentheses: ()
  2. Exponents: **
  3. Multiplication/Divison: *, /
  4. Addition/Subtraction: +,-

When in doubt, of course, it’s always good to wrap things in parentheses for safety/clarity’s sake. Some arithmetic examples:

a = 12
b = 2
c = 16
d = 3
e = 2.5

print "the value of a is", a
print (a / b) * 5
print a + b * d
print (a + b) * d
print b ** d
print c - e
a = a + b
print "the value of a is", a
will give the output
the value of a is 12
30
18
42
8
13.5
the value of a is 14

Taking User Input

The point of most of the programs you’ll be writing is to take some input from a user, do something to it, and give the user some output. JES gives you four easy ways to ask for input, depending on what the input is:

  • requestNumber()
  • requestInteger()
  • requestIntegerInRange()
  • requestString()
For the most part, you’ll use requestNumber() and requestString(), but the other two are useful as well. Each of these functions will pop up a dialog box where the user can enter a value. In order to store that value, you’ll assign it to a variable. You can specify the instructions on the dialog box by entering a string between the parentheses of the function. For instance:
name = requestString("Enter your name:")
print name
first pops up a dialog box (where you can enter a name, say ‘John Doe’):
Dialog Box
then gives the output

John Doe

For taking numerical input (that’s allowed to be a non-whole number), you’ll use requestNumber(). The dialog box will reject any entries that aren’t numbers. You’ll therefore be able to perform math on any input by the user. For example:

num = requestNumber("Enter a number to be squared:")
print "Your number:", num
print "Your number squared:", num*num
(assuming the user inputs ‘7’) will give the output
Your number: 7
Your number squared: 49

For taking text or other non-numeric input, you’ll use requestString(). Note that this means you won’t be able to use arithmetic on it, even if the user enters numbers, since the computer will treat it as a string. For example:

name = requestString("Enter your name:")
print "Hello", name, "!"
(assuming the user inputs ‘John Doe’) will give the output
Hello John Doe !

For taking input that must be an integer, you’ll use requestInteger(), which is similar to requestNumber() in that it rejects non-integers, and allows arithmetic on the resulting variable. You may only want integer-type input in cases where the input has to do with a number of people (since there aren’t fractions of people), or a number referring to a pixel, since the built-in pixel functions can only handle whole numbers.

RGB-style color functions only work with whole numbers between 0 and 255. There are also more advanced built-in functions for working on pictures which can only take whole numbers (which refer to specific pixels) in the range of the size of the picture. In these cases and others, where you want to only allow input within a given range, you’ll use requestIntegerInRange(). For example, say you’re asking the user to input a quiz grade, which has to be an integer between 0 and 100:

grade = requestIntegerInRange("Enter your grade for quiz 1:", 0, 100)
print "Your quiz 1 grade:", grade
(assuming the user inputs ‘85’) will give the output
Your quiz 1 grade: 85

The For Loop

The for loop, formally called the ‘definite loop’, is a very important one in Python, and so is worth getting your head wrapped around completely. Basically, it allows you to specify a list of items (these could be numbers, words, letters, etc.), and specify action(s) to be performed on each one. Real life example: imagine you’re a police officer working at a station. Your boss lines up a bunch of suspects, and tells you that for each one you should collect a name and fingerprints. You’d start at the beginning of the line, asking the first person for their name and taking their fingerprints, before flipping to a new form and doing the same thing to the next person. You’d repeat this process for as many times as you had suspects. In a for-loop type notation, your boss’s instructions might look something like this:

lineOfSuspects = [guy #1, guy #2, guy #3, ...]
for suspect in lineOfSuspects:
   ask suspect his/her name
   fingerprint suspect
Notice that the instructions to be carried out on each consecutive suspect are indented. The official form for the for loop is this:
for <var> in <sequence>:
   <body>
To deconstruct all that, <var> is a variable name that you’ll specify, which can then be referenced in the instructions in the body. <sequence> is the list of items you want the instructions performed on, and can take the form of a range of values, a list, or a string. The <body> section holds the instructions. So, a simple example:
phrase = "Hello world!"
for letter in phrase:
print "the next letter is:", letter
will give the output
the next letter is: H
the next letter is: e
the next letter is: l
the next letter is: l
the next letter is: o
the next letter is:
the next letter is: w
the next letter is: o
the next letter is: r
the next letter is: l
the next letter is: d
the next letter is: !
This looks like Python knows what a “letter” is, but notice that if you change both instances of the variable “letter” to anything else, the results are exactly the same. What’s happening here is that Python has been told to run through items within the phrase, and it automatically takes that to mean “go through it one character at a time”. So any time you put a string in the <sequence> position of a for loop, the computer will go through it character by character. Also notice that since a new print statement is being executed each time the computer iterates through the loop, each entry ends up on a new line. As discussed above in the “print” section, there are ways to alter this.

What if you want to work with units of a phrase that aren’t characters, like words? To do this, you’ll need to put something in the <sequence> position that isn’t just a string, since we know the computer will just look at the string’s characters. Another option for <sequence> is a list. You could put in an actual list, like [this, is, a, list], but that only works if you already know what words you want to work with. If you’ll be working with a user-given phrase, you can use a nifty method called “split()”. You can tack “.split()” onto the end of a string-type variable, and the result is a list of all the items in the phrase that are separated by spaces. For instance:

phrase = "Hello beautiful world!"
for word in phrase.split():
  print "the next word is:", word
will give the output
the next word is: Hello
the next word is: beautiful
the next word is: world!
In fact, if you printed phrase.split() to see what it looked like, you’d get ['Hello', 'beautiful', 'world!'], a list containing each “word”.

Accumulator Variables

When you’re using a for loop, sometimes you want to keep a running total of numbers you’re calculating, or re-combine bits of a string. For this you’ll need an accumulator variable. Using one involves two steps: defining it for the first time before the for loop starts, and then redefining it as itself plus some operation in the body of the for loop. Consider a simple example:

total = 0
for num in [1,2,4,10,20]:
  total = total + num
print "Total:", total
will give the output
Total: 37
To break this down by step, first we define the variable “total”, so as not to break the rule that requires you to define each variable on a line before it’s used on the right-hand side of an equation. Notice that if we put “total = 0” in the body of the for loop, “total” would get reset to 0 each time the computer went back through the loop, and the end result would be “Total: 20”. We then make a for loop that goes through the instructions five times, once for each number in the list we gave it. For-loops will automatically cycle through for as many times as there are items in the sequence. Then we instruct the computer to reset the value of “total” to be whatever it is then plus the current value of “num”. After it’s gone through the loop as many times as it needs to, we tell it to print out the final value of total.

You can do the same type of thing with text. Here, instead of setting our accumulator variable to “0”, which we do for numeric ones, we’ll set it to "", a string with no text.

phrase = "Hello beautiful world!"
smushedPhrase = ""
for word in phrase.split():
  smushedPhrase = smushedPhrase + word
print smushedPhrase
will give the output
Hellobeautifulworld!

To take a look at how this works, you can put the print statement inside the for loop:

phrase = "Hello beautiful world!"
smushedPhrase = ""
for word in phrase.split():
  smushedPhrase = smushedPhrase + word
  print smushedPhrase
will give the output
Hello
Hellobeautiful
Hellobeautifulworld!
Experiment to see how it will change the final output to add “word + smushedPhrase” instead of “smushedPhrase + word”.

Working with ASCII

Since computers only deal the binary options of “on” and “off”, they need some set of rules for which sequences of binary translate to which letters, numbers, and other characters. ASCII is one such encoding scheme, and it’s one you’ll work with in CS101. For a basic idea of how ASCII is laid out, try Googling an ASCII chart, which will tell you which decimal numbers correspond to which ASCII characters. You can also use this for loop to print out a list of just the lower- and upper-case alphabet in your command area:

for i in range(65,123):
  print i, "-->", chr(i)

You’ll notice a new function above, chr(). It’s a built-in function that takes a number and gives back the corresponding ASCII character. You can use it at the command line to quickly look up ASCII conversions. For instance:

chr(97)
will give the output
'a'

The quotes tell you that that’s “a” as a string, not some variable named “a”. To go in the opposite direction, you can use a function called ord(). It’s important to note that ord() only takes strings, so if you’re going to put a single letter in, you’ll need to wrap it in quotes. For example:

ord('S')
will give the output
83

One last useful function, though it’s not strictly ASCII-related, is the int() function. It takes two inputs, a string-formatted number and an optional base (binary is base 2), and provides the decimal conversion for the number you gave it. It takes the form int(‘string-number’, base), so:

int('11001010', 2)
will give the output
202

Pictures and Sound

File Functions

Working with pictures and sound involves more advanced steps than we’ve taken with raw data, but don’t worry, they’re easy to master. The first step is understanding how files work, since pictures and sounds live within files. Up until now, you’ve been working with numbers, strings, and other input provided by a user within your program. But to work on a picture or sound, you’ll have to somehow get your program to go find and read a file that’s somewhere else on your computer. Doing this takes a couple steps: first, you’ll store the “address” for the file you want as a variable, and then you’ll use functions to read, display, or modify the file at that location. To break it down:

file = pickAFile()
The pickAFile() function brings up a ‘file selector dialog’, which looks just like what pops up when you use the ‘Open’ dialog in, for example, Microsoft Word. You’ll choose a file and hit the ‘Open’ button. When you pick your file, the pickAFile() function notes the ‘path name’ (as a string) of your file. This is a fancy way of saying that it notes the “address” of that file on your computer. Of course, in order to use this address, you’ll need to store it somewhere so you can reference it later. In the example above, we’re calling it “file”.

Next, we’ll make the computer actually recognize the file that’s living at that path name. Say it’s a picture:

pic = makePicture(file)
Now the computer has our picture stored in memory, and we can refer to at any time by referencing “pic”. If our file were a sound, we could do the same type of thing by using the function makeSound(file) . It’s important to note that neither of the last two functions (pickAFile() or makePicture(file)) will actually make anything appear. So far, things are just stored in the computer’s memory, invisible to the user.

After modifying your sound/picture (which we discuss below), you may want to save it as a new file, since ‘repainting’ a picture or ‘playing’ a sound will simply show you your work, not save it anywhere. To do this, you can use the writePictureTo and writeSoundTo functions. Let’s take a look at one:

path = "/Users/JohnDoe/Documents/CS101/editedpic.jpg"
writePictureTo(pic,path)
The function writePictureTo takes two parameters: the picture variable and the pathname. (writeSoundTo takes the sound variable and the pathname.) The first is the variable into which you’ve stored your picture, which will be the variable you defined when you used makePicture (above we called it “pic”). If anything has been done to it since then (such as resetting color values), the changes will be saved to the new file. The second parameter is the file name, and this is one that students often have trouble with, for good reason. Since your situation is highly dependent upon what type of computer you have and how it’s set up, your TF is your best resource if you’re having problems with path errors.

Picture Functions

In the section above, we talked about storing a pathname and ‘making’ a picture of the file that lives there. One problem quickly becomes apparent: this doesn’t display the picture! To do this, there’s a nice, simple function: show(pic). So:

file = pickAFile()
pic = makePicture(file)
show(pic)
shows a window containing the picture.

Next, you can use a variety of pixel and color functions (which often start with ‘set’) to change the appearance of your picture. Again, you’ll quickly notice that nothing is happening to the display of your picture! This is because when you change pixels within your picture, you have to instruct the picture to repaint itself for the changes to actually show up. So, if we start with the previous example, and assume that we’ve made some changes:

repaint(pic)
changes the picture in your window to reflect the changes.

The first step of making changes to your pictures is understanding what your images are made up of: pixels. A neat way of taking a look at them is the explore function. Once you’ve used makePicture to define your image, you can run explore on it:

explore(pic)
opens a window where you can see the x,y coordinates, RGB values, and displayed color of any pixel by clicking on it.

Pixel Functions

So how do you make changes to your picture? Well, the first step is to target either specific pixels or every pixel in an image. Let’s start with targeting a specific pixel. For this, you’ll need to use the getPixel function. (Note: getPixel and getPixelAt are identical, in case you were wondering. We’re going to stick with getPixel here.) getPixel takes three parameters, the picture to take the pixel info from, the x-value of the desired pixel, and the y-value of the pixel, in the form getPixel(pic, x, y). So:

aPixel = getPixel(pic, 5, 10)
stores the color information of the pixel located at (5, 10) in the picture “pic”.
Note: remember that x,y coordinates start at (0,0) in the top left and progress downward and rightward as positive numbers.

While that might come in useful a little later on, some of the first picture work you’ll do will involve doing something to every single pixel in a picture. Good news: there’s a really cool way to do this. It’s getPixels, which takes the form getPixels(picture). The getPixels function amasses a list of every single pixel in an image. Why is that useful? Because you can then use a for-loop to perform an action on each pixel on that list, which makes it look like that action has been done to the whole picture. For example, say you want to remove all the red from a picture. You’ll need to go through, and for each pixel, set the red to 0. Let’s continue our example from earlier, using the picture “pic”.

for px in getPixels(pic):
  setRed(px, 0)
repaint(pic)
shows our picture with the red removed.
Here, we go through the list of all pixels in “pic”, using ‘px’ as the arbitrary way we refer to the pixel we’re dealing with, and set its red value to zero. [For an explanation of setRed, see the setGreen example below.]

When you’re working with pixels, sometimes it’s useful to get the x- and/or y-values for a pixel you’re working with. For instance, if you want to transpose a pixel from one picture to another, part of the process will be using the x,y coordinates of the pixel and its color values. So, to get the coordinate values of a pixel, continuing with our “pic” example, let’s look at a very obvious example:

pixel = getPixel(pic, 5, 10)
x = getX(pixel)
y = getY(pixel)
print "x-value:", x
print "y-value:", y
will give the output
x-value: 5
y-value: 10

Some of your assignments will require you to work with color, which you’ll fiddle with on a pixel-by-pixel basis. One method is to get the color of a pixel. Keep in mind that “color” is just a compound of the red, green, and blue values of the pixel. Let’s stick with our example pixel from above (the pixel at (5,10) in the picture “pic”), and assume that we’re doing this in the command area:

getColor(pixel)
gives you something that looks like:
Color(0, 255, 255)
The pixel we were looking at is cyan (no red, and all of the green and blue channels). [For more information on using getColor, see the section on the distance function below.]

Sometimes you won’t want or need the information about all three color channels. In these cases, you can grab the red, green, or blue value of a predefined pixel. Say you want the green value from our pixel above:

green = getGreen(pixel)
print green
will give the output
255
Naturally, this works the same way for getRed and getBlue.

Jython also has a set of functions called setRed, setGreen, and setBlue to redefine the RGB values of a pixel. Say we want to reset the green value above to zero:

setGreen(pixel, 0)
changes the green value for that pixel to 0. Remember that this won’t appear in the picture window until you’ve used repaint.

Color Functions

In CS101, getColor will mainly be useful for grabbing the color of a pixel and comparing it to some other color. To compare colors, you’ll need to use the distance function, which takes the form distance(color1, color2) . You might be wondering how exactly one measures the distance between two colors. The answer is that it’s complicated, and involves “Euclidean color distance” (which you’re welcome to Google), but basically that distances range from 0 (between two identical colors) to about 441.7 (between black and white). To measure distance, you’ll need to first define both colors, then use the distance function. Staying with our earlier ‘pixel’ definition (whose color was cyan, or RGB: 0,255,255):

color = getColor(pixel)
red = makeColor(255,0,0)
print distance(color, red)
will give the output
441.6729559300637
The distance function concludes what might be apparent from looking at the RGB values: the color of our pixel (cyan) and the color red are completely contrasting.

We’ve just used another color function above, makeColor. This one allows you to assign RGB values to variables, so that you can use those variables as colors. Some examples:

black = makeColor(0,0,0)
red = makeColor(255,0,0)
white = makeColor(255,255,255)
r = getRed(pixel)
newColor = makeColor(r, 0, 0)
Notice that you can use either a value between 0 and 255 or a variable that’s storing a relevant value.

Sound Functions

Working with sound can seem intimidating, but the good news is that many of the sound functions in JES work a lot like the picture-related functions you’ve used. To start, we’ll look at the sound versions of the picture functions makePicture, show, and writePictureTo. They are makeSound, play, and writeSoundTo. The first step, as with pictures, is to assign a (sound) file’s path to a variable, and then use makeSound on it. From there, you can play the sound. So:

file = pickAFile()
sound = makeSound(file)
play(sound)
will play the song. Note that nothing will appear on the screen as this happens. Also remember that your sound files must be in .wav format to work.

We can also save the sound to a new file:

Path = "/Path/Name/editedsound.wav"
writeSoundTo(sound,path)
[For more information on writeSoundTo, see the ‘File Functions’ section above.]

If you’re having trouble with any of these, take a look at the corresponding picture sections, since they work on the same principles.

Once you’ve opened your file, what about changing things about the sound? The first step in this process is figuring out how to get some data about your sound. Depending on the function you’re trying to use, you may need to know how many samples your sound contains, what the sampling rate is, or what the value of a specific sample is.

Finding out how many samples a sound has is useful for two reasons: 1) given several sounds, you can find the one with the fewest samples (the shortest if their sampling rates are the same), and 2) several sound-modifying functions need sample count as one of their parameters. So, working with the sound we defined above:

sampleCount = getNumSamples(sound)
print sampleCount
gives you some number, for example:
523500
Each of these samples is assigned a number, so that you can refer to them individually. This number is called an ‘index’. The first sample in a sound has an index of 0, the second has an index of 1, and so on.

For taking the minimum of two or more numbers (such the sample counts of 2 or more sounds), you can use the function min. Let’s look at a non-sound example:

x = 7
y = 9
z = 16
print min(x,y,z)
will give the output
7

Another useful bit of information about a given sound is the sampling rate, or number of samples per second. Conveniently, there’s a function called getSamplingRate. Working again with our “sound” example:

samplingRate = getSamplingRate(sound)
print samplingRate
outputs, for example:
44100.0
You might recognize this (44,100 samples/second) as the sampling rate used for CD audio. Note that since some functions need the sampling rate as an integer, you may need to wrap getSamplingRate in an int() function to convert it from a ‘float’ (a number with a decimal point) to an ‘integer’ (a whole number).

When you get to the point of doing things to sounds, the process starts to differ from working with pictures. When you modified pictures, you were able to change the picture itself and repaint it. With sounds, however, you’ll make a new, blank sound, and put your modified samples into it. To make an empty sound, you’ll use the function makeEmptySound, which takes sample count and sampling rate as parameters. For instance, using “sound” and “samplingRate” from above:

newSound = makeEmptySound(10*samplingRate, samplingRate)
creates an empty sound that’s 10 seconds long and has the sampling rate we measured above.

Now we’re ready to take sample values from an original sound, optionally do things to them, and write them into the empty sound we created, so that the finished product (using our example) will live in the variable “newSound”. There are 2 or 3 steps to this, depending on whether you need to do anything to the sample before writing it into the new sound.

Let’s take the simple case, where we’ll create a copy of our original sound (“sound” from above) without making any changes to it. We’ve already figured out the sample count and sampling rate of our sound (“sampleCount” and “samplingRate”, respectively), so we can make an empty sound that has the same properties:

soundCopy = makeEmptySound(sampleCount, samplingRate)

Now we want to go through our original sound, sample by sample, to take the value of the sample and write it to the same sample number in “soundCopy”. For this, we’ll use getSampleValueAt and setSampleValueAt, which are similar to, for instance, getGreen and setGreen (although luckily for us, sound only has a single value at each sample, instead of the 3 RGB values that make up color!). getSampleValueAt takes two parameters: the sound to look in, and the index of the sample whose value you want to get. [‘Index’ is explained in the paragraph on sample counts.] setSampleValueAt takes three parameters: the sound to write into, the index of the sample to be written, and the value you want to write in. So to copy the contents of ‘sound’ into ‘soundCopy’, we’ll use the two of these with a for-loop:

for i in range(1, sampleCount):
  sampleValue = getSampleValueAt(sound, i)
  setSampleValueAt(soundCopy, i, sampleValue)

The last part of working with sound is understanding how to mix two sounds. The good news is that it’s ridiculously simple: just grab the sample values of two samples, and take an average of those two numbers. For example, say we have two sounds, “sound1” and “sound2”:

sampleValue1 = getSampleValueAt(sound1, 0)
sampleValue2 = getSampleValueAt(sound2, 0)
mixedSample = (sampleValue1 + sampleValue2) / 2
Here, “mixedSample” is now a mix of the first samples from ‘sound1’ and ‘sound2’.

JES Stuff

How to Use JES’s ‘Explain’ Feature

There are a couple built-in tools in JES that mean you don’t need to memorize the exact structure of every single function you’ll be using, which is good news. We’ve already looked at the “Explain” button quickly above, but as a reminder: the “Explain <click>” button, which will change name when you click on a function it recognizes, will explain how to use the special built-in functions that come with JES. The explain button opens up an information pane that tells you how to use that function.

Of course, reading the information that pops up in the information pane can still be a little tricky for anyone new to programming, so let’s take a look at some examples. This is the explanation you’ll get if you click on requestString in your code and hit “Explain requestString”:

requestString(message):
message: the message to display to the user in the dialog
returns: the input string
This will allow the user to input any string.
Example:
def printName():
   name = requestString("What is your name?")
   print "Hello " + name + "!"

This will open a dialog box asking the user's name and then print it back out.

The first line, “requestString(message)”, gives you the name and parameters (the things you need to put in the parentheses) of the function. Here, the function is requestString, and you’ll need to put some kind of message inside the parentheses.

The next line, “message: the message to display to the user in the dialog”, explains what they mean by message. Here, they’re telling you that you need to provide a message prompt that the user will see during the execution of your code.

The third line, “returns: the input string”, tells you what you get back from running that function. In this case, you’ll get back the string that the user inputs after being prompted by your message.

The next chunk is an example that JES provides you so you can see the function as it would look in your code. Looking at these is probably the easiest way to get the hang of how to use a function. In the example above, they’re defining a new function, “printName()”, that uses requestString to ask a user for his/her name. It stores whatever the user enters into the variable “name”, then prints a statement that says “Hello” and the person’s name. You can test it yourself by copying the example (the part in Courier font) into your program, saving/loading it, and calling the printName() function.

The last bit is JES’s explanation of what the example accomplishes, and is basically a shorter version of what we just talked about above.

Another example, which shows an optional parameter:

makeEmptySound(numSamples[, samplingRate]):
numSamples: the number of samples in the sound
samplingRate: the integer value representing the number of samples per second (optional)
returns: an empty sound with the given number of samples and sampling rate
Takes one or two integers as input. Returns an empty Sound object with the given number of samples and (optionally) the given sampling rate. Default rate is 22050 bits/second. The resulting sound must not be longer than 600 seconds. Prints an error statement if numSamples or samplingRate are less than 0, or if (numSamples/samplingRate) > 600.
Examples:
def make10SecondSound():
   return makeEmptySound(10 * 22050)

This will return an empty sound lasting 10 seconds long, using the default sampling rate (22050 bits/second).
def make10SecondSoundWithSamplingRate(samplingRate):    return makeEmptySound(10 * samplingRate, samplingRate)
This will return an empty sound lasting 10 seconds long, using the given sampling rate.

Notice that the second parameter, ‘samplingRate’, is in brackets. This is because samplingRate is optional. You can use the function two ways: as makeEmptySound(numSamples) or as makeEmptySound(numSamples, samplingRate). If you don’t specify samplingRate, it will use the default (here, 22050 bits/second, as the first example explains).

One last Python capability to take a look at is return. Sometimes, you'll write a function that performs an action on a variable, and want to use that output inside another function. For this, you'll need to write your function so that rather than printing/playing/showing the result after performing the action, it can be passed into your second function. For example, say you write a neat little function to print out the happy birthday song for a pre-given name:

def singHappyBday(name):
   return "Happy birthday to you, happy birthday to you, happy birthday dear", name, ", happy birthday to you!"
If part of another function requires that you collect the user's name and sing them happy birthday, you can use your singHappyBirthday function as a shortcut:
def someOtherFunction():
   userName = requestString("Enter your name:")
   print singHappyBirthday(userName)
(assuming the user entered "John") will give the output
Happy birthday to you, happy birthday to you, happy birthday dear John , happy birthday to you!
Here, we call singHappyBirthday, giving it the name assigned to the variable "userName" (in our case, John), and then printing what it returns.

How to Use JES Help

JES Help, which is on the top menu bar, includes a lot of information, only some of which will be useful to you in CS101. Since functions will usually be introduced in lecture or lab before you have to use them in your own programs, you’ll often have an idea of how they work, and hopefully using the “Explain” function will fill in the rest. But what if you’re confused about something more general than a function? JES Help has a few interesting pages that explain some common concepts, which can be accessed from the table of contents under “Help”:

  • Getting Started with JES > The JES Interface – This page explains every button and menu item within JES, and is a good resource for familiarizing yourself with what JES has to offer.
  • Programming in Jython > Formatting in Jython – This gives a quick explanation of indentation, and how it controls the flow of programs.
  • Programming in Jython > Basic Data Types – This one explains the difference between ‘integer’, ‘float’, and ‘string’.
  • Programming in Jython > Loops – This page explains the ‘for’ loop.
  • Understanding Sound in JES > How Does a Computer Store Sound? – This page explains the concept of storing sounds on a computer, and might be useful if you’re having trouble wrapping your head around ‘sound samples’.
  • Understanding Sound in JES > Sound Objects in JES – This page reviews ‘sounds’ and ‘samples’, and explains how to refer to a specific sample (by its index).
  • Understanding Pictures in JES > How Does a Computer Store Images? – This page explains ‘pixels’ just as the concept of ‘sounds’ are reviewed above. Good if you don’t understand what a ‘pixel’ is, how RGB color values work, or how to refer to a specific pixel.
  • Understanding Pictures in JES > Picture Objects in JES – This one reviews the ideas of ‘pictures’, ‘pixels’, and ‘color’.

It’s entirely possible you’ll have a question that isn’t answered by this guide, the “Explain” feature, or JES Help. In these cases, you can definitely try Googling it, but don’t be disheartened if you don’t find clear ansers to your question. Many of the people discussing this stuff online are working at a more advanced level, with prior knowledge of Java or other programming languages, and so their answers can often include words and code that may as well be written in Sanskrit. If you’ve checked this guide and tried both built-in features within JES (“Explain” and Help), your TF is a good next resource. If you find yourself struggling with the Python-based homeworks, try to start them as early as possible, so that you can go to office hours or schedule a one-on-one meeting with your TF to review some concepts.