Lab 5: I'm Thinking of a Number

Sun Nov 8 09:37:56 EST 2009

This lab is meant to help you learn the rudiments of the Javascript programming language and understand something of how web pages use Javascript well enough to write a basic Javascript program that implements a simple game. You will also begin to develop some appreciation of why programming is not entirely trivial. It really does require orderly thinking and meticulous attention to detail.

Please read these instructions before beginning the lab.
Please follow the instructions about program format, variable names, etc.
Please use the template in Part 3.
Please pay attention to syntax and grammar and language constructs.
Follow the highlighted hints. Things will work better if you do, and you may even find that programming is kind of fun, especially when your program works.

You can do this lab anywhere, but you will likely find that the lab assistants offer valuable advice not obtainable elsewhere.

Part 1: Introduction
Part 2: The Javascript Language
Part 3: Writing your own Javascript Program
Part 4: Finishing up

Part 1: Introduction

Programming languages provide a way to express computer algorithms in a form that is convenient for humans yet easily translated into a computer's machine language: languages are the way that we tell computers how to perform a task.

In class, we have studied the very low-level instructions that the computer itself understands (for example, the Toy), and talked about a variety of programming languages, much easier for people to use, that are translated into machine instructions by programs like compilers and assemblers. There are many such languages, each with its own good and bad points, and often with noisy adherents and detractors.

Javascript, the topic of this lab and the next, is one of the most widely encountered languages, largely because it's available as part of every Web browser, and probably the majority of web pages include Javascript code. You too can write Javascript programs that will be run by whoever views your web page. We don't expect you to become a full-fledged Javascript programmer, but you will do enough in this lab and the next to get some understanding of what programs look like and what is involved in taking an algorithm and turning it into a program that implements the algorithm.

You'll also be able to better understand the Javascript pages that you encounter when you browse, and if you like, you'll be able to adapt and modify them for your own pages too.

There is an enormous amount of Javascript information on the Web, and thousands of books. You might start with this list of tutorials, or Google for "javascript tutorial".

Javascript has three major components:

In this lab, we're going to concentrate on programming, not on making the web page do something fancy. This will mean using variables, arithmetic, loops and decisions, and functions, while doing only minimal interaction with the browser, just enough to get data from a user and to display results. The focus is on figuring out what the pieces are and how to combine them into logic that does a computational task.

Although a programming language provides a way for you to tell a computer what to do, you have to spell out the steps in sometimes excruciating detail (which is one thing that makes programming a challenge). To do this, you have at your disposal statements for:

Programming languages provide a number of piece-parts that you can use to help create a program quickly; in fact, you couldn't do much without some of these, and it would be very time-consuming to create others from scratch. In effect, these component are like prefabricated components for houses -- windows, doors, kitchen cupboards -- that can be used even by comparatively unskilled users to create polished products.

Some of the components are basic computational units: functions for mathematical operations (computing a square root or generating a random number, for example), or processing strings of characters (like finding or replacing a word within a sentence, or converting between upper and lower case).

Other building blocks let you manipulate things on a web page: forms, buttons, text display areas, and dialog boxes. When you run Javascript in a browser, sometimes your code makes the browser do things (pop up a dialog box, for example), while other times an external event causes the browser to run some of your code (a person pushes a button on a form). We saw a bit of this in an earlier lab, and there will be more in the next lab, but not much in this one.

Because Javascript runs within the confines of a browser and is meant to control some of what the browser does, it provides access to some browser facilities. It would be nice to say that this access was easy, clean, regular, and the same in all browsers, but that would be a lie. In fact, the interface is not too hard, but it's far from clean and regular, and different browsers sometimes interpret identical Javascript statements differently, which is a source of frustration and irritation.

If you can, use Mozilla/Firefox instead of Internet Explorer and Safari, which are not helpful about identifying errors. With Firefox, under Tools, select Error Console to bring up a window that often identifies syntax errors and other problems in your program. This will save you a lot of grief. Do not ignore this suggestion.

Part 2: The Javascript Language

Here we will provide a very brief overview of some of the commands and syntax available in Javascript. This is by no means a complete reference, however, so you will want to look at some of the web pages we suggested above, and review what was covered in class.

Since Javascript is mostly intended for behind the scenes operations in web pages, it's pretty clumsy for just printing things, and the printing in this lab is clumsy too. But it's enough to get started, and you can refine it later on.

Displaying messages with alert

Step 1 is to refresh your memory of what happened in the earlier lab. Create a new web page lab5.html that has this minimal information, and calls the library function alert to display a dialog box when the page is loaded:

	<html>
	<head>
	<title> My Javascript Guessing Game </title>
	<script language="javascript">
	alert("Got here")
	</script>
	</head>
	<body>
		Test
	</body>
	</html>
This is the basic framework that you will now flesh out -- the single alert will gradually be replaced by more and more statements. You should create this file with whatever text editor you used for the earlier labs, using plain text. Be sure to save the results often, and reload the resulting web page after each change so you can be sure that your changes are working. Frequent small steps is the best strategy for both web page design and programming.

Output with document.write

You can write any amount of any HTML with the statement document.write(...), and it will appear on the page that is being displayed as if it had been in the original file. This isn't entirely idiot-proof, but it's adequate for this lab. If you take the example above with alert and change it slightly:

	<html>
	<head>
	<title> My Javascript Guessing Game </title>
	<script language="javascript">
	document.write("<P> This comes from the script.")
	</script>
	</head>
	<body>
	This comes from the body.
	</body>
	</html>
it will display
	This comes from the script.  This comes from the body.
That is, output from the script at the beginning comes before the body text because the script occurs before the body. If you put the script after the body text, however, the output will also be reversed.

We'll use document.write to produce some of the output for this lab.

Internet Explorer and Safari, bless their hearts, do not always display output from document.write until after the page has been processed. Use Firefox if you want to see output as your program runs.

Input and Output with prompt

The library function prompt pops up a dialog box with a message and a place for you to type a value. Whatever you type is returned as a sequence of characters that can be used in the rest of the program.

	<script language="javascript">
	var reply
	reply = prompt("Type your name")
	alert("Hello " + reply)
	</script>

This sequence declares a variable called reply. It then calls prompt and stores the resulting value (what the user typed) in the variable reply. Then it displays Hello and the reply text. (The operator + joins two sequences of characters into one longer sequence of characters. You'll use it a lot in this lab.)

The detailed behavior of prompt is a bit subtle. If you press the OK button or if you push Enter without typing anything, prompt returns an empty sequence of characters (that is, ""). If you hit the Cancel button, the returned value is null, which is a Javascript word for "nothing at all, not even no characters." Otherwise, what comes back is what the user typed in the box. This sequence will let you test for these conditions:

	answer = prompt("What's your name?")
	if (answer != "" && answer != null) {
		// get here if there was a non-empty answer
	}

In Internet Explorer, the first prompt displays "undefined". You can get rid of this by saying

        prompt("Type your name", "")

Finally, the library function confirm is like prompt: it pops up a dialog box, then returns true if the OK button is pushed, and false if the Cancel button is pushed. This lets you write the if statements that will decide whether to play another game or quit, depending on the user's response; for example, it might be some variation on

	if (confirm("Another game?")) {
		code to play another game goes here ...
	} else {
		code to quit goes here ...
	}

This is enough to get through the rest of the basics; later on we'll show how to do somewhat better. From now on, we will show just the Javascript code but the <script> and other HTML tags have to be there.

Declaring Variables

A variable is a name that refers to a place in your program where information is stored; it ultimately corresponds to a location in memory. Variables can hold different types of information, but you don't generally have to worry much about it -- Javascript handles the details for you. The main types that you should be aware of are integers (like 123), floating point numbers (with a decimal point and fractional part, like 3.1415), and text (a sequence of characters, like "hello").

Before you can use a variable in a Javascript program, you must declare it with the var statement; this tells the Javascript interpreter that you're going to be using a variable of this name so it can set aside some space in memory. For example:

var first_name, last_name
var GPA
Javascript distinguishes between upper case and lower case, so gpa and GPA are two different and unrelated variables.

A variable is a place to store a value so it can be used later in a program. To store a particular value in a variable, just write variable = value. For example, if you want to save the reply from a user, you would write something like this:

    var reply
    reply = prompt("What's your name?")
Then you can use the user's name later on in the program by using the variable reply.

Quotes and quoting

If you need a literal string of characters in your program, like Hello, there, enclose it in either single ' quotes or double " quotes. If the string contains one kind of quote, you can quote it with the other. If you inadvertently omit a quote or don't balance quotes properly, it's an error and the most common symptom is that your program just doesn't work.
Make sure that your editor (e.g., Notepad) preserves the ASCII quote characters (the regular double-quote character on the keyboard); word processing programs think they are doing you a favor by using so-called "smart" quotes. If you see something about "errors" in the status bar or the Javascript console, check these possibilities.

Arithmetic Operators and Expressions

Operators are special symbols like the + and - of ordinary arithmetic. An operator acts on values and variables to compute a new value; an expression is a legal combination of values and operators, like (my_ht+your_ht)/2 or area = pi * r * r. These are the important operators:

Operator Description
=
Assigns the value on right to the variable on left (e.g., next_year = year + 1)
+ - * /
Arithmetic: add, subtract, multiply, divide
+
Strings: make a new string by joining the two operands
< <= > >=
Comparisons: less than, less than or equals, greater than, greater than or equals
== !=
More comparisons: equals, doesn't equal
&&
Conditional AND (true if left and right expressions are both true)
||
Conditional OR (true if either left or right expression is true)

Control Flow Statements

Control flow statements like if-else, while, and for determine what the program will do next, depending on the evaluation of some expression. These are the Javascript versions of statements like goto and ifzero in the Toy machine, but easier to work with.

The If-else Statement

The if statement is used to select which one of two groups of statements to do next:
if (it's raining) { I will stay home } else { I will go outside }
or in code:
if (condition) {
	statements 
} else { 
	other_statements
}

If the condition is true, then the statements are performed, otherwise the other_statements are performed. Both groups of statements can be one or more lines. The braces surround the groups; you can omit them for a single statement, but it's safer to just use them all the time.

The else part is optional; sometimes the logic doesn't require it and you can just omit it. You can also string together a bunch of else if clauses to describe a sequence of decisions:

var temperature
temperature = prompt("What's the temperature?")
if (temperature > 212) {
	alert("boiling")
} else if (temperature < 32) {
	alert("freezing")
} else {
	alert("in between")
}
Make sure you understand how this piece of code works. How would you modify it to work with Celsius temperatures?

Indentation and Spacing

Notice that we've indented the statements in the if-else code. Indentation emphasizes the structure and makes the code easier for humans to read and follow. It has no effect on how Javascript processes your program, but it makes a lot of difference in how easy it is to read. You must indent your code, following the patterns we use here. We're more likely to be able to help you find problems if you have indented as required, and we're much more likely to be sympathetic if you do have problems.

Comments

Comments provide a way to add explanatory text to your code, making it more understandable to human readers. In Javascript, comments are indicated by // (a pair of slash characters). Everything on the line after the // will be ignored by the compiler.

var eecummings, EECummings   // two different names

The While Loop

The while statement is a loop that causes a group of statements to be repeated while some condition is true:
while ( my room is a mess ) { pick up junk; throw it out }
In Javascript, this would look like
while (condition) {
	statements
}

As long as the condition is true, then the statements will be repeated. As with if-else, the condition is surrounded by parentheses, the statements are surrounded by braces, and indentation is used to make it obvious what is included in the loop.

So, for example, you might show a sequence of temperature conversions like this:

var celsius, fahr
fahr = 0
while (fahr <= 212) {
	celsius = 5 / 9 * (fahr - 32)
	document.write(fahr + "F is " + celsius + "C <br>")
	fahr = fahr + 10
}
When you use while, watch out for infinite loops. Make sure that you increment or decrement the loop variable, or otherwise ensure that the loop ends eventually. (If you do create an infinite loop, you may have to kill the browser to recover.)

Functions

A function is a chunk of program that can be used or called from other places in a program to do an operation or compute a value; it's a way to wrap up a computation in a package so it can be easily used just by naming it. The Javascript library includes functions that have already been written for you -- mathematical functions like square root (which is called sqrt in Javascript) are good examples -- and you can write your own too.

For example, you could write a function to do the Fahrenheit to Celsius temperature conversion; putting the computation in a function makes it easier to change if necessary, and reduces clutter and confusion in the rest of the program. Here is such a function, called ftoc:

function ftoc(fahr) { // convert Fahrenheit to Celsius
	return 5 / 9 * (fahr - 32)
}
The return statement transfers control back to the function's caller, and sends the computed value back too if there is one. Notice that the statements of the function are enclosed in braces and indented.

Functions usually have parameters, so that they can operate on different data values, just like alert and prompt do. Thus ftoc has a single parameter, the temperature to be converted, which will be referred to as fahr within the function.

Now you could use ftoc in a loop like this:

function show_temps(low, high, step) {
	var f
	f = low
	while (f <= high) {
		document.write(f + "F is " + ftoc(f) + "C <br>")
		f = f + step
	}
}
and then call the function in a statement like this:
show_temps(0, 212, 10)
Variables declared within a function are only accessible within that function; variables declared outside of any function are accessible anywhere in the program.

This program is available here so you can see how the components fit together,



Part 3: Writing your own Javascript Program

Your assignment is to implement a program that will play the old guessing game "I'm thinking of a number between 1 and 100". A no-frills version is only about 10 lines of code, and you should be able to do something nicer in fewer than 20 lines. If yours is getting much bigger than that, you're probably off on the wrong track and should review the notes and examples.

Please pay attention to syntax and grammar and language constructs. You can't just throw code fragments randomly into a file and expect them to work. Read the instructions. All the information you need is right here. Uer Firefox's Javascript error console to warn of syntax errors.

 

Your program should do the following:

  • When the page is loaded, a confirm dialog box asks if the user wants to play the game. OK means yes, Cancel means no.
  • When the game starts, it generates a new secret number, then prompts the user to enter a guess.
  • When the user enters a new guess in the "Guess my number" prompt, the program displays the appropriate message (like "50 is too high", "25 is too low", "37 is right"), using an alert. The guess should also be displayed on the page with document.write.
  • If the answer was wrong, the user is prompted for another guess.
  • If the answer was right, that's the end of this game. The program tells the user it's right and displays the answer with document.write.
  • The user should then be asked about another game with confirm. OK means yes, Cancel means no.
  • It's a nicer user interface if you combine the appropriate message with the prompt for the next guess, but it's not required.

    Program structure template

    You must put all of the logic for playing a single game in a function called play1game. The main part of your program then consists of a while loop that asks the user whether he or she wants to play a(nother) game, and if the answer is OK, calls play1game. Writing a separate function cleanly separates the logic for deciding whether to play again from the logic for playing one game, and you can test them separately. In particular, you can write a temporary version of play1game that just prints a message and returns, to be used while you're worrying about managing a sequence of games.

    Thus the structure of your program must be like this (inside <script> ... </script> tags):

            while (confirm("Want to guess my number?")) {
                play1game()
            }
    
            function play1game() {
                // statements to play one game go here
            }
    
    Download and use this template! Notice that this template works! Don't make gratuitous changes.

    Playing one game

    Now you can work on playing a single game properly. The sequence of events is
    Generating a secret number

    You will need to declare a variable to hold the secret random number that the user is to guess. Call it secret. At the appropriate place in your program, you will need to compute a new secret number. Copy this line and paste it into the proper place in your Javascript code.

       secret = Math.floor(100*Math.random()) + 1  // random number between 1 and 100
    
    The built-in function Math.random produces a different (pseudo-)random number between 0 and 1 each time it is called. Multiplying that value by 100 gives a number (including a fractional part) between 0 and 99.999... The built-in function Math.floor discards any fractional part, leaving an integer between 0 and 99. Adding 1 yields an integer between 1 and 100.

    Temporarily add an alert statement after this line to display the secret number, then test this part of the program. (It's much easier to test your program if you already know the right answer! Comment out this line of code once everything is working, but leave it in the code.)

    Fetching the Guess
    The next step is to fetch the guess that your user makes. This is the value that comes back from calling prompt. Store it in a variable called guess (which you must declare). Your code should handle Cancel and empty input properly; see the description of prompt above.
    Evaluating the guess

    Now you can go on to the real logic of the program: is the user's guess too high, too low, or just right? Your task is to do this test and decide what message to display and what to do subsequently. This will require a while loop that continues while the guess doesn't equal the secret value, an if statement inside the loop that compares the guess to the secret number, and another prompt() to fetch the next guess. Look back at the discussion of control flow and the examples in the class notes if you need to.

    One Step at a Time

    If this is your first Javascript program you are liable to make mistakes. Finding the bugs (debugging) will not be too hard if, as we suggested above, you write a small section at a time, and test as you go. This approach makes it much easier to determine what section of your code has the error: it's probably the one you just added.

    Use alert statements to display results as your computation proceeds, or to verify that your program is going where you think it is. These are easy to add and help narrow down problems quickly.

    Inside your program, literal text values must appear inside quotes (e.g., "What's your guess?"). The + sign is used to join two text strings to form a new one (e.g., "Hi " + "There" is the same as "Hi There"). If you find that your program is printing text when you wanted numbers, recall the parseInt function, which converts a sequence of numeric characters into their integer value.

    Comments

    Comments are annotations added by programmers but ignored by Javascript when it is compiling and running your program. Comments are used to make the code more readable for other people that may have to work on it, or to remind you of what you were thinking when you wrote a particular line of code. Javascript comments start with // and go until the end of a line. We have included comments in some of the code above; you are advised to include comments of your own to remind yourself and others of what you are doing.

    When you prepare your lab for submission, you should leave any debugging statements in the program source code, but "commented out" so they can be easily restored if something goes wrong.

    Portability

    Make sure that your game works on different kinds of browsers. As mentioned above, it's often easiest to develop Javascript with Firefox, since the debugging facilities are better. But no matter what, you should try your program out with as many of Internet Explorer, Firefox, Opera, or Safari as you can. Enlist the help of friends, family and the TAs. This program is simple enough that it should just work everywhere (famous last words); make sure it does.


    Part 4: Finishing up

    Make sure that you have implemented what we asked for, listed above. When we grade, we will be looking to see that your program works, that it's reasonably cleanly written (properly indented, for instance), and whether you did anything special to make it more than the bare minimum. For instance, you could add a line or two to offer the user an upper limit different from 100, or a couple of lines to count the number of guesses.

    When you're all done, send email to cos109@princeton.edu with the subject Lab 5 and your name and netid. Include the file lab5.html as an attachment. If you wish, you can copy your lab5.html file to your public_html directory so others can play your amazing game. If you do, please spell the file name correctly.

    It is a good idea to check with one of the lab assistants to make sure that they have seen your program in its working state, that your file has been properly saved, and that you are sending the right file for grading. Mail the file to yourself as well and be sure that it arrived safely. Do all of these before you leave the lab or turn off your machine.