First Tutorial: Processing and programming basics.
Welcome to the Processing Architecture course at KTH School of Architecture. During the course we will be learning how to to write computer programs using the Processing language, its framework and IDE (integrated Development Environment). Before we start, I guess that a little disclaimer is in place: Programming is not too difficult, but it usually involves a few “steep learning” moments, in which new concepts need to be understood and used; often these concepts may appear difficult and their learning may involve a certain amount of patience. Besides the fun of overcoming a difficult step, you will soon forget that these hard-learned concepts were difficult at all, they will just become second nature. Similarly, installing programs and setting up different software in the computer can often be easy and trouble-free, but now and then one may encounter unexpected problems, so have some patience! First we will install Processing:
1. Installing Processing:
Download the correct version for your operating system from here:
http://processing.org/download/?processing
-On Windows you will get a zip file. Open it and drag the folder inside it wherever you want processing to be installed (like the “Program Files” folder, for example). You can choose the 32 or 64 bit version. According to some information online (as of February 2014), The 32 bit is more trouble free, but the 64 bit should be faster (obviously this only make sense if your Windows is a 64 bit version). To run it, click the processing.exe file.
-On Mac OS X, open the zip file and install normally (drag the Processing icon into the “Applications” folder). You can now run it as any other program.
-On Linux, you will need to untar the tar archive in your location of choice. Then open the terminal and change the current directory (through the cd command) to the newly untarred directory. Write ./processing on terminal to run (you can always create and run a small shell script to do this automatically).
Now that the program is installed we can setup a few things. Particularly it is important to set the location for your sketches. You can use the default one, but I always set one that makes sense with the way I organise documents and code in my system. You can change this at any time, but better to set it up right from the beginning… you can change the sketchbook location in “preferences” (which can be in the “File” menu in Windows, or under the “Processing” menu in OS X, for example) You can change other preferences there, and through editing the preferences.txt file.
Hopefully you will have gone through this without much trouble, and now we are ready to get started programming. By the way, the following text is rather “verbose”… it both explains basic concepts and tries to give a bit of background about them. This is not just anecdotic information (at least that is not my intention) but to make clear some basic theoretical implications of programming, which will hopefully will also help you grounding the concepts better.
2. What is programming.
The word program is made of the greek words pro-, meaning forth or forward and -gram, which means writing.Then literally program means to write in advance, or to write forth something that is going to happen.This is the same meaning as the program of a theatre performance or a TV program. Computer programs consists usually of texts written in a programming language.If you are interested in the history of programming languages, there is a nice entry on wikipedia. The history of computers and programming are closely related to the developments of logic during the nineteenth century and early twentieth century, and to the associated “linguistic turn” in philosophy during the twentieth century; for example the philosopher Charles Sanders Peirce, already demonstrated in the nineteenth century the possibility of using electric circuits to perform logical operations; a closer example is the influence of Noam Chomsky’s theories of language in the development of computer languages during the sixties. Languages have developed different paradigms (for example procedural or object-oriented, both used in processing); most computer languages include a number of basic concepts and paradigms, shared to a large extend between them. We are going to look at some of these basic concepts in the Processing language.
3 Basic concepts.
Syntax.
A difference between natural languages -the everyday spoken, signed or written languages- and formal languages (like programming languages) is that the former are more strictly formalised. This means that the instructions a program is made of need to be written strictly following certain rules, or syntax, in order to be executed. In a natural language one may have grammatical or syntactic errors and the meaning of a sentence understand (to make a point… you still get the meaning of this last sentence even if the form and tense of the verb “understand” is wrong… as it may be the case of other sentences in this tutorial, I am afraid). This is not the case in computer languages, which need to follow a rather strict syntax and logic. We are going to write our first line of code now.Write the code below within the Processing IDE:
println("Hello world");
Press the arrow (run) key above to execute it. It surprisingly enough prints a line, with the string “Hello world” (more about strings later) Not very exciting, so we can try instead:
rect(10,20,20,30);
Which draws a rectangle with a corner at X coordinate 10 and Y coordinate 20 (in pixels), 20 pixels wide and 30 pixels high (coordinates on processing 2D have their origin on the top left corner of the window, with the X positive axis going to the right and the Y positive axis pointing down). You can change the coordinates and see what happens…
Both println and rect are functions; they take a number of parameters within their parenthesis (in the case of println a string, in the case of rect coordinates and dimensions), and they end with a semicolon “;”. This is the basic syntax convention of the C programming language, and common to Java, C++ or Javascript, for example (since processing is based on Java, it follows most of its conventions). There are many predefined functions in processing, which you can check at the processing reference, also accessible in the processing IDE through the “help” menu.
You should try some of the functions in the Processing reference, particularly those for drawing in 2D, and get familiar using the reference…you can of course write a sequence of functions one after each other. You can try to write sequences of functions that change the states of the current fill colour ( fill() ), the stroke colour (stroke() ) or the background colour (background()), for example.
Before we continue I should also talk about comments. Computer languages can often produce cryptic expressions that may be difficult to understand at first sight. Comments exist to add explanations and notes to code, and in processing (as in Java, C, C++, Javascript..) are possible by using “//“ or “/* */“. These symbols tell the compiler or interpreter of the code (depending if the code has been written in a regular programming language or a scripting language) to ignore the commented text, in effect meaning that the text is not part of the program. “//“ means “ignore everything in this line from this point to the right”, and “/* …. */“ means ignore everything between these two signs.
//this is a comment, of one line
/* this is a comment of many lines */
/*this draws a red line, from point with coordinates 10,10 to point with coordinates 50,70. Remember the direction of the x and y axis! */ stroke(255,0,0); //this sets the stroke to be red line(10,10,50,70); //this draws the line
Lines of code can be broken. The “;” indicates really the end of a line. For example we can write:
line( 10, 10, 50, 70);
Types.
As you have seen in the functions above, they can take parameters of types String, for strings of text, or numbers, such as coordinates and dimensions. In the case of rect, if you check the reference, it says that it can take a number of float values. Float stands for floating point number, and it basically means that it can represent a number with a fractional part (commas) up to a certain precision (you can try changing some of the values on your lines, for example instead of 10, you can write 10.35, and see what happens).
The idea of type is also an essential aspect of programming. Types identify the kind of values that the language can represent, and how they behave, particularly in relation to arithmetic or logic operators and functions (for example, what happens if we wrote something like “hello” + 35). Many languages allow also to define own types.The types in processing are the same as the basic types in Java, but generally only a few of them are really used; you can check them under the Data Primitives in the reference. The ones we are going to look at now are:
boolean, which is used to represent a true or false value.
int, which is used to represent negative and positive integers (that is, without commas) between the values -2147483648 and 2147483647.
char, an integer type really, but generally used to represent single characters, like ‘E’ or ‘#’.
float, that represents numbers with commas between -3.40282347E+38 and 3.40282347E+38.
Besides the above basic types String is used to represent and manipulate strings of text, such as “Hello World” above.
Variables.
We have so far seen how how literal values of different types are passed to functions. Programming would be quite limited if this is the only thing we could do… Variables are symbols of a type that can store a value. They can be given any name. Here is a simple example:
float x=40; float y=30; float diam=50; ellipse(x, y, diam, diam); x=60; diam=diam -10; //observe that = means "assign", not equal, as the math expression! ellipse(x, y, diam, diam);
Try changing the names of the variables, and calling them anything else, like “banana” or “foo”, for example…it is however convenient to give variables meaningful names, so the code is readable and easier to understand.
Variables are really parts of the computer’s memory to which we can give a symbolic name, define the type of value we want to store in them, and access by that symbolic name. Variables are declared (there is a line in the code that says that there will be a symbol of a certain type), and assigned, that is, given a value. They need to be declared before they are assigned or used. This does not work:
x=60; //x is assigned before it has been declared! float x=40; ellipse(x, 10, 20, 20);
But this does:
float x; //x is declared, but not assigned. x=60; //try commenting out this line, by writing “//“ in front of it… ellipse(x, 10, 20, 20);
Here comes another example with a String, which is declared and assigned in the same line. When a variable is given a value the first time, it is said that the variable is initialised.
String sometext="Hi there"; println(sometext);
Some types can be automatically converted to others, like int to float.
float banana; int pineapple=10; banana=pineapple; println(banana);
They can also be added:
float a=10.36; int b=10; float c=a+b; println(c);
This will also work in Processing, but it will truncate the comma.
float a=10.36; int b=5; b+= a; //this is the add assign operator, short for b=b+a; println(b);
Variables of the same type can also be declared and assigned followed by commas, so we can write:
float x=10, y=20, w=40, h=30; rect(x,y,w,h);
Play a bit with the variables, so you understand how they work. You can check the operations that are possible to do with each type in the reference, under “Math” and “Operators”.
Control flow.
At the risk of oversimplifying we can say that a program is just a text defining certain operations that the computer reads in a predeterminate sequence and executes accordingly. All programs have usually an entry point, that is, a place in the text from which the computer starts reading and executing it. So far these operations have been executed by starting at the top of the text and reading one instruction after the other; but this order, also known as control flow, can be branched and looped.
Conditional statements:
One of the most basic forms of doing this is through conditional statements, which evaluate an expression and do different things if the expression is true or false. The most common form of conditional statement in Processing is achieved through the use of the if, and else statements(The other forms are in the reference under “Control” and “Conditionals”). The operators used for evaluating expressions, such as the != (inequality), == (equality), < (less than) or > (greater than) result always into a boolean value, true or false (all operators are in the reference under “Control” and “Relational Operators”). The set of instructions to be evaluated are always placed between curly brackets, “{“ and “}” For example:
int a=10; if(a>5){ line (0,0,100,100); //only if a>5, which it obviously is, since we have set it to 10… }
We can also add an else statement:
int b=20; //try with different values of b if(b<3){ //you can also change the condition (equal? larger?…) ellipse(50,50,30,30); }else{ ellipse(30,30,10,10); }
Statements can also be combined through logical operators, such as &&, which means AND, || which means OR, or !, which means NOT. For example:
int a=10; String s="what?"; if(a>3 && s=="what?"){ fill(255,0,0); //set fill colour to red }else{ fill(0,0,255); //set fill colour to blue } ellipse(50,50,30,30);
Loops:
Besides conditional branching, we can also make the control flow to go into loops, that is, the program to repeat something until a condition is met. This is often achieved through for or while loops. For loops are rather common, and are in most cases used to repeat a bit of code a certain number of times. A for loop includes a variable initialisation (often also its declaration), a condition that needs to be met to execute the loop, and an operation to do (usually increment or decrement the variable). This is its most usual form:
int myTone=0; //initialise the myTone variable to 0. for(int xpos=0; xpos<10;++xpos){ //here goes anything you want to repeat fill(myTone); //set the fill to myTone (one value means a tone of grey) myTone+=20; //increment myTone by 20 ellipse(10*xpos,50,10,10); }
It is also possible to put loops inside loops…
int fillTone=0; for(int xpos=0; xpos<10;++xpos){ fillTone+=20; //increment fillTone by 20 for every xpos fill(fillTone); //set the fill to myTone (one value means a tone of grey) int strokeTone=0; for(int ypos=1; ypos<20;++ypos){ strokeTone+=20; stroke(strokeTone); ellipse(10*xpos,10*ypos,10,10); } }
Play a bit with the for loops, change the ranges of the values (can they be negative? can you rename the variables?, change the amount they increment using the += operator that we have previously used ?). Try using some other drawing functions instead of the ellipse… You can also check the while loop and try to use it in the first example.
Scope
A thing to notice in both the conditional statements and the loops is the use of the curly brackets “{“ and “}” to define a bunch of code. An interesting property of these brackets has to do with the visibility of variables declared within them. Each variable is visible within the curly brackets it is defined, and in any curly brackets inside those, but not outside them. This is called the scope of the variable. For example, you can add this line and the end of the last example:
println("the stroketone is " + strokeTone);
It will give you an error when processing tries to compile the code. Now you can move it within the first curly brackets, and see what happens…
The basic setup in Processing.
Before we continue further with another essential aspect of programming we are going to look at the basic setup of processing. We have been writing instructions directly on the text window, but this is only valid for simple code that is going to be executed just once, (called static mode). Processing has a dynamic mode which consists of two basic functions, in which you will put most of your code: One called setup() , which is called once at the beginning of the program, and the other called draw(), which continuously executes the lines of code inside (it re-starts at the beginning after it has finished executing…). There are also a number of functions such as noLoop() loop() or redraw() to control further how this is done, but we want look at these basic once at the moment. In the setup() we usually initalise variables and call functions that only need to be called once in the program. Typical things to do here is to define the dimensions of the window or the background colour. For example
/* pos and increment need to be here, so they are visible from draw they could have been initialised in setup() also. */ int pos=0; int increment=3; void setup(){ size(500,100); stroke(100); //dark grey fill(200); //light grey background(0); //not really necesary if repainted in draw() } void draw(){ background(0); //this is needed to "clean" the screen ellipse (pos,50,10,10 ); if(pos > width) { //if larger than width, set to negative, that is, move to left increment=-3; } if(pos < 0) { //if smaller than 0, set to positive, that is, move to right increment=3; } pos=pos+increment; }
You can get the position of the mouse in processing with mouseX and mouseY. Can you modify the code above so the ellipse follows the mouse? Can you clean the code of all variables that are no longer needed?
Functions and sub-routines
The very last bit is also an essential part of programming, and it is the capacity to define own functions. This is the equivalent to define concepts or words in a language, particularly it allows to define verbs, or actions. We have been using ready made functions from processing, but now we are going to create our own. The syntax of functions consists of a return value, the name of the function, and the parameters it takes, like this:
int addTwoIntegers(int a,int b){ int c=a+b; return c; }
Which defines a function called “addTwoIntegers” which takes two ints, a and b, and returns another integer. Some functions don’t return any value, for example:
void printSomething(String sv){ //void means that it does not return any value. println("this is silly: " + sv); }
or they don’t take any value
void printSomethingSillier(){ println("this is even sillier: "); }
We can combine some of the examples above, and write:
int pos, increment; void setup(){ pos=0; increment=3; size(500,100); stroke(100); //dark grey fill(200); //light grey background(0); //not really necesary if repainted in draw() } void draw(){ background(0); //this is needed to "clean" the screen drawARowOfCircles(pos,40,mouseY); //call our function drawARowOfCircles(pos-10,60,mouseX); //call it another time if(pos > width) { //if larger than width, set to negative, that is, move to left increment=-3; } if(pos < 0) { //if smaller than 0, set to positive, that is, move to right increment=3; } pos=pos+increment; } void drawARowOfCircles(float x, float y, float spacing){ int myTone=0; //initialise the myTone variable to 0. for(int xpos=0; xpos<10;++xpos){ fill(myTone); myTone+=20; ellipse(x+spacing*xpos,y,10,10); } }
Before the next tutorial, look at the examples again and understand the basic concepts. Check the reference, and try to write some “interesting” code that includes at least a loop, a conditional statement, and your own function.
There are more tutorials at the Processing website: