# October 9 & 12

# More Objects

Today, I will borrow some code from Khan Academy on object-oriented programming. This online course is really well done. It uses a variant of p5.js and also a variant on function definition.

## Functions as values

This is a good place to describe the alternative syntax for function definition used by Khan Academy and others.

Recall that we define functions as follows:

```
function area() { // compute area of canvas
return width * height;
}
```

This gives the appearance that “area” is something special — a function — but at some level, “area” is just a global variable, like “width” or “height,” only its *value* is *a function*. It may seem odd that a function can be a value. What does that mean? If a function is a value, you should be able to assign it. You can!

var canvasArea = area;

Now, `canvasArea`

is another name for `area`

, and we can call it with `canvasArea()`

. Notice we did not write:

var canvasArea = area();

By putting the “()” after `area`

, we’re saying “call the `area`

function and use the return value (in this case, a number), so in this case, `canvasArea`

would be set to the area of the canvas, *not* the function that *computes* the area of the canvas.

## Anonymous Functions

The syntax used by Khan Academy (and many others) for function definition looks like this:

var area = function() { return width * height; }

In this expression, `function()`

— and notice the important parentheses — means “create a new function as follows.” This is an *expression* that returns a *function* (which is a value). It does not give the function a name, so it is an *anonymous* function. The `var area =`

part assigns the function value to a global variable, `area`

, which has the same effect as our familiar style of function definition: `function area() { ... }`

.

Note: When you write an anonymous function expression, you can also add parameters as you would expect, e.g. `function(x, y) { ... }`

.

## Syntactic Sugar

Languages often introduce special syntax to make things look pretty when no special syntax is needed. JavaScript does not really need the syntax we use for function definition. All you need as variable declarations and anonymous functions. The addition of a “prettier” form of function declaration is often called “syntactic sugar.” Another example might be “+=”. Instead of `a += 2;`

we can always write `a = a + 2`

, so “+=” does not add any new capability.

## More Objects

Here is some code based on the Khan Academy “Challenge: Flower Grower” example. Click to “grow” the flowers.

```
function Tulip(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
fill(255, 0, 0); // red
var y = this.y - this.height;
ellipse(this.x+5, y, 44, 44);
triangle(this.x-16, y, this.x+20, y, this.x-20, y - 31);
triangle(this.x-14, y, this.x+24, y, this.x+3, y - 39);
triangle(this.x+-4, y, this.x+26, y, this.x+29, y - 36);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Sunflower(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
stroke(0, 0, 0);
fill(255, 221, 0); // yellow
// var y =
ellipse(this.x-10, this.y-this.height, 20, 18);
ellipse(this.x+5, this.y-this.height-15, 20, 18);
ellipse(this.x+5, this.y-this.height+15, 20, 18);
ellipse(this.x+20, this.y-this.height, 20, 18);
fill(20, 20, 20); // dark center
ellipse(this.x+5, this.y-this.height, 20, 20);
};
this.growBy = function(amount) {
this.height += amount;
}
};
var tulip;
var sunflower;
function setup() {
createCanvas(400, 400);
tulip = new Tulip(38, 390, 150);
sunflower = new Sunflower(186, 390, 100);
}
function draw() {
background(207, 250, 255);
tulip.draw();
sunflower.draw();
};
function mousePressed() {
tulip.growBy(5);
sunflower.growBy(10);
}
```

### Using this

Note the use of `this`

, e.g. `this.y`

or `this.height`

to reference properties of the object inside functions `draw`

and `growBy`

.

### Common subexpressions

The Sunflower `draw`

function computes `this.y-this.heigth`

a total of 5 times! In Khan Academy’s version, Tulip’s `draw`

used the expression 10 times! Notice, in Tulip’s `draw`

function, I’ve defined a new variable, `y = this.y - this.height`

. Now, I can rewrite the code in terms of `y`

, saving a lot of typing and resulting in much nicer code.

Suggestion: do the same for Tulip. I’ve included `// var y =`

to suggest how and where to make this change.

### Methods vs. Functions

The functions `draw`

and `growBy`

are properties of flower objects, so we call them using “dot” notation, e.g. `tulip.draw()`

. A function associated with an object or class of objects is conventionally called a *method*. (You may also hear the term *member function*.)

Why methods? Why not just write a function? Yes, we could define `tulipDraw(tulip)`

and `sunflowerDraw(sunflower)`

and accomplish the same thing. The advantage of using methods is that with methods we can write:`flower.draw()`

where `flower`

is a variable containing either a tulip or a sunflower. The alternative is to figure out which function to call:

```
if (isTulip(flower)) {
tulipDraw(flower);
} else if (isSunflower(flower)) {
sunflowerDraw(flower);
}
```

## Creating a New Class of Flowers

Here is a new version with a new flower type, Violet.

```
function Tulip(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
fill(255, 0, 0); // red
var y = this.y - this.height;
ellipse(this.x+5, y, 44, 44);
triangle(this.x-16, y, this.x+20, y, this.x-20, y - 31);
triangle(this.x-14, y, this.x+24, y, this.x+3, y - 39);
triangle(this.x+-4, y, this.x+26, y, this.x+29, y - 36);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Sunflower(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
stroke(0, 0, 0);
fill(255, 221, 0); // yellow
// var y =
ellipse(this.x-10, this.y-this.height, 20, 18);
ellipse(this.x+5, this.y-this.height-15, 20, 18);
ellipse(this.x+5, this.y-this.height+15, 20, 18);
ellipse(this.x+20, this.y-this.height, 20, 18);
fill(20, 20, 20); // dark center
ellipse(this.x+5, this.y-this.height, 20, 20);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Violet(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke()
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals -- rotate an ellipse
stroke(0, 0, 0);
fill(73, 92, 160);
push();
translate(this.x + 5, this.y - this.height);
for (var i = 0; i < 5; i++) {
ellipse(0, 15, 20, 30);
rotate(radians(360/5));
}
fill(255, 221, 0); // yellow
ellipse(0, 0, 15, 15);
pop();
};
this.growBy = function(amount) {
this.height += amount;
}
};
var tulip;
var sunflower;
var violet;
function setup() {
createCanvas(400, 400);
tulip = new Tulip(38, 390, 150);
sunflower = new Sunflower(186, 390, 100);
violet = new Violet(250, 390, 125);
}
function draw() {
background(207, 250, 255);
tulip.draw();
sunflower.draw();
violet.draw();
};
function mousePressed() {
tulip.growBy(5);
sunflower.growBy(10);
violet.growBy(8);
}
```

In Violet’s draw function, I tried to improve on the style of the other draw methods. The other methods drew a lot of detail at `this.x`

and `this.y - this.height`

. Thus the flower was “translated” in x and y by adding these x and y offsets. I thought it would be nicer to just use `translate`

to make the origin (0, 0) be the center of the flower. Then, since flower petals have radial symmetry, let’s use `rotate`

inside a loop to draw each petal. (Originally, I drew 4 petals, and it was quite gratifying to simply change the rotation angle and the loop count in order to draw 5 petals, which look much nicer.)

By now, you should be able to make another object, say a house or a dog, with position, size, and other properties and a draw method.

## An Array of Flowers

This is getting a little tedious, with an explicit draw call to each flower on the canvas. Why don’t we just put everything to draw in an array and iterate through the array, drawing each object there?

Think about what you would change in the previous code example to use an array of flowers. See if your imagined changes match the code below.

```
function Tulip(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
fill(255, 0, 0); // red
var y = this.y - this.height;
ellipse(this.x+5, y, 44, 44);
triangle(this.x-16, y, this.x+20, y, this.x-20, y - 31);
triangle(this.x-14, y, this.x+24, y, this.x+3, y - 39);
triangle(this.x+-4, y, this.x+26, y, this.x+29, y - 36);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Sunflower(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
stroke(0, 0, 0);
fill(255, 221, 0); // yellow
// var y =
ellipse(this.x-10, this.y-this.height, 20, 18);
ellipse(this.x+5, this.y-this.height-15, 20, 18);
ellipse(this.x+5, this.y-this.height+15, 20, 18);
ellipse(this.x+20, this.y-this.height, 20, 18);
fill(20, 20, 20); // dark center
ellipse(this.x+5, this.y-this.height, 20, 20);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Violet(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke()
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals -- rotate an ellipse
stroke(0, 0, 0);
fill(73, 92, 160);
push();
translate(this.x + 5, this.y - this.height);
for (var i = 0; i < 5; i++) {
ellipse(0, 15, 20, 30);
rotate(radians(360/5));
}
// var y =
fill(255, 221, 0); // yellow
ellipse(0, 0, 15, 15);
pop();
};
this.growBy = function(amount) {
this.height += amount;
}
};
var tulip;
var sunflower;
var violet;
var flowers = []; // an empty array
function setup() {
createCanvas(400, 400);
flowers.push(new Tulip(38, 390, 150));
flowers.push(new Sunflower(186, 390, 100));
flowers.push(new Violet(250, 390, 125));
}
function draw() {
background(207, 250, 255);
for (var i = 0; i < flowers.length; i++) {
flowers[i].draw();
}
};
function mousePressed() {
for (var i = 0; i < flowers.length; i++) {
flowers[i].growBy(5);
}
}
```

What changed? I made a `flowers`

array and initialized it to an empty array `[]`

. I used `flowers.push()`

to insert new flowers at the end of the array. Then, I wrote a for loop to call the `draw`

method on every element of the array and another for loop to call `growBy`

in `mousePressed`

. (I did *not* implement a different growth amount for each flower.)

Challenge: How would you give each flower a different amount to grow by when the mouse is pressed?

## Many Flowers — Random Acts of Violets

In this example, I removed the initialization that creates 3 flowers, and I add code to create a new random flower each time a key is pressed.

Think about how you would do this before reading the code.

```
function Tulip(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
fill(255, 0, 0); // red
var y = this.y - this.height;
ellipse(this.x+5, y, 44, 44);
triangle(this.x-16, y, this.x+20, y, this.x-20, y - 31);
triangle(this.x-14, y, this.x+24, y, this.x+3, y - 39);
triangle(this.x+-4, y, this.x+26, y, this.x+29, y - 36);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Sunflower(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke();
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals
stroke(0, 0, 0);
fill(255, 221, 0); // yellow
// var y =
ellipse(this.x-10, this.y-this.height, 20, 18);
ellipse(this.x+5, this.y-this.height-15, 20, 18);
ellipse(this.x+5, this.y-this.height+15, 20, 18);
ellipse(this.x+20, this.y-this.height, 20, 18);
fill(20, 20, 20); // dark center
ellipse(this.x+5, this.y-this.height, 20, 20);
};
this.growBy = function(amount) {
this.height += amount;
}
};
function Violet(x, y, height) {
this.x = x;
this.y = y;
this.height = height;
this.draw = function() {
noStroke()
fill(16, 122, 12);
rect(this.x, this.y, 10, -this.height);
// petals -- rotate an ellipse
stroke(0, 0, 0);
fill(73, 92, 160);
push();
translate(this.x + 5, this.y - this.height);
for (var i = 0; i < 5; i++) {
ellipse(0, 15, 20, 30);
rotate(radians(360/5));
}
// var y =
fill(255, 221, 0); // yellow
ellipse(0, 0, 15, 15);
pop();
};
this.growBy = function(amount) {
this.height += amount;
}
};
var tulip;
var sunflower;
var violet;
var flowers = []; // an empty array
function setup() {
createCanvas(400, 400);
// flowers.push(new Tulip(38, 390, 150));
// flowers.push(new Sunflower(186, 390, 100));
// flowers.push(new Violet(250, 390, 125));
}
function draw() {
background(207, 250, 255);
noStroke();
fill(0);
text("Press key for acts of random violets.", 10, 20);
for (var i = 0; i < flowers.length; i++) {
flowers[i].draw();
}
};
function mousePressed() {
for (var i = 0; i < flowers.length; i++) {
flowers[i].growBy(5);
}
}
function keyPressed() {
// pick a random flower maker
var AllFlowers = [Tulip, Sunflower, Violet];
var index = floor(random(AllFlowers.length));
var Flower = AllFlowers[index];
flowers.push(new Flower(random(width), height - random(100), 90 + random(50)));
}
```

### Choosing a Random Element

In `keyPressed`

, we choose a flower to create. There are many ways to do this. I chose a method based on a p5.js example. Here, the choices are in an array, so we make an array with the choices:

```
var AllFlowers = [Tulip, Sunflower, Violet];
```

Notice that the choices are all *functions*!

Next we pick a random number between 0 and the length of the array. The number returned by `random`

is a floating point (fractional) number, but we need an integer to serve as an array index, so we use the `floor`

function, which rounds down to the nearest integer. (Don’t round to the nearest integer or round up because the result could be AllFlowers.length, which is greater than the last valid index. Recall than the valid index values go from 0 through length-1.)

```
var index = floor(random(AllFlowers.length));
```

Finally, we get the random flower function from the array:

```
var Flower = AllFlowers[index];
```

Even though this is truly a variable and the value of the variable is randomly determined, we know it is a function, and we can call it using `new Flower(...)`

to make a new flower. The new flower is immediately pushed onto the end of the `flowers`

array:

```
flowers.push(new Flower(random(width), height - random(100), 90 + random(50)));
```

Challenge: Modify the code to remove flowers one-by-one. How would you remove the oldest flower? How would you remove the youngest flower?

# Infrequent Events

Here’s an interesting technique for making things happen infrequently and randomly. The condition choose a random number from 0 to 1. If the number is less than 0.01, the “unusual thing” happens (here, we just draw an ellipse). The probability is 0.01. You can of course use a larger number to make the “unusual thing” more frequent, or a smaller number to make the thing less frequent.

```
function setup() {
createCanvas(100, 100);
frameRate(10);
}
function draw() {
background(200);
if (random(1) < 0.01) {
fill(250, 250, 0);
ellipse(50, 50, 40, 40);
}
}
```

# October 12

# Making Choices with Weights

Let’s extend the previous example. Now the challenge is this: Choose a flower according to a set of probabilities. These are sometimes called weights, as in “give more weight to some choices.” To make a selection with weighted probability, consider the following picture (credit: Eli Bendersky — eli.thegreenspace.net):

Here, w0 through w5 represent weights. First, we arrange intervals of size w0 through w5 along a line. Next, we pick a *random* location along the line. It should be clear that the chances of picking any particular interval is proportional to the size of the interval. Thus, we have weighted selection!

Now, what should the algorithm be? First, we pick a random number from 0 to 100 (let’s assume the weights are percents and add up to 100). Now, what interval does that number fall into? If it is less than w0, it falls into the first interval. If not, but it is less than w0 + w1, it falls into the second interval. Generalizing this to more intervals, we’ll just keep a running sum of interval sizes from w0 to w*n* (for each value of *n*). When the sum exceeds our random number, we’ve found our interval. Here’s a new version in which I’ve compressed all the code except for the Flower selection code. (I do not recommend this for any JavaScript, but here I want to direct your attention to changes, and you can find the rest nicely formatted above.) This version also prints the number of each type of flower and the percentage so you can see that the weighted selection really picks different numbers of each flower.

```
function Tulip(x,y,height){this.x=x;this.y=y;this.height=height;
this.draw=function(){noStroke();fill(16,122,12);rect(this.x,this.y,
10,-this.height);fill(255,0,0);var y=this.y-this.height;ellipse(
this.x+5,y,44,44);triangle(this.x-16,y,this.x+20,y,this.x-20,y-31);
triangle(this.x-14,y,this.x+24,y,this.x+3,y-39);triangle(this.x+-4,
y,this.x+26,y,this.x+29,y-36);};this.growBy=function(amount){
this.height+=amount;}};
function Sunflower(x,y,height){this.x=x;this.y=y;this.height=
height;this.draw=function(){noStroke();fill(16,122,12);rect(this.x,
this.y,10,-this.height);stroke(0,0,0);fill(255,221,0);ellipse(
this.x-10,this.y-this.height,20,18);ellipse(this.x+5,this.y-
this.height-15,20,18);ellipse(this.x+5,this.y-this.height+15,20,18);
ellipse(this.x+20,this.y-this.height,20,18);fill(20,20,20);ellipse(
this.x+5,this.y-this.height,20,20);};this.growBy=function(amount){
this.height+=amount;}};
function Violet(x,y,height){this.x=x;this.y=y;this.height=height;
this.draw=function(){noStroke();fill(16,122,12);rect(this.x,this.y,
10,-this.height);stroke(0,0,0);fill(73,92,160);push();translate(
this.x+5,this.y-this.height);for(var i=0;i<5;i++){ellipse(0,15,
20,30);rotate(radians(360/5));}fill(255,221,0);ellipse(0,0,15,15);
pop();};this.growBy=function(amount){this.height+=amount;}};
var tulip;var sunflower;var violet;var flowers=[];
function setup(){createCanvas(400,400);frameRate(10);}
function draw(){background(207,250,255);noStroke();fill(0);
textSize(12);text(
"Press key for acts of random violets.",10,20);for(var i=0;i<
flowers.length;i++){flowers[i].draw();}
noStroke();
textSize(20);
fill(0);
var sum = 0;
for (var i = 0; i < counts.length; i++) {
text(counts[i], 10, 45 + 25 * i);
sum = sum + counts[i];
}
for (var i = 0; i < counts.length; i++) {
text((counts[i] * 100 / sum).toFixed(2) + "%", 50, 45 + 25 * i);
}
};
function mousePressed(){for(var i=0;i<flowers.length;i++){
flowers[i].growBy(5);}}
var counts = [0, 0, 0];
function keyPressed() {
// pick a random flower maker
var AllFlowers = [Tulip, Sunflower, Violet];
// We want to pick 10% Tulip, 20% Sunflower, 70% Violet
var weights = [10, 20, 70]; // weights in percent
// We'll pick a number from 0 to 100. If the number is in the range
// 0-10, pick Tulip, if 10-30, pick Sunflower, if 30-100, pick Violet
var percent = floor(random(100));
var threshold = 0;
var Flower = Violet; // default value in case percents don't add to 100
for (var i = 0; i < weights.length; i++) {
threshold += weights[i];
if (percent < threshold) {
Flower = AllFlowers[i];
counts[i]++;
break;
}
}
flowers.push(new Flower(random(width), height - random(100), 90 + random(50)));
}
```

In the code, `threshold`

keeps the running total of `weights[i]`

.

## The break Statement

**Important:** When the interval (flower) is found, we need to stop the loop. Once we find that the random number (`percent`

) is less than the running sum (`threshold`

), then of course the condition will hold for the next iteration when `threshold`

is even bigger, and the next iteration after that, etc. So the problem is we have to “break” out of the loop.

There are several ways to do that:

- In this example, we use the
`break`

command. The`break`

command*exits the innermost loop*, resuming execution at the next statement after the loop, which is the`flowers.push(...)`

statement. - Alternatively, we could perform the
`flowers.push(...)`

immediately inside the`if`

statement (in place of`break`

). Then, we could simply exit the entire function using a`return;`

statement. (There is no need to return a value from`keyPressed`

, so it is legal to write`return;`

rather than returning a value, such as`return true;`

). - Another approach will be shown below: Use a
`while`

loop.

## The continue Statement

Sometimes, you want to skip the rest of the body of a loop and *resume* the loop at its next iteration. The `continue`

statement does this. Every blue moon, `continue`

is very handy and can make code more readable than bracketing the rest of the loop body with an `if`

. You can read about `continue`

, and it’s good to know about, but I don’t have a compelling example, so we will not dwell on this now.

# While Loops

A `while`

loop is actually simpler than `for`

loops. We introduced looping with `for`

loops because `for`

loops are best for looping a certain number of times, and there’s a fairly standard form to loop 10 times or loop N times. The `while`

loop is used to loop until some condition becomes true. We’ll use a `while`

loop to iterate until `threshold`

is greater than `percent`

— a nice and direct expression of our random weighted selection algorithm.

```
function Tulip(x,y,height){this.x=x;this.y=y;this.height=height;
this.draw=function(){noStroke();fill(16,122,12);rect(this.x,this.y,
10,-this.height);fill(255,0,0);var y=this.y-this.height;ellipse(
this.x+5,y,44,44);triangle(this.x-16,y,this.x+20,y,this.x-20,y-31);
triangle(this.x-14,y,this.x+24,y,this.x+3,y-39);triangle(this.x+-4,
y,this.x+26,y,this.x+29,y-36);};this.growBy=function(amount){
this.height+=amount;}};
function Sunflower(x,y,height){this.x=x;this.y=y;this.height=
height;this.draw=function(){noStroke();fill(16,122,12);rect(this.x,
this.y,10,-this.height);stroke(0,0,0);fill(255,221,0);ellipse(
this.x-10,this.y-this.height,20,18);ellipse(this.x+5,this.y-
this.height-15,20,18);ellipse(this.x+5,this.y-this.height+15,20,18);
ellipse(this.x+20,this.y-this.height,20,18);fill(20,20,20);ellipse(
this.x+5,this.y-this.height,20,20);};this.growBy=function(amount){
this.height+=amount;}};
function Violet(x,y,height){this.x=x;this.y=y;this.height=height;
this.draw=function(){noStroke();fill(16,122,12);rect(this.x,this.y,
10,-this.height);stroke(0,0,0);fill(73,92,160);push();translate(
this.x+5,this.y-this.height);for(var i=0;i<5;i++){ellipse(0,15,
20,30);rotate(radians(360/5));}fill(255,221,0);ellipse(0,0,15,15);
pop();};this.growBy=function(amount){this.height+=amount;}};
var tulip;var sunflower;var violet;var flowers=[];
function setup(){createCanvas(400,400);frameRate(10);}
function draw(){background(207,250,255);noStroke();fill(0);
textSize(12);text(
"Press key for acts of random violets.",10,20);for(var i=0;i<
flowers.length;i++){flowers[i].draw();}
noStroke();
textSize(20);
fill(0);
var sum = 0;
for (var i = 0; i < counts.length; i++) {
text(counts[i], 10, 45 + 25 * i);
sum = sum + counts[i];
}
for (var i = 0; i < counts.length; i++) {
text((counts[i] * 100 / sum).toFixed(2) + "%", 50, 45 + 25 * i);
}
};
function mousePressed(){for(var i=0;i<flowers.length;i++){
flowers[i].growBy(5);}}
var counts = [0, 0, 0];
function keyPressed() {
// pick a random flower maker
var AllFlowers = [Tulip, Sunflower, Violet];
// We want to pick 10% Tulip, 20% Sunflower, 70% Violet
var weights = [10, 20, 70]; // weights in percent
// We'll pick a number from 0 to 100. If the number is in the range
// 0-10, pick Tulip, if 10-30, pick Sunflower, if 30-100, pick Violet
var percent = floor(random(100));
var index = 0;
var threshold = weights[index];
while (percent >= threshold) {
index = index + 1;
threshold += weights[index];
}
var Flower = AllFlowers[index];
counts[index]++;
flowers.push(new Flower(random(width), height - random(100), 90 + random(50)));
}
```

With a `while`

loop, there is no “initialization” part as in `for`

loops, so you must be careful to set up variables before the `while`

. We initialize `index`

to zero, then initialize `threshold`

to `weights[index]`

. That way, if `percent`

is less than `threshold`

the `while`

loop body will not execute even once, and we will continue with `index = 0`

.

It’s usually a good idea to consider what happens if the `while`

loop executes *zero* times and use this to your advantage.

Once the “zero” case is handled, fill in the loop body to consider each succeeding case. For weighted selection, we move to the next case by incrementing `index`

to advance to the next weight, and adding `weights[index]`

to `threshold`

to get ready for the next comparison.

When a `for`

loop exits, we usually do not use the loop variable(s). When a `while`

loop exits, we usually *need* the variables updated inside the `while`

loop body. Note that in this case the whole purpose of the `while`

loop is to determine the final value of `index`

, which is used *after* the loop in the expressions `AllFlowers[index]`

and `counts[index]++`

.

# splice

See this online tutorial to learn about splice.

# Converting a Program into an Object

This example is intended to give some perspective and insights into objects. When we started programming, we declared global variables and operated on them with functions. Let’s make a little program in that style.

```
var ballX = 50;
var ballY = 50;
function setup() {
createCanvas(200,200);frameRate(10);
frameRate(10);
}
function drawBall() {
ballX += random(-2, 2);
ballY += random(-2, 2);
fill(0, 222, 0);
ellipse(ballX, ballY, 50, 50);
}
function draw() {
background(255,250,180);
drawBall();
};
```

This “works” but as you add more things to your program, it gets cluttered with unrelated global variables. Objects let us put essentially all the action here into one place:

```
var ball;
function Ball() {
this.ballX = 50;
this.ballY = 50;
this.draw = function() {
this.ballX += random(-2, 2);
this.ballY += random(-2, 2);
fill(0, 222, 0);
ellipse(this.ballX, this.ballY, 50, 50);
}
}
function setup() {
createCanvas(200,200);frameRate(10);
frameRate(10);
ball = new Ball();
}
function draw() {
background(255,250,180);
ball.draw();
};
```

Notice that almost the whole of the previous program is “encapsulated” into the Ball object: it contains the variables ballX and ballY, and the draw function. The only global now is the ball object. Things are more organized. We can make a “face” with two balls as eyes:

```
var left, right;
function Ball() {
this.ballX = 50;
this.ballY = 50;
this.draw = function() {
this.ballX += random(-2, 2);
this.ballY += random(-2, 2);
fill(0, 222, 0);
ellipse(this.ballX, this.ballY, 50, 50);
}
}
function setup() {
createCanvas(200,200);frameRate(10);
frameRate(10);
left = new Ball();
right = new Ball();
right.ballX = 150;
}
function draw() {
background(255,250,180);
fill(100);
ellipse(100, 80, 200, 200);
left.draw();
right.draw();
};
```

Notice that with the object-oriented version of Ball, we do not have to duplicate lots of code to make two balls, and we do not clutter the code with many new global variables. In fact, if wanted to, we could make a Face object and put the “eye” Balls into Face properties — there’s no need to have global variables to represent the eyes.

Challenge: Clean up this code, making a Face object that creates Ball objects for two “eyes”. The Face draw method should call the draw method of each “eye.” If you do not understand how, give it a shot and post for help on Piazza.