Python and Processing are programs are comprised
of commands, also known
as statements, also known
as instructions. Each exists on its own
line. Statements are generally comprised
and operators. Expressions are things that
have a value, like the number
250, and operators
are things that have effects, they do something, combining
values in various ways.
When you're doing a new sketch for a HW assignment you'll want to do the following:
Save the sketch.
Name it accordingly, for example, homework_2_emma
This will make a new folder called homework_2_emma
Inside that folder will be your pyde file and perhaps another folder called data with any images you've included in your sketch.
Upload your entire folder to your folder in our shared Google drive (link on the info page). If you are running into errors in your code, create a new GitHub gist (instructions for this are on the help page). Don't forget to @ me so that I receive a notification for it!
The grid system: starts at the top-left of the window at
x increases to right and
On Mac you can use the screencapture utility to measure pixel values. On my computer the shortcut is ⌘-SHIFT-4, then click and drag, then press ESCAPE or else you'll end up with a bunch of funny screenshot fragments!
I know that you can do this on Windows as well but I'm not sure of the shortcut. I know you can definitely use a tool like http://pixelzoomer.com/
Commands use parentheses to specify parameters make sure they always come in pairs, open
( and close
Color is specified with RGB by default, but it can also include a fourth parameter for transparency (alpha), and it can also be specified as HSB (hue, saturation, and brightness). Use the "Color Selector..." tool to help.
Some syntax rules:
All text is case sensitive
Whitespace means spaces, line breaks, tabs, etc., and Processing mostly ignores this. So these are all equivalent:
rect(10,10,50,50) rect( 10,10, 50,50 ) rect ( 10, 10, 50, 50 )
And you can use this to help make your code more readable. Personally, I find the second line above to be the easiest to read.
The exception to this rule is that spaces at the beginning of the line (indentation) is very important and we'll talk more about this next week.
Comments are specified two ways:
# With a hashtag symbol, which go to the end of the line rect(10,10,50,50) # Single line comments can also start at the end of a line
""" Or with three quotation marks like this. This marks off a block of text and is useful for entering longer explanations, like describing what the program does for example. At the top of all of your homeworks, please add a comment like this and include your name, date, assignment number, and any other comments. I would also like you to submit your reading notes this way """
In class notes I will indicate Processing code by highlighting it in blue and using a fixed-width font:
Whenever text is formatted in this way, it is valid Python / Processing syntax. I will try my best to also use a fixed width font when specifying code in any emails.
When my notes work through an example by making incremental changes, modified code will be in pink and new code will be highlighted with a yellow background.
Use the Processing PDE "Auto Format" command frequently, and always use the command before sharing your code when asking for help. In the menu: Edit > Auto Format (or ⌘T on Mac). This helps keep your code nicely lined up. For now this doesn't matter that much, but soon, as we learn new types of syntax, this will actually help you debug your code and help you see the structure of your programs.
Have you memorized the URL for the Python Processing reference yet Processing reference yet?!?
A way to introduce variation on a theme, generalization within a formal structure, or the abstraction of some parts of a process.
The word comes from vary (dictionary.com) like variety and variance, and means a thing that is able to change.
A variable is a placeholder. A placeholder for a value. Instead of using a specific value (like a number), you create a name, and then use that name in your code. When looking at your code, you don't know exactly what the value of that variable is. You can set it to a specific value, or change that value later. This means that one bit of code is now able to do different things.
This creates a kind of abstraction. Think of other examples of abstraction that you're aware of. Like maybe Cubism, for example. There is an aspect to this of being "not specific", somehow general in some sense. Thinking back to the recipe metaphor from week 1, think of a recipe that might say something like "now add your sweetener" or "now add your protein". Often recipes can also be halved, doubled, or tripled. The person following the recipe may modify the amount of something or swap out an equivalent item. But still the recipe would just say "now add the spices" — the recipe specifies the amount and kind of spices, but that amount may have changed, but still, the recipe can proceed without knowning the exact amount. This is what a variable allows.
Variables allow algorithms to have generality. So the google search algorithm works approximately the same whether the user is searching for "apples", "bananas", or "carrots". When you write code that uses variables, you don't know exactly what your code will do in advance.
A little more specifically:
How this works in Python Processing:
size(600,600) treeHeight = 50 rect( 100, 100, 20, treeHeight )
The first line creates the variable. In some programming languages, you have to declare variables before you can use them. In Python, you don't have to do that. You simply create a variable by using it: by using placeholder name in your code.
An important rule is that you have to give the variable
a value before you can use it. Usually you do this as I
did above, with an equal sign (
=). This is
called variable assignment, and the
equal sign is sometimes called the assignment
Read that equal sign almost like an arrow pointing from right to left. Variable assignment is a declaration. You are telling Processing: "This placeholder that I'm calling treeHeight now contains the value 50." (Later we will use equal signs to ask Processing what the value of a variable is, but for now, we are telling.)
treeHeight is a name I made up. Your
variables can be any name as long as they are not
already special Python Processing words,
additional rules about variable names are below.) But
you should use things that will be useful to you and
others later when reading your code.
Please use good, informative variable names that describe what the variable will be used for.
The next line above is using the variable. After assigning it a value, you can use it over and over. You can also use it with arithmetic, and you can modify the value.
So if the above
rect() draws a tree trunk,
and I wanted to draw another tree with the same height to
the right of it, I could say:
# draw a second tree rect( 150, 100, 20, treeHeight)
And now I could change the value of the variable once and both tree heights would change.
Valid variable names:
must start with a letter or the underscore character
cannot start with a number
can only contain alpha-numeric characters and
treeHeight are all different
Variables can be used for all sorts of values. This week we will primarily be working with variables that store numerical values. For example:
armLength = 100 curveAngle = PI/2 legToArmRatio = 1.5
Later in the semester we will be working with other values. For example:
True / false values called booleans:
(This funny word is acutally a very common term in computer science that comes from George Boole, a 19th century mathematician who invented a formal system of logic, like an entire arithmetic that operates only on the values true and false instead of numbers. Booleans use keywords
name = "Rae"
stopKey = 's' # for keyboard interaction
You can also use variables to store colors. So you could specify a color like this:
r = 255 g = 150 b = 150 fill(r,g,b)
Or, you could also specify a color with
color() command, which creates a color
variable, like this:
c = color(255,150,150) fill(c)
You can even use variables to store images, like this:
img = loadImage("clouds.jpg")
And now maybe you hopefully understand a little bit more about
loadImage() line was doing in last
These different kinds of values are called types and we will be talking more throughout the semester about this idea of different kinds of placeholders.
Later in the semester you will even be able to create your own custom variable types.
Going back to the recipe metaphor, you can kind of imagine your variables as the ingredients list. Most recipes list all ingredients at the beginning so you know what to expect, and specify all the values, but later on only reference the item and not the quantity.
Processing comes with special some built-in variables. For example:
width — the width of the draw window
height — the height of the draw window
And some others we'll talk about next week:
mouseX — the horizontal part of the mouse position
mouseY — the vertical part of the mouse position
Arithmetic is done with the following operators:
+ — addition
- — subtraction
* — multiplication
/ — division
Question: So how would you draw a shape in the center of the window, and make sure it was in the center no matter what the window size was?
ellipse( width/2, height/2, 50,50 )
Start with this code:
size(600,600) background(255) stroke(100,100,100) fill(255,100,100,100) rect(250,100,100,100) fill(255,255,100,100) rect(250,200,100,100) fill(100,100,255,100) rect(250,300,100,100)
What if we want to make the first square wider? What should we change? Check the Processing reference
So we need to change the third parameter of
rect() command. And since we want the square
to be wider, we'll make that number bigger.
size(600,600) background(255) stroke(100,100,100) fill(255,100,100,100) rect(250,100,200,100) fill(255,255,100,100) rect(250,200,100,100) fill(100,100,255,100) rect(250,300,100,100)
OK great. And if we want the other two squares to also be the same width, we could change them too:
size(600,600) background(255) stroke(100,100,100) fill(255,100,100,100) rect(250,100,200,100) fill(255,255,100,100) rect(250,200,200,100) fill(100,100,255,100) rect(250,300,200,100)
But now what if we wanted to play with this width a bit, make
some adjustments. We'd have to keep changing all
rect() commands each time. Since we want
them all to have the same width, we can use a variable as a
placeholder for this value. Here's how:
squareWidth = 200 # variable assignment (creates the variable) size(600,600) background(255) stroke(100,100,100) fill(255,100,100,100) rect(250,100,squareWidth,100) fill(255,255,100,100) rect(250,200,squareWidth,100) fill(100,100,255,100) rect(250,300,squareWidth,100)
Now to make tweaks, I can simply change the value
200) in the variable assignment, and all my
squares will be drawn using this value. (Note: my variable
squareWidth is arbitrary and can be
anything I want. I could have called
spaghetti and I just chose a name that would
be informative to the purpose for which I was using it.)
Let's keep going. What if we wanted to make the first square taller? Let's change it's height and see what happens.
squareWidth = 200 # variable assignment (creates the variable) size(600, 600) background(255) stroke(100, 100, 100) fill(255, 100, 100, 100) rect(250, 100, squareWidth, 120) fill(255, 255, 100, 100) rect(250, 200, squareWidth, 100) fill(100, 100, 255, 100) rect(250, 300, squareWidth, 100)
If you run that, you'll see that the first square is taller, but now there is an overlap between the first and second square. What if we want the other two squares to automatically adjust their position?
Let's add a variable for the first square's height, and use that to position the second square. Like this:
squareWidth = 200 # variable assignment (creates the variable) firstSquareHeight = 120 size(600, 600) background(255) stroke(100, 100, 100) fill(255, 100, 100, 100) rect(250, 100, squareWidth, firstSquareHeight) fill(255, 255, 100, 100) rect(250, 100 + firstSquareHeight, squareWidth, 100) fill(100, 100, 255, 100) rect(250, 300, squareWidth, 100)
OK, looks good. So now we can adjust just the value of
firstSquareHeight and it's height will
change, and the second square will move accordingly.
But now we have the same problem with the third square! So we
have to repeat the pattern. The vertical postiion
y) of the third square should be the top point of
the first square, plus the height of the first square, plus the
height of the second square. So we can write that out, like an
squareWidth = 200 # variable assignment (creates the variable) firstSquareHeight = 300 size(600, 600) background(255) stroke(100, 100, 100) fill(255, 100, 100, 100) rect(250, 100, squareWidth, firstSquareHeight) fill(255, 255, 100, 100) rect(250, 100 + firstSquareHeight, squareWidth, 100) fill(100, 100, 255, 100) rect(250, 100 + firstSquareHeight + 100, squareWidth, 100)
Note that if
firstSquareHeight is 100 (it's
original value above), then this equation works out to 300,
which was its original value above as well.
Great. So now we can change only the
firstSquareHeight and the composition will
To keep going, can you add a variable for the
position of the squares, and have that adjust the position of
all three squares? What if you add two more squares to make a
small cross ("+" sign) and want the composition to adjust
So, how much "variance" can you achieve with 1 variable? with 2?
How many variables would you need to draw a shape that varied its height, and also its horizontal and vertical position?
Let's say you were trying to implement Pong for your midterm project. (A totally feasible project by the way!) How may variables would you need? What is moving or changing in this game?
One thing that works really nicely with variables is creating randomized variation of those variable values. You will need this for your homework this week.
In Processing, this is done with the
random(). For a detailed explanation, check
the Processing reference
random() returns a
floating point (a
number with a decimal point).
firstSquareHeight = random(10,300)
The parameters to
random() are minimum and
maximum values. They define a range from
random() chooses a number. Like asking a
person to "pick a number between 10 and 300".
Putting that altogether, here is how we could use random values to draw the above composition:
squareWidth = random(10,300) # variable assignment (creates the variable) firstSquareHeight = random(10,300) size(600, 600) background(255) stroke(100, 100, 100) fill(255, 100, 100, 100) rect(250, 100, squareWidth, firstSquareHeight) fill(255, 255, 100, 100) rect(250, 100 + firstSquareHeight, squareWidth, 100) fill(100, 100, 255, 100) rect(250, 100 + firstSquareHeight + 100, squareWidth, 100)
Stop and run that a few times to see what kinds of variation we've just created.