TOC HELP SIX STEREO

PROJECT CODEPEGS

Coding for every mind.

Patent pending
© 2015 Georgiy Kuznetsov

The introduction

It takes a click.

Before running away in fear, why wouldn't you click on the gray board and watch? The black text area on the right shows computer code. The gray board on the left shows what this code does.

If you aren't getting it, that's fine. Everything will be explained. Read, click, watch and get used to the look of computer code.

To show what can be taught and learned in CODEPEGS, we are going to build one and the same pattern in four different ways. These examples are not for the beginners, but they are not very advanced either.

1. Please click here to load code, then click on the board. This code will produce the pattern in the most direct and hard-to-get way: by rotating the whole method of building a triangle 3 times.

2. Please click here to load code, scroll up to the playbox and click on the board. This fancier method is, in fact, easier because the color spots are rotated one-by-one.

3. Please click here, scroll up to the playbox and click on the board. This code replicates the board with a single triangle on it. Then it rotates the replica and copies the triangle back to the board 3 times. Rotating a square is easy.

4. Please click here, scroll up to the playbox and click on the board. This code turns the color spots into living cells. Every cell wants to become a quincunx. Every cell in a quincunx wants to become a quincunx too. Code drops 4 strategically placed seeds and let the cells fill the space with their colors.

Besides computer programming as such, CODEPEGS helps to learn the most popular professional computer technology in the world: web programming and the language of web browsers JavaScript.

CODEPEGS is spatiotemporal. This ugly word means that the pattern develop is space and time. In the previous examples, the same pattern resulted from the different transformations. This multiplies diversity of the programming problems and often adds difficulty to them.

Spatiotemporal patterns invite and encourage to play in code. Try to replace the four easily recognizable seeding lines before of the final loop at the end of the example 4 with the following:

f[d-1][d-1].beMine('y');
f[d-1][d].beMine('b');
f[d][d].beMine('y');
f[d][d-1].beMine('b');

The cells will grow into a different pattern.

To change the size of the board, assign another value to the variable named d in the first line of code. This value will be doubled. The speed is defined by the value passed to the function tick() in the second line of code.

CODEPEGS grew from my previous projects MAKE THEM MAD and FIREPEGS. I wanted you to know about them all and draw connections. Spatiotemporal patterns are paramount for teaching, and they are what we need to teach the fundamentals of computing. Computer programs are just spatiotemporal pattern makers, after all.

The learning of spatiotemporal patterns and computing may start very early. A short movie linked to the SIX PROJECT home page extends from early development to computer programming. In the interim, elementary math is learned as computing too.

CODEPEGS is for everybody. Spatiotemporal patterns are accessible, intellectually attractive and rewarding. A learner doesn't have to be a computer artist.

The virtual toy pegboard is the departure from the legacy of Logo language. CODEPEGS is not about vector graphics. The little squares on the board are oversized pixels. Remember how many games were created for alphanumeric computer terminals.

Except for the patterns and computer programming itself, nothing in CODEPEGS is beyond the knowledge and skills of a regular 4th grader. Recently, I taught it my almost 8-year old daughter. I tried and proved on her many patterns when she was only 4. Schools don't teach such things, but kids get them quite easily.

The technique is language-independent. I had to use JavaScript, which is a terrible choice for beginners. I did my best to make it accessible.

CODEPEGS is patent pending. This website is a part of SIX PROJECTS. My email address is

PART 1: SOURCERER'S APPRENTICE

The fun of the web.

The secret of spells

Knock knock.

Scattered along this and the following pages are playboxes like the one found below. The black area on the left is a simplified CodeMirror text editor. Who knows one simplified text editor, knows them all.

On the right, there is a rectangle filled with the little gray rounded squares. In memory of the toy pegboard from the MAKE THEM MAD, I refer to them as pegboard and pegs.

Important: the FIREPEGS is not here yet. The little squares are not connected to each other and do not behave on their own.

To change the color of a peg, let's click inside the black area and type the following spell:

change(1,1,'blue');

We can copy/paste and drag/drop a piece of text selected anywhere on the page, but we must be careful not to pick something else.

To cast the spell, let's click anywhere on the board. To re-cast, we can do it again. Browsers know some color names. We can try blue or green. We may change only the name. We must leave the quotation marks in place.

The numbering of the squares may be different. On this board, the column number is the first and the row number is the second. Both numbers start from 0.

Can we color another square. What makes them change? Are they reading our spells?

More magic: Let's select the following spell, drag it into the textarea, drop, and cast by clicking on the board. The whole window must change its color:

document.body.style.backgroundColor='gray';

To get the page's background back, we have to carefully replace gray with white. One wrong letter voids the power of the spell. To do the editing right, we change only the name of the color. We don't touch anything else, including quotation marks. Just in case, the second spell must look like this:

document.body.style.backgroundColor='white';

If we didn't clean the board and added the second spell after the first one, that's perfectly fine. We will change gray to gray, then gray to white. However, dropping a spell in the middle of another spell ruins both.

What the spells mean

Where and what.

Look again at how we've made the whole page's background white.

document.body.style.background='white';

Although strange, it's certainly more legible than, for example, barcode. The words are more or less English, but what do they mean?

Here is a new spell:

your.cmdw.style.background='white';

For your convenience, it comes preloaded into the following playbox. Click inside and outside to cast. By the way, all playboxes do the same. You may erase preexisting text and drop any spell anywhere. To change the size of the board, use the spell size(), For example, size(6,4) make a board 6 pegs high and 4 pegs wide.

Uh-oh, what have we done! Hurry up, click where the textarea was and hit Ctrl/A. See it? White letters are no longer visible on white and the whole textarea became invisible on the page, but the spell is there. Delete the selection. Select, then drag and drop the following.

your.cmdw.style.color='black';

Click inside and outside to cast it. The text is now black, but where is the textarea?

Try this.

your.cmdw.style.border='thin solid black';

Did you draw the border? Good.

Now let's compare the last two backgroundColor spells.

document.body.style.backgroundColor='white';
your.cmdw.style.backgroundColor='white';

Did it start making sense to you? The dots separate the intermediate destinations, like US.Ohio.Cincinnati, etc. Once we've navigated to where we want, we can address something called style and tell it which color to paint its owner's background. This last part is the same for the page and for a text area because, after all, they both are rectangles on the screen.

Another, and even more important way to think about it, is that everything belongs to something else. Street belongs to the city, building belongs to the street, etc. Street name is not enough if we don't know which city it belongs to. Just style is not enough. Both the document's body and the textarea have styles. Every peg has it. We have to tell whose style we are talking about.

What the spells do

Find a rectangle and color it.


A spell as simple as setting backgroundColor reveals how browser fills the  s   p   a   c   e . Web pages is made out of rectangles. This, I believe, is essential to learn first and foremost.

Now how about change(1,1,'white')? A peg is a rectangle, OK, and we set up its color. Why does this spell look so different?

Because it was sugarcoated. The spell under the sugar is:

board[1][1].style.background="white"

This spell must work for any two numbers, as long as they fit the board, and with any color name known to the browser.

The spell board[1][1].style.background="white" was hidden inside this change() thing called function for three reasons. The first one is easy: to make its name short.

Second, the change() spell bunches up several spells with the actual color-changing one, so that they would always come together. For example, it can change colors by numbers. Try to put numbers from 0 to 11 in place of the color name, with quotation marks or without them. It will work, but only for my pegs. The page will not get it.

Third, the change() spell addresses the pegs through numbers. Remember US.Ohio.Cincinnati? Next will be the street name and then the street number. Assigning a name to every door would be utterly impractical. For the similar reasons, CODEPEGS doesn't name every peg. It numberes them.

The numbering of the board is reliably consistent. All the pegs are visible. We can navigate from peg to peg by adding and subtracting distances. Click inside and outside to cast the following preloaded spell, and try to understand what's happened.

Kicking a web browser is an engaging method to explore the mechanisms behind WWW. Textarea is a hatch hacked through the web page into the darkness of the browser's belly. We may imagine ourselves standing at it calling: "Dear document, I'd like to speak to your body! Hello body, may I say something to your style? Hi style, please ask the browser to make the body's background pink."

What you just read, was another kind of sugarcoating called metaphor. Without metaphors the harsh reality of computer systems would be unbearable even for the brainiest. Unfortunately, there are too many metaphors floating around. This one is very useful, even if not quite applicable. In web browsers the objects do not talk to each other nicely. They simply take what they want.

What CODEPEGS can teach

Procedural thinking.

Do internet users know how accessible is the magic, which they call "technology". A simple playbox lets us tinker with the existing web page immediately, through the browser's Document Object Model, or DOM, avoiding the famous "tag soup" of HTML. We see it, we change it, we can add new elements and configure them. We can even build web pages this way.

The science of education calls this experiential learning. Some speculate it is omnipotent, or, at least, more powerful than a traditional systematic approach. Just give them computers and leave them alone.

Every bit of my experience with the kids having practically unrestricted access to computers tells me the opposite, but I agree that we usually provide the answers and demand the students to remember them before they asked any questions.

A virtual pegboard in CODEPEGS is integrated with a webpage. Technically, it's a grid of web-elements. We play with it using the most popular computing language in the world JavaScript, and, despite some enhancements, this is no-nonsense industrial JavaScript in its native environment.

CODEPEG spells are also known as code, scripts, programs or software. In this setting, we can start learning and teaching general purpose computer programming or web-programming or both. For web-programming, this will be a radical departure the from the traditional mindset, in which web-browser is a text-formatting tool, but the technology evolves in this direction.

Although the programming problems in CODEPEGS are real and the skills it teaches are practical, its goal is not to train another generation of coders. CODEPEGS was meant to achieve what school failed to achieve: to integrate the new way of thinking brought about by the creators of computers into education.

PART 2: LET'S LEARN SPELLISH

From phrases to grammar.

What's Spellish

A language to change pegs and us.

Your must be very familiar with magic. Most people are nowadays. I am, in fact, a die-hard illiterati. I've never opened a single Harry Potter book and know next to nothing about Hobbits. To the best of my knowledge, true spells are simply words and phrases in the languages, which we have never had a chance to learn.

This particular dialect is very accessible and fully open to the public. Every web browser understands it, and browsers are not very smart. Last time I checked, there were only 38 words, all in plain English. The rules are not nearly as complicated as in any language used between us humans.

I could have given thousands very good reasons to learn and use this stuff. It's just not my goal at the moment. Let me say that I unconditionally want my children to learn it. I mean, no matter what they are going to do with their lives, this will be the most empowering and useful skill.

Mastering computer spelling makes you a different, and a much more capable person. You learn to fight staying cool, to avoid mistakes and to find them quickly. You explore, invent, design and build at the pace unimaginable in any other trade. You research, diagnose, investigate, set up and run experiments to prove and disprove your ideas, and you often do it many times a day.

Computer spelling is the cream of the crop of intellectual occupations. It teaches to understand, design, troubleshoot and manage complex dynamical systems, be it business, family, or your body. It does not teach everything we need for success—in a sense, it's rather narrow— but it's very rewarding, especially if we do it for yourself.

In the beginning of PART 1 you we tried playboxes and saw few simple spells. Let's now learn what the sorcerer's apprentice did not.

Sidewalk TIME
Flash in time and send Morse code.

STOP
Welcome to Sidewalk TIME.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

If you don't see the blue message below the gray board, extend your window or zoom it out. Click to inject a spell to the playbox editor. To cast the spell, click on the gray board.

Step 0

The following spell creates a new virtual pegboard. The numbers are the height and the width. Try to change them and cast the spell again.

INJECT
size(4,3);

Be sure not to change anything else: the letters, the "banana peels", the comma and the semicolon must be in place.

Step 1

This spell (which can be also called code, script, program or software) makes a 2×2 board. Immediately (computers are very fast), it makes the upper left peg red. In due time, it makes it gray again, so the peg blinks.

INJECT
size(2,2);
change(0,0,1);
change(0,0,0);

Reminder 1: The peg won't blink on its own. After injecting the spell, please cast it by clicking on the gray board. Do it again.

Reminder 2: The rows and the columns of the pegs are numbered. The numbering starts from 0. The numbers are displayed in the pegs. Calling a function like change(), we supply the number of the row, the number of the column and the color we want this peg to have.

We can tell the colors as words or numbers. The number 0 stands for light gray. Then we have 1 for red, 2 for blue and 4 for green.

Step 2

We are going to make pegs blink many times. To simplify the spelling, let's define a function. Please inject the function definition, but do not cast it yet.

INJECT
size(2,2);
function blink(){
  change(0,0,1);
  change(0,0,0);
};

In coding, functions are not like those in school math. They are like parts of somebody's work. Executing the blink() function, the browser makes a peg blink.

A function is a named spell. We set some code apart using curly brackets and name it blink. The familiar spells change() and size()are functions too. We don't have to know how they work. We just call them by name.

Let's cast the spell. Nothing visible is supposed to happen. Invisibly, CODEPEGS has learned a new function and forgot it. This function is only good while the piece of code (or spell) is being executed. Good thing, however, is that JavaScript has not reported any mistakes.

Step 3

To use a function, we call it by name. Let's try to inject and cast the function call blink(). I put the function definition below the call. JavaScript collects and learns the function definitions first.

INJECT
size(2,2);
blink();
function blink(){
  change(0,0,1);
  change(0,0,0);
};
Step 4

The programs in this and the following steps will follow this order: working code first, function definitions next.

To make the peg blink more, let's call the function again().

INJECT
size(2,2);
blink();
again(); //this one is new

function blink(){
  change(0,0,1);
  change(0,0,0);
};
A sorcerer apprentice kind of trap? Well, yes, except this one is harmless. To stop a running spell, we click on the black text editor.

By the way, the playboxes with virtual pegboards, text editors and ready-to-use functions like change() and size() are not found in standard JavaScript. They are the learning aids created for CODEPEGS.

Step 5

Every change() function call postpones the call to the next such function for 1 tick. We can change the time between the calls adding one more number to the change() function call. The following spell shows the given color for 2 ticks before replacing it with gray. The gray stays for 1 tick. Tick is the unit of time in CODEPEGS.

INJECT
size(1,1);
change(0,0,2,2);
change(0,0,0);
again();

A zero in the fourth position in the "banana peels" of a change() function makes the next change() function call to be executed immediately. If we replace 2 with0, the peg will go from blue to gray so fast that we will see nothing but gray.

The function again() casts the spell sitting in the editor. In doing so, it casts itself, so the spell repeats forever unless we close the window, reload it or click on the editor to return to writing.

Step 6

The blink() function knows only red. To teach it colors, let's remember that the functions change() and size() have something between their "banana peels".

Please inject and cast the following.

INJECT
size(2,2);
blink(4);
function blink(clr){
  change(0,0,clr);
  change(0,0,0);
};

Calling the blink() function, we put the number of the color between the "banana peels" like in the message box. JavaScript makes this color available inside the curly braces under the name of clr.

The function call blink(4) acts like

change(0,0,4);
change(0,0,0);
Step 7

Once we have learned that the number of the color supplied to the function blink() becomes known to the function change() through the name clr, we can try to blink different colors.

Please inject and cast the spell. It uses two color shortcuts: 1 for red and 2 for blue.

INJECT
size(1,1);
blink(1);
blink(2);
again();
function blink(clr){
  change(0,0,clr);
  change(0,0,0);
};
Step 8

To tell the blink() function where to blink the color, let's pass the numbers of the row and the column.

function blink(row,col,clr){
  change(row,col,clr);
  change(row,col,0);
}
The new function now looks like change(), except it blinks. Care to try it out?

INJECT
size(2,2);
blink(0,0,1);
blink(0,1,2);
blink(1,0,3);
blink(1,1,4);
again();
function blink(row,col,clr){
  change(row,col,clr);
  change(row,col,0);
}
Step 9

We are about to stage a more complicated dance on a bigger board. Please inject, cast and watch.

INJECT
size(4,6)
blink(3,0,2);
blink(1,1,1);
blink(1,2,1);
blink(0,3,8);
blink(1,4,1);
blink(2,5,4);
again();
function blink(row,col,clr){
  change(row,col,clr);
  change(row,col,0);
}

Was it hard to recognize?

Step 10

Let's add music. The code is a courtesy of kittykatattack. It works, what else can I wish?

INJECT
size(4,6)
blink(3,0,2); sound(220.00,0,1);
blink(1,1,1); sound(329.63,1,1);
blink(1,2,1); sound(329.63,2,1);
blink(0,3,8); sound(349.23,3,1);
blink(1,4,1); sound(329.63,4,1);
blink(2,5,4); sound(293.66,5,1);
again();
function blink(row,col,clr){
  change(row,col,clr);
  change(row,col,0);
}
Step 11

We have learned that change() and size() are function and understood that we can use them to build new functions like blink(). A change() function delays the following change() function and we know how to set up the time interval between them. We are now ready to code dances of colors in time and space.

Such dances may not require much programming skill, but they are not necessarily easy to code. Most people are poorly prepared to understand spatiotemporal patterns. The one below may look like two feet shuffling back and forth, but, tracing the steps, we will discover the hourglass-shaped track from Step 8. Unlike the pattern in Step 8, every peg stays blue for 2 ticks, but let the following peg change its color in 1 tick. The illusion emerges because brains perceive changing colors as moving objects.

INJECT
keep();
size(2,2);
tick(1/2); //to make it slower.
change(0,0,2,0);
change(1,0,0);
change(0,1,2,0);
change(1,1,0);
change(1,0,2,0);
change(0,0,0);
change(1,1,2,0);
change(0,1,0);
again();
Step 12

The duration of a tick can be programmed as follows.

tick(1); // 1 second (rather slow)
tick(1/10) // reasonably fast
tick=0.01 // unreasonably fast
tick() // reset to 1/4s

The spell in the previous lesson is a good opportunity to try various durations of a tick. The shorter is a tick, the faster is a pattern. In a single spell, there can be several tick() functions, each one affecting the code after itself. Before executing a spell, CODEPEGS resets the duration of a tick to its default value of 1/4s.

Step 13

CODEPEGS cleans up the board before executing every spell and creates a new clean board if we call the size() function. Both actions would break the 2 and 1 tick pattern in Step 11. Try to remove the keep() from its code. Watch carefully and find what goes wrong.

In the beginning of code, we call the keep() function to tell CODEPEGS to execute the size() once and not again() and not to clean up the board.

Step 14

The following playboxes demonstrate how a keep() function works. The first spell makes the peg at (0,0) yellow and tells CODEPEGS to keep the color through the beginning of the next spell.

INJECT
keep();
size(2,2);
change(0,0,8);

We are going to make the (0,1) peg blue. The (0,0) peg will keep its yellow color, and the spell tells CODEPEGS to keep the colors further on.

INJECT
keep();
change(0,1,2);

It worked, but now we are not asking to keep the colors.

INJECT
change(1,1,8);

When we will cast the following spell, the former colors will disappear and the peg (1,0) will become blue.

INJECT
change(1,0,2);
Step 15

In CODEPEGS' sibling project FIREPEGS, we can create and investigate spatiotemporal patterns linking the pegs in space in time. This is easier than programming, although the patterns may be hard to understand.

The playbox below demonstrates one of an infinite number of patterns not possible in FIREPEGS. Apparently, the blue peg drugs along a light blue peg. Nothing really moves, the pegs are only changing their colors, but the sequence of the changes becomes obvious.

INJECT
keep();
size(2,2);
tick(1/2); //to make it slower.
change(0,0,2,0);
change(1,1,10,0)
change(1,0,0);
change(0,1,2,0);
change(0,0,10,0);
change(1,1,0);
change(1,0,2,0);
change(0,1,10,0);
change(0,0,0);
change(1,1,2,0);
change(1,0,10,0);
change(0,1,0);
again();

Building patterns peg by peg is not the best method. We can add any two numbers one by one, but we know better ways to do it.

Step 16

Morse code (which, in its moders form, was invented by Alfred Vail) allows to encode text messages using only one on-off device like an electrical switch. The most accessible sender is, probably, a flashlight.

Please use the link above to find the code table. One short flash and one long flash stand for A. one long and three short flashes mean B, etc. This method of telegraphy was developed in the middle of 19th century and it's still in use.

If one short flash (a dot) is 1 tick long, a long flash (a dash) must be 3 ticks long and the idle time between any two flashes (a gap) must be 1 tick long. The idle time between two letter is required to be 3 ticks long. Between words, we must wait for 7 ticks.

INJECT
size(1,1);
tick(1/4); // Make it faster or slower
change(0,0,2); // A dot
change(0,0,0); // A 1-tick gap
change(0,0,2,3); // A dash 
change(0,0,0,3);  // A three-tick gap
again();

We can turn this code to a function (how about morseA()), then add more one-letter functions and use them to send words. Later in CODEPEGS we will create a function to send long texts.

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk TIME ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scroll.
Good bye.

Browsers are brute

They know no manners.

If we made mistake and the browser responded with a curse, let's remember this chapter.

At some moment in the history of human-computer relationships, it was widely thought that everybody must and will master some Spellish. Needless to say, this did not happen. The most immediate obstacle, I believe, is that computers are very stupid, but they talk back to us like accomplished smartasses. Not because they are, but because smartasses made them respond this way. They would not do this if they were smartheads.

I opened playboxes in three major browsers and entered two letters: hi. Not sure if you noticed, below every textarea is an empty line for the browser's response. Here is what they said.

ChromeReferenceError: hi is not defined
MSIEReferenceError: 'hi' is undefined
FirefoxReferenceError: hi is not defined

Let me explain. Web browser understands couple hundred words plus unlimited number of names. Names are names everywhere. The ancient scribes invented phonetic writing to express foreign names because they did not have pictures for them. My second name, being one of the most common in my native country, makes absolutely no sense and is practically unpronounceable in English. This has never prevented anybody from building correct English sentences around it. Likewise, names in Spellish are not supposed to make any sense. Browsers only match them up and pass around.

Normally, if a browser meets an unknown word, it assumes it is a name and memorizes it as such. However, CODEPEGS casts a spell prohibiting this. I don't want accidental names resulting from my mistakes. If we want a new name, we declare it as a variable (var). So the browsers report to us every time they see something unknown and undeclared.

Let's try one more time: hi there. Here is what the browsers barked back.

ChromeSyntaxError: Unexpected identifier
MSIESyntaxError: Expected ';'
FirefoxSyntaxError: missing ; before statement

Dealing with such an attitude takes guts. Many parents tried, suffered, failed and told their kids that computers are unforgiving, arrogant and outright impossible to please. No wonder most people do not want to talk to computers anymore.

Let's be prepared and don't get put off. Browsers are not doing this to humiliate us. The browser developers could have done much better job, but they could not have coped with human languages anyway. So they didn't even try.

Computers are not smart enough to understand us. We are the smart one. Let's understand computers and help them do what we want. It pays.

Sidewalk SPACE
Getting around.

STOP
Welcome to Sidewalk SPACE.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

If you don't see the blue message below the gray board, extend your window or zoom it out. Click to inject a spell to the playbox editor. To cast the spell, click on the gray board.

Step 0

For this and the following steps, we are going to use the blink() function from the TIME sidewalk. It now has one more parameter dur (duration). The function divides dur by 2 and uses the result to set the time in the change function call, so the color appears for 1/2 of the time.

The spell below has two parts. The invisible part draws the challenge: a red peg. This part leaves behind a template for us to fill out and cast.
INJECT
your.org="w";
origin(0,0);
your.challenge00();

If we replace the question marks ? with the numbers of the row and the column of the challenge peg, the red color disappears. To get a new challenge, please inject and cast the code again.

If you are not in the mood to learn more about coordinate systems in CODEPEGS, please advance to Step 5. This subject is not required to learn coding. It extends the area from where we can derive the fun and useful coding projects.

Step 1

In the previous step, the board is organized according to the writing order: rows first, columns second, the numbering of both starts from 0 and the origin is in the top left corner.

CODEPEGS has more organizations. In the Cartesian order, the origin is in the bottom left corner. The number of the column (X) goes first, the number of the row (Y) goes second. To enable the Cartesian ordering, we assign a string 'c' to the name your.org. Then we have to call the function size() to make a new board

INJECT
your.org='c';
origin(0,0);
your.challenge00();

Not working? In this organization, the number of the column must be the first. Counting forward, we go through the rows in a column from the bottom up, then to the next column.

Step 2

In CODEPEGS, we can set up the origin (the (0,0) peg) of the grid. We don't have to take into account the organization of the board and the current origin. We tell the new origin as the number or the row and the number of the column in the default writing order. We start from the peg (0,0) in the top left corner, then count down and to the right.

INJECT
your.org='c';
origin(-4,-4);
your.challenge00();

If one or both dimensions of the board are even numbers, the board doesn't have a central peg.

Step 3

We can shift the origin out of the board, but keep counting from this imaginary point.

INJECT
your.org='c';
origin(2,5);
your.challenge00();
Step 4

To return to the default organization, please cast the following.

INJECT
your.org='w';
origin(0,0);
your.challenge00();
Step 5

How can we color all the corners of a 4×5 board?

INJECT
your.org='w';
origin(0,0);
size(4,5)
change(0,0,'b');
change(0,4,'r');
change(3,4,'g');
change(3,0,'y');
wait();

The code works only for the given size and origin. Trying to change those, we either miss some corners or hit some non-existing pegs.

Step 6

For every new board in the friendly writing (and only in the writing) organization, CODEPEGS supplies four names: start, stop, left and right. They tell the borders of the board taking into account the origin. We can color the corners as follows.

INJECT
your.org='w';
origin(0,0);
size(4,5)
change(start,left,'b');
change(start,right,'r');
change(stop,right,'g');
change(stop,left,'y');
wait();

Let's try to change the size and the origin.

Step 7

The CODEPEG border names start, stop, left and right are very helpful, but JavaScript does not provide anything like them. A coder can only obtain a number of elements (usually named length). Everything else must be calculated.

If you are not yet interested in using JavaScript outside of CODEPEGS or to learn math through programming, it's OK to skip the rest of this sidewalk. You may return and learn more later.

Step 8

Creating a new board, CODEPEGS supplies the values of two names: height and width. Those are the dimensions: the numbers of the pegs counted vertically and horizontally. Essentially, height and width are vertical and horizontal lengths.

Typical of modern programming languages, the numberings in JavaScript start from 0. A height×width board is numbered from 0 to height-1 and from 0 to width-1. Those minus ones are distracting, and they tend to pile up. Here is a JavaScripty way to color the corners.

INJECT
your.org='w';
origin(0,0);
size(5,5);
wait();
change(0,0,'b');
change(0,width-1,'r');
change(height-1,width-1,'g');
change(height-1,0,'y');

The origin is not taken into account, but the spell is good for any board size.

Step 9

To deal with the origin, let's use the uniform notation: vor, hor and vdim, hdim. The values of the names vor and hor are the vertical and the horizontal components of the origin (the numbers supplied through the origin() function). The names vdim, hdim are for the dimensions: vdim is height and hdim is width. CODEPEGS understands all those names.

INJECT
your.org='w';
your.vor=5;
your.hor=-3;
size(5,5);
wait();
change(vor,hor,'b');
change(vor,hor+hdim-1,'r');
change(vor+vdim-1,hor+hdim-1,'g');
change(vor+vdim-1,hor,'y');

This code works with any size board and any origin. Just try. It work with different organizations, but only on a square board. It can be easily converted to use rectangles.

Step 10

Space in CODEPEGS is always finite. Let's try to reach a non-existing peg and watch for a blue message below the board.

INJECT
your.org='w';
origin(0,0);
size(2,2);
wait();
change(0,0,'b');
change(2,2,'b');
change(1,1,'b');

This space has only 4 pegs: (0,0), (0,1), (1,0) and (1,1). There is no peg (2,2). Our script was terminated after line 2. This CODEPEGS feature is called guarding.

To reach non-existing pegs without breaking the script, we can call the function offguard().

INJECT
your.org='w';
origin(0,0);
size(2,2);
wait();
offguard();
change(0,0,'b');
change(2,2,'b');
change(1,1,'b');
Was the call change(2,2,'b') ignored?

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk SPACE ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scroll.
Good bye.

Desk top or bento box

A brief history of user interface.

With the advent of home PCs, I remember how parents were eager to teach their children to use computer mice. By now. those kids have barely entered a productive life, and they are teaching their toddlers touch interfaces like the whole their future depends on this.

What's wrong? Only the direction. Computers are not running away from us. They are struggling to approach us. The later we will start teaching our kids consumer-grade computing, the less they will have to forget and to regret. Don't teach them at all, they'll learn this stuff anyway because it's made to be easy for everybody. Advanced skills, meanwhile, do and will require advanced learning and thinking.

Through all the changes, one kind of user interface has been standing unshaken since it emerged in the late 50s as so-called console typewriter, and then evolved into alphanumeric video terminal. In modern systems, it's the most dreaded, cryptic and powerful black screen, through which wizards talk to computers in spells. If you want your kids to learn something durably marketable, teach them command line.

The recent developments allowed us to admit that, in spite of (or, maybe, because of) the abundance of mandatory education, we hate abstractions. Most people tolerate speaking and listening, but reading and writing is too taxing for them.

In 1972 - ages before YouTube - the team of Xerox scientists made a groundbreaking concession to the popular demand. They developed the first graphical user interface, also known as GUI, or WIMP (windows, icons, menus, pointer). The seed took ten years to germinate, but in the end everybody wanted the fruit, and got it. Unfortunately, GUI had become possible via a new tool: computer mouse.

We humans hate any tools, but computer mouse was (and still is) particularly noxious. To this day, serious users avoid GUI, preferring keyboard shortcuts. Mice tie us to chairs and tables, causing pain in our arms, hands and butts. Billions of users rejoiced over usable, portable, affordable touch screens when they finally became available. Tectonic move from chairs to sofas came to be known as mobile computing revolution. For the limbs, by the way, touch is hardly better than mouse, but which body part is more important, after all?

Like many words in computer business, graphical user interface was a misnomer. Instead of describing the users' experience, it was telling how the computer monitor was being operated. It could have been an overshoot too. As far as I can tell, the majority of users open one maximized window at a time.

Computer programmers are not much different from the rest of us. The same team that gave us WIMP, created the first program called browser. It was not for the web, and it was not like a web-browser. It probably was the mother of modern Integrated Development Environments. The big idea was to keep everything in one window divided into panes. Hence, being two-dimensional thinkers themselves, software developers cold-bloodedly confined their customers to the terrifying three-dimensional desktops.

A well-known example: it took years and years to introduce the tabs allowing web browser users to switch between multiple almost full-screen windows. The masses have been asking for this, but nobody listened.

Sidewalk LOOPS
Think you know what is boring?

Remember sorcerer's apprentice? He enchanted the broom and made it carry water by buckets. Here we are going to learn how such dangerous spells work and how to build them.


STOP
Welcome to Sidewalk LOOPS.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

Step 0

Thanks to YouTube user AUCKarl, I could link exactly what I wanted. Please click on the picture, then on the icon in the bottom right corner to make the picture big. Hit Esc on the keyboard to make the picture small again. Sorry for the quality, the video is almost as old as the water powered machines. All those useful devices had one thing in common: they were able to run in loops repeating the same routines on their own.

The creators of the first true computer had the same problem to solve. Suppose, the machine could add two numbers. How to make it add two other numbers, then again and again, without somebody pushing the levers? We still use the solution, which they found at around 1840.

For a starter, let's create a new board and draw a vertical red line of pegs. To achieve this, we keep the second (the column) number the same, changing only the first (the row) number by one. Please inject the spell. To cast it, click on the gray board.

INJECT
size(5, 5);
change(0, 2, 'red');
change(1, 2, 'red');
change(2, 2, 'red');
change(3, 2, 'red');
change(4, 2, 'red');
again();

To stop a self-repeating spell, we click on the black screen editor. CODEPEGS understands that we'd like to return to editing.

Step 1

Thanks to CODEPEGS, our peg painting machine repeats itself, but it paints the same pegs and never stops. Besides, it's not good for bigger boards. To paint 1,000,000 pegs, we need to write change() with the appropriate numbers 1,000,000 times.

To start building a better peg-painter, let's put the number of the row in computer memory. Computer memory is like a storage facility with billions identical units. If we want a memory space, we tell JavaScript a name. JavaScript keeps track of the names. If we assign a value to the name, JavaScript put this value into memory. When we mention a name, JavaScript replaces this name with the copy of its value. Later on, we can ask JavaScript to store another value under this name. This allows us to use storage boxes as mailboxes.

Computer values aren't apples. They are information. Our code can copy information and take it away leaving it in place.

Last but not least: while going through the lessons, let's stop and play with the code. For example, we can change a color or erase a line of code. If something went wrong and we don't know how to recover, we can always reload the browser tab.

Step 2

The code builds another column or pegs. This time, the color it teal. Instead of telling the number of the row straight to the change() function, we pass it through the name my.j. In line 1, we assign to the name my.j the value of 0. In line 2, the name my.j will be replaced with 0. In line 3, the value of my.j becomes 1. In line 4, the name my.j will be replaced with 1, and so on.

INJECT
size(5, 5);
my.j = 0;
change(2, my.j, 'teal');
my.j = 1;
change(2, my.j, 'teal');
my.j = 2;
change(2, my.j, 'teal');
my.j = 3;
change(2, my.j, 'teal');
my.j = 4;
change(2, my.j, 'teal');

What's the point? Well, bear with me for one more step. Solving problems, we often walk away from the goal or do something apparently senseless.

Why do we use the name my.j instead of something like columnNumber? Because my.j is shorter. Our names have no meaning to JavaScript. It memorizes them, looks them up and substitute if needed.

Step 3

Since this moment, I am going to use the operation of increment. Increment is counting (or, in terms of addition, adding one).

In computer coding, increments are so important that many computer languages offer the signs of operation ++. Every time JavaScript sees my.j++, it makes the value of my.j one bigger.

INJECT
size(5, 5);
my.j = 0;
change(my.j ,1, 'deeppink');
my.j++;     
change(my.j ,1, 'deeppink');
my.j++;     
change(my.j ,1, 'deeppink');
my.j++;
change(my.j ,1, 'deeppink');
my.j++;
change(my.j ,1, 'deeppink');
my.j++;

Executing my.j=0, JavaScript assigns 0 to my.j. Then, ++my.j does the same as my.j=1. And then, ++my.j does the same as my.j=2. Increment is different from assignment because we don't need to know what value to assign. We only instruct JavaScript to increase the existing value by one.

Step 4

The semicolons mark the ends of so-called statements. In JavaScript, statements are like sentences in human languages, except statements are usually simpler and the rules for building them are very precise and strict.

The most important rule is that a statement can be executed. JavaScript will not not understand just change;. If we add parentheses to show that we want to call the function, our change(); will be accepted, even though it will not do anything.

Unfortunately, JavaScript is made to please bad coders. JavaScript "knows" that people hate semicolons and it closes the statements if they deem complete. This and many other little niceties often make JavaScript puzzling for diligent code writers.

To make our change() work, we have to supply 3 values: the number of the row, the number of the column and the color.

A statement is not the same as a line of code. A statement can occupy several lines and there can be several statements in one line. This is why Javascript needs the semicolons.

Step 5

Here is the new edition of our peg painter.

INJECT
size(5, 5);
my.j = 0;
change(my.j ,4, 'green'); my.j++;
change(my.j ,4, 'green'); my.j++;
change(my.j ,4, 'green'); my.j++;
change(my.j ,4, 'green'); my.j++;
change(my.j ,4, 'green'); my.j++;

Now the five color-changing spells look exactly the same. They don't do the same because the value of my.j is changing, but we don't see it, so why should we care?

Step 6

Can we leave only one color changer and cast it repeatedly? Yes, but it will take two parts.

The first part: the following code must be injected and casted every time before we go through the second part of this step. You will see why.

INJECT
size(5,5);
my.j = 0;

The second part borrows a single line from the previous Step 5. Let's try to inject it and cast several times without changing anything and casting anything else.

INJECT
keep();
change(2, my.j, 'crimson'); my.j++;
In the end, the value of my.j is no longer equal to 0. To repeat the painting, we have to inject and cast the first part and reset my.j.

The function keep() asks CODEPEGS not to clean the board before executing the next spell.

Step 7

Let's try it without keep() to better understand what's going on.

LIke before, the following spell prepares the painting. Let's inject and cast it now and do it again while repeating this step.


INJECT
size(5, 5)
my.j = 0;

Let's now inject the following clicking on the board several times.

INJECT
change(my.j, 3, 'blue'); my.j++;

Without keep(), the blue peg appears to be traveling down like a fire in FIREPEGS. That's how the classical computer animation works. You clean up first, then drop the sprite next to its previous location.

Step 8

When we step across the border of the board, CODEPEGS sends a blue message telling us that the peg we are trying to reach does not exist. Unfortunately, CODEPEGS doesn't return us to the beginning of the board. Let's do it.

JavaScript can execute statement conditionally. We too. If the color is red, we stop. If it's Saturday or Sunday, we sleep more. If the color isn't red, we ignore the instruction to stop. If it's not Saturday or Sunday, we don't allow us to sleep more. Complicated, isn't it? OK, below is the starter for this step. Let's inject and cast it first.

INJECT
size(5, 5)
my.j = 0;

The following spell has to be casted repeatedly. Let's inject it and keep clicking on the board.

INJECT
change(my.j, 1, 'brown'); my.j++;
if (my.j > 4) my.j=0;

The painting function change(my.j,2,'brown') goes from peg to peg because the value of the name my.j changes from 0 up. When this value gets over 4, the spell if in line 1 brings it back to 0.

Step 9

In our code, we have two statements in one line. The first—the change()statement—uses the number assigned to my.j. The second statement increments it.

We can use a number and increment it at once. JavaScript just needs to know what to do first: to increment or to use. Since we put the ++ sign after the name, the increment must be performed after the use. Hence, my.j++ tells JavaScript to use the value of the name before making it one bigger.

The following code prepares two names. Let's cast it one time. Casting many times would not hurt, it's just useless.

INJECT
size(5, 5);
my.i = 0;
my.j = 0;

Let's inject, and then keep casting the following code until we reach the opposite corner. Every time, JavaScript will increment the values of both names.

INJECT
change(my.j++, my.i++, 'purple');
if (my.j > 4) my.j = 0;
if (my.i > 4) my.i = 0;
Step 10

Can we do away with the obnoxious business of casting a piece of code once and another piece many times? Why wouldn't we return to the change() statement and replay it with the new value of my.j? In the imaginary non-JavaScript code below, line 3 has a label LOOP:. The GOTO instruction in line 4 sends JavaScript back to line 3. When my.j becomes equal to 5, the return doesn't occur. The loop is over and JavaScript continues to line 5.

//This is not JavaScript!
size(5, 5);
my.j = 0;
LOOP: change(my.j++, 2, 'white');
if (my.j < 5) GOTO LOOP;

On a 5×5 board, the opposite side is not very far away, but what if we have a list of email addresses to send the same message to every one of them? Spam lists can be quite big today. Billions of entries, maybe. Who is going to click so many times?

The imaginary code, which can go back and replay a part of itself, can handle any list. All it takes is to enter 1000000000 (one billion) in place of 5.

Step 11

Long time ago, when computer programming was in its infancy, we could leap back or forth to continue execution from anywhere. In 1968, a prominent Mufti named Edsger Wybe Dijkstra published a fatwa, in which he claimed that such statements are evil, and "should be abolished". So abolished they were.

Computers were not affected, they still have the same jumping instructions as before, but modern languages like JavaScript don't let the coders GOTO. We only have dedicated loop statements like, for example, do/while. Let's apply one of them to our code.

INJECT
size(5,5);
my.j=0;
do 
  change(my.j++,2,'orange');
while (my.j<5);
$("Done")

The spells between do and while was replayed 5 times. We got an enchanted broom, which knows where to stop.

There are many ways to code a loop. The one we just created knows how to begin (my.j=0), how to proceed (j++), when to stop (my.j=5), and it's easy to understand. The j++ or increment operation is, probably, the hardest for those who allowed school math to stiffen their brains, and the knowledge of names is required.

Step 12

The do/while statement in lines 2 and 4 wraps around our "payload" code in line 3 and limits the broom's job description. Everything before do will be played only once. Everything between do and while will be played and replayed while my.j is smaller than 5. The question in "banana peels" after while makes or breaks the loop. After the first play and the every following replay, JavaScript asks itself if my.j is smaller than 5. If the answer is yes, the payload will be replayed. If no, the browser will go on to the next statement. The blue message in the function call $('Done') must appear under the board after the loop breaking condition was satisfied.

Here is the best part. We checked for 5 because we knew the height of the board. Our code doesn't have to rely on our knowledge. For every playbox, there is a name height. If we type in this name instead of 5, our code will be good for any board.

INJECT
size(10,12);
my.j = 0;
do 
  change(my.j++, 2, 'black');
while (my.j < height);
$("Done")

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk LOOPS ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scroll.
Good bye.

More loops

And more ways to loop.

Another kind of a loop control spell defines all the critical elements of a loop in one place.

INJECT
size(12,10);
for (var j=0;j<height;++j) 
  change(j,2,'green',0.1);

The keyword is for, and it can accommodate 3 or more other spells. The first is var j=0;. It creates the loop control variable and/or assigns the initial value. The second i<height; is the loop breaking condition. The third is j++, and it tells how the loop control variable must be advanced.

If the breaking condition (given by the second spell in the parentheses after for) is not worded right or if the loop control variable is not advancing properly, your loop may never start, or stop too early, or, worst of all, never stop. This is what the story of the enchanted broom was about.

Unless you water cool your processors, there will be no flood, but your browser window will become unresponsive. Should this happen, just wait. After a while, the browser will ask you if you want to stop the script (which is another name for code, software, a program, or a spell. Agree, but remember, clicking on the board will start the script again to the same result. If you want to investigate, click inside the editor and comment out the loop control statement putting // spell in front of it. You may also clean off the program text altogether (Ctrl+A, then erase). You can always close the tab or the whole browser.

To color a rectangle of pegs, we need a loop-in-loop. It may seem strange, but how else can you do this? Imagine, the pegs are on the wall in front of you. You are holding a marker. You start in the upper-left corner, you color this peg, then you move to the right. Since you are repeating the same movements, that's a loop.

Having finished a row of pegs, you return to the left and start coloring another row. The whole activity of coloring a row of pegs unfolds in the same way as before. Hence we have the second loop, which goes from row to row.

A simple loop inside another loop is demonstrated in the piece of code below. It comes preloaded into a new playbox.

INJECT
size(8,12);
for (var j=0;j<height;++j)  //1
  for (var i=0;i<width;++i) //2 
    change(j,i,'orange',0.1);     //3

I added the comments with the numbers. The loop control statement for in line 1 has lines 2 and 3 to replay. The statement for in line 2 replays only line 3. The first for goes through the numbers of the rows from 0 to height-1. It makes these numbers one by one and leaves them available to its payload. The payload is the second for, and it makes the numbers of the columns from 0 to width-1. Every time the change() statement starts, it finds new pair of vertical and horizontal numbers under the same names j and i, so it colors the next peg.

Sidewalk LINES
Along and across.

STOP
Welcome to Sidewalk LINES.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

If you don't see the blue message below the gray board, extend your window or zoom it out. Click to inject a spell to the playbox editor. To cast the spell, click on the gray board.

Step 0

The most complex kind of a loop spell in JavaScript is the for loop. It has all three elements: how to get ready to start, what to look for to stop and what to do to proceed.

for (my.j=0; my.j<height; my.j++)
  change(my.j, 2, 'maroon');

Below, the same spell comes in 3 lines (JavaScript doesn't mind extra witespaces). The magic is built around a single value named my.j. The name doesn't matter. It only points to the place in memory where we put the value of my.j, make it bigger one by one and compare it to to the stopping value until they match.

INJECT
size(5,5);
for ( // Includes S1, S2, S3 and P
  my.j=0; //S1
  my.j<height; //S2 
  my.j++) //S3
  change(my.j, 2, 'maroon'); //Payload P

Let's look closer. The first word of a for spell is for (as in line 1 above). Then, there are "banana peels", as if for were a function. Inside the "banana peels", there are 3 inner spells. JavaScript executes the first one (let's call it S1) before starting the loop. Then, still before starting the loop, JavaScript goes through the second spell S2. It's a question, to which the answer can be true or false. Then JavaScript executes the payload P for the first time. and returns to the question in S2. That's where it loops. Like this:

S1 S2 (P S3 S2) (P S3 S2) … (P S3 S2) 

The spells S1, S2 and S3 are the parts of the vehicle. They create a loop, but don't do anything else. The P part works for us, so it's a payload.

Step 1

A for spell doesn't wrap around payload code. It repeats everything after the closing banana peel and to the next semicolon.

If we need more code, we put it in curly brackets {}. JavaScropt treats the code lines in curly brackets as one. We can repeat them, skip them or name them (turning them into a function).

In the following example, the for spell repeats the 5 change() spells in lines 2…6. JavaScript executes them one after another, then again and again, while my.j is smaller than the value of the name width. The change() spells are telling JavaScript to execute the following change() spell immediately, so all 5 appear to change the colors at once. Only the last of them allows a 1-tick wait.

INJECT
size(5,5);
for (my.j=0; my.j<height; my.j++) {
  change(my.j, 0, 'darkgreen', 0);
  change(my.j, 1, 'forestgreen', 0);
  change(my.j, 2, 'limegreen', 0);
  change(my.j, 3, 'forestgreen', 0);
  change(my.j, 4, 'darkgreen');
}

Every pass of the loop creates a single horizontal line of 3 different colors. This is how the same color vertical lines emerge.

Step 2

Let's try it without the curly brackets.

INJECT
size(5,5);
for (my.j=0; my.j<height; my.j++)
  change(my.j, 0, 'darkgreen', 0);
  change(my.j, 1, 'forestgreen', 0);
  change(my.j, 2, 'limegreen', 0);
  change(my.j, 3, 'forestgreen', 0);
  change(my.j, 4, 'darkgreen');

Without the curly brackets, only the change(my.j,0,'darkgreen',0); in line 2 takes part in the loop. The other 4 in lines 4…6 do not. JavaScript executes line 3 only after the loop is over. The loop ends inside S2 (after JavaScript answers the question). The value of the name my.j remains 5. JavaScript attempts to execute line 3 as change(5,0,'darkgreen',0);. Since there is no such peg on the board, the guarding function in CODEPEG stops the spell with a message: I: (5,1) is not on the board.;

Step 3

The formula of the for spell

S1 S2 (P S3 S2) (P S3 S2) … (P S3 S2) 

allows us to make several more useful observations.

A for spell loops until the answer to the question in S2 is false. If the answer is false immediately, the loop never starts. Try to replace the less-than sign < with a greater-than sign > in the stopping condition of a for spell.

If the answer is always true, the spell loops unless something stops it - in case of Sorcerer's Apprentice, this was the sorcerer himself. The code below was modified to blink. The spell S3 is commented out, so the value of the name my.j is not changing and the loop cannot stop on its own. Let's inject it and try to cast.

INJECT
size(5,5);
for (my.j=0; my.j<height; /*my.j++*/) {
  change(my.j, 2, 'maroon');
  change(my.j, 2, 'gray');
}

The loop must have been stopped by CODEPEGS. Is there a I: Too many changes. message below the board? CODEPEGS processes spells with the computer speed and plays out the changes at our pace. It instantly knows if the reasonable number of the changes (say, 10000) was exceeded.

Step 4

Let's try again. This time, both the spell S3 and the payload spell P are empty. The big spell doesn't interact with CODEPEGS and can't stop itself.

INJECT
size(5,5);
for (my.j=0; my.j<height;);

Let's cast the code. At first, nothing is supposed to happen. The web page freezes. It does not respond to the keyboard and the mouse. However, the cooling fan may indicate that the computer is hard at work. Of 3 major browsers, only the Microsoft Edge shows a hourglass cursor. In less than one minute, Chrome and Firefox offer to stop the script. Edge does it earlier, but only if we click anywhere. The browsers handle such situations differently, yet in the end they let us reload the page and continue working.

Step 5

The last scenario: everything works, but the question in S2 is wrong, and it cannot stop the script. At the border of the board, the script must be stopped by the guard.

INJECT
size(5,5);
for (my.k=1; my.k>0; my.k++) {
  change(my.k, my.k, 'black');
  change(my.k, my.k, 'gray');
}

Without the guard, the script must exceed the limit of changes.

INJECT
size(5,5);
offguard();
for (my.k=1; my.k>0; my.k++) {
  change(my.k, 2, 'darkgreen');
  change(my.k, 2, 'gray');
}
Step 6

Like practically everything in computing, the lines in CODEPEGS are patterns, where either width or hight is equal to 1. Unlike the lines in geometry, CODEPEGS lines are not infinitely thin. Neither they are infinitely long, and we cannot place another peg between any two pegs.

A line in codepegs begins and ends. It's more like a vector. However, unlike math, computing happens in time. We draw lines not only from place to place, but from a moment to another moment.

For now, we are going to draw only two kinds of CODEPEGS lines: a straight and a diagonal one. A straight line aligns with one of the borders of the board. A diagonal line goes along the diagonal.

INJECT
size(10,12);
offguard();
for (my.j=0; my.j<width; my.j++){
  change(my.j, 2, 'firebrick', 0);
  change(2, my.j, 'indigo', 0);
  change(my.j, my.j, 'limegreen');
}
Step 7

For this and the following steps, we are going to use the blink() function from the sidewalk "Time". It now has one more parameter dur (duration). The function divides dur by 2 and uses the result to set the durations of the change spells, so the color blinks for 1/2 of the time. Here is how it looks.

function blink(row,col,clr,dur){
  change(row,col,clr,dur/2);
  change(row,col,0,dur/2);
}
The spell below has two parts. The invisible part draws the challenge—a red line—and leaves behind a template for us to fill out and cast. The blink() function is a part of the templates. To meet a challenge, we replace the question marks in the template with the name my.k and a number.

INJECT
your.challenge00();

Our green line must go along the red or blue challenge line and erase it in one casting.

Step 8

We've seen enough lines yet to make our owns from scratch. The following challenge01() leaves behind a piece of code to draw few parallel lines. Let's fill the board with lines typing the code by hand, so our fingers learn this magic. The commented out lines are there to remind us what to do.

INJECT
your.challenge01();
Step 9

On the previous step, the challenge lines were drawn too fast to perceive their directions. Our lines were likely drawn from start to stop (from top to bottom) or from left to right. The preferred directions depend on the cultural background, but, after all, that's how the rows and the columns are numbered.

Drawing in the opposite direction, we have to revert all the three elements of a for loop. Let's compare a forward loop and a backward loop coded below.

INJECT
size(6,6);
for (my.f=left; my.f <= right; my.f++)
  change(start, my.f, 'blue'); 
for (my.b=right; my.b >= left; my.b--)
  change(start+1, my.b, 'green');

The same lines in the regular JavaScript notation (assuming that the origin is (0,0)):

INJECT
size(6,6);
for (my.f=0; my.f < width; my.f++)
  change(0, my.f, 'blue'); 
for (my.b=width-1; my.b >= 0; my.b--)
  change(1, my.b, 'green');
Step 10

The forward and backward lines started from the bottom right corner:

INJECT
size(6,6);
for (my.f=stop; my.f >= start; my.f--)
  change(my.f, right, 'blue'); 
for (my.b=start; my.b <= stop; my.b++)
  change(my.b, right-1, 'green');

The same lines in the regular JavaScript notation assuming that the origin is (0,0):

INJECT
size(6,6);
for (my.f=height-1; my.f >= 0; my.f--)
  change(my.f, width-1, 'blue'); 
for (my.b=0; my.b <= height-1; my.b++)
  change(my.b, width-2, 'green');

Too much code? In fact, there are 2 more substantially different ways to draw those back and forward lines.

Step 11

The following patter is called boustrophedon. That's how Ancient Greek plowmen directed their oxen through the field. At certain time, the Ancient Greeks inscriptions were written in this manner. The plowmen are not famous for their intellectuality, so, hopefully, practicing boustrophedon may be an easy way to master for loops.

INJECT
size(6,6);
tick(0.1);
my.color='blue';//Change it
for (my.k=start;my.k<=stop;my.k++)
  change(start,my.k,my.color);
for (my.k=stop;my.k>=start;my.k--)
  change(start+1,my.k,my.color);
for (my.k=start;my.k<=stop;my.k++)
  change(start+2,my.k,my.color);
for (my.k=stop;my.k>=start;my.k--)
  change(start+3,my.k,my.color);
for (my.k=start;my.k<=stop;my.k++)
  change(start+4,my.k,my.color);
for (my.k=stop;my.k>=start;my.k--)
  change(start+5,my.k,my.color);

Let's code boustrophedon starting from every other corner.

Step 12

The boustrophedon code from Step 11 is good only for 6x6 board, and it's clumsy.

The following code draws the same pattern on any size board using only one change() spell. No fancy programming and only elementary math, but how does it work?

INJECT
//boustrophedon
size(6,8);
tick(0.1);
var i,j,d=1;
for(j=0;j<height;j++){
  for(i=(d<0)?width-1:0;
    2*i*d+(d-1)<width*(d+1);
    i+=d)
    change(j,i,2);
  d=-d;
}

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk DANCE ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scroll.
Good bye.

Substitute and rule

Every teacher a substitute.

Water is just water. Every bucket of water is the same. Inside computer everything is personalized in some way, and everything belongs to something. If we pick a peg. It's always some particular peg, linked to the board and made different from any other peg. Technically, we can create just a peg, but it will immediately disappear.

A terrifying secret of any rule is: the subjects must be made indistinguishable from each other. The rule may mention a student or a motorist. You substitute yourself for a student, leaving out your personality.

The following spell colors a row of pegs red. Remember, even if a spell is preloaded, you need to click inside and outside the textarea to cast it.

Like before, both vertical and horizontal numberings start from 0. The peg numbered (0,0) is in the top left corner. The vertical number (the number of the row) comes first.

On 5x5 board, the central peg is numbered (2,2), and every peg has the first number of 2 because it belongs to the same row. If we replace the first 2 with, say, 3, the spell will make row 3 red. It's boring, OK, but it works.

We can rewrite the spell to make changing the row easy

var rowNumber=3;
change(rowNumber,0,'red');
change(rowNumber,1,'red');
change(rowNumber,2,'red');
change(rowNumber,3,'red');
change(rowNumber,4,'red');

The spell var rowNumber=3; in the code line 1 is a substitution called name or variable. It's not the same as variable in math. The equal sign has a different meaning too. It solves the problems instead of making you solve them.

Here is what var rowNumber=3; means: Dear browser, find all the worlds rowNumber in my spell, replace every one of them with 3 and color those pegs.

Look, we took away the personalities of the pegs, and made the five line spell from the beginning of this chapter good for any row! There is one problem though. Row 2 is already red. Rows 0, 1, 3, 4 are left for you to play, and it's not much. Well, you may cast this to make a fresh gray board...

size(5,5);

or here is a better idea: we can substitute the color too, and make the rows easy to repaint.

var rowNumber=3;
var pegColor='blue';
change(rowNumber,0,pegColor);
change(rowNumber,1,pegColor);
change(rowNumber,2,pegColor);
change(rowNumber,3,pegColor);
change(rowNumber,4,pegColor);

What's left? Why capital letters in the names? It's a tradition in computer spelling, which came from the time of the first graphical user interface and the browser. Reportedly, the XEROX scientists forgot to put the _ (underscore) sign on the keyboard of their experimental computer. However, the programmers got used to it because they were not allowed to break the names with the spaces (even today computers are not smart enough for such things). So they invented this

camelCaseMethodToBreakTheNamesWithoutSpacesOrUnderscores

and use it to scare off the public since then.

You teacher? Oh, yes. How could I forget. Your teacher is a role, which can be played by practically anybody. Names in computer spelling means very much the same as roles. That's how this could look.

var Miredyth_Undervincle=new Teacher(); 
var Jakop_Stenchmyar=new Teacher();
var my_teacher;
//Then...
my_teacher=Miredyth_Undervincle;
//That's why in computer spelling they call 
//the the equal sign = the assignment operator.
//At any moment you can reassign...
my_teacher=Jakop_Stenchmyar;
//...or choose to have no teacher at all
my_teacher=undefined;

What? I did not tell you about //? It's a short spell, which for your browser means "I am not talking to you". The browser pretends it does not see anything from // and to the end of the line.

Sidewalk BRICKS AND STICKS
The elements of coding.

JavaScript is a typed language. Coding is largely a job of typing and erasing computer characters. The later include every written sign from every language, dead or alive, but not only them. Many characters are not found in human alphabets. Some characters may look in several different ways or not look like anything at all or be more like gestures. Not every computer character is on our keyboards, and not everything on our keyboards is a character.


STOP
Welcome to Sidewalk BRICKS AND STICKS.
Stop if you are scrolling up.
Click to hide the header and freeze the window scroll.
Click here or in the end to unfreeze.

Click on the stop sign right away. If you don't see the blue message below the gray board, please enlarge your window or zoom it out.

Step 0

Computers were created in United Kingdom and thrived in the US. Knowing some English is still enough to learn and use practically every computer language. For JavaScript, we need 26 small English letters, the space and (to make our code easier to read) the Tab and the Enter keys. Plus the numeral digits, the mathematical signs, the punctuation marks and most of the other symbols overtly written on the keyboard keys.

Please try to read the following spell. Click to inject it to the playbox editor. To cast the spell, click on the gray board. These are the bricks and sticks of computer code.

INJECT
n0='abcdefghijklm';
n1="nopqrstuvwxyz";
n2='~!@#$%^&*,.\'';
n3="+-={}[]()<>:;";
n4='= ?_|\\/`';

The n0, n1, n2, n3, n4, n5 and n6 are names. Names in computing can be longer than 1 character.

Step 1

JavaScript expects our writings to be correct code. We must compose correct words in correct order, use correct signs and correct punctuation. One important exception is any text enclosed in quotation marks "" or ''. Between quotation marks, we can put almost anything we want.

A text between any of the two kinds of quotation marks is called a character string. The spell in the previous step has 5 strings.

INJECT
"Don't expect JavaScript to be"; 
"consistent or even make sense."; 

//It doesn't look like JavaScript 
//was made for beginners. 

In this playbox, lines 0 and 1 have character strings. Lines 3 and 4 have comments. A comment mark // (a double slash) tells JavaScript to ignore everything until the beginning of the next line of code.

Unlike character strings, comments are not code. We can use comments to explain code, to hide (to "comment out") some code lines from Javascript's attention, to express ourselves behind JavaScript's back or for any other purpose.

Step 2

CODEPEGS may use its virtual pegboards as output devices for texts. At first, it may seem taxing, but it's very close to how computer works. Usually, computer comes in a disguise. A simple text editor imitates an ancient video terminal. A computer screen looks like a desktop. This is easy for users, but video terminals and desks are not computers.

Computer images are tiny color dots arranged into picture elements called pixels. To see them, we need a good magnifying glass or, better yet, a portable microscope. The pegs on the virtual pegboards are enlarged pixels. To see how pixels make letters, let's inject and cast this spell.

INJECT
size(13,13);
n0='';
n1=n6=n12='  BBBBBBB';
n2=n5=n7=n11='  BB    BB';
n3=n4=n8=n9=n10='  BB     BB';
colorize();

Lines 2-4 in the playbox above build an outline of the big letter B. The image is compressed. The big letter B is broken into 3 unique rows of little letters B.

Lines 5 calls the colorize() function to color the pegs according to the letters found in them. The functions in CODEPEGS can receive colors as initials: 'R' for red, 'B' for blue, etc.

Step 3

To color a peg, we may pick any single letter from 'NRBOGPCZYMAW'. A character N (neutral) stands for the color of the board. Z is for black... what else? OK, O is orange, P is purple, C is cyan, M is magenta and A is aqua.

INJECT
size(13,13);
n0='NRBOGPCZYMAW';
n1='WNRBOGPCZYMA';
n2='AWNRBOGPCZYM';
n3='MAWNRBOGPCZY';
n4='YMAWNRBOGPCZ';
n5='ZYMAWNRBOGPC';
n6='CZYMAWNRBOGP';
n7='PCZYMAWNRBOG';
n8='GPCZYMAWNRBO';
n9='OGPCZYMAWNRB';
n10='BOGPCZYMAWNR';
n11='RBOGPCZYMAWN';
colorize();

A virtual pegboard is like a computer screen. The variables for the rows of pegs are video memory. In the end, we see the content of this memory on the screen.

Please select another letter or shape, build it out of the color initials, compress it and colorize it. Remember to cast code.

Step 4

The first part of code adds 5 to several other numbers. The second part assigns 5 to the name n4 and adds it under this name to the same numbers.

INJECT
// 1st
n0 = 0 + 5;
n1 = 1 + 5;
n2 = 2 + 5;
n3 = 3 + 5;
// 2nd
n4 = 5;
n5 = 0 + n4;
n6 = 1 + n4;
n7 = 2 + n4;
n8 = 3 + n4;

The names like n0, n1, etc are special. After execution of our code, CODEPEGS displays their values on the board. We may change any numbers and cast the code again. We may change the names too. Nothing terribly bad can happen.

In this example, we have one numbering too many. A number of a name matches the number of the row on the board, but both those numbers are independent from the number of the line of code. Multiple numerations are distracting and very common in coding.

Step 5

One might think that we need names to enter a value once and use it many times. Names do play this role, but only because they represent computer memory. Computer memory is like a self-storage facility with billions identical units. The units (called bytes) are numbered. The numbers are used as addresses. One byte (or unit) can only hold a single English letter. For a character string, we may need thousand bytes or more.

We can instruct the computer to use a number found at a certain memory address. If we place another number at this location, this number will be used everywhere instead of the previous one. A memory address already works as a name.

Names are useful because we can remember them. With the help of the operating system, JavaScript maps names to memory locations. Names are the addresses of the things we named.

The value of undefined is a placeholder. A name in JavaScript can point to a number, a character string, a function, etc. When a name is created, it doesn't point to anything yet. it cannot point to 0 (zero) because 0 is a number. By the same reason, a new name cannot point to an empty string '' because it's a string. The value of undefined means: we don't know the value and we don't even know what kind of value is it.

Step 6

Line 0: Placing a character in a peg, CODEPEGS changes the color of the peg's border to the value found under the name of 'lettbc'. Setting the value of lettbc to lightblue, we make every letter-filled peg change the color of its border accordingly. This allows to spot the spaces: They are invisible, but the borders indicate there presence.

Line 1: The name pbw has the width of the borders. We can change it and see the borders changing.

Line 2: The borders are rounded. The name pbr tells the radius of the rounding. Let's try to change it too.

Line 3: To make those changes work, we restyle() the board.

INJECT
lettbc='lightblue'; //try 'white'
pbw=1; //in pixels
pbr=10; //in percents, please!
restyle();
n0='MEET MY CAT';
n1='           ';

As usual, we have to be wary of changing anything else. Or suffer.

IMPORTANT we'd better inject and cast the following to restore the values before advancing to the next step.

INJECT
pbw=1;pbr=20;restyle();lettbc='white';
n0='SO IT WAS';

Step 7

Despite many non-accidental similarities, computing is profoundly different from math or any other subject. There are graphemes, but no sounds. That's why whitespaces are computer characters, but not English letters. Computer numbers are not symbols. Computer arithmetic is much closer to finger reckoning then to numeracy learned at school.

Often, computing makes as rethink familiar knowledge and find unexpected meanings. For example, the equal sign = was meant to be a statement. It tells that something on the left is equal to something on the right.

In elementary education, the equal sign came to mean "go figure". Somewhat later, the children learn that the equal sign can be also used between a letter and a number, and they rightfully find this frustrating. In JavaScript, the "go figure" meaning is called evaluating, and the frustrating part is called assigning. Evaluation and assignment happen together, but they are not the same.

Step 8

The code line 0 evaluates a very simple expression 7 and assigns the value to the name n0. Since this moment, the name n0 points to the value of 7 and evaluates to it.

INJECT
n0 = 7;
n1 = 3 + 7;
n2 = n0 * n1 + 5; // n2 will change.
n3 = n2; // To save the value of n2.
n2 = n4; // n4 is undefined.
n5 = 'undefined';
n3 = n3 + 25; // See the next step.

Line 1 evaluates the expression 3+7, gets the value of 10 and assigns it to n1. The name n1 now points and evaluates to 10. The name n0 still points to 7. Does it mean that line 1 adds 3 to 7? Certainly, but evaluation means something much bigger.

Line 2 evaluates n0*n1+5 and assigns the result to n2.

Line 3 evaluates n2 and assigns its value to n3.

Line 4 evaluates the name n4 and finds the value of it to be equal to undefined. In school math, the things like n4=n2 or, more commonly, y=x are equations. Not so in computer programming. The value of n2 becomes undefined too.

Line 5: 'undefined' is fully defined character string. It's not undefined.

Step 9
In the previous playbox, code line 5 says: n3=n3+25;. How can n3 be 25 bigger than itself?

In elementary school, the equal sign is not about being equal. They don't even read it as "is equal to". For them it's "equals". Elementary school teacher can throw the statements like
7 + 6 =
(seven plus six equals nothing) or
7 + 6 = ?
(7 plus 6 equals a question mark).

In JavaScript, the equal sign means "evaluate and assign", and it works from right to left. Evaluating a name, JavaScript replaces the name with the value to which the name is currently pointing. Then the resulting value can be assigned back to the same name. Why not?

JavaScript must refuse to execute the expressions like

7 = n0;
'a string' = n1;

In coding, we can only assign to names.

Please play with assignments to understand them. To see the results on the board, please remember to assign your values to the names from n0 to n12.

Step 10

JavaScript refuses to assign nothing. Please try to cast this:

n0=;

JavaScript doesn't assign to nothing either.

=2;

However, JavaScript happily evaluates without assigning. How can we know?

INJECT
n3=function(){
  for (var n=0;n<1000000000;n++) 
    Math.random();
}();
change(6,6,4);

The self-starting function in lines 0…3 generates an awful lot of sequential and random numbers. They all are discarded. Nothing is returned. Yet, the execution of this function takes considerable time. It's over when the green color appears and if the editor is no longer "frozen".

The empty "banana peels" in line 2 tell JavaScript to execute the new function immediately. The function sort of calls itself. Let's remember this trick.

We can make 1000000000 bigger or smaller. If the browser offers to stop the script, we may ignore it and wait more. A sure way to exit is to close the browser tab.

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk BRICKS AND STICKS ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scroll.
Good bye.

Coding is a writing job

Don't fall in the mouse trap.

The spell in the following playbox makes a simple spatiotemporal pattern. Please cast it and remember what you see.

In the text editor, please click anywhere in the first long line. Put down the mouse, please.

Hit the Home key to move the cursor to the beginning of the line. Hold the Shift key and press the down the arrow key to select everything up to the beginning of the second line. Keep holding the Shift key and press the Delete key. Release all the keys. Press the down arrow key again. Now hold the Ctrl key and press the V key. Cast the spell and watch a different pattern.

Please click on any long line and go to the beginning. Hold the Ctrl key and press the right arrow key 6 times. Now hold both Ctrl and Shift keys and press the right arrow one more time. The word green is now selected. Release all the keys and simply type the word red. Do not change anything else. The word red must be enclosed in quotation marks just like the word green was. If you got it wrong, please use Ctrl+z to go back through the changes. Otherwise, please cast the spell.

Physically, keyboard is much less stressful. Intellectually, it's harder because it requires to think and devise the strategies. This must be the reason we fall for mice, but does textual programming belong to the age of YouTube at all? Why programming isn't visual yet?

In 1986, the company called National Instruments released one of the best known visual programming system LabVIEW. At the same time, it started working on its textual counterpart called LabWindows/CVI. The target audience of LabVIEW was (and still is) defined as knowledgeable and experienced workers who are too old, too busy, unprepared or unwilling to learn computer programming (but not important enough to justify hiring programmers to serve their needs). In short, it was paraprogramming. Please excuse me if I put it too bluntly.

At approximately the same time, the idea of computer literacy had begun circulating. The next generation of workforce must have been able to use computer languages like their own.

Computer literacy failed to happen. Instead, in 1998, LabVIEW became a part of Lego RCX, which later evolved into MINDSTORMS! Reportedly, LabVIEW was chosen because it was easy. After all, it was created to avoid learning programming.

Last time I checked, MINDSTORMS had nothing to do with real robotics. The robot designers were using textual languages and tools. As a parent, I considered several local MINDSTORMS courses. None of them was teaching even LabVIEW. The most professional local coach - a middle school math teacher by her main occupation - had happily admitted that she does know how to program at all.

A better example of a visual language can be MIT Scratch. Or, rather, it is an exemplary visual language. Scratch have been known since 2002. Neither it, nor the the textual language in which Scratch is written, are being noticeably employed in commercial programming.

The language of Scratch is Smalltalk. Sweet like high fructose corn syrup, Smalltalk greatly influenced many modern languages (even JavaScript) only to fall out of view. With Scratch, the children received a gift, which grownups did not want.

Visual programming (VP) is quite old, well known and widely used. If it has not grown into a mainstream software development technology yet, that's not for the lack of trying.

Textual programmers, especially the good ones, are not much loved and cherished. If their employers could find a technology suitable for less demanding workers, they would hold it dear. Yet, textual programming thrives with no end to it in view.

Is watching and listening poised to ditch reading and writing? Will we have video laws, video science or video management? Most importantly, would such hypothetical innovations empower or disable us?

Sidewalk OPERATIONS AND FUNCTIONS
Some recipes.

This sidewalk teaches the common patterns of operations using only few of them: those with the + and = symbols in their operators. The art of calling functions is presented through the functions handling character strings.


STOP
Welcome to Sidewalk OPS AND FUNCS.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

Click on the stop sign right away. If you don't see the blue message below the gray board, extend your window or zoom it out. Click to inject a spell to the playbox editor. To cast the spell, click on the gray board.

Step 0

Despite their names, operations and functions don't work. They only provide reusable recipes for doing something. JavaScript allows us to create our own functions, but not operators. The concepts of operators and functions in programming were derived from math, but their usage is quite different.

Functions are easy. A function is a named piece of code, like size(), change() or blink(). Calling a function by the name, we can put a list of the things to work on in the parentheses (commonly known as "banana peels").

Operators are the symbols of operations like +, ++, =, == or +=. Most of them have emerged centuries ago. They form the patchwork of mathematical notation: the sacred knowledge, which is not easy to learn and use. Just think about the order of operations.

Functions can fully replace operators. In the following example, we create and use the function add(). The functional notation looks less familiar and it may be less accessible, but we don't need to remember the order of operations because banana peels are everywhere.

INJECT
n0=5;
n1=n0+25;
function add(addend1,addend2){
  return addend1+addend2;
};
n2 = add(add(add(n0,25),n1),-15);
Step 1

Both operations and functions serve to change the values, and a value in programming is any discernible piece of information. Numbers and strings are values, functions are values and even code is. To execute our spells, CODEPEGS calls the function eval() (to evaluate means to find the value).

Since the 18th century, mathematicians learned to express their ideas through functions. Yet, operators now flourish in programming languages constituting a big part of what we human have to learn.

The authoritative description of JavaScript operators is an interesting and highly recommended readind.

And here is the page covering strings and string method.

Step 2

I am going to explain why I use white spaces so erratically.I hate to see dropped spaces in human writing,and,as a young information engineer, I was meticulously spacing my code. Recently, as I returned to coding after many years, I realized that the spaces waste my time not helping me read, and started dropping them wherever they were not required. Browsers, by the way, have programs making even my code perfectly spaced. Only in the beginning of CODEPEGS, I use spaces to make my code look "normal".

They say, JavaScript does not care about spaces. This is not true. The playbox in the previous step has the following:

  return addend1+addend2;

Try to go back, remove the space after return in line 3 and cast. This space is required. The spaces around the + are not.

Step 3

JavaScript puts the recipes referred by operators and functions to work through the activity called evaluation. Evaluation is what JavaScript does with our code. The whole content of the black screen editor gets evaluated when we cast it. JavaScript replaces every name with the value, to which the name is pointing. It calls every function, it takes apart expressions and performs computations. That's how it executes every statement.

While doing this, JavaScript collects returns and (possibly) assigns them to names. Please keep this "big picture" in mind.

Explicitly, returns happen only in functions and only if we write: return this. JavaScript catches this, evaluates it and assigns according to our instruction.

The following code defines a new function. The empty "banana peels" in the end tell JavaScript to call the function immediately and to assign the value it returns to the name n2. The definition of the function has nothing but return.

INJECT
n0=function(){return 'ANY'+'NEWS?'}();
Step 4

Operations return values on their own (this is what operations are for). Learning and using them, it is important to understand and know what an operation takes, what it changes and what it gives (or returns). Here are some examples.

In code line 0, the operation of addition (it's operator is the + sign) takes two numbers, adds them creating a new one and returns the new number, so JavaScript assigns it to n0.

In code line 1, Javascript just goes in the direction of assignment from right to left. First, it figures out n0+1. Next, Javascript assigns the resulting value of 6 back to n0. Attention, please: asignment is an operation, and it returns the value that was assigned. In this case, JavaScript ends up assigning 6 to n2. I just wanted to save the value of n0 before making it another one bigger.

INJECT
n0 = 2 + 3;
n1 = n0 = n0 + 1;
n2 = ++n0;

Line 2 demonstrates the operation of increment ++. Increment makes a number one bigger. Increment is counting, and counting is the foundation of all integer arithmetic. Every integer operation can be performed by just counting ones. The integer numbers include the natural numbers, their negative counterparts and zero. Another word for integer is whole.

Code in line 1 works exactly like code in line 2, but the one in line 1 is clumsier. The increment operation is not necessary. It worth learning because it's compact and cute.

Step 5

Code lines 0, 1, 2 in the following playbox came from the previous step. We are going to learn more about increment and decrement operations.

The increment operator ++ works both ways: it increments the value pointed by a name and returns this value. Which value? The increment before a name (like in line 2) makes the value one bigger before assigning it. The increment after a name (like in line 3) returns the value and only then makes it bigger. In this case, the returned value and the resulting value are not the same.

INJECT
n0 = 2 + 3;
n1 = n0 = n0 + 1;
n2 = ++n0;
n3 = n0++;

Before line 3, the value of n0 is 7. Line 3 assigns this value to n3 and increments n0. The final value of n0 displayed on the board is 8.

Everywhere in this and in the following step, we can use the minus sign in place of the plus sign to subtract or decrement the values.

Step 6

Increment can be a part of an assignment. This allows as to increment a value not only by one, but by any other value. In code line 2 below, the value assigned to the name n1 is incremented by the value assigned to n0. JavaScript evaluates n0, makes the value pointed by n1 n0 bigger, returns the incremented value to the left and eventually assigns it to n2. Please inject and cast to confirm.

What is NaN? Please excuse me. NaN means Not a Number. Subliminally, I assumed that the value of n1 in line 2 was 0 and tried to add to it the value of n0. The value of n1 was, of course, undefined. Did I tell you that undefined is not a number?

Before incrementing n1, I had to assign to it an initial value. The value of 0 would be just fine. Please uncomment line 1 and cast the spell again. Uncommenting a line makes it visible to JavaScript. To uncomment, we simply remove // (both of them) from the beginning of the line.

INJECT
n0 = 2;
//n1 = 0;
n2 = n1 += n0;
//n1 += n0;
//n1 += n0;
//n1 += n0;

Please uncomment line 3 and cast. Then line 4. Then line 5. Every time, the value of n1 becomes the value of n0 bigger. Meanwhile, the value of n2 stays the same.

Step 7

I have covered the operators of +, =, ++, +=… what's left? Let's talk ==. Surprisingly, == isn't an assignment. It's an operator comparing two values. The meaning of == is close to the original meaning of the equal sign, but it's different. The equal sign is a statement. It tells that the value on the left is equal or (in case of equations) must be equal to the value on the right. In computing, the == is a question. There are two possible answers: false and true.

Line 0. From right to left, 1is not 0, so == returns false.

Lines 1, 2. We make n1 point to 0 and compare it to n0 (which was false last time we checked. Surprisingly, == returns true. For most practical purposes, 0 in JavaScript serves as false and 1 serves as true.

Lines 3, 4, 5, 6. Indeed they do.

INJECT
n0 = 0 == 1;
n1 = 0;
n2 = n0 == n1;
n3 = false == 0;
n4 = 1 == true;
n5 = false + 1 == true;
n6 = true - 1 == false;

Step 8

If we use false and true as if they were numbers, JavaScript turns them into numbers. The proof is in code lines 3 and 3.

INJECT
n0 = false + true;
n1 = false * true;
n2 = true + 10;
n3 = true + true;

By the way, the * is the operator of multiplication. The creators of computer languages had to use it because nothing else was available on the keyboards. The low case x is only good for humans. Computers are not so smart.

The "true or false" business in JavaScript was made so complicated, it's practically a new area of computer science. Let's stay away from it for now. I only wanted to introduce the operator ==.

Step 9

You've seen this code before. It demonstrates the characters used in computer coding. The uppercase letters were missing because JavaScript is lowercase only.

INJECT
n0='abcdefghijklm';
n1="nopqrstuvwxyz";
n2='~!@#$%^&*,.\'';
n3="+-={}[]()<>:;";
n4='= ?_|\\/`';
n5=n0.toUpperCase();
n6=n1.toUpperCase(); 

The uppercase characters in JavaScript do exist, and they are available to the coders. Instead of entering them, we can convert two lowercase strings to uppercase.

In lines 5 and 6, toUpperCase() is a string function used as a method. All the strings have it. The () appendage in the end of string.toUppercase() is useless, and, frankly, annoying, but JavaScript requires it.

Step 10

As the name suggests, we may use this method to convert the low case characters to their upper case counterparts. There is a method to convert every character to the lower case too.

INJECT
lettbc='chartreuse';
n0 = 'New York, NY';
n1 = n0.toLowerCase();
n2 = n1.toUpperCase();
n3 = n0.length;
n0='abcdefghijklm';

Why methods? It's safe to say that there are two different styles of using names, and JavaScript incorporated both. The archaic change(row, column,color) style appeared approximately 60 years ago: We call the function and ask it to change the color of a given peg. The string.toUppercase() style is 50 years old, but it's still considered modern and trendy: We call the string and ask it to change itself using it's method.

One obvious advantage of methods is that the names are better organized. Every global name like change(row, column,color) or class='cp'>width must be unique. The names of the methods are localized. Only the names of the string methods must be different from each other. In some other kind of objects, there can be another method called toUpperCase() like in some other town there can be another Main St.

Not only names of the functions can be local. In JavaScript, every string has a name length. The value of length is equal to the number of characters in the string (see code line 3).

Step 11

In code line 0, Javascript executes the operator + taking two numbers, summing them and assigning the new number to n0;

In line 1, executing the same operator +, JavaScript takes two strings, concatenates them and assigns the new string to n1. Concatenating means chaining.

In line 2, JavaScript + takes a number and a string, converts the number into a string, concatenates them and returns a string (never a number!). JavaScript assigns the new string to n2. Personally, I think that using + and += for strings is a terrible idea, but it's certainly not the worst of JavaScript.

JavaScript has a string method concat()to do this (see line 4 and row 3), but a method is not as handy as an operator. Compare lines 3 and 4.

INJECT
n0 = 2 + 3;
n1 = '2'+ '3';
n2 = 2 + '3';
n3 = n1.concat(' FROG').concat(' LEGS');
n4 = n1 + ' FROG' + ' LEGS';

In line 3, JavaScript evaluates the sequence of methods from left to right building up the value of n1.

Please remember, playboxes are for playing with code. Talking to JavaScript is the best way to learn it. That's how we learn our language. JavaScript is always available and ready to suffer. It may seem grumpy, but it's not. It's just a very useful machine.

Step 12

JavaScript offers several more string methods (they may be called strings functions). The following code demonstrates some of them.

INJECT
n0='I play yo-yo';
n0=n0.toUpperCase();
n1='I play yo-yo'.search('yo');
n2=n0.search('yo');//oops
n3=n0.search('YO');
n4='YO';
n5=n0.search(n4);
Line 0 assigns the string 'I play yo-yo' to the name n0. This name is to be displayed in the board's row 0.

Line 1 converts n0 to the upper case. The n0.toUppercase() method doesn't change the value behind the name n0. It gets changed because we assign the new (the uppercased) value to n0.

In Line 2, the string method search() finds the string yo inside the string 'I play yo-yo'. It's supposed to return the number of the first matching character, and the characters in a string are always numbered starting from 0.

In line 3, the same method fails to find the same string because the string value assigned to the name n0 has been converted to the upper case. In line 4, the string value YO is to be be found.

In line 5, the string to search for is assigned to the name n4. Next, we use this name instead of a literal string, and it works.

Step 13

Lines 1 and 2 introduce two more string methods. The method indexOf() returns the index of the string found inside the "banana peels". The single-character string is 'F'. Its index, which is the character place counted from 0, is 4. The method lastIndexOf() finds and returns the index of the last occurrence of the string OF().

In line 3, the method substr(from,length) copies and returns the lengthcharacters of a string starting at the from position forward. The string remains unchanged.

In line 4, the method substring(from,to) copies returns a piece of the string up to the to position, but not including the character at it. The new string is 'F F'. The original string stays the same.

INJECT
n0='A LIFE OF FUN';
n1=n0.indexOf('F');
n2=n0.lastIndexOf('OF');
n3=n0.substr(8,3);
n4=n0.substring(8,11);
n5=n0.search(n0.substr(8,3));

In line 5, the method substr() is nested inside the method search(). We find substr(8,3) first. Immediately, we search for the same sub string and find it at the position, from which it was copied.

Step 14

Do we have to stuff the letters into pegs? Can we just write freely?


INJECT
your.tovl.style.color='red';
your.tovl.style.fontSize='680%';
your.tovl.textContent="WE CAN!";

This said, breaking strings into addressable, individually configurable characters fills the void at the core of the language or web pages HTML. Web technology doesn't support the idea of an individual character. Playing with them is possible, but immensely wasteful. Meanwhile, operations with strings are indispensable for practical programming and have always been an important source of projects for beginners.

INJECT
n0='YOU'
n1='SEE YOU SOON!';
n2=n1.search(n0);
for(i=0;i<n0.length;i++)
  change(1,n2+i,8);

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk OPS AND FUNCS ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scroll.
Good bye.

PART 3: LESSON IDEAS

Few out of many.

This part is 3 years old, and it may not reflect the current state of technology.

Loops and patterns

Both are about repeating something.

Once we learned loops, we opened the door to entirely new kind of challenges. We can turn computers into pattern making machines. Let's start from building a simple periodic tessellations. The spell is preloaded.

INJECT
size(8,8);
tick(0.2);
for (var j=0; j<height; j+=2)
  for (var i=0; i<width; i+=2) 
    change(j,i,'green');

Mysterious j+=2 makes j two bigger. We skip every odd number along the horizontal and the vertical loops.

Adding 2 every time is multiplication. Instead of j=1 and j+=2, we can increment the loop variables and multiply them by 2 to figure out the index numbers.

INJECT
size(8,8);
tick(0.2);
for (var j=0; j<height; j++)
  for (var i=0; i<width; i++) 
    change(2*j,2*i,'green');

This idea may not be useful here and now, but let's save it for later.

Let's repeat this double loop 4 times to create a four-color pattern. First loop colors every second peg green. It starts from j=0 and i=0 ((0,0) for shortness). The red loop starts at (0,1), the yellow one at (1,0) and the blue one at (1,1).

INJECT
size(8,8);
tick(0.2);
for (var j=0; j<height; j+=2)
  for (var i=0; i<width; i+=2) 
    change(j,i,'green');
for (var j=1; j<height; j+=2)
  for (var i=0; i<width; i+=2) 
    change(j,i,'red');
for (var j=0; j<height; j+=2)
  for (var i=1; i<width; i+=2) 
    change(j,i,'yellow');
for (var j=1; j<height; j+=2)
  for (var i=1; i<width; i+=2) 
    change(j,i,'blue');

Here is the same code preloaded.

We can use this technique to make periodic tessellations of any complexity. Here is another example. Try to change dimensions in the first line.

INJECT
size(8,8);
tick(0.2);
function paint(J,I,c){
  for (var j=J; j<height; j+=3)
    for (var i=I; i<width; i+=3) 
      change(j,i,c);
};
paint(2,0,'green');
paint(0,0,'green');
paint(0,1,'red');
paint(0,2,'red');
paint(1,1,'blue');
paint(2,1,'blue');
paint(1,2,'orange');
paint(1,0,'orange');
paint(2,2,'white');

Even though the pattern was not awfully complex, I could not resist defining a function.

This tessellation was produced like the one before. We ran a nested double loop 8 times to paint 8 tessellations. I could have spent another day demonstrating how this can be done from inside a nested double loop tile by tile, or use a nested triple loop and a table. Remark that 2-pegs same-color elements are not tiles. The real tiles are 9 pegs big. There are many ways to carve them out. If you are interested, look for nonomino. You can even find a four-color spinner here (which is, of course, an octomino, but we may count a white peg as a hole).

Tessellations may be not the most impressive patterns available in CODEPEGS, but they are a good starting point for the beginners.

Finally, let's do some photoshoping. The triple loop produces a crude color gradient. Don't try this at home.

INJECT
size(10,10);
var j,i,k,c,r,g;
for (k=0;k<height/2;++k)
  for (j=k;j<height-k;++j)
    for (i=k;i<width-k;++i) {
      r=(k==0)?0:(k*64-1);
      g=127+k*32;
      c='rgb('+r+','+g+',0)';
//10 changes per second
      change(j,i,c,0.1);
    }

Let's use the following code to cut out the shapes.

INJECT
load([
  'wxxwwwwxxw',
  'xxxxwwxxxx',
  'xxxxwwxxxx',
  'wxxwxxwxxw',
  'wwwxxxxwww',
  'wwwxxxxwww',
  'wxxwxxwxxw',
  'xxxxwwxxxx',
  'xxxxwwxxxx',
  'wxxwwwwxxw'
]);

The load() function loads a color layout coded in letters. In this example, w is white and x instructs CODEPEGS to keep the existing color.

Loop controls and control loops

Toilets and mousetraps.

Loop controls and control loops sound like practically the same. Ever since I learned control theory and programming, I have been wondering if they actually have anything in common. Correct me if I am wrong - quite likely I am - but I have never seen their commonality investigated.

Due to the lack of time, knowledge and readers, my investigation will be short. As usual, I only wanted to point your attention to some learning opportunities.

A simple control loop, universally recognized as such, is found in every toilet bowl. You pull up the flapper and the water gushes out. The float falls down opening the fill valve while the flapper returns to its closed position. As the water fills the tank, the float goes up. When the water level gets high enough, the float closes the fill valve.

Let's now consider a mousetrap, particularly a cage-based one. Until I came to the US, my experience with mouse catching was rather limited. More precisely, I've never done this. When I was a child, we lived in an old apartment building, where my grandmother was waging perpetual war on mice. Every night she set a cage trap. Next morning - not every day, but often - another mice would be found inside, perfectly alive. The old lady then would boil a tea kettle and disappear behind the toilet door carrying the kettle in one hand and the trap in the other. Once I asked her what she was doing there. Reluctantly, she explained that she poured the water on the mouse, opened the trapdoor and flushed the toilet. I was probably twelve years old at that time, but I was very impressed with her ruthlessness. I don't think she was looking at the mouse while boiling it alive, though. The side effect of this procedure was, probably, cleaning and disinfecting of the trap.

In the US we rented two relatively old homes, then bought the third, which was new and expensively built. All three were infested. The one we bought was uninhabited for a while, so the mice were not there. I immediately took measures to prevent them from coming back. With the first two, however, I had to learn how people catch mice in this country.

I'm afraid you thought my grandmother's method was barbaric. How about glue traps then? The first mouse I caught I threw in the trash alive. I am still sorry about it. I felt so bad that I carefully pulled my next catch off the glue and released outside. I was afraid I damaged him, but no, he ran away quite lively. I did not know that a regular mouse can jump so high.

There was no moral to that story. I only wanted to draw connection between flush toilets and mouse traps. But now I am going to take a hard look at it.

The most obvious difference between two devices is that mousetraps usually have only one gate. If you think this is important, then OK, I found two-gate varieties. One gate may serve for flushing mice out, alive or dead, the other one for letting them in. Either way, upon entering the cage, the mouse pulls the bait, activating feedback loop. Eventually the latch releases the gate, and it closes. The device then stands full until the next flush.

The real difference is in the eye of the beholder. Or call it the designer's intention. Flush toilet has automatic regulator, which is supposed to keep the water in the tank at a certain level. We don't think a mousetrap has an automatic regulator, which is supposed to keep the population of the mice inside the cage at a certain level, but why not?

A flush toilet's adds more water as it leaks through the flap or evaporates. A mousetrap would not compensate for partial loss of mouse but, after all, live mice are indivisible like we humans.

There is a different difference though. A properly configured feedback can make the system oscillate. Oscillation is a spatiotemporal pattern. You can see plenty of oscillations in FIREPEGS. They happen due to delayed feedbacks.

We can make flush toilet oscillate by tying the float to the flapper. When the tank is full—but slightly before the fill valve closes—the float must pull the flapper up and drain the tank. I don't think it's going to work on your toilet. The float may not be big enough, and the system may need some hysteresis to oscillate. But, since the running out water keeps the flapper open it may be feasible. I've seen antique public toilets flushing themselves automatically every once in a while.

Mousetrap would not oscillate, but not because of any fault in its design. What's missing is a steady stream of energy, which in a toilet is being provided with running water. The tank stores potential energy ready to carry the mass of the water out. Mice, in comparison, are weak and unreliable. The mousetrap operates on it's owner's energy, not to mention the origin of baits.

We can think about design, which would kick the mouse out because it pulled the bait or tried to reach it. The mouse would then return, which may count as oscillation. Unfortunately, such returns are not guaranteed. We might consider fixing the bait to the wall and putting the mouse into a running wheel. Rotation is closely related to oscillation. Yet, any such solution will not be more predictable than making the bait inedible, leaving the gate open, and watching the mice walking in and out.

Yes, I am talking about stochastic process. You don't need a mouse farm for this. Just, maybe, a school toilet to watch. It's another kind of spatiotemporal pattern, and I am not sure yet what can be the age for understanding such things. With my 6-year old, I reviewed several kinds of magnitudes—distance, volume, angle, force—time was included, but, playing with FIREPEGS, I realized she was not quite getting it. Checking on her siblings' temporal thinking, I found that it was very poor. I am sure I was much better at their ages, but I walked alone twice a day for 30 minutes from school and back since the first grade. Guess, in couple years from now TLG will be able to plot simple processes.

The kind of program loops I demonstrated thus far were very similar to flush toilets. In a program we change the value of the loop variable, zeroing (flushing) or incrementing it. The gates are in computer's hardware. Often, zeroing and incrementing are even handled differently. You may think that the purpose of the loop is to keep the loop variable value at a certain level. But wait, the level of the water in toilet tank is not what we want! We really want to accumulate a given volume, or amount of water, and in the loop variable we want to accumulate a given number of ones.

Computer programs' propensity for oscillating is well known to everyone who has tried to develop them. To prove that a program can serve as a model of a flush toilet, I am going to turn a simple incremental loop to an oscillator flushing the loop variable before the breaking condition kicks in. Conceptually, this is no different from tying a float to the flapper.

The following code runs once, coloring all the pegs in the column from the bottom up. Then it will stand waiting for you to flush it by clicking on the board, just like a real toilet does. Let me remind you that you can press (even press and hold) the Enter key to advance through the alerts. Don't agree to prevent them from appearing. If you do, the page will stop working. In such a case, close it entirely and reopen.

INJECT
var n,k=3;
size();
for (n=1;n<=height;++n){
  change(0,n,'blue'); 
//  if (n==height) flush(); //The tie
}
function flush(){
  if (--k==0) return; //The stopper
  all(0,1);
  n=0;
};

Two lines are tail-commented, and one of them is also commented out entirely. If you uncomment it, the "float" (the loop variable) will be linked to the "flapper" (the flush() function) and the system will oscillate. The second line is always on. It stops oscillation after a given number of cycles. The number is in the first line of code. It's equal to 3, and you may change it.

Below are two simplified plots. The upper one is approximately what I would expect from an oscillating toilet. Ideally sharp corners are impossible in macroscopic systems, and the falling part of the sawtooth (so-called relaxation) must be non-linear.

The lower plot is exactly what we see in computer model, except computer time is not the same as physical time. The browser can only use time slots, which the operating system allocates for it to run.

The plots are heavily out of scale. Web browsers are laggards, but 1000 cycles per second is a reasonable expectation. Think of a toilet flushing in 1/1000 of a second. That would be quite a water show. Don't stand anywhere near it.

The upper plot is smooth because the water is coming through a pipe at a constant rate. The digital models always have steps. Imagine, however, that you enchanted a toothbrush and made it fill the tank carrying water in a cup.

Remember the sawtooth pattern. Soon we will see it again.

Save leftovers for math

Modulo and programming.

This chapter is about the Cinderella of elementary math teaching. They don't even consider it an operation. It's a by-product of the operation called division with remainder.

Discussing it with my American children, i realized that they were not even sure about its name. Is in reminder or remainder?

At school, remainders are for beginners. Advanced learners know how to convert them to fractions. Fortunately, not everybody is smart enough to do this. In computing, they call the operation of finding a remainder the modulo. In math, they even invented modular arithmetic.

The following program demonstrates the so-called Euclidean division with the modulo. This code is hard to understand. Let's say, it's just a spell.

INJECT
function pirate(){
  your.fps=3;
  this.div=function(dvd,dvs){
    win.clearTimeout(your.tmr);
    win.clearTimeout(this.t);
    if (!((this.dvd=dvd)&&(this.dvs=dvs))) return;
    this.nid=your.nid;
    this.c=1;
    this.dvd=dvd;
    this.dvs=dvs;
    size(Math.ceil(dvd/dvs)+1,dvs);
    this.adv();
  };
  this.adv=function(){
    keep();
    engage(this.nid);
    this.q=Math.floor(this.c/width);
    if (!(this.r=this.c%width))
      for (var i=1;i<=width;++i) change(i,this.q,3,0);
    else change(this.r,this.q+1,1,0);
    if (this.c<this.dvd)
      this.t=your.tmr=win.setTimeout(this.adv.bind(this),1000/your.fps);
    if (this.c++>width*height) this.div(--this.c,this.dvs);
			keep();
      engage();
  };
};
client.cmws.height='300px';
size();
(your.Euclid=(new pirate())).div(6,4);
your.cm.setValue('your.Euclid.div(6,4)');

As usual, please click on the board to cast the preloaded spell. It creates a software object named Euclid. The last two lines clean the textarea and leave the call to Euclid, which you can change. To recover the original spell, please use the injector.

The last line of preloaded code made Euclid demonstrate division of 6 by 4. Six ones (coins, cupcakes, carrots or just pegs) are to be distributed between 4 recipients (pirates, students, rabbits or just stacks) as evenly as possible. Which means, two of them must be left, and this is a modulo.

The following spell tells Euclid to take control of the board and to play out the division of 53 by 7. Instead of copying it, please change the numbers in the spell, which has been left in the editor.

your.Euclid.div(53,7);

The number your.fps sets so-called frames per second rate. If you just created Euclid, it must be running at the pace of 3 frames (or just changes) per second. The rate of 10, like below, is fast. The rate of 1 is slow.

your.fps=10;

Once Euclid has finished it's job, you may make the divisor one bigger and see how your division changes. Drug the following code to the empty textarea and cast it as many tines as you like.

your.Euclid.adv();

Modulo is the red shnumber on top of the orange stack. Very briefly, shnumber is a lineup of pegs, which stands for its own quantity. If number is 3, shnumber is 111, where 1 can be anything countable.

Modulo behaves like an oscillating toilet tank changing from 0 to just one short of the value of the divisor. Then it falls back to 0 and climbs up again. Another good metaphor would be the punishment of the ancient king Sisyphus. In the realm of the signals, this one is called a sawtooth wave.

Euclid uses the traditional JavaScript timing with a callback function. In fact, it was written before CODEPEGS was timed.

For computer programming, modulo may be just a convenient notation. Like other math functions, it's not being taken literally. Computers do not draw triangles and measure their sides to figure out trigonometry.

Not only modulo is a periodic function—we can use it to build any other integer periodic function. Rotations, even calculus are here too. The challenges are abundant, and all this wondrous stuff is ready to be learned by a third grader, if only we cared to teach them.

Let's create a square wave out of two sawtooth functions. Understandably, the length of the wave must be an even value, so we start with a number d and multiply it by 2.

in JavaScript and is some other computer languages, there is the modulo operator % (they do not use percent sign for any other purpose). Unfortunately, the modulo in JavaScript is not exactly the modulo. I don't know what they were thinking and could not find an explanation, but we can only rely on JavaScript % for the positive numbers. In the following chapter, I will apply a popular workaround.

Here is the code, and a new playbox is waiting for you.

INJECT
//Sawtooth to square
var d=5;
var D=d+d;
var x,y,b=0; 
tick(0.1);
size(d*4,d*4);
for (x=0;x<width;++x){ 
  for (y=1;y<=x%D-x%d;++y)
    change(x,y,"g");
  b=D+1; //bottom
  for (y=1;y<=x%d;++y)
    change(x,b-y,"b");
  for (y=0;y<x%D;++y)
    change(x,y+b,"r");
}

Using shnumbers, we don't need zero level lines. To make sure that your computer is not cheating you, just subtract the blue shnumber from the red shnumber along the same column according to the color formula.

G = R - B

Another familiar face is a triangular wave. In JavaScript, the method Math.abs() returns an absolute value, which, coincidentally, is also known as modulus. You may drop the following spell into the playbox above.

INJECT
//Sawtooth to triangle 
var d=8;
var h=(d-d%2)/2;
var x,y,b=0; 
tick(0.1);
size(d+h+1,d*2);
for (x=0;x<width;++x){ 
  for (y=1;y<=Math.abs(x%d-h);++y)
    change(x,y,"g");
  b=h+2; //bottom
  for (y=0;y<x%d;++y)
    change(x,y+b,"r"); 
}

Adding a modulo to the same modulo, which was inverted and shifted, we can produce rectangular wave with a variable duty cycle. The width of the rectangles depends on the value of the name s (shift) in line 2. To keep the triangles at the same level, I included the value of the shift in the addition.

INJECT
//Variable duty cycle
var s=1,d=8;
var l,x,y,b=0;
var p=['green','blue','magenta','red'];
tick(0.05);
s=s%d; 
size(d*3+s,d*2);
for (x=0;x<width;++x){ 
  l=x%d-(x+s)%d+s;
  for (y=1;y<=l;++y) change(x,y,p[0]);
  b=d+d+1; //bottom
  for (y=1;y<=(x+s)%d;++y)
    change(x,b-y,p[1]);
  for (y=0;y<s;++y)
    change(x,y+b,p[2]);
  b=b+s;
  for (y=0;y<x%d;++y)
    change(x,y+b,p[3]);
}

The vertical shnumbers add up as follows

G = R + M - B

Here is how the code is calculating them

Y = X%d + s - (X+s)%d

Please feel free to change the value of d (divider) and s (shift). Divisor changes the sizes of the saw teeth. Shift defines their relative position.

This trick is funny, even if not very valuable. It allows us to build any integer periodic function, but in programming we can achieve the same results comparing modulo to a number.

You may not care how modulo enables cryptography, but even these demo pages are thickly sprinkled with them. Modulo is in every board and every loop, which walks the value of a variable from here to there. Modulo lurks in the positional notation of quantity. We use it to count objects and to convert numbers. Being a periodic function, modulo is handy for periodic tessellations, especially because we can map numbers into colors. Here is a compact modular way to produce the 4-color tiles (we've seen them before in the chapter about loops and patterns). The board, loops and the positional notation are working together.

INJECT
size(8,8);
tick(0.1);
for (var j=0; j<height; ++j)
  for (var i=0; i<width; ++i)
    change(j,i,2*(j%2)+i%2+1,0.1);

Let's use a modulo to variegate the board with stripes.

INJECT
var step=2;
size(10,10);
tick(0.1);
for (var j=0; j<height; j++)
  for (var i=0; i<width; i++) 
    if ((j+i)%step==0) change(j,i,'g',0.1);

Oops, this looked more like a chessboard, but if you make step bigger, you will see what I mean.

Superposition of stripes makes moires. This one is simple and good looking. See, we are getting closer to a loom.

INJECT
var s1=3, s2=4, k;
size(24,24);
tick(0.1);
for (var j=0; j<height; j++)
  for (var i=0; i<width; i++){
    k=j+i+1;
    if (k%s1==0||k%s2==0) 
      change(j,i,'y',0.1)
    else change(j,i,'b',0.1);
  }

Can you think of crossing two such moires? And, by the way, how big is a tile in this tessellation? The underlying math: moires visualize the concept of the least common multiple.

Here is one more tessellation (the last one, I promise) and below is the story. The size of a tile is size(28,28).

INJECT
//tessellation with H
tick(0.1);
size(28,28);
var i,j,is,cs,s,c;
var a=['#ff0000','#00ff00','#0050ff','#f0a000'];
tick(0.01);
for (c=0;c<4;++c){
  cs=c*21;
  for (i=0;i<width;++i){
    is=i*5;
    for (j=0;j<height;++j){
      s=j+is+cs;
      if (s%28<3) change(j,i,a[c]);
      if ((s+18)%28<3) change(j,i,a[c]);
      if ((s+22)%28<1) change(j,i,a[c]);
    } 
  } 
}

If you think I am making my living designing pattern, you are wrong. This stuff is new to me, or, in some parts, it's well forgotten. I didn't even remember polyomino when I was living through MAKE THEM MAD. I have read the Martin Gardner's columns, but it was ages ago.

For 10x10 board polyominoes are too much, and most of them are... uninspiring. Yet having this new media—a programmable pegboard—I decided to try my hand and picked a recognizable heptomino, which you just saw. With the additional complexity of four colors, I was wondering how challenging would it be to program such a pattern.

First, I drew it. I wanted to see the rule, and here is what I found.

The line marks the repeating red part, which on the picture is not completely assembled. Once I saw it, I knew how to build the whole using variable duty cycle functions.

Rotational symmetries are more interesting, but this one is impressive too. The parts look like organic molecules sticking to each other.

Kaleidoboarding

How to rotate the board.

To rotate a space around (0,0), we multiply vectors by a matrix. The problem is, not every board has a central hole. An evenly dimensioned square, for example, does not. Technically, we can assume 0 to be in the middle, surrounded with 4 holes, but then we'll have to count the distances to the holes in halves (fractions, that is).

True 90 degrees rotation of any board in whole numbers is surprisingly easy. Instead of rotating it around it's center, we can rotate it around a corner hole translating it back in place at the same time. Here is an example, which must be familiar for those who went through the pictures in MAKE THEM MAD.

INJECT
var D=10;
var X,Y;
tick(0.1);
size(D,D);
for (X=0; X<D/2; X++)
  for (Y=X; Y<D-X-1; Y++){
    change(X,Y,8);
    change(D-1-Y,X,2);
    change(D-1-X,D-1-Y,8);
    change(Y,D-1-X,2);
  }

To understand what's going on, you may comment out change() statements and uncomment them one by one. This is an awkward, but otherwise the best way to execute your program piece by piece.

Initializing a board, we can define the origin (which does not have to be (0,0)) and the numbering order. I currently use three orders: writing, Cartesian and numerical. The origin of this board is in the bottom left corner, which implies Cartesian order.

E-motions

Using pegboard as keyboards.

Euclidean motions change what we see while keep it the same because they preserve the distances between every two points. A shape that was moved or rotated looks differently, but it hasn't changed. Preschooler can perform euclidean motions in numbers on a media like a toy pegboard. Euclidean motions are a rich source of material for learning programming. I added mirroring to the group, although technically it doesn't belong to it.

The projects in this chapter are rather advanced, yet very simple. We are going to mirror, rotate and move single pegs. The next step can be moving complex shapes like, for example, letters.


Catching the clicks

In CODEPEGS, we grew familiar with the virtual pegboards using them as output devices for our programs. The pegboard can also be an input device catching our clicks or taps and starting programs to respond.

The following code enchants every peg on the board with a little spell. The spell is in the lines 6, 7, 8, and it's a single statement folded. That's how web programming really looks. Onmousedown, function, currentTarget and backgroundColor two times - believe or not, the favorite word of javascripters is elegant. Only line[k] and style[k] came from CODEPEGS. Without them, this simple color changing spell would be even longer.



CAST
RENEW


What else is here? Lines 2,3,4 remove some functionality of CODEPEGS. After this, clicking on the board will not cast code. In this chapter, we are going to use the CAST controls on the blue bars.

Line 5 starts a loop, which allows us to visit every peg and enchant it. Finally, lines 9 and 10 clean up the editor leaving behind only the spell to change the color of the peg in the top left corner.

The editor works as follows. First, we have to cast the long code. It creates 10x10 board, on which the pegs are already clickable (but the board itself no longer is). Clicking on the pegs, we make them change their colors to the color of the peg in the top left corner.

Time to cast the short code. From now on, we do it using the CAST control on the blue bar above the playbox. The corner peg becomes red, and every peg we click becomes red too. Let's change the color of the corner peg by casting the change(0,0,'blue') spell and click on the board to make the pegs blue. We now know everything to draw a picture.

Pegs in CODEPEGS are oversized pixels, and we just made an elementary pixel editor. It would take more programming to make our creation usable, but it already works: We can select colors and apply them to the pegs.

To load the initial code and start from scratch, please use the RENEW control on the blue bar.


Mirroring

This is how we compute the mirror reflections of a peg at the row number v and column number h:

(vd-v-1, h) // Horizontal mirror
(v, hd-h-1) // Vertical mirror

The spell (preloaded to the playbox editor) enchants every peg to watch for a click. The clicked peg casts another spell, which calculates and displays the two reflections. For another turn, we simply click again, but if we have changed the spell, we must to CAST the changes before clicking. To get back the preloaded spell, we click on RENEW.

The mirror reflections may overlap the initial peg leaving it green or blue. The central peg and both its reflections are the same, so the color goes from red to blue to green.

The students can be challenged to modify this and the following code to reflect the initial peg in the diagonal mirror as follows.

(d-h-1,d-v-1) // Bottom left to top right
(h,v) // Top left to bottom right

To keep the work reasonably simple, let them configure a square-shaped board. To use this playbox for something else, the name LOCK is better be set to false.



CAST
RENEW

CAST
INJECT
// REFLECTOR CHALLENGE
size(9,9);
client.brd.onmousedown=undefined;
client.tovl.style.display='none';
for (var j=0;j<height;j++)
  for (var i=0;i<width;i++){
		pegs[j][i].style.cursor='pointer';
    pegs[j][i].onmousedown=function(){
			var v=j, h=i, id=client.nid, 
        turn=client.turn;
      return function(){
  	    alter(v,h,'#00ffff',0, id);
  	    alter(v,h,'#808080',0.1, id);
      }
  	}()
  }
var v=Math.floor(Math.random()*9);
var h=Math.floor(Math.random()*9);
pegs[v][h].onmousedown=undefined;
//changeone(client.nid,-1,v,h,'#ff0000',0);
alter(v,h,'#ff0000',0, client.nid);
var j=height-v-1;
pegs[j][h].onmousedown=function(){
  var id=client.nid;
  return function(){
    alter(j,h,'#00ff00',0, id);
  }
}();
var i=width-h-1;
pegs[v][i].onmousedown=function(){
  var id=client.nid;
  return function(){
//    changeone(id,-1,v,i,'#00ff00',0);
    alter(v,i,'#0000ff',0, id);
  }
}();

The second spell challenges us to find the mirror reflections. It chooses one peg at random, makes it red and enchants the other pegs to react to our clicks. Most of the pegs are programmed to blink pale blue. The two right pegs changes their colors to blue and green.


Rotating

Like before, we have a preloaded spell. It enchants the pegs to wait for a click. Once clicked, the peg starts the spell. We may click again for a new rotation. Asymmetrically placed clicks yield more interesting results.

The little spells enchanting the pegs are created by the other spells while they are being executed. During the execution, the spells have access to CODEPEG resources made to simplify the programming. CODEPEGS provides the names like height, width, left, right, pegsline and style. It tells which playbox we are using. We rely on the change() function to find the colors and apply them on time.

The programmed pegs are left to wait for a click. By the time we click, CODEPEGS resources will not be available. It's up to us to decide what to provide. Some enchanting spells need a minimal information to run. Through this chapter, we see some tricks allowing the left-behind spells to do their jobs.

For example, the value of the name LOCK tells CODEPEGS not to drop the helping names after the spell is over. We can also call the engage() function to do only the part of the casting job. The function alter() working behind the change() is less functional and less demanding.

The first rotating spell is preloaded in the following playbox. We cast it, then click anywhere on the board. The peg we clicked on becomes the starting point. It calls the spell, which figures out and colors 3 other pegs. The lines 12…20 are this spell. The formulas to perform rotation are in lines 15…18.


CAST
RENEW

CAST
INJECT
// ROTATOR CHALLENGE
size(9,9);
client.brd.onmousedown=undefined;
client.tovl.style.display='none';
for (var j=0;j<height;j++)
  for (var i=0;i<width;i++){
		pegs[j][i].style.cursor='pointer';
    pegs[j][i].onmousedown=function(){
			var v=j, h=i, id=client.nid, 
        turn=client.turn;
      return function(){
        alter(v,h,'#00ffff',0, id);
        alter(v,h,'#808080',0.1, id);
    	}
  	}()
  }
var v=Math.floor(Math.random()*9);
var h=Math.floor(Math.random()*9);
alter(v,h,'#ff0000',0, client.nid);
var j1=vdim-h-1, i1=v;
pegs[j1][i1].onmousedown=function(){
  var id=client.nid;
  return function(){
    alter(j1,i1,'#00ff00',0, id);
  }
}();
var j2=hdim-v-1, i2=vdim-h-1;
pegs[j2][i2].onmousedown=function(){
  var id=client.nid;
  return function(){
    alter(j2,i2,'#0000ff',0, id);
  }
}();
var j3=h, i3=hdim-v-1;
pegs[j3][i3].onmousedown=function(){
  var id=client.nid;
  return function(){
    alter(j3,i3,'#ffff00',0, id);
  }
}();
pegs[v][h].onmousedown=undefined;

The challenging code (the one below the playbox) must be injected and casted. It randomly choses one peg and makes it red. Our goal is to identify 3 other rotated pegs and click on them. Please cast again to get another challenge.


Translating

Translation—the simple linear motion—is the most challenging in CODEPEGS. Unlike reflection and rotation those stay inside the board, translation can bring us anywhere. To make it possible, the code handles the board as a torus. Behind the board, the top border is connected to the bottom border, the right border is connected to the left border, and the diagonally opposite corners are connected to each other.

Even bigger difficulty is that we don't have an infinite (or just a high enough) density of pegs to draw smooth lines. We can only hop a given distance. Distance in CODEPEGS is two numbers: one for the rows, another one for the columns.

The casted spell makes one random peg (like before, it's red). The pegs wait for us to click on one of then. This click tells the distance: how many columns and how many rows to skip. The peg we clicked on extracts this information and colors the other pegs maintaining the distance and going alone the surface of the torus. The name s in line 2 tells the number of the steps. There can be more of them.

A clicked-on peg casts the walking spell exactly as a playbox casts the spell in the editor. Every time, CODEPEGS is fully enabled. The programming is no different, but not without a complication. To cast a program, we submit it as a character string. In JavaScript, long character strings are quite clumsy to handle. Long code must be framed as a regular function. Then, the function call can be framed as a string.



CAST
RENEW

CAST
INJECT
// WALKER CHALLENGE
var d=10;
size(d,d);
client.brd.onmousedown=undefined;
client.tovl.style.display='none';
LOCK=true;
var walker=function(){
  this.id='P00_00_00';
  this.r=0.0000001;
  do{
    this.r=Math.random();
    this.j0=Number(String(this.r).substr(2,1));
    this.i0=Number(String(this.r).substr(3,1));
    this.j1=Number(String(this.r).substr(4,1));
    this.i1=Number(String(this.r).substr(5,1));
  }
  while (this.j0==this.j1&&this.i0==this.i1);
  this.sj=this.j1-this.j0;
  this.si=this.i1-this.i0;
  this.n=function(){return Number(this.id.substr(1,2))};
  this.j=function(){return Number(this.id.substr(4,2))};
  this.i=function(){return Number(this.id.substr(7,2))};
  this.nj=function(j){
    var r=j+this.sj;
    if (r<0) r+=d;
    if (r>=d) r-=d;
    return r;
  };
  this.ni=function(i){
    var r=i+this.si;
    if (r<0) r+=d;
    if (r>=d) r-=d;
    return r;
  };
};
var w=new walker;
for(var j=0;j<d;j++)
  for (var i=0;i<d;i++){
		pegs[j][i].style.cursor='pointer';
    pegs[j][i].onmousedown=function(e){
      w.id=e.currentTarget.id;
      var c=e.currentTarget.style.backgroundColor;
      alter(w.j(),w.i(),'#00ffff');
      alter(w.j(),w.i(),c,0.2);
    }
  }

alter(w.j0,w.i0,'#ff0000');
alter(w.j1,w.i1,'#00ff00');
pegs[w.nj(w.j1)][w.ni(w.i1)].
  onmousedown=function(e){
    w.id=e.target.id;
    alter(w.j(),w.i(),'#0000ff');
}

Finally, here is the walking challenge. The code below the playbox throws two random pegs: red and green. We are invited to make one more step clicking on the peg at the same distance from the green peg that the green peg is from the red peg. The right peg knows it must becomes blue.

Shapes and objects

OOP in JavaScript: wordy, but it works.

Originally, is was a three-part study on handling shapes in different programming paradigms. It was too long, so only the last chapter has made it to this demo. I wanted to see how imaginary learners could program the maneuvers, which I performed 4 years ago with a 4-year old. We did rotations too.

Take 1 was about hardcore procedural programming. In Take 2 I tried cels, like in classical animation. Take 3 was about the object-oriented programming or OOP. I found it to be too verbose, but surprisingly easy. To appreciate the difference, compare how we rotate the colors in this chapter with the Euclidean motion.

Let's build a simple shape.

INJECT
tick(0.1);
size();
function quincunx(){
  this.color='r';
  this.appear=function(){
    change(0,0,this.color);
    change(0,2,this.color);
    change(1,1,this.color);
    change(2,0,this.color);
    change(2,2,this.color);
  };
};
new quincunx().appear();

Congratulations, we used JavaScript's OOP, and we got a quincunx. Or so I hope. Well, JavaScript is JavaScript. Thises, functions everywhere.

Now I am going to get rid of the scary coordinate numbers in favor of the distances to the top (t) and to the left (l) borders.

Will it be easy enough? How about addition? The following code tells quincunxes where to appear. To do the trick, the numbers in appear() must be added to the initial positions. Subtraction, of course, is merely an addition of a negative number.

INJECT
tick(0.1);
size(8,8);
function quincunx(color){
  this.color=color;
  this.available=true;
  this.appear=function(T,L){
    change(0+T,0+L,this.color);
    change(0+T,2+L,this.color);
    change(1+T,1+L,this.color);
    change(2+T,0+L,this.color);
    change(2+T,2+L,this.color);
  };
};
new quincunx('r').appear(+2,+1);
new quincunx('b').appear(+1,+4);
new quincunx('g').appear(+4,+2);
new quincunx('y').appear(+3,+4);

The spell above isn't worth trying. It's the same change() function calls, four times five of them. However, for most practical purposes, they are not worse than arrays and loops, which I used before because they are bound to this particular shape.

Let's add two methods. The new version of the constructor will be attached to the playbox, and the spell will be erased. Past this point, we can use prototype.

INJECT
my.quincunx=function(color){
  this.color=color;
  this.available=true;
  this.appear=function (T,L){
    this.toTop=T;
    this.toLeft=L;
    change(0+T,0+L,this.color);
    change(0+T,2+L,this.color);
    change(1+T,1+L,this.color);
    change(2+T,0+L,this.color);
    change(2+T,2+L,this.color);
    return this;
  };
  this.go=function(t,l){
    this.toTop+=t;
    this.toLeft+=l;
    this.appear(
      this.toTop,this.toLeft);
    return this;
  };
  this.rotate=function(){
    this.available=false;
    this.next.newcolor=this.color;
    if (this.next.available) 
      this.next.rotate();
    this.available=true;
    this.color=this.newcolor;
    this.go(0,0);
  };
};
your.cm.setValue('');

The spell below creates four quincunxes and attaches them to the playbox. This must be the playbox, to which the constructor was previously attached.

Variables h and w in the beginning define halves of the pegboard dimensions. I want them be even. I also added a simple calculations placing quincunxes around the center of the board of any size. With h=12 and w=12, the board will be 24x24.

INJECT
//CREATE
tick(0.01);
var h=6;
var w=6;
size(h+h,w+w);
my.N=new my.quincunx('r').appear(-3+h,-2+w);
my.E=new my.quincunx('b').appear(-2+h,0+w);
my.S=new my.quincunx('y').appear(0+h,-1+w);
my.W=new my.quincunx('g').appear(-1+h,-3+w);

In javaScript Complete Idiot's Department, the favorite example of objects are cars. The cars can have anything you want, except they are not drivable. Quincunxes only remotely look like cars, and they have nothing a car must have, but you can drive them. Right now.

Please inject the following piece. Cast it several times. Attention, please: it injects to the playbox, to which the quincunxes were attached, so please scroll back. Sorry for the inconvenience.

INJECT
//FAN OUT
keep();
tick(0.01);
offguard();
my.N.go(-1,0);
my.E.go(0,+1);
my.S.go(+1,0);
my.W.go(0,-1);

Oh no. I left uncomment the keep() spell. The quincunxes are leaving the trails like pens. Please re-create the quincunxes. It's eazy. Press Ctrl-Z, get the //CREATE spell back and cast it. Inject the //FAN OUT spell and start casting.

Hope it worked. If it did, quincunxes must have disappeared by now. We are not on torus anymore.

Can you change //FAN OUT spell to make quincunxes fan in? Can you get them fan diagonally?

Our first objects knew only their colors, and they were ephemeral. Every quincunx lived as long as the browser was working on the code submitted by the playbox. The pegs on the board are the objects linked to the page, and they persist keeping any changes.

The current version of quincunx evolved to be aware of it's position through dead reckoning. Linking the quincunxes to the playbox and, ultimately, to the page, we extended their lives. They persist after the flow of control went away from our code.

Currently, the quincunxes are listening to us only. Can we introduce some kind of organization. A control center, to which we could talk, maybe? The supershape?

Let's suppose the quincunxes form a wheel, and think about rotation. In a front-wheel drive car the front wheels are rotated by the hub, but there is no central shape in our layout to take this role. The rear wheels, however, are being pulled or pushed by their tires!

The following spell links the shapes, so every one of them knows which one is next. This powerful technique was invented in Artificial Intelligence research. Linking the pegs, we can bring a flexible orders to the board. The pegs do hot have to be near each other.

//LINK
my.N.next=my.E;
my.E.next=my.S;
my.S.next=my.W;
my.W.next=my.N;

The linking spell will be included in the next spell. Please don't cast it.

We already have rotate() method in the code. Any shape can receive it and pass it to the next shape until it returns to the originator. In doing so, the shapes send forward their colors. In the following playbox you have everything to define, create and link four quincunxes.

Did you cast the code? If you did, we can now rotate the colors endlessly. Sorry again, this and the following pieces of code inject to the same playbox. Please scroll back.

INJECT
tick(0.001);
my.N.rotate();

We can combine rotation with fanning out and we can start rotation from any quincunx. They are all the same.

INJECT
tick(0.001);
offguard();
var h=12;
var w=12;
size(h+h,w+w);
my.N.go(-1,-1);
my.E.go(-1,+1);
my.S.go(+1,+1);
my.W.go(+1,-1);
my.N.rotate();

The quincunxes are with us even if they went out of view. Would you hack the last spell to pull them back to the board?

Translating all the quincunxes in the same direction for the same distance is easier. A student may take rotate() method and convert it into move(top,left). I even linked it to go(top,left) already.

Finally, here is the terrible truth: the method

  this.rotate=function(){
    this.available=false;
    this.next.newcolor=this.color;
    if (this.next.available) 
      this.next.rotate();
    this.available=true;
    this.color=this.newcolor;
    this.go(0,0);
  };

may be obvious, but it's only easy if somebody else wrote it. Not only it's tricky to write—it's tricky to debug. You go through rotate() calls and realize, like every beginner did at some moment, that objects in OOP are more or less elaborate fakes covering up the same old flow of control.

PART 4: LET'S LEARN BROWSERS

What makes them work for us.

This part has been written 3 years ago. Since then, web technology has changed. Most importantly, pegs are now border-boxes, so many explanations were reworked.

Web programming could make a treasure chest for school science. So much can be uncovered through experimentation, observation and speculation. And you know what? This keeps the community of web developers busy.

Sidewalk ARRAY

The pegs part and join back.

To make the lessons look simpler (and my playboxes easier to use), I prepared two more sugarcoats.

In addition to two-dimensional numeration of the board, I will use one-dimensional numeration available through the name line. For 5x5 pegs, board[4][4] is the same as line[24]. The spatial order is the one of the Western writing. You'll see how it works.

To access the styles of the pegs, I will use the name styles. Instead of writing

board[0][4].style

or

line[4].style

I will write

style[4]

I will also use loops. The loops are thoroughly explained in PART 2. These imaginary lesson plans are about web-programming.

Magically speaking, loops are like brooms. We can use them to repeat certain actions. A broom can carry the water bucket by bucket. A loop can change the styles peg by peg. I borrowed the look from MIT Scratch. Some readers may remember those brown grips.

The following step-by-step instruction scrolls separately from the page. The playbox stays in place. This bounding allows you to click on the link to inject the spells right into the textarea. You only need to cast it then, but be careful doing this, especially if you changed the spell: another click on the link will inject the same code again.

The scratch, by the way, is right below, and it marks the beginning of the Sidewalk ARRAY. You may click on the stop sign to invoke the spell, which freezes window scrolling. When the window scrolling is frozen and as long as your cursor is in the sidewalk, you are safely confined to it. Even with a motorized mouse like mine, you will never fall off. Hint: to scroll through the sidewalks quickly, unfreeze window scroll and keep the cursor on the right side of the screen (where the playboxes are).

One more time, to freeze window scrolling, please click on the stop sign or next to it. To unfreeze, click on it. You may also click to the similar sign in the end of the sidewalk.

Happy sidewalking. Web programming could make a treasure chest for school science. So much can be uncovered through experimentation, observation and speculation. And you know what? This keeps the community of web developers busy.


STOP
Welcome to the Sidewalk ARRAY.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

Step 0

Come or return here to start from scratch. The following spell creates a brand new board (and erases any changes made to it). Next it makes every peg small and numbers each one. It also gives the pags another other ugly color. Is pink appropriate for a playground?

Like Alice in Wonderland, pegs can contract and expand keeping their identities. Pegs may contain any text, although I only needed one digit here.

You may click on the injector link to get the spell into the textarea.

INJECT
your.background='rgb(255, 192, 203)';
size();
for (var i=0;i<line.length;++i){
  style[i].height='32px';
  style[i].width='32px';
  style[i].fontSize='24px';
  style[i].padding='4px';
  line[i].textContent=String(i);
}  

By the way, px after a number means pixels. You know, those tri-color dots on your screen. Without this or some other unit of measurement, such spells would not work.

Step 1

Let's remove the glue holding the pegs in this neat array.

INJECT
for (var i=0;i<line.length;++i){
  style[i].cssFloat='none';
  style[i].clear='none';
}  

I hope you understood that we just canceled two so-called properties of every peg's style. One is officially called cssFloat (or simply float). Another one is called clear.

The name of the property cssFloat suggests that there was another float, but there is none. The word floathas been reserved, never used, eventually released, etc.

Step 2

Before we proceed: the following package brings the board to this point from scratch.

INJECT
your.background='rgb(255, 192, 203)';
size();
for (var i=0;i<line.length;++i){
  style[i].height='32px';
  style[i].width='32px';
  style[i].fontSize='24px';
  line[i].textContent=String(i);
  style[i].padding='4px';
  style[i].cssFloat='none';
  style[i].clear='none';
}  
Step 3

If we don't tell how to arrange the pegs, the browser floats them to the left and stacks them down. Such is the default behavior.

Let's change the pegs one by one. Here is the spell, but please don't cast it yet.

INJECT
style[?].cssFloat='left';

Before using this spell, please replace the question mark between the square brackets with the number of the peg to enchant. Without a loop spell, this is our responsibility.

Let's start with peg 0. Erase the question mark and type in 0 instead. Did you cast the spell? What's happened?

Nothing should have happened to peg 0, but where is peg 1? And where is the number of the peg 0?

Please change the number between the square brackets to 1 and cast the spell. The missing peg 1 emerged to the right from peg 0. The following peg 2 is nowhere to be seen.

Further floating will not uncover much new. Every time, the peg next to the last floated peg disappears and the previously floated peg appears on the right.

Step 4

Let's use the spell from Step 2 to restore the order. Now let's try something dramatically different. The last peg is peg 8. Where can it go if we float peg 7 Do it now using the spell from Step 3.

You must be able to see that the body of peg 8 has truly gone, so this is what must have happened to every other peg after a floated peg. But where are they hiding?

To find out, let's change the color and the height of peg 8.

INJECT
style[8].height='48px';
style[8].background='magenta';

Looks like peg 8 has left its number behind and moved to overlap peg 7! Please try it one more time on peg 2: float it first, then change the color of peg 3.

INJECT
style[2].cssFloat='left';
style[3].height='48px';
style[3].background='magenta';

We have confirmed our assumption and found the number from peg 3. It was hiding behind peg 4. when we pushed peg 4 away, part of the digit 3 became visible.

Web browser is programmed to lay out floated elements with its left hand, non-floated elements with its right hand, and not to let the right hands know what the left hand is doing. Once we told peg 0 to float, the left hand is taking care of it, and for the right hand this peg no longer exists. The right hand puts peg 1 at the top left corner, then the left hand slaps peg 0 over it. OK, but how about the peg numbers?

Step 5

To prevent overlapping, we may use the clear property. Do it for the two "lost and found" pegs.

INJECT
style[3].clear='left';
style[8].clear='left';

Hence, the browser was very well aware of every peg on the board, floated or not.

I hope you already learned something about the perils we face and fight in trying to set up a rectangular layout covering the page and organizing the texts on it. Disappearing areas are frustrating enough, but web browsers have more tricks up their sleeves. We naturally assume that area containing text is like a display on a dashboard. It can go hide, OK, but how can the text fall off? What were they thinking?

Step 6

The case of disappearing pegs can now be closed but the problem was not solved yet. How to get those little pink squares back into order?

First of all, let's make them all float and cancel any clearances. I am not asking you to enchant every peg by hand anymore. We have the loop spell for this.

INJECT
for (var i=0;i<line.length;++i){
  style[i].cssFloat='left';
  style[i].clear='none';
}  

What you see is the default behavior of floating pegs. They line up from left to right, next to each other, like letters or words. Order them to float right (try it) and see them lining up from right to left - that's how the other part of humankind learns to write.

One difference between how browsers display the floated pegs and the printing traditions in English (Latin) world is immediately obvious. Pegs align their tops and hang down if they are bigger than their neighbors. A bigger letter extends upward aligning its bottom with the rest of the line and pushing the line down.

Step 7

Do the floated pegs behave like letters or like words? More specifically, can pegs "wrap" like words? See, for example, the Format menu in Windows Notepad if you are not sure what Word Wrap means.

Let's find out. At this moment, I expect you to see a line of pegs numbered from left to right, all 32 pixels wide. Pegs 0, 1, 3, 4, 5, 6, 7 are 32 pixels high, pegs 3 and 8 are 48 pixels high. The following spell will make every peg 64 pixels wide, which is two times bigger than they currently are.

Please inject and cast this spell. If pegs can wrap, they will start forming a new line once the first one is full.

INJECT
for (var i=0;i<line.length;++i){
  style[i].width='64px';
}  

This lesson is already too long, so let me tell you how I understand what the browser was doing. The pegs did "wrap" very much like words, but not exactly. The browser was placing them from left to right (with its left hand, yes). The space was limited. Peg 7 did not fit, so it dove down and started sliding left under the bottom of the last successfully placed peg, which was peg 6.

Leftbound peg 7 kept sliding at the level of the bottom of peg 6, until it hit a snag. That happened to be another left-floated peg, i.e. peg 3, because its bottom was protruding down. Hence peg 7 stuck to the right side of peg 3, and every consequent pegs piled up to the right because this is what floating left is about.

Step 8

Please adapt the spell from Step 4 to make peg 6 48 pixels high. At this level, overflown pegs must travel the whole way to the left unstopped.

You certainly realized that we just found one method to build a 3x3 array. We can make the pegs even wider, so only 3 of them will fit the line. The width must be around 150 pixels, I guess. You may try to do it later. If you chose to play now, that's fine, but remember, by the beginning of the next step I expect all the pegs to be 32 by 32 in size.

The following spell tidies up everything I could think of. I don't care about the numbers any more, but I don't want snagging.

INJECT
for (var i=0;i<line.length;++i){
//Make this peg 32 pixels wide.
  style[i].width='32px';
//Make this peg 32 pixels high.
  style[i].height='32px';
//Make this peg light green.
  style[i].background='lightgreen';
//Disable clearance for this peg.
  style[i].clear='none';
//Make this peg float left.
  style[i].float='left';
}  

Lines starting with two slashes // are called comments. The browser is not supposed to pay attention to anything from double slash to line's end. For sorcerers, the comments can be very helpful. Unlike my writings on the sidewalk, the comments are embedded in the spell at certain points, explaining what is supposed to happen next.

Step 9

If everything was done right, you now see a horizontal line of 9 light green pegs of the same size. I am going to demonstrate another method to fold this line into a 3x3 array, which will be completely independent from the ratio of the width of the pegs and the width of the board. Simply speaking, such an array will be stable not only in a room tight enough to hold it, but anywhere, if only the room is big enough to accommodate it.

To achieve it, I will force some pegs to start a new line. Not sure if you know or care, but in computers a new line is a character. Often, even two characters. In typewriters the Carriage Return (CR) character makes the sheet of paper move the whole way to the right or the printing head move the whole way to the left, depending on the design. Line Feed (LF) advances the paper up. Nothing is printed, but the next printable characters appeared in the leftmost position of the next line.

Pegs are complex objects with attributes like background color, dimensions, etc. We can make any peg a new line peg. You already know how to do it. If the pegs are floated left, you set clear to 'left'. The pegs' attributes are held in its style, so here is what you do to make peg 3 an end-of-line peg:

INJECT
style[3].clear='left';

Please enchant peg 6 too. Problem solved. Note that both peg 3 and peg 6 remain floated left, but the following pegs start building new lines after them.

If you froze the window scroll (which means, there is no main scrollbar along the right side of the window), click below to unfreeze it.


STOP
Sidewalk ARRAY ends here.
Stop if you are scrolling down.
Click to unfreeze window scroll.
Good bye.

Recess: play a game

The board as a puzzle.

I thought that the piece of information technology introduced in Sidewalk ARRAY above looked weird enough to lend itself to a computer game. Here I am going to offer a conceptual prototype. Not only to entertain, but also to prepare you to take on the next sidewalk.

The game is not very exiting, even boring, but so is practically every free web-game offered by Disney, Nickelodeon, PBS and you know better whom. I am sure I could rival them by adding motions, colors, sounds delivered by generic ghosts, knights, robots, fairies, dinosaurs, jesters and other funny animals.

HTML and CSS themselves provide unlimited opportunities. I could mix the pegs of different sizes to create playful pileups, or combine floating and non-floating pegs to add a thrill of hide-and-seek. Don't let me forget, from this game you may actually learn a little bit of something useful and well paid.

The game will start with the pegs on the board being intentionally disarranged. The goal is to order them using as few moves as possible. There is only one way to make a move: pick a peg and place it right before some other peg.

Textarea below is preloaded with the spell to create the numbers and the colors. Just cast it. In case you need this spell again, here it is.

size(1,3);
var color=['#ff2020','#fcfc00','#10ff10'];
for (var i=0;i<line.length;++i){
  style[i].background=color[i];
  style[i].clear='none';
  line[i].textContent=String(i);
}

The following spell changes the order of the pegs. Make sure to clean the textarea before loading it. The numbers in the square brackets tell the browser which peg must be inserted before which respectively. The spell casted as below will tell the browser to insert peg 1 (yellow) before peg 2 (green).

Keep the following spell in the textarea as you play. Change only the numbers. Remember, they start from 0.

INJECT
your.brd.insertBefore(line[2],line[1]);

Not sure if you'd like to do it again, but you may. Anyway, here is more challenging case: the board below has 9 pegs, all floated left, and they are forming a 3x3 array because 3 of them (0, 3, 6) have their clear properties set to 'left'. The textarea is preloaded with the spell. Please cast it to make the pegs small, number them and disarrange them, all at once. Then you may try to order the pegs using the same spell as before:

INJECT
your.brd.insertBefore(line[2],line[1]);

I could do it in 3 steps.

You may use the previous spell to create a new board and prepare it for playing. To shuffle the pegs differently, please edit code line 2. Currently, it means: put peg 3 in the first place, peg 6 in the second pace, etc.

In the language of mathematics, rearranging a set without changing it is called permutation. The modern American school curriculum includes some combinatorics, and permutations are mentioned, even though briefly. Indeed, they are mostly useful for artists, scientists, engineers, statisticians and other hard-to-meet folks. Imagine a medical office assistant or a grocery shelf stocker doing this.

In practice, a set may contain practically anything - for example, sounds. So-called method ringing invented by English church bell ringers - please excuse me, I could not find out how long ago - was about permutations. A braid is a sequence of permutations too.

Some permutation games are notoriously hard. Rubik's Cube is one of them, if you are not allowed to permute the stickers. Ordering a 3x3 board is very easy. Yet, if you solved the last problem, you must have understood how float and clear work together.

Any permutation can be achieved through a sequence of transpositions of two adjacent elements. The spell that puts an element in front of another elements is more powerful than that. It shifts everything between the pegs back or forth because the peg moving to a new position disappears from where it was. Draw the arrows showing how the pegs move, and you will see that they make a cycle.

This game, like the rest of pegboarding, descended from MAKE THEM MAD. Before my student turned four, I started testing her trying to find out if she really learned the patterns and the symmetries I taught. One such test involved reshuffling the layouts that she just built, transposing some pegs in pairs. She immediately cracked this strategy, so I started building long cycles of transpositions encouraging her to remove all misplaced pegs, and then repair the patterns taking the right pegs from the pool of those previously removed.

Sidewalk SPINNER

Rotation and text formatting.

Spinner is a rotational shape most suitable for the polar coordinate system. Building it illustrates how isotropic-space dwellers struggle with web browsers because browsers are text formatting tools working left to right and top to bottom.

Let me remind you what a spinner is. The playbox below is preloaded with the spell to build one.

The spell colors 8 pegs red. The other 8 pegs remain gray and form the background. However, if we put such 4x4 rectangles next to each other, the plane will be tiled with red and gray spinners, and nothing else.

We'll try to build this layout from 8 elongated elements using their float and clear properties. Please remember, it's not a lesson for a student, it's merely suggestions for a teacher, but you may take it on your own. Essentially, it's just a puzzle in disguise, and I provided plenty of magic carpet rides.

Allow me one very important warning. A spell casting job may seem safe and easy like texting with friends, but it's not. In fact, it requires the most meticulous attention to every minor detail of your wizardry. You got to spell exactly right, or face the consequences. Spell it wrong, and your spell will do nothing at best.

The ancient tale of the sorcerer's apprentice had a happy ending. That's why we know it. The overwhelming majority of sorcery students disappear without a trace before acquiring any practicable magic power. As the progress of this trade went on, the rate of survival kept falling, and the number of graduates became statistically insignificant. That's why your chances to meet a real magus nowadays are negligible.

I don't expect you to cause any harm to you or your computer yet, but in this lesson you may annihilate some or all of your pegs. I mean, they will be lost forever. In such a case, please start from scratch.

The scratch, by the way, is right below, and it marks the beginning of the Sidewalk ARRAY. You may click on the stop sign to invoke the spell, which freezes window scrolling. When the window scrolling is frozen and as long as your cursor is in the sidewalk, you are safely confined to it. Even with a motorized mouse like mine, you will never fall off. Hint: to scroll through the sidewalks quickly, unfreeze window scroll and keep the cursor on the right side of the screen (where the playboxes are).

One more time, to freeze window scrolling, please click on the stop sign or next to it. To unfreeze, click on it. You may also click to the similar sign in the end of the sidewalk.


STOP
Welcome to the Sidewalk SPINNER.
Stop if you are scrolling up.
Click to freeze window scroll.
Click in the end to unfreeze it.

Step 0

Let's number the pegs, arrange them in a line from left to right (float='left', clear='none'), slightly change their style, and make them disappear.

INJECT
size();
for (var n=0;n<line.length;++n){
  style[n].height='60px';
  style[n].width='60px';
  style[n].fontSize='20px';
  style[n].borderRadius='8px';
  style[n].float='left';
  style[n].clear='none';
  style[n].display='none';
  line[n].textContent=n;
}

In the first written account of invisibility (which, as it is widely believed, was given by Plato), the invisible man was not stripped of his body. It might not immediately follow from the story itself, yet subsequent speculations made it clear enough. The invisible man of H. G. Wells - probably, the most famous and exceptionally well documented case - could have been caught and killed. A web browser can serve invisibility, but disappearance is more than that. The display='none' piece of the spell above renders the pegs completely bodiless. They take no room in this world.

A disappeared peg still exists. It simply is not here. As long as we have a way to address it, we can change it and call it back.

Step 1

Let's pull peg0 out of nowhere and make it look different.

INJECT
var n=0;
style[n].height='120px';
//style[n].width='120px';
style[n].background='gray';
//style[n].background='red';
style[n].display='block';
//style[n].display='none';
style[n].float='left';
//style[n].float='none';
style[n].clear='none';
//style[n].clear='left';

Please cast the spell and keep it in the textarea. You will use it to enchant the other pegs. Read through the lines to understand what the spell does. Changing size, color (called background), float and clear is nothing new. We did this before. Display is a property, which makes elements disappear and appear. After display='block' the element appears.

The spell in textarea is a tool kit. Double slash // tells the browser to ignore the rest of the line because it contains a comment. Wizards often use comment markers to make parts of complex spells invisible to the browser. This is known as commenting out.

Step 2

To build a spinner, we need horizontally and vertically elongated paddles. Setting the height of a peg to '120' pixels (and keeping the width of '60px'), we turn this peg into a vertical paddle. The width equal to '120px' (again, with unchanged height) makes a horizontal paddle.

Spell kit has two separate spells for making width and height equal to '120px'. It's up to you to comment out one of them, and leave the other one visible to the browser. Don't uncomment both at the same time, or you will make a peg 120x120 pixels big. Should this happen, uncomment both height and width, and set them to '120px' and '60px' as appropriate. Then change '60px' to '120px' and comment out one of them.

There is a spell to make a peg gray. The next one makes it red. Leave both spells uncommented, and the second spell will override the first. Comment out the second spell, and the first spell will rule.

Setting display='block' will make a peg appear. The next spell sets display='none', and it is commented out. Remove the comment mark, and the peg will disappear. Similarly, you can turn on and off float='left' and clear='left'.

To fix a mistake, get the comment marks right, and recast the whole kit. If you changed something other than a comment mark and got lost, inject the spell again. Please remember, a single slash is just a slash. It takes two of them to comment out.

If you are done playing with the properties of the peg, please inject the last spell and cast it again. We want peg0 to be gray, vertically extended, floated left and not 'cleared'.

Step 3

The spell kit enchants one peg at a time. Which one?

The pegs can be addressed as line[?], and the number in place of the question mark tells the browser which peg to enchant. In addition, CODEPEGS lines up the styles. Instead of line[?].style, we can address any peg's style simply as style[?].

Look at the spell kit again. To enchant a peg, do we have to put its number between every pair of square brackets?

The kit employs a magic trick allowing to type the number only once and use it many times. The first line var n=0; creates a single-letter name n and gives it the value of0. The name n appears between every pair of square brackets. The browser is smart enough to understand: there has to be a number here, and they gave me a name. Is there a value behind the name? Eventually, the name will be evaluated, which simply means, it will be replaced with 0.

And here is the best part: if you replace 0 with any other number, the browser will happily substitute it for n everywhere. To apply the spell kit to a different peg, just type that peg's number on the right side of the = sign. I packed many spells together to change them all from one place.

Step 4

The following table tells how we need the pegs to look. It does not tell how to make them look this way. Use the kit to set up long dimension, background color, display, float and clear properties for peg1, peg2, and peg3 (peg0 must be ready yet).

n'120px'backgrounddisplayfloatclear
0height'gray''block''left''none'
1height'red''block''left''none'
2width'gray''block''left''none'
3width'red''block''left''none'

Why didn't I turn this table into a web-form? Simply because CODEPEGS do not teach how to use web-forms.

INJECT

OK, here is a better deal. Click above to inject a magic carpet spell, which will bring you to this point from scratch. It has display:none, but you may view it in the teхtarea.

Step 5

Parking peg3 under peg2 might make one half of a spinner. Let's try to do this. Here is an excerpt from the spell kit.

INJECT
var n=3;
style[n].float='left';
//style[n].float='none';
style[n].clear='none';
//style[n].clear='left';

Congratulations, we've got the first problem. Trying all the four combinations of none and left for float and clear, we can either overlap pegs 0 and 1 with peg3, or put peg3 below them. What else can we do?

Comment out clear='left', uncomment clear='none' and recast. Let's leave peg 3 where it wants to be for the time being, and move ahead.

Step 6

To move ahead, we need spell kit again, and here it is, customized for peg4. Please note, it's setting clear='left' for the first time.

INJECT
var n=4;
//style[n].height='120px';
style[n].width='120px';
style[n].background='gray';
style[n].background='red';
style[n].display='block';
//style[n].display='none';
style[n].float='left';
//style[n].float='none';
style[n].clear='none';
style[n].clear='left';

Looks like peg4 fell in place. Or did it?


Step 7

The following table defines the transformations for peg5, peg6 and peg7.

n'120px'backgrounddisplayfloatclear
5height'red''block''left''none'
6height'gray''block''left''none'
7width'gray''block''left''left'

Would you prefer a magic carpet? Click below...

INJECT

and don't forget to cast.

That's a bad sign. The pegs were numbered in the order we used to write: from left to right, then down. Starting from peg4, this rule is not quite applicable. Two vertical pegs 5 and 6 are to the right of it, but their bottoms are not higher than the bottom of peg7 will be.

Peg7 poses a real problem. Without clear='left' would stick to the right side of peg6. With clear='left' it slipped under its bottom and floated the whole way to the left, staying at the same level as pegs 5 and 6. We've seen this behavior before.

Step 8

Did we take a wrong turn? How about counting down after 4, and only then to the right?

To try this method, I could make peg5 horizontal, gray and "cleared" left like peg7. Peg 6 would be like peg5, and peg7 like peg6.

Moving peg7 in front of peg5 is much easier to do, but harder to understand. Hope you don't need an injector for this.

INJECT

your.brd.insertBefore(line[7],line[5]);

Time for another explanation. Remember how the pegs stayed organized before we even numbered them? That's because they are lined up in the browser's mind. My spell, which runs playboxes on this page, told the browser to create the pegs one by one, and the browser remembered them in that order. Array of pegs on the board is really the line of pegs folded up. We labeled the pegs with numbers, but the browser did not care. We could just as well use any letters or words.

The spell insertBefore() shuffles the pegs in the browser's mind. The pegs are moving around with all their possessions - background, height, width, textContent, etc. So after the move the browser thinks that peg7 stands before peg5 and after peg4.

What's the difference? Well, before the move peg5 was sticking to the right side of peg4, aligning it's top with peg4's top. After the move peg5 is sticking to peg7 under the same rules. And this is not what we want.

Before going ahead, please hack the last spell to return peg7 to its birthplace. Where? Before peg8, of course. We have 9 pegs, numbered from 0 to 8. You only need to change one number. Peg 8 is not with us yet, but the browser remembers it.

Step 9

Walking through the Sidewalk ARRAY, we forced nine pegs into 3x3 order by making them bigger, so that only 3 of them could fit into one row. We can do it again, and that's where peg8 may come in handy. Or, rather, the other pegs could handy come into it. The spell for this is appendChild(). But first, let me remind you that you are supposed to be back at the point, to which the magic carpet spell from Step 7 brings us from scratch. Inject and cast it if you are lost.

Let's call peg8 and change it to suit our purpose. The size will be set to 400x400 pixels, the background color will be white... excuse me, but aren't you getting spellish yet?

INJECT
style[8].height='400px'; 
style[8].width='400px';
style[8].background='white';
style[8].border='2px solid black'
style[8].display='block';
style[8].clear='left';
style[8].borderRadius='0';

The last line of the spell erases everything inside peg8. At that moment, there was only number 8 in it.

INJECT
line[8].textContent='';

To move peg0 into peg8, please inject and cast this and never use the red spell again.

INJECT

line[8].appendChild(line[0]);

Let me translate. Dear peg number 8 in the line, please adopt peg number 0 in the line.

Step 10

I strongly recommend you to move the pegs one by one, changing 0 to 1, to 2, etc, and trying to understand how and why your layout is changing. But if you prefer not to do it, then OK, here is a magic broom, which casts adoption spell on every peg from 0 to 7.

INJECT
for (var n=0;n<8;++n) 
  line[8].appendChild(line[n]);

Now as all the eight pegs are captured, let's tighten the noose. Want a bet? Which misplaced peg will submit? Use this spell to find out.

INJECT
style[8].height='350px';
style[8].width='350px';

The first problem solved. Now try '280px'. You may change the height only.

Step 11

Failure to squeeze peg7 in place gave me a fresh idea. When we tried to put peg7 before peg5...

INJECT

...the gap between them became the sticking point for pegs 5 and 6. What if we cover this gap, putting peg 4 and 7 into another peg? We don't even need to break the natural order of the pegs for this.

Use the injector below and cast the spell to restore the natural order of the pegs (the number will be removed from peg8).

INJECT

Prepare peg8. It will emerge as a tiny black rectangle right under peg7.

INJECT

Ask peg8 to adopts peg4, then peg7. For every peg, click on the link, make sure the injection worked, and cast.

INJECT line[8].appendChild(line[4]);

INJECT line[8].appendChild(line[7]);

Finally, manipulate the browser's mind to make it think that peg8 with both it's "children" is in front of peg5 in the line.

INJECT your.brd.insertBefore(line[8],line[5]);

Step 12

We did not have to size peg8. Peg8 holds pegs 4 and 7 snugly, as long peg8's dimensions are set to 'auto' and float to 'left'. We could apply this technique to pegs 2 and 3, but we don't have any pegs left.

We can make more pegs, but let's try something else. Until this moment, we have been relying on the browser occasionally trying to trick it into doing what we want. Instead, we can just tell it what to do (and hope it will get it).

We can position a peg by setting its margins. Look how it works. The following spell will move peg3 down by 60 pixels.

INJECT style[3].marginTop='60px';

In this sidewalk, we are using the writing coordinate system. The positive directions are down and to the right. We need to shift peg3 to the left, so the horizontal margin must be negative.

APPEND style[3].marginLeft='-120px';

One more touch. This one must be obvious.

APPEND style[8].borderWidth='0px';

Step 13

Let's get rid of the white borders. A magic carpet first? Right here.

INJECT

The spell below zeros the borders and their corners's radii.

INJECT
for (var n=0;n<9;++n){
  style[n].borderWidth='0px';
  style[n].borderRadius='0px';
}

Oh, I forgot the margins.

APPEND
style[3].marginTop='60px';
style[3].marginLeft='-120px';

Much better.

Step 14

As I mentioned in the beginning of this part, CODEPEGS pegs are now border-boxes. This made this project considerably easier. The fundamental trouble with the box model was hiding in plain view for years, and years, and years, but only recently it has been upgraded.

Web creation is a business like no other. Something as simple as building a spinner easily turns into a research project, which may keep a developer busy for days.

If you froze the window scroll (which means, there is no main scrollbar along the right side of the browser's window), click below to unfreeze it.


STOP
Sidewalk SPINNER ends here.
Stop if you are scrolling down.
Click on the sign to unfreeze window scrolling.
Good bye.

We can build a whole spinner putting rectangles into squares. It's only necessary for the top right and the bottom left corners, but I made all four to elucidate the striking differences between the ours and the web's geometries. To begin with, the two top pegs are gray on red, and the two bottom pegs are red on gray. Before I started putting this layout together, I expected a chessboard kind of tessellation. There are other options, but none of them works. We can push a vertical paddle to the left or to the right, but we cannot push a horizontal paddle all the way down. Web browsers are text formatters to the core, the only thriving offspring of this all but bygone class of software. They can't do rotation properly.

Here is the spinner. To show how the parts are coming together, I left it slightly loose. The spell is on the left, and it's a different kind of spell. Even to display this text on the page, I had to rewrite it beyond recognition. Unbelievable, but true.

<style>
.sr,.sg {float:left;margin:2px;
  height:228px;width:228px;}
.vr,.vg,.hr,.hg {margin:4px;} 
.vr,.vg {height:221px;width:118px;}
.hr,.hg {height:118px;width:221px;}
.sr,.vr,.hr {background-color:red;}
.sg,.vg,.hg {background-color:gray;}
</style>
<div style='float:right;width:480px;'>
  <div class='sr'>
    <div class='vg'></div>
  </div>
  <div class='sr'>
    <div class='hg'></div>
  </div>
  <div class='sg'>
    <div class='hr'></div>
  </div>
  <div class='sg'>
    <div class='vr'></div>
  </div>
</div>

Not sure if it was useful, but the experience of building a spinner was different. Normally, they teach us a new word, show a new rule, and offer an oversimplified example: suppose you want to do this. I usually think, excuse me, I don't want to do what you wanted to do, I want to do something else. And often, I don't even understand what did you want to do.

Spinner provides a lucid abstract goal. Don't ask me why do I want to build it, and forget for a moment what did you want to build. Let's build this funny shape, just for the heck of it. That's how we stop collecting the recipes and start getting the meaning.

A whole lot of meaning, by the way, and I have barely scratched the surface. I could have built many more lessons around this shape, given the sheer amount of complications piled around container elements in CSS. The evolution of this technology is truly amazing. Who would believe that it started as an accessible way to format web-pages, and that in the beginning, even a total stranger like me could build a website to own.

Superficially, HTML and CSS still look like they were invented for programophobes. They grew to become like those complete idiot's books. A walk by a bookshelf proves that, of all readers, only dummies can rival complete idiots in erudition and diligence. To afford the modern web-design as a modest hobby, I need to live ten lives at the same time.

Web world is weird like quantum mechanics, except it's changing. Analogies derived from observations and depictions of the real world, will be defied. Expectations, based on what we learned before, can only deceive us.

Think floats and clears are strange? Get a new 3x3 board, make the pegs smaller (or return to the beginning of the Sidewalk ARRAY), load the margin setting spells from the end of the Sidewalk SPINNER, change 3 to 4 (the number of the central peg) and play with the small margin numbers making them negative and positive. You will quickly realize that the interactions of the repositioned peg4 with it's neighbors is not symmetrical, but there is a method in it.

Absolute and relative positioning in general is a very enabling knowledge. Yet I would not want to explain CSS positioning to my kids. They may forget how to find the bathroom.

In the wonderful world of web, few teachers are developing the laws of innature, and they make them wild. Millions of students are spending hundreds millions hour trying to figure out the rules, finding the ways to circumvent them and passing this sacred knowledge to the others through increasingly diluted and distorted messages. And it's not Minecraft. Everybody is getting paid for what they do.

Did I tell you I am not? That's why I am putting down this chapter without regret.

PART 5: LET'S LEARN COMPUTERS

They worth it.

Computers are blind mice

who run unnaturally fast.

The following playbox comes preloaded with a spell, and the board is colored up. Can you find the blue pegs?

If you could see the blue pegs, you could have spotted them at once. We take for granted our 3-color 2-dimensional stereoscopic vision. Computers, even if they have built-in cameras, can't see and have no idea of color. This causes numerous misunderstandings and frustrations.

The following spell demonstrates how a blind computer can canvass the board and find a given color. Please keep clicking on the board and reading the responses until you've seen enough.

The colors in CODEPEGS are numbered: red was 1, blue was 2, etc. The pegs on the board are numbered as follows:

(0,0) (0,1) (0,2) (1,0) (1,1) (1,2) (2.0) (2.1) (2.2)

For every pair of numbers, the browser retrieves the number of the color from my.c[] and checks if it's equal to 2.

Looking for a pencil on a desk, we don't break the desk top into squares. Instead, we direct our eyes to visually prominent areas. Often, we become distracted and fail to see what we are looking for. Computer's way to do it is profoundly unnatural, but it works.

Due to their simplicity, computers are very fast. The next spell looks for the orange pegs on a 32 × 32 board. You can run it repeatedly. After every run, it reports the time passed between the beginning and the end of the search repeated 1000 times. On my computer, a single search takes about 1 millisecond. Now, 1 millisecond is 1/1,000th of a second, and the board has 1024 pegs. Each pegs takes approximately 1 microsecond (1/1,000,000th of a second) to serve. By today's computer standards, it's slow.

The number of the times to search is found in code line 10. Please change it to see how fast your computer works. You may also compare different browsers.

Not sure if you were impressed. The question lingers: I see a fruit in the foliage, I grab it—why do I need all those squares?

Imagine it's an island in the ocean. The pirates marooned on the Treasure Island were very natural types, but they would not get back home even if the Hispaniola was their. They didn't know how to navigate. The squares on the map meant nothing to them.

By the way, the dismal quality of hand-made navigation tables was an important factor behind the first attempt to create a computer.

Running the 32x32 search again and again, we see the different values of time. This is because of time-sharing. Most people are familiar with time-sharing of vacation real estate properties. The idea could have been borrowed from computing, but anyway, both method emerged at approximately the same time, and they are similar.

In computing, the residents—the programs—have no other place to live. Every once in a while, the operating system hibernate the current resident program while it sleeps, moves it to the storage room, moves in another hibernated program and brings it to life. Then: today is April 29th. What? Yesterday it was September 16th! Am I still dreaming?

The number 1024 (210) is so-called computer thousand or kibi. Popularly, it's called kilo. The next big computer numbers are:

1024 × 1024 = 1,048,576: mebi or mega,
1,048,576 × 1024 = 1,073,741,824: gibi or giga,
1,073,741,824 × 1024 = 1,099,511,627,776: tebi or tera
Computers don't program themselves

We do!

The color searching exercises from the previous chapter might make somebody laugh. What's the point of producing the random squares and searching for them 1000 times? The board exists only in computer memory. The spell tells the browser which squares to color blue. Then it asks the very same browser to find the very same squares!

Indeed, why would a browser play against itself? It's so smart! It has the whole Internet to learn from. Browsers know all the passwords. They can impersonate any human. Practically every computer programs today is created by computers. Some people are already afraid that browsers can unite and conquer the world.

The boring reality is, browsers are information machines doing what they are told, even if we don't understand our own instructions. Browsers have no interests. You can promise your browser a new computer or a mate browser - it would not care. Unless programmed to do so, a program will never even try to look for a better way to achieve its goals simply because it has no goals.

Human babies are preprogrammed to make apparently erratic motions. They try out their 639 muscles and find out how to use them: eyes, hands, toys to watch, touch and move. Slowly, it starts making sense. Young children keep this gift of rapid experimentation. If engaged, they learn computer skills faster than any grownup can teach, but without a teacher such knowledge remains shallow.

Computers don't play. Given a new appendage, they don't start operating it at random. At best, they can look for a software that a human wrote.

Extensive programming may create some kind of computer vision. Researches are trying to teach computers to behave and act like us. Can some kind of free will crawl out of this attempts some day?

I am not offering a proof of impossibility, but If tomorrow you'll find that your computer has encrypted your files and wants a ransom, you will not assume that it's a sign of an emerging computer mind, or will you?

Computer characters

They make spells.

The digits like 1, 2, 3, 4 are no different from letters like A, B, C, Dand punctuation marks like \, ., ', ;. In computer coding, they all are characters. So-called whitespaces, like the one produced by the long bar, including but not limited to backspace, tabulation and newline, are characters too.

Counting all the human languages, dead and alive, the number of the standard computer characters today is huge. In CODEPEGS, I only tell the bare essentials for learning to code. Computer coders stick with 26 English/Latin letters and few others. Some of those characters are invisible, but we don't have to learn them. If a program asks us to press something like Ctrl+F5, we just do that.

The alphabet of computer English was defined by the available input-output devices. The first such devices were teleprinters (also remembered as teletypes, or TTYs). Imagine two electric typewriters connected wires, so that both printers can print the lines typed on the local or on the remote keyboard. Your TTY prints what you type, then it prints what your party types. Your party's TTY does the same. Plugging a TTY into a an appropriate interface, we can have a "conversation" with the computer.

Early teleprinters had only 32 keys: just enough to tell something important. To transmit numbers, they passed along a special character (attention, from now on my letters mean digits: I will send Q for 1, W for 2, E for 3, please type them out accordingly). The lower case letters were an unaffordable luxury.

Why I am telling this? Those 32-key teleprinters are still with us. Behind the shiny graphical interface, Windows 10 on my computer knows only one letter case. MyFile.txt is no different from myfile.txt.

The alphabet of the first computer languages had only capital letters. When low case letters were finally allowed, it took much time to realize that they are more frequent, and to switch to using only them. The core dictionary of JavaScript - so-called reserved words - is low case. The users, however, may do with their texts what they want.

Computer coders needed new characters, but they had to keep their code suitable for the existing terminals. Example: The letter x as a multiplication sign is confusing even for us humans, the Ancient Roman interpunct · is not on the standard keyboards, and dropping multiplication signs altogether is only acceptable between one-letter names. Hence, the sign of computer multiplication had become the asterisk *.

Another episode from the character soap opera. Struggling with multi-word names, the coders came to using the_underscore_ character to separate the words while keeping them together. An anecdote, true or not, has it that an innovative computer Xerox Alto was created with an electronic display and without the underscore key, so its programmers had to resort to camelCase. Such was the origin of now glamorous names like iPhone.

Colors as numbers

Colors are quantities, aren't they?

Our eye has 3 kinds of color sensors. They loosely cover so-called primary colors: red, blue and green. The majority of electronic devices producing or acquiring colors use three color sources or three color filters.

The method of representing colors in computer is called True Color. Sure enough, there are better (truer?) ways, but True color is currently the most common one.

In True Color, every primary color may change its brightness from 0 (no this color) to 255. Why 255? In the binary system this number looks like 111111112. It fills 8 bits or 1 byte. Long time ago, the bit became a unit of information because it can hold 1 character.

All in all, a color is 3 times 8 bits. The numbers 000000002, 000000002, 000000002 make black. The numbers 111111112, 111111112, 111111112 make white. The other colors are in between.

The following app teaches binary numbers and colors together. It has 3 color channels: From top to bottom, there are red, green, blue. The big digits are the binary positions (the bits). In the beginning, all the positions have 0. A tap or mouse click changes the value of a position from 0 to 1 or from 1 to 0.

Changing the big digits in a channel, we build a binary number, which sets up the brightness of the color. The small digits below show the decimal values of the binary positions and the total brightness.

0 0 0 0 0 0 0 0
0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 0
0 0 0 0 0 0 0 0
0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 0
0 0 0 0 0 0 0 0
0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 0

If a binary position has 1, the corresponding positional multiplier gets added to the total value. A 0 in a binary position adds 0. Any number (including a decimal number) is a sum of the powers of 2.

The total number of the colors represented by a 24-bit number is 16,777,216. If clicking on 20s, 21, 22, 23 and 24 does not change the color, your monitor is a poor color maker. Most of the modern flat panel screens are.

What made computer so weird?

But first, what they are.

In the beginning, computers were people who knew how to reckon, and they reckoned in style, using the newly learned positional decimal system. The binary system was known, but hardly ever used for computations. I know of only one application of it, which was proposed in cryptography.

The early numeral systems were positional and not necessarily decimal. They were forgotten. For many centuries, Europeans have been stuck with Roman numerals. This system was quite clumsy and unsuitable for computations. To add or subtract, people had to use an abacus or pay to an abacist.

The Hindu-Arabic decimal positional numbers came to Europe in 12th century through the Latin translations of the books of a Persian scientist al-Khwarizmi. His name was transliterated as Algoritmi, so the fashionable skill of doing computations in writing had become known as algorism. The modern word algorithm has the same origin. Algebra, by the way, was the first word of the name of one of the al-Khwarizmi's books.

The word computer casually emerged in 1613 in the book of an English poet Richard Brathwaite. Most likely, his computer was an algorist. Abaci by that time were outmoded. Everyone who learned algorism could compute.

Adoption of the decimal system took forever. In some countries, weights or measures remain non-decimal even today. The early computing devices were mechanical and decimal. Things like number wheels appeared to be indispensable. Hardly anybody has ever questioned their practicality.

In 1821, Charles Babbage, a British mathematician, wished to God that calculations were executed by steam. Instead of waiting for his wish to be granted, he started working in this direction and devised the first fully functional mechanical computer.

An electric battery was invented in 1800, but long before it has become available, people were musing over passing messages with static electricity. The mechanical computer of Charles Babbage died unbuilt and was forgotten. Electrical telegraph was hotly anticipated and desired.

Unlike mechanical parts, electricity has no color or shape. How to use it to transmit different letters? Several solutions were tried. One of them was to use many different levels of an electric current. By 1830, the binary telegraphy emerged. Some 50 years later it's poised to dominate the market.

In 1847, a British mathematician George Boole made logic binary using two values: true and false. Modern computers think boolean.

The first commercially successful calculator (mechanical, of course) appeared in 1851. It was not an answer to Babbage's wish. Human mistakes were not eliminated to say the least.

In 1900, another wily Brit named Bertram Russel kicked the bucket from under Boolean logic's feet, invoking an ancient paradox:

THIS IS FALSE

If it's false, it's true, etc. Whom can we trust?

In around the same year of 1900, David Hilbert, a preeminent German scholar, published the list of 23 unsolved mathematical problems. Apparently, he thought he was helping to find the solutions. Much to his disappointment, he also promoted the understanding that not every mathematical question can be answered.

Hilbert was a humanist. The last 20 years of his life were mired with a chronic avitaminosis, unexplainable and incurable back then. Yet his gravestone carries the words from his speech: "Wir müssen wissen, wir werden wissen" (we need to know, we will know). This was his response to the famous "ignoramus and ignorabimus" (we are ignorant, and will ever be") coined by electrophysiologist Emil du Bois-Reymond.

One of the Hilbert's problems was particularly unlucky. In 1928, he reformulated it to ask (in my layman's terms) if it's possible to decide that a question can be answered without answering it. Most certainly, Hilbert had in mind his pet idea of metamathematics. Yet, in a few years, his colleagues started finding the situations where such a decision wasn't possile. The first, in 1936, was the Hilbert's American friend and a former student Alonzo Church.

The close second in the race came another British mathematician Alan Turing. By the time of the publication, he became a postgraduate student of Alonzo Church. Like everybody else, Turing delivered a counterexample. He imagined a machine and proved that it was not able to tell if another such machine would fail or accomplish its job.

Alonzo Church called his invention lambda calculus. Who can love such stuff? Turing machine was understandable. This made it a teddy bear of computer science and industry.

A basic Turing machine is very easy to think about. Building one is much more challenging, but here is the link to the website of Mike Davey who did exactly this. Be sure to watch the video at the bottom of the page.

A Turing's computing machine was not just a device. It came bundled with a set of instructions. Change them, and the same imaginary hardware would become a different machine. Every Turing machine was specialized on solving certain problem.

Turing wrote: "We may now construct a machine to do the work of this computer" (see page 251 if you care). Computer for him was a human. By the way, his machine was binary. He defined two figures: 0 and 1. This allowed him to keep the explanations simple.

In his 1936 paper, Turing showed how, by putting instructions on the tape together with data, he could create a universal machine that could be able to act as any specialized one. 15 years before the first computer was built, Turing anticipated it. He only needed memory. Tape was OK for math - mathematicians keep saying that there is no time in math - but you've seen how practical it was.

Running a Turing machine by hand, let alone programming it, can teach anybody appreciate the mystery and power of rules and procedures. Please don't miss the chance, but if you are going to, remember one thing: no computer, including ourselves, could do more. Given enough time and tape, Turing machine could solve any problem the newest and most expensive computer can solve. Many historical computers were expensive and big, but less capable than a Turing machine. Technically speaking, they were not Turing complete. Remarkably, the Babbage's Analytical Engine was.

One hundred years after the Babbage's wish, computers were a theoretical possibility again. At that time, the binary system was firmly established in the industry of information transmitting.

The workhorses of the industry of information processing (think IBM) were tabulators, and tabulators were decimal. At first, they were used as counters (press the button to make the mechanical decimal number one bigger). Soon, they started counting holes on hand-punched cards (so the operator's activity was documented). Eventually, tabulators became electromechanical and, in due time, they were fitted with some electronic circuitry. They got keypunches with keyboards, and fast paper printers. They could sort data. The most advanced tabulators incorporated calculators and performed multiplication and division. Tabulators could punch results on cards. Those cards could be feed into the other machines in the data processing centers, forming some kind of networks.

Tabulator had been produced until approximately 1975. They even were called computers, but by today's standards this was a misnomer because tabulators were not Turing complete. A tabulator would not go back through the stack of punched cards, change something and restart from that point, and the cards were mostly for data.

An imaginary tape carrying instructions allowed Turing to do such tricks, but how did he come to this idea? The most likely source was the British Post Office. In 1927 they started printing telegrams on self-sticking paper tape.

It's tempting to assume that tabulators evolved into computers. Evidently, they did not. At some moment, however, IBM had won bragging rights on the first electronic calculator. The programmable binary electronic computers took the devices like punches, readers, printers, but obsoleted the primitive decimal "brains". Computers were dreamed up by several advanced thinkers, most importantly by Alan Turing and American John von Neumann, who once was a David Hilbert's assistant. Independently or not, Turing and von Neumann found the simplest way to create a universal problem-solving machine.

During WWII, Turing was working for an insanely secret governmental program creating and using the specialized computing machines to crack the German military codes and monitor their communications . He was not allowed to disclose this experience. His early article probably went unnoticed and did not affect the early computer designs. Turing completeness must have been obvious by that time. Turing and his work was not known to the public until 1970. In the US, he is mostly remembered as a homosexual who suffered from a judicial persecution.

At the peak of popularity of personal computers, all of what were based on so-called von Neumann's architecture, only the professionals remembered the name of its creator (not necessarily praising him). Von Neumann was one of the first users of the Harvard Mark I. He was seriously involved in Project Manhattan, but this did not prevent him from passing to computer designers the ideas circulating among the mathematicians. The first computers were built according to his revelations.

In 1946, Turing got a chance to build a computer, which could have become not only world's first, but the most sophisticated one: It was the Advanced Computing Engine or ACE. Turing withdrew from the project too soon because of the lack of appreciation and support. The others did not believe electronic machines were possible, and Turing could not tell them that he'd seen them working. Nonetheless, the first mass produced British computer descended from the Turing's prototype.

As computers were getting real, their creators were borrowing the existing parts and solutions. By that time, the industry of telecommunication had radio and automated telephone exchanges. The radically new technology born for radio was electronics. In the age of electromechanics, mechanical motions controlled electrical currents, and electrical currents controlled mechanical motions. As long as the mechanisms were there, machines remained slow and unreliable. In electronics, electricity controls electricity.

Few electromechanical computers were ever built. A large piece of the monumental ASCC (the Mark I) is still available to the public in Harvard University. IBM claims that the Mark I did almost everything Charles Babbage wished for (except it was not powered with steam), but only with the advent of electronics, computers became practical. However, the Mark I brought the aspirations of Charles Babbage back from the oblivion. The idea of a smart machine lived again.

By the Second World War, the engineers created binary electronic devices and understood how they could use them to implement Boolean logic. As electronics (in form of vacuum tubes) was replacing mechanical assemblies making information processing thousands times faster, a problem lingered: where to keep programs and data? Electronic memory was prohibitively expensive, but - except for wire jumpers and perforated paper - hardly anything else was available. Paper was hopelessly slow. Wires were fast, but computer could not reconnect them to alter the data or the program.

The solution came from radars, and it was called a delay line. Delay lines were created to hold electric signals for a short time and replay them. Sending the signal back into the line allowed to store the information for as long as the circuitry had electric power and to access the stored items virtually at random. Delay line memory was such an important solution that its inventor J. Presper Eckert entered computer business and pioneered computers in the US.

The first fully developed computer ever is believed to be the British EDSAC, or Electronic delay storage automatic calculator. The memory tanks (today's banks) and the processor registers were delay lines. Director of Cambridge University mathematical laboratory Maurice Wilkes, who built this marvel, once worked at a radar. EDSAC's performance was limited to 600 instructions per second.

The second team was working in University of Manchester and again, at the top were two former radar guys: Frederic C. Williams and Tom (not sure if he was ever called Thomas) Kilburn. They even scored an earlier success with their prototype called "Baby". The grown up machine was Manchester Mark I. Williams and Kilburn invented a different kind of main memory, which was truly random and could run faster than delay lines (their computer, however, was not faster than EDSAC).

Reading the description of EDSAC, I find it nostalgically similar to the microcomputers I've been using in 1980. The instruction set was much simpler, the processor was much slower and we had much more memory - nothing of this constitutes a real difference. EDSAC was minimalistic, but flexible. For example, it did not have hardware division. There were apps for this.

There was a teleprinter, but only for printing. To enter a decimal digit, they had a telephone dial. The large round cathode ray tubes (from radars, I assume) allowed to monitor the system. They were displaying green dots for 1s like the virtual pegboards here in CODEPEGS.

To ensure its survival, the machine, which we call computer today, was created to be simple and fast. It was binary and electronic, it had random access memory and it handled instructions and data in the same way. It was Turing complete. Subsequent designs had higher performance, they allowed to code more efficiently, they could run many programs at the same time and support many users - the list of innovations is too long, but none of them allowed to compute something what the others computers cannot.

IBM kept designing decimal computers until around 1960. The last trace of decimality in binary computers were so-called binary coded decimals or BCD. In mass market processors, they are no longer used.

The bits became the bricks of information. The binary system is the simplest. It's cheap, fast and good for everything. Importantly, computers are flexible and malleable bricks. The engineers quickly realized that they can program simple, fast and cheap processors instead of designing complex and expensive specialized devices.

Inexpensive electronic calculators were (and, probably, still are) highly specialized custom designs. A calculator in your computer or smartphone have nothing in common with them, but it works the same way because the universal central processor is programmed to do so.


Patent pending
© 2015 Georgiy Kuznetsov