This series of tutorial posts covers Processing.py, with the purpose of introducing non-programmers to the fundamentals of computer programming in a visual context. If you’re an artist, student, designer, researcher, or just somebody who is keen on learning how to code, Processing is a great place to start.
I would estimate each lesson to take around 2–4 hours to complete, of which a large part of that time will be spent on the tasks/challenges. The speed at which you get through the lessons is likely to be influenced by your prior experience in relatable areas. That said, it is not a race – enjoy the ride and stop for breaks wherever. Hey, if you’re really feeling inspired, feel free to head off-road!
My thanks go to Åke Jonsson for his feedback on these lessons.
Intro to Processing
As somebody teaching programming fundamentals to creative students – who will proceed to take courses in web, game, and interactive design & development – combining Processing with Python provides an ideal learning tool. What’s more, Processing costs nothing, is open source; and runs on multiple platforms, including Windows, Mac, and Linux.
You can think of Processing.py as a kind-of extension of the Python programming language, with all sorts of drawing features and an editor rolled-in. Sometimes it may seem that these notes use the terms “Processing” and “Python” interchangeably. I will usually refer to Processing-exclusive features in the context of “Processing”; and standard Python features in relation with the term Python. If this confuses you, think of them as one and the same! At this point, it is not important that you are able to distinguish Processing from Python, although you will come to understand the differences in time.
Before you can write any code, you will need to download Processing. Head over to the Processing download page, and download the relevant version (Windows/Mac/Linux):
Run the application. Note that the default mode is “Java”. As these tutorials cover the Python variant, you’ll need to switch to Python mode.
Click on the down arrow next to “Java” and select Add Mode… . Then, from the Contribution Manager window that appears, choose Python Mode for Processing 3. Finally, click Install.
Once this is complete, you can switch to Python mode.
You are now ready to write your first line of code! If you would like a demonstration of what can be accomplished, perhaps take a look through the examples (File > Examples…) included with Processing.py. If you are ready to begin writing your own code, move onto the next section.
You will encounter the term algorithm frequently from here onward. For these tutorials, the definition of an algorithm is: a set of rules a computer or machine follows to achieve a particular goal. As an example, an algorithm for making a cup of instant coffee will read as follows:
- place one heaped teaspoon of instant coffee in a mug;
- fill the kettle with water;
- switch-on the kettle;
- once boiled, add 240 ml boiling water to the mug;
- add one level teaspoon of sugar to the mug;
- stir the contents of the mug.
However, this set of steps would likely be insufficient for programming a coffee-making robot. Should the sizes of the mugs vary, smaller ones would overflow; and any requests for milk or extra sugar would be ignored. Computers cannot make any assumptions and therefore require explicit and unambiguous direction, and this requires communicating in a language the machine understands – like Python. Learning to write code may be the challenge you currently face, but as you grow more fluent, this will shift more towards mastering algorithmic thinking.
Processing refers to programs as “sketches”. Given the visual and artistic nature of what you are likely to produce, it’s a fitting term. Create a new sketch by selecting File > New, or using the associated keyboard shortcut (which is listed alongside the menu entry).
Type in the following lines of code:
Using File > Save as… save the sketch (to wherever it is you wish to store it) and name it “hello_world”. You will notice that each sketch is saved as a new folder – in this case, a folder named “hello_world”. Within this are two files: hello_world.pyde and sketch.properties.
You may also add other assets to your sketch folders, such as images and fonts – but more on that later.
Hit the ▶ button to execute the code. Better yet, use the associated keyboard shortcut: Ctrl+R for Windows and Linux; or ⌘+R for Mac.
You have used two Processing functions here –
print(). Functions consist of a function name followed by an opening and closing paren (or round bracket, if you prefer). Within these brackets, you supply arguments. The
size() function takes two arguments: the first represents the width of your sketch; and the second, the height. In this case, the display window is 500 pixels wide by 500 pixels high. For reference purposes, you could write out the size function with the required arguments named according to the values they accept:
Throughout these notes, you will find functions presented in this manner to explain their operation.
print() function writes to the Console area – the black rectangle at the bottom of the editor. Print takes a single argument; in this case, the phrase
'hello world'. Because this is text – or, more correctly speaking, string data – it must be wrapped in quotation marks. You may use single- or double-quotes, but be sure to close-off using the same type with which you have opened.
What separates Processing.py code from Python code are the functions. The
size() function is Processing-specific. In other words, it will not work outside of the Processing environment. The
print() function, on the other hand, is a built-in part of the standard Python programming language. It will, therefore, work in any Processing.py or Python application.
For a complete list of Processing.py functions and the arguments they require, you can refer to the online reference:
Note that the reference also includes many standard Python language structures, keywords, and functions – most of which we will cover along with the Processing functions.
Comments can be used to leave notes to yourself or anybody else editing your code. These come in two types: single- and multi-line. Use a
# character for single-line comments, and
""" for multi-line comments. Add some comments to your current sketch to see how they work:
While working through these lessons, add your own comments to remind you of what you have learnt. You can also comment out select lines of code, which can prove useful when debugging.
Python, and by extension Processing.py, is whitespace-sensitive. As an example, add a few space characters at the beginning of the
size() line; then run your sketch.
Because Python relies on indentation to distinguish blocks of code, the indented line breaks the program. Processing displays an error in the Console, as well as highlights the line on which the problem was encountered.
You will come to understand more about when and where to use indentation as you progress through these lessons. You may even be familiar with some programming language that uses braces (
}) to define blocks, in which case: Python replaces the need for these using indentation. For now, though, be aware that you need to pay careful attention to any space and tab characters that affect the indentation of your code.
Whitespace errors are not the only type logged in the console. You are likely to miss-out the odd paren, comma, or quote mark, especially when starting out. Remove the closing bracket/paren on your size function:
Now run the code and observe the console output:
Note the white-on-red suggestion. Pretty smart, huh? To be honest, the console is not always so clear or correct, but it usually provides a clue as to where to start looking for bugs.
There are various ways to specify colour in Processing. To keep things simple, we will stick with hexadecimal values for the first tutorial. If you are familiar with graphics software like Adobe Photoshop, Illustrator, Inkscape, or Gimp, you will have seen these values in your colour mixer. Processing includes its own colour selector. To access this, select Tools > Color Selector…
Screens rely on three primaries to mix colours, namely red, green, and blue. A hexadecimal colour value is comprised of 6 hexadecimal digits (
E,F) and can be split into three pairs. Each pair corresponds to a primary colour. In the case of red:
FF represents red; the middle
00 green; and right-most
00 blue. For reasons I won’t get into here,
FF is the equivalent of
100%. Also, remember that you are mixing light, so
#FFFFFF is white, and
#000000 is black.
fill() function sets the colour used to fill shapes. It accommodates up to four arguments, depending on the colour system you are using. For hexadecimal use the 6-digit value prefixed with a
# and wrap it in quotes:
To see the fill colour in effect, add a rectangle. The
rect() function is used to draw rectangles (or squares) and takes four arguments:
rect(x_coordinate, y_coordinate, width, height)
The x-coordinate values begin at the left-edge of the display window; and the y-coordinate from the top edge. Add the following code to your “hello_world” sketch; then run it to confirm that the output matches the image below:
rect() is one of its many drawing functions. You will be introduced to some others soon.
Fills and Strokes
When you write a
fill() function, every shape after that is filled in the specified colour – that is, up until the next
fill() line. If you want to disable the fill altogether, use
noFill(). In this way, Processing is like painting: you grab a brush and dip it in some paint, then everything you paint is influenced by the brush and colour you last selected. When you wish to paint in a different style or colour, you simply change-out your brush or dip it in a different pot.
Add the following code to your “hello_world” file. Note that comments have been added to give you a better idea of what each chunk is doing:
“Stroke” is another term for “outline”. There are three stroke functions you are likely to make frequent use of:
stroke() to change the colour;
strokeWeight() to change the width; and
noStroke() to disable the stroke altogether. Like
noFill(), the stroke functions affect everything below them. For a white stroke, three-pixels in width, add the following code (above the existing shapes):
To change the background colour use the
background() function. Add a background line to the end of your sketch:
Run the sketch and notice how everything has disappeared and the whole display window is a flat shade of blue. This because the
background('#004477') draws over everything before it. This is useful for when you get to animation, but for now, ensure that you place your background function somewhere near the top of your code:
You have been using hexadecimal values to represent colour thus far. We will stick to them for the rest of the lesson, but before moving along, here is a quick introduction to some other approaches. There is no need to write any code for this section – just read through it to gain a basic grasp of the concepts involved.
For various reasons, you may need to express colours in something other than hexadecimal. Here is one such scenario: you wish to write some code that darkens the bright red fill. Firstly, consider that this shade of red:
can also be represented as:
fill(255, 0, 0)
As you can probably deduce,
255 is equivalent to
FF (which itself is equivalent to 100%, as previously explained). To make the red half as bright, you can subtract
255. However, trying to subtract
FF is more tricky because you are dealing with a mix of hexadecimal and decimal numbers.
In the previous scenario, the Processing
colorMode() was set to
RGB. You didn’t need to specify this, though, as it is the default mode. In this mode, values represent the screen’s primary colours. However, there is another mode you can make use of:
HSB. Once set to HSB, one enters values representing Hue, Saturation, and Brightness.
To mimic the GIMP mixer above, one must first set the colour mode accordingly using:
colorMode(HSB, 360, 100, 100)
HSB represents the mode;
360 represents the range of degrees; and the two
100 arguments a range of 0–100% for saturation and for brightness. You would now write a red fill as:
fill(360, 100, 100)
This is because red lies at 360 degrees of rotation on the Hue ring (which begins at ‘East’ in the GIMP mixer) with the saturation and brightness set to 100%:
For a dark-greyish violet, one could use:
fill(270, 50, 50)
In HSB mode, shifting along the colour spectrum – from red to orange to yellow to green, etc. – is a matter of adding or subtracting from the H-value. Attempting the same in RGB mode is more complicated as you need to manage the quantities of each primary.
In this section, you will look at a number of drawing functions.
Begin a new sketch (File > New) and then save it as “drawing” (File > Save As…). Add some code to set things setup before proceeding:
When you run the sketch, an empty blue display window appears. What follows below are descriptions for several drawing functions, along with some code to add to your working sketch. Feel free to experiment with the arguments to see how things respond. Each example builds on the code before it, so you’ll need to work through all of them, entering each line as you progress.
Draws a point, the width of which is determined by the
strokeWeight(). The arguments represent the x- and y-coordinates respectively.
Draws a triangle. The six arguments represent three x/y-coordinate pairs.
Draws an ellipse. The first pair of arguments represent an x/y coordinate that marks the centre of the ellipse; the second pair of arguments represent its width and height.
Ellipse and Rect Modes
You have seen how rectangles are drawn from the top-left corner, and ellipses are centred on the x/y coordinate. If you wish to change this behaviour – for example, have the
rect function draw from the center – refer to the following functions:
Draws a quadrilateral (a four-sided polygon). The eight arguments represent four x/y-coordinate pairs.
Draws a straight line between two points. The first pair of arguments represent the starting x/y coordinates; and the second pair, the ending x/y coordinates.
Time for a challenge!
Begin a new sketch (File > New) and then save it as “rainbow” (File > Save As…).
Add some code to get started:
Using what you’ve learnt thus far, complete the rainbow below:
Clue: you can overlap shapes to mask-off others.
Variables are placeholders for information – much like when you use letters in algebra to represent a value. In fact, Python variables look and behave similarly.
Begin a new sketch and then save it as “variables”. To keep things simple, we’ll print to the Console area. Add the following code:
height are system variables that store the dimensions of the display window. However, you are not limited to system variables. When declaring your own variables, you assign a value using an
= sign (assignment operator). Try this out with a new variable named “x”:
You may name your variables whatever you wish, provided the name: contains only alpha-numeric and underscore characters; does not begin with a number; and does not clash with a reserved Python keyword or variable (like
width). For example:
Whether you should name a variable using camelCase, underscores, or some other convention is a matter of style (and vociferous debate). However, it is good to decide upon and stick to a naming convention, as you will make extensive use of variables in Processing. Add three more variables to your script, using them as arguments in a
Variables are far more useful when you perform arithmetic operations using them. Add the following code to your “variables” sketch:
I’m guessing that did exactly what you expected? You can also subtract:
Multiplication is performed using the
Now add the code below, but before hitting run, see if you can predict what the total is:
The console displays a
7 – and not a
9 – because multiplication occurs before addition. Certain operators take precedence over others. Remember BEDMAS? Or BODMAS (depending on where you’re from)? It is an acronym to help you recall the order of operations. If you want to override this order, use brackets:
For division, use a forward-slash:
Be aware, though, that dividing two integers always produces an integer result (integers are ‘whole’ numbers, as opposed to those with a decimal point). For example:
Python discards any decimal digits, effectively ‘rounding-down’ the result. To allow decimal results, define at least one of your operands using a decimal point:
Decimal numbers are usually referred to as floating point, or float values, in programming terminology.
Of course, division by zero operations will result in errors:
The modulo operator is written as a percentage sign (
%). It calculates the remainder of a division operation. Take five divided by two as an example:
- one could say the answer is
- or, that the answer is
1, because two ‘goes into’ five twice with one left over.
The modulo operator performs the latter. Here is some code contrasting a division and modulo operation:
It may not be evident why this is operator useful. However, many important algorithms – such as those used in cryptography – make use of it. For now, consider that modulo operations resulting in a
0 indicate that numbers divide exactly. Among other uses, this is handy for establishing whether a number is odd or even:
You will be making use of modulo operators in future lessons.
Image Reveal Task
Time for another challenge!
The idea here is to follow the instructions to reveal a symbol. Create a new sketch and save it as “symbol_reveal”. Add some code to get started:
To begin revealing the symbol, follow instruction steps 1 to 6. To get you started, here is the first instruction, along with the correct code:
- Draw a line beginning at an x-coordinate of half the display window
width, and y-coordinate of a third of the window
height. The endpoint must have an x/y-coordinate equal to
– which will be coded as follows:
Now, carry-out the rest of the instructions:
Draw a centred ellipse with a width that is an eleventh of the display window
width, and a height that is a fourteenth of the window
Draw a centred ellipse with a width that is a nineteenth of the display window
width, and a height that is a twenty-second of the window
Draw a line beginning at an x/y-coordinate equal to
ycorespectively. The endpoint must have an x-coordinate of the display window
xco, and a y-coordinate equal to
Draw a line beginning at an x-coordinate of the display window
xco, and y-coordinate equal to
yco. The endpoint must have an x-coordinate of half the display window
width, and a y-coordinate of a third of the window
Draw a centred ellipse with a width that is a fifth of the display window
width, and height that is a twelfth of the display window
Clue: if this seems like a conspiracy, you may be on the right track.
Disk Space Analyser Task
Here is the final challenge before moving onto lesson 02. However, before tackling this one, you will need an introduction to drawing arcs.
arc() function is used to draw elliptical arcs. It’s best to try out a few examples to see how it works. Create a new sketch and save it as “disk_space_analyser”. Add some code to get things started:
arc() function takes the following arguments, expanded across multiple lines here for easier comprehension:
Add an arc to your sketch using a
The green overlay helps illustrate how things work. The arc is drawn along the perimeter of an invisible ellipse that is centred on the given x/y coordinates. An angle of
0 is positioned at ‘East’, which then opens clockwise to an angle of
2 – which looks more like, around, 115 degrees of rotation? The reason for this is that Processing uses radians and not degrees. Why radians? Well, to answer a question with a question: why are there 360 degrees in a whole circle, anyhow? I mean, why not 500 or 100, or 1 million degrees? In fact, while we’re on the topic, why are there 60 minutes in an hour? Or 24 hours in a day? The answer has to do with influences from ancient civilisations and is beyond what you need to know for now. What you do need to know is that radians are a standard unit of angular measure used in many areas of mathematics. Rather than try to explain in writing how large/small a radian is, here is a neat animation from Wikipedia:
There are plenty of online degree-to-radian converters out there, but it’s good to know a few key measurements. For starters, zero degrees is equal to zero radians, and 180 degrees is equal to approximately 3.142 radians. You recognise that number? Yep, it’s pi! Therefore, 360 degrees is equal to 2π. Add the following code:
To close an arc, so as to form a ‘slice’, add an additional
A disk usage analyser presents a graphical representation of what is on a disk drive. The Linux GNOME Disk Usage Analyzer is one example of such software. You will recreate the storage ring-chart below. The text and number labels have been added to assist you; you need not add them to your recreation.
That’s it for lesson 01. I hope it was enjoyable, if somewhat challenging. Take a break – you deserve it! When you are ready to move on, proceed to lesson 02 using the link below. If you are familiar with vector graphics (Adobe Illustrator, Inkscape, etc.), you’ll be gaining some new insight into their inner-workings.
Begin Lesson 02: Bézier, Catmull, and Rom walk into a bar …