Welcome back! I hope your week was as nice as you are.
In the past two weeks, we’ve gotten into the mindset of being hyper-descriptive - using lots of words to be extremely specific in describing even simple scenes, and then slid over to a more technical side to introduce tools like variables, coordinates, and math to make these descriptions more accessible to a computer.
This week, we discuss… coffee (and functions)!
I woke up this morning, got out of bed, brushed my teeth, put some clothes on, and walked into the kitchen to make myself a coffee.
Let’s get descriptive!
Benjamin’s Coffee Ritual
Turn on espresso machine
Weigh coffee beans (18g) using a scale
Grind beans
One scoop of creatine into a mug
Tamp the grounds in the portafilter
Secure the portafilter in espresso machine
Place scale under portafilter with mug on top
Press the double-shot button
Wait, smell :)
Press double-shot button again to stop once scale measures nearly 36g
Top up mug with hot water, stir to ensure creatine is mixed
Skipping the cleaning steps, voila - Americano!
That could have been more detailed, but it will be sufficient for getting my point across - the first point being that there are quite a few steps! I suspect that there’s a decent chance some of you reading this have never used an espresso machine before, and almost certainly a high chance creatine doesn’t usually make it into your coffee. Imagine if I had to describe all 11 steps every time I asked someone to make me a coffee - inconvenient! I just think to myself “I want to make a coffee” and these steps come as second nature due to hundreds of repetitions over a long period of time.
In coding, what I’ve just described is called a function! Similar to a variable, a function has a name and allows us to save something to be re-used later. Variables save a value. Functions save a series of instructions that we can use again and again! Rather than enumerating the steps each time, I can define them once and then tell the computer to execute “Benjamin’s Coffee Ritual” to get my brain juice. Thinking back to high school math, you’ve already seen a sort of function - trigonometric functions which have a name such as sin, take an angle as input, and output a ratio.
Elaborating on that, functions in coding have:
A name - “Benjamin’s Coffee Ritual”
Input (usually) - 18g of coffee beans
A series of instructions to execute - steps 1 through 11
Output (usually) - Americano
The best time to use functions (particularly for art, but generally as well) is when we have a series of instructions or calculations that we think we’ll need to use repeatedly. Now, there’s technically no reason we couldn’t just write out the full set of instructions every time instead of using a function - it’s just a pain in the ass and quickly makes code unpleasantly unreadable.
Let’s jump back to visuals now for an example. I promised we’d move away from circles this week - helloooooooo rectangles!
For this example, I’m trying to write a function that allows me to draw rectangles of arbitrary size and position. Let’s say that a kind soul has already written a line
function which allows us to easily draw a line on the screen. Remembering what we discussed last time regarding coordinates, it makes sense that this line
function would take two pairs of them - one for the beginning, and another for the end of the line. These would then be the inputs to the line
function - x0, y0, x1, y1
- these are just variables!
We’re pretty much at a point where we should start writing code - we’ll be using a language called JavaScript which is what a good chunk of the modern web is built on. Don’t worry too much about syntax - I’ll do my best to explain things as we go and will be keeping plenty of the descriptions in plain words.
We say that we call a function to execute it - in code, that might look like:
// This is a comment (the computer won't do anything with this)
// Anyways, let's define some variables first
let x0 = 0
let y0 = 0
let x1 = width
let y1 = height
// Then call the line function with the variables we just defined
line(x0, y0, x1, y1)
Assuming the kind soul who wrote the line
function knew what they were doing, we’ve now drawn a diagonal line across the screen ((0,0) is the top left corner, (width,height) is the bottom right). Now that we know what calling a function looks like, let’s define our rectangle function. Defining the function is when we write the instructions out (without actually executing them), and calling the function is when its contents are performed.
What make sense as input variables to our rectangle function?
Similar to the line
function, let’s go with a pair of coordinates (x, y)
for the top left corner of the rectangle, as well as the width and height (w, h)
.
// Curly brackets help us tell the computer where blocks of code (such as our function) start and end
// Once again, we're just defining the function here (not calling it)
function rectangle(x, y, w, h){
// Top side
line(x, y, x+w, y)
// Right side
line(x+w, y, x+w, y+h)
// Bottom side
line(x+w, y+h, x, y+h)
// Left side
line(x, y+h, x, y)
}
Breaking that down:
function
tells the computer that we’re defining a function (duh)rectangle
is the name we’ve given to the function(x, y, w, h)
tells the computer the inputs to the function (which will be passed in when it is called)Everything within
{}
is part of the function
If we were to then call this function using a constant x
and y
and varying w
and h
over time, it would look something like this (with added info/colour for clarity)!
There you have it - we’ve begun drawing with actual code!
We’ve covered quite a bit in just the past three posts:
Functions to save and execute sets of instructions
Variables to save values and use them repeatedly
Coordinates to provide a structure for describing where things are on our digital canvas
Basic Math to make our lives easier when calculating where to draw things
and a little bit of Code in JavaScript to use our newly developed descriptive superpowers to tell the computer what we want to draw!
We’ve gotten into the reasonably technical content quite quickly - kudos to you for making it this far! Next week, we’ll take a step back and discuss some higher-level concepts related to coding and computer art, possibly with a bit of additional math sprinkled in.
Stay vigilant!
Things I’m doing soon:
InterAccess Gallery in Toronto, Canada is running a digital arts fundraiser exhibition called flashDRIVE that ~60 (!!!) artists including myself are participating in, with an opening reception on Thursday, May 1st from 7-10pm. Proceeds from sales will be split between InterAccess and the artists. The exhibition is on until May 17th - hope to see you there!
Weekly quote:
“My heart is a fish, hiding in the water grass.”
~ Ann Leckie, Ancillary Justice
This post was mostly written on my couch between 12-2am and finished off at my desk the following afternoon :^)
Album of the week: “Revenge Fantasy” (2024) by Uncaught (in Promise)
If you have any feedback or questions about this or any other post (or just want to say hi!), I’m always happy to chat!