Lesson 16: If Statements & Counters

Due by the beginning of class on Friday, Mar. 5

In Lesson 12, you looked at several applications that called for summing up values. By initializing a variable to zero and then repeatedly updating it to add new values, you could keep track of a running total. With the addition of if statements, it now becomes possible to consider related applications which involve counting. For example, suppose you wanted to roll a pair of dice 1000 times and keep track of the number of times a 7 was obtained. Or, suppose you wanted to flip two coins 100 times and keep track of how many times the flips were identical. This lesson will consider several such applications that involve counting.


Consider the task of rolling a pair of dice and keeping track of the number of 7's. A naive approach might be to write a for loop which repeatedly simulated the dice roll and displayed the result. You could then sift through the output and count the number of 7's that were obtained. For example,

for (rep = 1; rep <= 1000; rep++) { roll = diceRoll(6); document.write("roll #" + rep + ": " + roll + "<BR>"); } While this approach might work well if the number of dice rolls was small, say 10 or 20, it does not scale well. The above for loop will display 1000 lines of output, each line corresponding to a roll of the dice. Sifting through screen after screen of output and counting 7's would be extremely laborious and error prone. A slight improvement over this solution would be to add an if statement inside the for loop, causing the message to be displayed only if a 7 was rolled. for (rep = 1; rep <= 1000; rep++) { roll = diceRoll(6); if (roll == 7) { document.write("roll #" + rep + ": " + roll + "<BR>"); } } The if statement inside the loop compares the value obtained for each roll of the dice. If that value is a 7, then the message is displayed (otherwise, no message is displayed). In order to count the number of 7's then, you need only count the number of lines of output. This can still be a daunting task, however. For example, one execution of the above code produced 167 line of output, corresponding to 167 rolls of 7. Counting the number of lines is still a lot of work on your part.

A better solution to this problem is to have the code itself keep track of the number of 7's, and then display that result at the end. What you need, then, is a variable to keep the running count. It should be initialized to 0 before starting, and then incremented every time that a 7 is rolled. The following code uses a variable named count to do precisely this:

count = 0; for (rep = 1; rep <= 1000; rep++) { roll = diceRoll(6); if (roll == 7) { count++; // uses increment operator (see below) } } document.write("I got " + count + " 7's<BR>"); Inside the if statement is the single statement count++. The ++ that appears after the variable count is the increment operator, which takes a variable and adds one to its current value. Thus, the statement count++ is equivalent to the assignment count = count + 1. Incrementing a variable is something that is done frequently in JavaScript (as in for loops), and so this special operator is defined to make this task easier.

When a variable is used to keep track of the number of times an event occurs, we call that variable a counter. A counter must be initialized to 0 before counting can begin, and then that variable should be incremented every time the desired event occurs. In the above code, the desired event was a roll of 7, so the counter variable count is incremented each time that happens.

You may notice that the use of the variable count is similar to the use of sum variables as introduced in Lesson 12. Indeed, both uses involve initializing a variable to 0, and then repeatedly updating its value. But while a sum variable can have any value added to it, a counter can only be incremented (have 1 added to it).

Exercise 1:     Cut-and-paste the code for counting the number of 7's into the interpreter and execute it. Then modify the code so that it counts the number of 2's, then 3's and so on up through 12's. Report the counts that you get for each dice total.

Are the counts symmetric? That is, are there roughly the same number of 2's as 12's? 3's as 11's? etc. Should they be?

Do the counts add up to 1000? Should they? Explain.

Exercise 2:     Consider the following JavaScript code, which defines a function for simulating coin flips and then calls that function repeatedly, keeping track of the number of heads. function coinFlip() // Given : none // Returns: either "heads" or "tails" (with equal prob.) { return randomItem(["heads", "tails"]); } //////////////////////////////////////////////////////////// numFlips = 100; headCount = 0; for (f = 1; f <= numFlips; f++) { flip = coinFlip(); if (flip == "heads") { headCount++; } } document.write("The number of heads was: " + headCount + " (" + headCount*100/numFlips + "%)<BR>"); Cut-and-paste this code into the interpreter and execute it 5 times. List the results? Are they close to 50% as you would expect? How consistent are they?

Next, change the number of repetitions from 100 to 1000, and then execute the modified code 5 times. Are the results more consistent now? Should they be? Explain.

Exercise 3:     Suppose that the coin you are flipping is not fair, but is instead weighted so that "heads" is twice as likely as "tails". Modify the coinFlip function so that it simulates such a weighted coin, and re-execute the code from the previous exercise. You should end up with "heads" roughly 2/3 of the time.

Hint: since you want the coinFlip function to return "heads" 2/3 of the time and "tails" 1/3 of the time, consider modifying the argument to randomItem so that it has three items in the list instead of two.

Exercise 4:     When you flip a fair coin, there is a 50% chance of obtaining "heads". If you flip two fair coins, there is also a 50% chance of obtaining identical flips, e.g., "heads heads" or "tails tails". (There are only four possible flip combinations. the other two being "heads tails" and "tails heads".) Now consider the weighted coin from the previous exercise, which is likely to come up "heads" 2/3 of the time. Try to predict the likelihood of flipping two of these weighted coins and obtaining identical flips? Would it be more or less than 50%? By how much?

Once you have made your prediction, write JavaScript code which simulates the flipping of the coins and increments a counter every time the flips are identical. Your code should display the number of identical flips at the end. Execute your code several times to verify your prediction, and report the results.

Note: your code will have a similar structure to the code from the previous exercise, so use that code as a starting place.

ESP Revisited

In Lab 2, you wrote JavaScript code for testing whether the user has ESP. Your code generated a random integer between 1 and 3, and prompted the user to try and guess the number. A message was then displayed telling them whether they guessed correctly or not. In a later lesson, you updated this code to make use of the randomInt function that is defined in random.js. For example, compPick = randomInt(1, 3); userGuess = parseFloat( prompt("Pick a number between 1 and 3:", "") ); document.write("My number was " + compPick + ". You guessed " + userGuess + ".<BR>"); In order to test someone's ESP abilities, you must execute this code repeatedly and keep track of the number of times that they guessed correctly. If they were correct more than 1/3 of the time, then you can conclude that they have ESP (or were just lucky).

Now that you know about for loops, if statements, and counters, it is finally possible to automate this entire process.

Exercise 5:     Modify the ESP code to do the following: For example, the output of your code might look like the following: My number was 3. You guessed 2. My number was 2. You guessed 1. My number was 3. You guessed 3. My number was 1. You guessed 1. My number was 1. You guessed 2. My number was 3. You guessed 3. My number was 2. You guessed 1. My number was 2. You guessed 1. My number was 1. You guessed 2. My number was 3. You guessed 3. You got 4 out of 10 correct (40%). Maybe you do have ESP!

Lesson Summary

Solutions to odd numbered exercises (posted late afternoon of due date).