Section outline

    • "A strange vase" by Mace Ojala (GNU GPL 3.0 license), using p5.js (GNU LGPL 2.1 license)

      We engage with basic, familiar objects of the digital such as the pixel. On our exploration we learn to appreciate how complexity is composed out of simple, elementary starting points into shapes, arrangement, colours, graphical user interfaces, data, and manipulations of the interfaces which bridge the insides and outsides of the computer such as like the screen, the keyboard and the camera. While doing so, we will touch upon shared history and possibilities of arts and technology, as well as Modernist art of the 20th century. What might be it’s implications for “post-internet art” and “new aesthetics”?

      Further use as Open Educational Resource (OER) is encouraged: This work and its contents are – unless otherwise stated – licensed under the Creative Commons (CC) BY-NC 4.0. Please cite according to the TULLU rules as “Creative programming in the wake of Modernism” by Mace Ojala, licensed under CC BY-NC 4.0. Other licensed content, works and works are excluded from the license (see https://moodle.ruhr-uni-bochum.de/course/view.php?id=54274).

      Code exhibition

      Check out a small code exhibition of programs made by students at Institut für Medienwissenschaft at Ruhr-University Bochum in 2022 and and 2023, accompanied by commentary.

      Who this is aimed for

      This OER is aimed for teachers, educators and learning facilitators who would like to take an explorative, playful and open-ended attitude towards conveying basics of programming, while keeping the meaning of the specific medium, the web, in view. This could be in media studies, the arts, digital design. It might be suitable as an introduction for web design, but is more exploratory than systematic. The course is poorly suited as a generic introduction to programming or software engineering. More straight-to-the-point, often at the cost of meaning and relatability, exist online.

      Learning goals

      • Express oneself through code.
      • Learn about addressing the screen as a geometric plane.
      • Learn to use reference documentation and error messages.
      • Rehearse basics of JavaScript syntax.
      • Rehearse iteration over a collection.
      • Learn about abstraction, and composing complex (graphical as well as conceptual) objects from elementary ones.
      • Learn about co-development of process-basedness in 20th century visual arts and 20th century computation.
      • Learn to appreciate web as a dynamic medium.

      How to adopt/adapt

      • Pixels onscreen ASAP.
      • Do as much of live-coding as possible, showing students your thinking and typing process in action.
      • Give students time to type the programs you live-code. This will take surprisingly much time and support, especially in the beginning. Some contemporary computers do necessarily indicate basic symbols such as { and } on the keyboard, and reading and typing is error-prone.
      • Introduce friction against copy-pasting. Typing code has bodily and experiential elements.
      • Assign explorations to do independently
      • Review the explorations in class, both readings especially codings. Relate everything to basic concepts such as arrays and iteration, and what is familiar to students e.g. lists and grid layouts, which are two-dimensional lists.
      • While pairwork is fine, I advocate learning elementary programming praxis individually. Computer use tends to be individualized – just look at the computer in front of you. Once basic capacities are in place, pairwork and teamwork can begin.
      • If pair up students, please do your utter best so that male students do not deprive others from the learning opportunity. Programming is highly gendered, as is breaking things – we have work to do.

      Literature

      This work builds on three books, first two of which capture an explorative, creative and reflexive attitude towards programming, and are aimed for creative programming rather than software engineering. The first book is Winnie Soon’s and Geoff Cox’ Æsthetic Programming. A Handbook of Software Studies which Winnie and Geoff have developed from their experience in teaching programming at Aarhus University. The second book is Nick Montford’s Exploratory Programming for the Arts and Humanities, the second edition of which was published in 2021 by MIT Press. It too draws from teaching experience. Both books are available for free as Open Access, and Winnie, Geoff and their published Open Humanities Press are very explicit about this point. I encourage you to study these books and enjoy the eloquence, and force of their writing. The third book this is built on is not a programming or software studies book at all, but Liam Cole Young’s 2017 List Cultures. Knowledge and Poetics from Mesopotamia to BuzzFeed. The book is indeed all about lists, and is a media studies excavation into the Kulturtechnik of lists, or Arrays as they are known in JavaScript. Liam’s book too is available as a free Open Access book via the publisher Amsterdam University Press. Thank you Winnie, Geoff, Nick and Liam for your work.

      Background

      [!note] Personal inspo p5.js is so satisfying, with a quick feedback loop between code and output.

      I wanted a seminar which starts with playful encounter with what is at hand, quickly does something visual and thought provoking.

      This OER is an outcome of a praxis seminar titled Programming for Media Studies at Ruhr University Bochum in 2022 and 2023, a beginner programming offered at the Institute for Media Studies. The seminar was ran twice before writing this OER. Like a play, the seminar was organized and paced as three “acts”, each ending with a show & tell in class to wrap up a topic. Each act is divided into a few “scenes”, which were two hour sessions in person. This specific OER covers the middle act of the seminar.

      I wanted a seminar which starts with playful encounter with what is familiar (pixels, the screen), and quickly does something visual and thought provoking. The starting gesture is making pixels on screen ASAP, and staying with something stupid rather than professional with computers. The research aim of our project was to think about media praxis, and I wanted to resist outcome-oriented, project-based learning/programming with open-ended praxis and exploration.

      This OER covers covers four teaching sessions and a show & tell where students given a chance to present their work in class. We made a field-trip to the Modernist art collection of the Ruth-University Bochum, and sketched artworks with pen+paper, and later in code. What you see here, is compilation of my presentation slides which I originally wrote in Markdown and presented via reveal.js. In the style of so-called “eat your own dogfood” aka dogfooding, a best(?) practice in software development and a gesture towards the wide applicability of these technologies and techniques, each slidedeck was therefore a small website made with HTML, CSS and JS the students could download and mess around with.

      I am grateful for the students who took the seminars and explored software with me.

      I hope this OER can help and inspire you and your students on the journey to learn programming, self-expression via code, and to think about code the as cultural medium.

    • p5.js web editor

      "P_1_2_2_01" by Benedikt Groß, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni from https://editor.p5js.org/generative-design/sketches/P_1_2_2_01. Licensed under the Apache License Version 2.0, using p5.js (GNU LGPL 2.1 license)

      Let’s get signed up to p5.js web editor

      🏭 Guided activity
      Tour of the web editor UI

      p5.js

      • What is p5.js? Where did it come from?
      • What is a “library” anyway?
      • Lauren McCarthy’s JavaScript version of Casey Reas’ and Ben Fry’s Processing.
      • Open Source, so community matters hugely!!
      • But what is “open source”?
      • Processing Foundation

      See Soon+Cox (2020) Æsthetic Programming start() in Chapter 1.

      The p5.js reference documentation

      p5.js reference 🔍 → https://p5js.org/reference/

      The reference documentation is just like a dictionary; you’ll learn which words exist, and how to use them.

      🏭 Guided activity
      Explore the p5.js reference documentation. The examples are interactive.

      See also Soon+Cox (2020) Æsthetic Programming Reading the reference guide in Chapter 1.

      Dan Shiffman

      Dan Shiffman is, among other things, a youtube creator of educational videos about p5.js. His channel is called 🚂 The Coding Train 🚂. Make sure to check it out, and see some of his videos.

      Canvas and 2D graphics

      • setup() and draw() as basic elements of almost all p5.js programs
      • canvas
      • coordinates, with (0, 0) in top-left corner
      • circle. Let’s look at the reference

      🏭 Guided activity
      Make four, individual sketches of which the first draws a small circle near top-left corner, the second a medium sized near the middle, the third a tiny two-third down near the bottom right area, and the final a very large partially off-screen.

      See Soon+Cox (2020) Æsthetic Programming My first program in Chapter 1.

      🖼 background()

      🖌 stroke() and 🪣 fill()

      Also noStroke() and noFill(). What would you think strokeWeight() does?

      🎨 color()

      [!note] Color itself is an amazing topic, worth a life of study.

      [!tip] Think of the current state “Which brush am I holding right now? Is it up or down? Where is it? Which fill is active?”

      🐭 mouseX and mouseY

      The graphical p5.js “Hello World!” is a circle drawn at mouseX and mouseY.

      Here is a more involved example for simple interaction with mouse. Can you read through the code? Try vocalizing the code.

      https://editor.p5js.org/mace/sketches/3gs4vNoq3

      …something completely different
      "At the beach steps on sand with seagull shriek refactored with functions" by Mace Ojala (GNU GPL 3.0 license), using p5.js (GNU LGPL 2.1 license)

      🏭 Guided activity
      Discuss why do we typically place a background() in the beginning of draw()?

      Exploration of p5.js, canvas and 2D graphics

      1. Scroll 5 meters of #p5js hashtag on Twitter or Instagram.
      2. Watch any one of Dan Shiffman’s videos.
      3. Combining ideas from this lecture, make 3 little programs out of circles.
        • Get familiar with the p5.js reference documentation.
      function setup() {
        createCanvas(333, 333);
        rot = 0;
      }
      
      function draw() {
        bgcolor = color(111, 222, 30, 10);
        background("#ffffff22");
      
        stroke("white")
        line(111, 222, mouseX, mouseY);
      
        translate(mouseX, mouseY);
        rotate(rot);
        textAlign(CENTER);
        text("Thanks", 0, 0);
        rot = rot + 0.02;
      }

       

       
      • circle
        • A special case of ellipse
      • rect
      • line
      • text

      You’ll find them, and others, in the reference documentation.

      Math

      The usual +, -, * and /

      circle(width/2, mouseY - 100, mouseX * 0.3);

      Iterating over a collection of items?

      For example the Celestial Emporium of Benevolent Knowledge (Borges 1942)

      animals = ["belonging to the emperor", "embalmed", "tame", "suckling pigs"];
      
      animals.forEach(animal => {
          console.log(animal);
      });

      We will want to move on to do something else than console.log the them.

      animals = ["belonging to the emperor", "embalmed", "tame", "suckling pigs"];
      
      animals.forEach(animal => {
          draw(animal);
          animate(animal);
          interact_with(animal);
          ...
      });

      For instance drawing them on the canvas.

      animals = ["belonging to the emperor", "embalmed", "tame", "suckling pigs"];
      
      function setup() {
        createCanvas(400, 400);
      }
      
      function draw() {
        background(220);
        
        animals.forEach(animal => {
            text(animal, mouseX, mouseY);
        });
      }

      Array of concentric circles

      Same idea, iterating over a collection of numbers circle sizes rather than peculiar animals (strings).

      https://editor.p5js.org/mace/sketches/gYF243mRu

      sizes = [30, 50, 60, 70, 30, 10, 5]; // I made them up!
      
      function setup() {
        createCanvas(400, 400);
      }
      
      function draw() {
        background(200);
        noFill();
        sizes.forEach(size => {
          circle(width/2, height/2, size * 5)
        })
      }

      Note the drawing order

      https://editor.p5js.org/mace/sketches/NnXYHnynN

      sizes = [30, 50, 60, 70, 30, 10, 5];
      
      function setup() {
        createCanvas(400, 400);
      }
      
      function draw() {
        background(220);
        angle = height/mouseY * 2;
        // noStroke();
        sizes.forEach((size, index) => { // NB. the second argument index
          ellipse(width/2,               // center horizontally along x
                  100 + (1/index) * 200, // lay them vertically along y
                  size*5,                // stretch horizontally
                  size*0.3*angle)        // squeeze vertically
        })
      }

      A composition of lines

      Still the same pattern: define an array of data, then iterate for each of them. This time drawing lines.

      https://editor.p5js.org/mace/sketches/y-TuBhQxU

      points = [[10, 40],
                [50, 60],
                [30, 150],
                [340, 250],
                [180, 100]
               ];
      
      function setup() {
        createCanvas(400, 200);
      }
      
      function draw() {
        background("white");
        strokeWeight(6);
        points.forEach(point => {
                      line(point[0], 0, point[1], height)
        });
      }

      You can study examples from Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni's book Generative Design: Visualize, Program, and Create with JavaScript in p5.js.

      Exploration of shapes and math

      Make 3 little programs, this time with feeling.

      • Explore use of math to place your shapes
      • Explore reacting to mouseX and mouseY
      • Explore iterating over a collection of items

      Try to read (and modify!) the code of one of the programs in Generative Design.

      [!note] Next time make sure to bring pen and paper!

    • Composing shapes

      https://editor.p5js.org/mace/sketches/ahSn0E5Yt

      function setup() {
        createCanvas(400, 400);
      }
      
      function draw() {
        background(220);
        fill("red");
        noStroke();
        rect(100, 100, 50, 50);
        circle(100+25, 100, 50);
        circle(100, 100+25, 50);
      }

      Abstraction, ie. naming new actions from a collection of basic actions

      // Without function
      function setup() {
        createCanvas(400, 400);
      }
      
      function draw() {
        background(220);
        fill("red");
        noStroke();
        rect(100, 100, 50, 50);
        circle(100+25, 100, 50);
        circle(100, 100+25, 50);
      }
      // With function
      function setup() {
        createCanvas(400, 400);
      }
      
      function draw() {
        background(220);
        drawHeart("red")
      }
      
      function drawHeart(color) {
        fill(color);
        noStroke();
        rect(100, 100, 50, 50);
        circle(100+25, 100, 50);
        circle(100, 100+25, 50);
      }

      Naming gives semantics and makes the code clearer what it does – drawing a rect and two circles vs. drawing a heart.

      Defining and calling a function

      Defining is “preparation”

      function drawHeart(color) {
        fill(color);
        noStroke();
        rect(100, 100, 50, 50);
        circle(100+25, 100, 50);
        circle(100, 100+25, 50);
      }

      The definition alone draws nothing before being called; it’s just added to the available “language”… analogous to the everyday meaning of “definition”.

      The above definition draws nothing before being called.

      drawHeart("red")

      The anatomy of a function definition

      1. The keyword function
      2. A descriptive name, often verb phrase
      3. Body inside {...}
      4. Optionally arguments (input)
      5. Optionally a return value (output)
      function drawHeart(color) {
        fill(color);
        noStroke();
        rect(100, 100, 50, 50);
        circle(100+25, 100, 50);
        circle(100, 100+25, 50);
      }

      Functions can take arguments (input)

      console.log("Hello world")
                  ╘═══════════╛ An argument
      createCanvas(400, 300);
                   ╘═╛       First argument
                        ╘═╛  Second argument
      rect(50, 100, 100, 300);
      
          ╘═╛                First argument (integer)
               ╘══╛          Second argument (integer)
                   ╘══╛      Third argument (integer)
                        ╘══╛ Fourth argument (integer)
      text("Hello world", 100, 300);
        
           ╘═══════════╛              First argument (string)
                          ╘═╛         Second argument (integer)
                               ╘═╛    Third argument (integer)

      Functions can return a value (output)

      sentences = preface.split(".")
      function whichSideIsMouseOn() {
          if (mouseX < width/2) {
              return "left";
          } else {
              return "right"
          }
      }

      Why functions?

      • To give collections of action better names
      • Blackboxing of concerns
      • To do the same thing many times
      • To do almost the same thing many times
      • Automatic library features e.g. setup(), draw(), mousePressed()

      See Soon+Cox (2020) Æsthetic Programming Function in Chapter 3.

      Functions for randomness

      We already saw Math.random()

      From https://p5js.org/reference/#/p5/random

      • random([min], [max])
      • random(choices)

      A composition of lines with random displacement

      https://editor.p5js.org/mace/sketches/qRNVBH1n1

      function setup() {
        createCanvas(400, 200);
        points = [[10, 40],
                  [50, 60],
                  [30, 150],
                  [340, 250],
                  [180, 100]
                 ];
        displacement = 0
      }
      
      function draw() {
        background("white"); 
        strokeWeight(6);
        points.forEach(point => {
                      line(point[0] + point[0]*displacement, 0,
                           point[1] - point[1]*displacement, height)
        });
      }
      
      function mousePressed() {
        displacement = random()
        // displacement = random(-0.5, 0.5)
        console.log("New random displacement is " + displacement)
      
      }

      Randomness is perhaps surprisingly useful in computation, e.g. in Machine Learning (ML), music &c.

      “The open work”

      • 📄 Eco (1962) Programmed Art.
      • 📄 Caplan (2018) From Collective Creation to Creating Collectives. Arte programmata and the Open Work.

      Different phenomenology of same process.

      Arte programmata Milan, 1962.

      At an Olivetti store.

       

      Monachesi. Arte programmata (1963)

    • For this activity, visit a modernist art collection. Bring pen and paper 📝. The place we visited with our original seminar was the Kunstsammlungen der Ruhr-Universität Bochum, but any modernist collection will work – it does not need to be large or comprehensive. If you cannot find a modernist art collection in your city or region, visit another modernist milieu such as a supermarket, a furniture store, an house appliance shop or toyshop, a transit hub, or a modern(ist) neighbourhood. Make sure to actually go out of the computer; an online art collection is no substitute. What you are looking for is designed and manufactured physical objects and artefacts.

      Make sketches of the objects you encounter. ### Modeling

      You can choose

      • already very abstracted models (modernist art)

      • less abstracted models (classical / figurative art) ## Exploration of modernist art

      • Watch Monachesi. Arte programmata (1963)

      • Model two artworks in p5.js

      [!task] Explore their attributes, composition, complexity, concepts, and phenomenology by rebuilding them from elementary graphic shapes in p5.js editor.

      Explore introducing randomness to your programs.

      [!tip] Start with pen and paper.

      [!tip] Looking at the shadows can help.

      Potential further reading

      • 📖 Soon+Cox (2020) Æsthetic Programming setup() in Chapter 5.o
      • 📄 Eco (1962) Programmed Art.
      • 📄 Caplan (2018) From Collective Creation to Creating Collectives. Arte programmata and the Open Work.
      • 📖 Ernst (2013) Underway to the Dual System. Classical Archives and Digital Memory.
      • What media æsthetic literature you have studied?
    • Exploration of post-internet photography

      Open the following p5.js program on your phone, and take a photo walk of at least 30 minutes. It is a little camera app which takes photos and then does pixel sorting, arranging each vertical column so that the total brightest pixels are at the top, and darkest at the bottom. It’s a kind of a photo filter, familiar from smartphones, Instagram etc.

      https://editor.p5js.org/mace/sketches/ualvv5LlX

      The app does not save photos anywhere on the cloud or on your phone/computer. If you want to save a photo, you can grab a screenshot. Screenshots themselves are interesting digital objects, and play special role in digital culture.

      What is an image on a computer?

      The program has a number of sort functions defined at the bottom, from line 103 onwards. One of them, sort_by_brightness is activated at line 90. Try the other ones. The functions can be copy-pasted, renamed and changed. Some of them given functions use the three channels, e.g. on blueness of the pixels, for sorting.

      Explore image manipulation

      • Prepare for Show&Tell
      • Try to modify the pixel sorting photo app.

      Ideas for modifying the pixel sorting photo app

      • Sort by redness instead of blueness.
      • Change the lighting conditions of photography (use p5.js! ;)).
      • Change the threshold values.
      • Condition Image.set() on y_index on line 93.
      • Change the UI.
    • In which we put ourselves at stake and show other what we have explored so far.

      At the end of this OER, look at all the programs created so far. Many of them don’t work, but some do, and many kind-of work. Show some of them, no matter how working, to someone. Explain to them what you were trying to do, why do you think it works or doesn’t. What did you learn from making each of them?

      It is worth acknowledging what you have accomplished so far: we know how to run code, collect data in a list, iterate over them, manipulate different kinds of digital objects familiar from the web (eg. images, text), and we have ran conditional, branching code 🎉

      If you have enjoyed this open educational resource (OER) or have found something for your teaching, studies, or general inspication, it would be great to hear from you! Comments, critique, and other discussion is also welcome of course, you email me at mace.ojala@ruhr-uni-bochum.de.

      Happy hacking smile