The programs you have written thus far execute line-by-line, beginning at the top of the code and ending at the bottom. You can visualise this flow as a set of steps chained together in a linear arrangement. In this lesson, we explore how to lay divergent paths for the program to follow.
A programmer can write various calls and conditions to reorder the linear sequence of execution – a concept referred to as control flow – thereby directing the program to skip, jump to, and repeat lines.
Control flow allows for more ‘intelligent’ programs. As an example: consider that you wish to fill the display window with circles.
A 9-circle arrangement requires writing nine
ellipse functions; this is manageable enough. However, writing eighty-one
ellipse lines is tedious. Using control flow statements, one can instead instruct Processing to add as many circles as are required, ceasing once eighty-one have been placed. This allows for more dynamic code, i.e. you specify the size of circles, and the program calculates how many columns and rows are required. Additionally, this approach can better cater for random diameter values.
This lesson covers topics involving conditional statements and iteration. Implementing such logic may require you to think in new ways. If you find yourself struggling with something, do not stress, that’s normal! With a little perseverance, you’ll soon grasp whatever is that has you snagged.
You will also explore randomness – one of the most powerful and exciting tools in the creative programmer’s tool-set.
Conditional statements are used to check conditions and provide appropriate responses. You can think of this as asking a question; receiving an answer; then performing an action in response to the answer. For example:
Question: Is the ball red?
Action: Place it in the bucket labelled “red balls”.
To explore Python’s various conditional statements, create a new sketch and save it as “conditional_statements”. Add the following code:
At this point, you are familiar with three datatypes: string, integer, and float. Before moving onto conditional statements, you require an introduction to a fourth type: boolean.
A boolean can represent one of two possible states:
False. Note that when writing these values, the first letter is always uppercase and no quotation marks are used (as this would make the value a string). Add the following code:
Relational operators determine the relationship between two operands. Consider this basic example:
3 > 2
In this case,
2 are the operands. The
> sign is the operator. Three is greater than two, so this statement is true. To see how this works in Python, add the following code to your “conditional_statements” sketch:
Take note of how the relational operations return a boolean value; this will be important in the next section. Here is a list of Python’s various relational operators:
!= operators have the ability to operate on both numbers and strings:
Relational operators are particularly useful when combined with
if and other conditional statements.
If statements are one of the essential means of introducing logic to your program. Add this basic example to your working sketch:
The code awards a PASS grade for any mark greater-than-or-equal-to fifty. In the above case the
mark >= 50 returns
True; so the
print('PASS') line is executed. It is vital that you indent the
if line is executed upon the condition returning
True. For example, the following code will print “PASS” and “Well done!” for any mark greater-than-or-equal-to fifty:
But, the following code will print “Well done!” regardless of whether or not the mark exceeds fifty:
To nest an
if statement within another
if statement, increase the indentation accordingly:
The above displays “Bien Hecho!”.
If you are evaluating a boolean value you may leave out the
== operator. For example:
ball_is_green variable is equal to
True, so typing
ball_is_green == True is equivalent to
True == True. Either way, the answer is
True! Still, if you find it helps to be more explicit, you can use the first version.
Currently, the grading program can only award a PASS. Ideally, it should assign letter grades (A/B/C/…). This requires additional if statements. Adapt your code:
As you would expect, the console displays a “C”. But there is an issue – a mark of
70 results in a “C” and “B”:
The problem here is that both
if statements operate independently of one another. If the grade is awarded a “B” then there is no need to check the C condition. An
elif (else-if) statement is required, along with some reordering of your code:
This correctly displays a “B” in the Console. Because the
if line returns
elif is skipped. This is why the correct ordering of
elif statements is vital; should the C condition to come first, every mark greater-than-or-equal-to 50 is awarded a C-grade, as the B condition is skipped.
elif statement to the code, adjusting the mark to test three different cases:
To visually group the connected
elif statements, the empty line between each has been removed; this is a matter of style, but you are welcome to add as many blank lines as you see fit. You may add as many additional
elif statements as you need.
A mark below
50 passes through all of the
elif statements without invoking any action. To handle FAIL cases, one can employ the
Else statements handle any condition that does not match that specified in the
if statement (or
elif grouping). Add an
else statement to your code:
else statement need not necessarily follow an
elif. For example:
Of course, this all depends on the logic you intend to implement.
Thus far, each of the
elif statements have been based on the outcome of a single relational operation; for instance:
is the mark greater-than-or-equal-to fifty?
However, there are many occasions where multiple relational operations must be evaluated within a single condition; for example:
is the mark greater-than-or-equal-to forty-five AND less-than fifty?
For these purposes, Python provides three logical operators:
True if both operands are true
True if at least one operand is true
not reverses the boolean (
False and vice-versa)
and condition to handle marks in the RESUBMIT range:
Now add an
or condition to catch marks outside of the valid range:
not operator has its uses but is awkward to apply in the working example. Instead, here is a one-line example of it in action:
print( not False ) # displays: True
In this challenge, you will apply conditional statements to a visual task. Create a new sketch and save it as “four_square”. Add the following code:
The above code divides the display window into four quadrants:
Next, place a character at some location determined by an x- and y-coordinate variable:
Your challenge is to write conditional statements to replace the
? character with an
O to match the colour beneath it. This way, one can adjust just the
y values and the character changes accordingly:
To start you off, here is the code for the red (
However, if you change the
y value to
400, an “R” is displayed over the orange quadrant. Begin by correcting this, then address the other quadrants.
Consider that you wish to tile a floor. Starting in one corner, you place a single tile. Next, you place another tile alongside that, repeating the process until you have reached the opposite wall; after which point you move down a row and continue. In this scenario, the placing of an individual tile is referred to as an iteration. In many iterative processes, the result of a previous iteration defines the starting point of another – in this case, the position of each tile is advanced by the one laid before it.
Tasks like tiling can be tedious work, though. Humans are exemplary in reasoning and creative thought, and if not sufficiently stimulated, lose interest in performing such repetitive tasks. Computers, however, excel in performing monotonous duties rapidly and accurately – especially where numbers are involved. Interestingly enough, the term “computer” originally referred to a person who performs mathematical calculations. Much of the work carried-out by ‘human computers’ involved calculating mathematical tables. These tables of numbers would be compiled into printed volumes that were used to simplify and speed-up other computations. As an example, logarithm tables were used extensively in sciences, engineering, and navigation.
Rather than perform tedious multiplication and division operations by hand, logarithm tables provide lists of pre-computed answers – like a more advanced version of the multiplication tables children are required to memorise in school. The forerunner of the modern computer, the Difference Engine, was built in the 1820s by Charles Babbage to automate the work of human computers. By devising a machine comprised of cogs and other moving parts, Babbage sought to automate the task of producing mathematical tables, while also providing more accurate results. Due to funding difficulties, a full-scale version of the machine was never completed – but its mechanical inner-workings paved the way for more complex electronic computers.
To begin exploring iteration in Processing, create a new sketch and save it as “concentric_circles”. Add the following code:
I’m sure you can see where this is heading – filling the display window requires writing many more
ellipse lines. Instead of adding these manually, you will make use of Python’s
while loop to insert them iteratively.
while loop statement looks and behaves much like the
if. However, the key difference is that the
while continues to execute the lines indented beneath it until the condition is no longer true.
Comment out your ellipse lines and add a basic
Running the sketch prints endless lines of single
0 digits to the Console.
This code has crashed your program by sending it into an infinitive loop. To explain,
i is equal to zero, and therefore less-than
24. But, unlike an
if statement, the
while repeatedly executes the
i reaches twenty-four – which is never.
i by one each time the line is printed, add one to it with each iteration of the loop:
You may name this
i variable whatever you wish, but it is a popular convention to represent the counter value using an
The final line (
i = i + 1) states that
i is equal to itself plus one. Once
i reaches twenty-four, the program can continue with any other code that follows beneath the loop structure. To draw twenty-four circles, place an
ellipse function within the loop:
Run the code. It appears that you have drawn a single circle:
However, what you are actually is seeing twenty-four circles of the same size drawn in the same location. Adapt the
ellipse, using the
i value as a multiplier for the width and height (third and fourth) arguments:
It should be pointed out that the width/height arguments (
30*i) of the first iteration are multiplied by
0, so the first circle is placed in the very centre of the display window but is effectively too small to be visible. The other twenty-three are sufficient to fill the 500 by 500-pixel area – but by changing the condition, you can draw as many (or as few circles) as you like.
Augmented Assignment Operators
You are already familiar with the
= operator, but not its arithmetic variants. In the “concentric_circles” example,
i was incremented using this line of code:
i = i + 1
To simplify this statement, one can instead write:
i += 1
Other similar operators include:
i -= 1 is equivalent to
i = i - 1
i *= 1 is equivalent to
i = i * 1
i /= 1 is equivalent to
i = i / 1
For anybody familiar with other programming languages, Python does not make use of
++ in/de-crement operators.
Rows of Circles Task
Time for another challenge!
Using a while loop, you will recreate this arrangement:
To begin, create a new sketch and save it as “rows_of_circles”. Add the following code to get started:
The following sequence of steps outlines the most straightforward approach to begin tackling this task:
- create a
whilestructure that loops twelve times (consider using a
print()to monitor your counter);
- using the loop, place the circles in one long row, extending past the right edge of the display window;
- once the above is working, use an
ifstatement within the loop to detect when the second row must begin.
It’s up to you to figure out the rest. Oh – and remember that modulo operator (%)? It may prove handy here.
When programming a loop structure, you are not limited to
while statements. The
for loop operates similarly; depending on the scenario, you may elect to use one over the other. Perhaps the easiest way to explain a
for loop is to convert something you have already written.
Create a new sketch and save it as “for_loop”. Add the following the code from your “concentric_circles” sketch:
Notice how the
i variable is created to serve as an counter. With each iteration of the loop, it is vital that you increment
i to avoid entering an endless loop. The
for loop does away with the need for counter variables. Adapt your code to make use of a
Notice how the
i = 0 line has been removed, along with the line to increment it (
i += 1). Despite these changes, the result remains the same:
range() function generates a list of values that the
for then iterates over. With each iteration, the acting
range value is assigned to the variable
i – although you may name this whatever you wish. For twenty-four iterations, the
range function requires an argument of
24; but the end value of twenty-four is never part of the generated list because the first iteration begins with
The range function can handle between one and three parameters. Provide two arguments for a start and end value:
Provide three arguments for a start, end, and step-size:
Any iterable object may be used in combination with a
for, meaning the
range() function is not always necessary. This concept is explored in the upcoming lessons dealing with lists and dictionaries (or “arrays” if you are familiar with other programming language terminology).
For Loops Task
In this challenge you will recreate these three patterns using
You will be referencing this image repeatedly during the task, so it may be useful to save a copy and open a preview of it alongside your Processing editor.
To begin, create a new sketch and save it as “for_loops_task”. Add the following setup code:
Here are a few clues to help you approach each pattern:
- Top-left pattern: you should manage this without any hints; it has twelve lines if you must know.
- Top-right pattern: the line spacing increases by a multiple of
1.5with each iteration.
- Bottom-centre pattern: consider using a modulo operator to establish
ifthe counter is odd or even.
After successfully completing this, you should have a decent grasp of loops.
The best a computer can do is simulate randomness. Think about this for a moment: if you request a random number from a computer, it will need to run some non-random set of instructions to pull a value. That said, computers can manage a pretty good job of this, relying on algorithms that generate pseudorandom numbers whose sequential appearance is statistically similar enough to a truly random sequence. This is okay for shuffling through your music collection, but best avoided for gambling and security applications.
For ‘true’ random numbers, computers can rely on things like key-stroke timings. For instance, you may have pressed your last key 684 milliseconds past the tick of the previous second. In the quest for true randomness, researchers have relied on everything from dice to roulette wheels, and between the mid-1920s and 50s one could even purchase special books full of random numbers. If you are really serious about plucking random numbers from the universe, there are hardware devices that rely on various quantum phenomena, like radioactive decay. However, for most applications, pseudorandomness will suffice.
So, what do random sequences look like? First, consider Perlin noise. In 1983, Ken Perlin developed an algorithm for synthesising organic textures and forms – like terrains, fire, smoke, and clouds. The graphs below plot random points (vertical axis) over fixed intervals of time (horizontal axis). The upper line represents a sequence of ‘purely’ random points, whereas the lower line charts values generated with Perlin noise. From this, you can visually appreciate why the ‘smoother’ Perlin noise is better suited for generating something like a mountain range.
Processing has functions for Perlin noise, but this lesson will focus on the
Create a new sketch and save it as “random_functions”. Add the following setup code:
random() function takes one or two arguments. One argument defines an upper limit:
The above code will display a random floating point value between
5 (starting at zero and up to, but not including, five). Two arguments represent an upper- and lower-limit respectively:
The above displays a random floating point value between
10. If it is a random integer you seek, wrap this the
x in an
int() function. This converts the floating point to an integer by removing the decimal point and everything that follows it (effectively, rounding-down):
The next step is to generate one hundred random values. Rather than print a long list in the Console area, plot them as a series of points along the same y-axis:
Now edit the loop. Change the range to
1000 and plot the
point using both a random x- and y-coordinate:
Each time the code is run, it produces a slightly different pattern. Recall, though, that these are pseudorandom sequences. What the
random() function does is pick an initial random number (based on something such as keystroke timing), then generates an entire sequence based upon this. The initial value is referred to as the seed. Using Processing’s
randomSeed() function, one can set the seed parameter manually, thereby ensuring that the same sequence of pseudorandom numbers is generated each time the sketch is run. Add a
randomSeed() to your working sketch – the argument may be any integer, but use
213 to verify that your output matches that depicted below.
Unlike the earlier versions in which no random seed had been defined, every run of the code produces the same pattern, on any computer that executes it. This is useful in many applications. As a concrete example, suppose you developed a platform game in which the positions of obstacles are randomly generated. This feature saves you a lot of time, as you no longer have to design each level manually. However, you find that certain sequences of random numbers produce more engaging levels than others. If you are aware of these key seed values, you can reproduce each good level with an integer.
Sébastien Truchet (1657–1729), a French Dominican priest, was active in the fields of mathematics, hydraulics, graphics and typography. Among his many contributions, he developed a scheme for creating interesting patterns using tiles – which have since become known as Truchet tiles. The original Truchet tile is square and divided by a diagonal line between opposing corners. This tile can be rotated in multiples of ninety degrees to produce four variants.
These tiles are arranged on a square grid – either randomly, or according to some pattern – to create aesthetically-pleasing patterns.
There are other Truchet tile forms, such as the quarter-circle tile:
Using the looping and randomness techniques from the lesson, you will now experiment with this. Create a new sketch and save it as “truchet_tiles”. Add the following setup code, which includes a single tile:
Now comment-out the
arc lines and tile the entire display window using a
The next step is to randomise each tile’s orientation. Because there are only two options, the loop must effectively ‘flip a coin’ with each iteration. A
random(2) will return floating point values ranging from
0.0 up to
2.0. Converting the result to an integer, therefore, produces a
After verifying that the above code prints lines of
0 to the Console, adapt it to display
Because this operation returns a boolean value, it can be used as an
if statement condition. Add an
Tiles are an exciting area to explore using Processing, and we’ll look at other types in the lessons to come.
Progressively-Jittery Quads Task
Here is the final challenge before moving onto lesson 04.
This one appears in Ira Greenberg’s Processing: Creative Coding and Generative Art in Processing 2 (page 80). It’s a great book that presents a fun and creative approach to learning programming. It is based on Processing’s Java mode (rather than Python) and well worth a read.
You will be referencing this image during the task, so it may be useful to save a copy and open a preview of it alongside your Processing editor.
Create a new sketch and save is “progressively_jittery_quads”. The display window is 600 pixels wide by 600 pixels high. Go ahead and complete the task.
That’s it for lesson 03. Kudos for getting through it – control flow is a tricky matter to get your head around at first! I trust that introducing random values has inspired some exciting project ideas.
The next lesson deals with animation. There is a bit you need to know about matrices and trigonometry, though. If you find yourself experiencing disturbing flashbacks of high school math class – take a deep breath and relax. Lesson 04 will be a practical and visual reintroduction to these concepts, with Processing crunching all of the numbers for you.
If statements and loops will reappear throughout this course, which will give you plenty of opportunities to master them. If you have some extra time, read up on the continue and break statements. These are two useful loop techniques that allow one to skip over iterations, or to ‘break-out’ of loop structures.
Begin Lesson 04: Animation and Transformation