Code-Along: Library of Babel
Follow these instructions to update an image generation program to use a for
loop!
Background - Library of Babel
There is a website right now that contains a photo of your funeral. It also contains anything that could ever be written. Check out this video to learn more about it:
Basically, the idea is that it is possible to create a program that, given an infinite amount of time, will generate any conceivable image. This is similar to the Infinite Monkey Theorem, demonstrated here:
For this activity, there is a much simpler version of this. It generates images that are 2 pixels tall and 2 pixels wide, and it only uses red, blue, and yellow. The goal will be to update the image-generating code so that it can generate more complex images.
Getting Started
Remix this project to begin. Run the program, click the button, and see the image it creates!
Next, take a look at the existing code to see how it works.
HTML
The HTML in the index.html file contains a couple key things:
- a
<button>
that runs thegenerateImage
function when clicked - a
<div>
with anid
ofcontainer
that contains nothing- this is where the generated image will go
CSS
The CSS in the style.css file only really styles the non-essential parts of the page. It sets the colors, fonts, positioning, and more. It will not be necessary to update the CSS for this activity.
JavaScript
The JavaScript in the script.js file is pretty extensive. There are three functions, each doing a different thing. When working with JavaScript, it is often necessary to use a bunch of different functions. Here's what each function does:
getRandomWholeNumber
This function returns a random number. It is similar to the one used in the Dice Roller activity. It takes in a maximum value parameter (max
), and generates a whole number between 1
and max
. It is called by the getRandomColor
function.
getRandomColor
This function returns a random color. It calls the getRandomWholeNumber
function to choose between yellow, red, and blue. It is called by the generateImage
function.
generateImage
This is the function that runs when the "Generate" button is clicked. It selects the HTML <div>
element with an id
of container
and stores it in a variable named container
. It empties out its inner HTML, and sets some styles on it:
- It sets the display to
grid
, and sets the grid to have two columns of equal width - It sets the
width
andheight
to200px
each
Then, it creates a new HTML <div>
element and stores it in a variable named newCell
. It sets the width
and height
to be 100px
each for the new element. It then sets the background
to be a randomly generated color by calling the getRandomColor
function. Finally, it appends the newCell1
element to the container
element as a child.
It repeats this "new cell" process for three additional cells: newCell2
, newCell3
, and newCell4
.
Summary
The existing code may be a little confusing - it's doing quite a lot! However, this activity is more about the concept of for
loops than anything else; try to keep that in mind, and focus on the looping aspect.
Refactoring the Cell Creation with a for
Loop
Now it's time to start updating the code. The first step is to refactor the generateImage
function to use a for
loop! The actual functionality of the site should stay the same for this part - the goal is simply to change the structure of the code itself.
Structure
Start by defining the structure for the for
loop
- Open the script.js file for editing
- In the body of the
generateImage
function, make a line space under thecontainer.style
statements- This should be somewhere around line
32
- This should be somewhere around line
- There, start building a
for
loop with thefor
keyword- Follow it with parentheses:
for ()
- This loop should execute once for each cell in the generated image
- Follow it with parentheses:
- Within the parentheses, add the first boiler-plate statement for initialization
let i = 0;
- Don't forget the semi-colon!
- After that, add the second boiler-plate statement for condition
- Consider how many times the loop should run:
4
! i < 4;
- Consider how many times the loop should run:
- After that, add the third boiler-plate statement for increment
i++
- Remember, there is no semi-colon for this statement!
- After the parentheses, add the curly brackets to create the body
That's it for the structure! This loop will repeat its body 4
times, one for each cell. The code should look something like this:
for (let i = 0; i < 4; i++) {
}
Body
Next, determine which code to run repeatedly! This should be the code that creates a new cell, sets its styles, and adds it to the container <div>
.
- Copy the five lines of code under the
for
loop starting withlet newCell1 = ...
let newCell1 = document.createElement("div"); newCell1.style.width = "100px"; newCell1.style.height = "100px"; newCell1.style.background = getRandomColor(); container.appendChild(newCell1);
- Paste that code into the body of the
for
loop- Between the
{
and}
- Between the
- For clarity and cleanliness purposes, adjust the indentation
- The code within the body should be one level deeper than the
for
- The code within the body should be one level deeper than the
- Change the name of
newCell1
to simplynewCell
- Make sure to update all five lines here
- Delete all code beyond the
for
loop from the body of thegenerateImage
function- None of this is needed anymore!
Run the program, click the button, and verify that it still works the same way!
At this point, the entire generateImage
function should look something like this:
function generateImage() {
let container = document.querySelector("#container");
container.innerHTML = "";
container.style.display = "grid";
container.style.gridTemplateColumns = "1fr 1fr";
container.style.width = "200px";
container.style.height = "200px";
for (let i = 0; i < 4; i++) {
let newCell = document.createElement("div");
newCell.style.width = "100px";
newCell.style.height = "100px";
newCell.style.background = getRandomColor();
container.appendChild(newCell);
}
}
Making a 4x4 Image
Now that the code uses a for
loop, it will be much simpler to adjust it for more cells! Instead of generating images on a grid with 2x2 dimensions, update the code so that it generates images on a 4x4 grid.
- Open the script.js file for editing, and find the
generateImage
function - Set the
gridTemplateColumns
property to be"1fr 1fr 1fr 1fr"
instead of"1fr 1fr"
- This will make it four equal-width columns wide
- In the body of the
for
loop, set thewidth
andheight
for the new cell to be"50px"
instead of"100px"
- To keep the same overall width/height, each cell will be 50x50:
200px
divided by4
yields50px
- To keep the same overall width/height, each cell will be 50x50:
- Finally, make the
for
loop repeat more times!- It should repeat
16
times total, because a 4x4 grid has 16 total cells
- It should repeat
That should be it! Run the program, click the button a few times, and make sure a 4x4 image appears. See if any interesting pictures come up!
The code for the generateImage
function should look something like this at this point:
function generateImage() {
let container = document.querySelector("#container");
container.innerHTML = "";
container.style.display = "grid";
container.style.gridTemplateColumns = "1fr 1fr 1fr 1fr";
container.style.width = "200px";
container.style.height = "200px";
for (let i = 0; i < 16; i++) {
let newCell = document.createElement("div");
newCell.style.width = "50px";
newCell.style.height = "50px";
newCell.style.background = getRandomColor();
container.appendChild(newCell);
}
}
Conclusion
By the end of the activity, the project should look something like this. Note that the only changes should have taken place in the script.js file.
The key takeaway from this activity is that for
loops make code much more extendable and maintainable. Imagine trying to update the original code to be a 4x4 grid without the use of a for
loop; it would have been really annoying! Now, it's possible to create images of any dimension without changing too much. For loops make it possible to make code do a lot with only a few lines!