Lab 5: I'm Thinking of a Number

Sat Nov 4 19:24:04 EST 2006

By the end of this lab, you will:

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 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 both convenient for humans yet easily translated into a computer's machine language: they 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, and talked about a variety of programming languages, much easier for people to use, that are translated by a program into machine instructions. 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 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 the features of Javascript the programming language -- variables, arithmetic, loops and decisions, 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 an 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 popup 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 an endless source of frustration and irritation.

If you can, use Mozilla/Firefox instead of IE, which is not helpful about identifying errors. With Firefox, under Tools, select Javascript Console to bring up a window that provides comparatively good diagnostics about syntax errors and other problems in your program.

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, including an alert that will display a dialog box when the page is loaded:

	<html>
	<title> My Javascript Guessing Game </title>
	<script language="javascript">
	alert("Got here")
	</script>
	<body>
		Test
	</body>
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 editor you used for the earlier labs. 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>
	<title> My Javascript Guessing Game </title>
	<script language="javascript">
	document.write("<P> From the script.")
	</script>
	<body>
	 From the body.
	</body>
it will display
	From the script.  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 the output for this lab.

Input and Output with prompt

The 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 string 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 whatevervalue comes back from prompt to reply. Then it displays Hello and whatever is stored in reply. (The operator + joins two strings of characters into one long string of characters. You'll use it a lot in this lab.)

The detailed behavior of prompt is a bit subtle. If you hit the OK button or if you push Enter without typing anything, it returns an empty string (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. Experiment to see what comes back when you type various things and when you push the OK and Cancel buttons.

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

        prompt("Type your name", "")

Finally, 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 ...
	} else {
		code to quit ...
	}

This is enough to get through the rest of the basics; later on we'll show how to do somewhat better. Henceforth, we won't show the <script> and other HTML tags, just the Javascript code.

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 strings (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 do something like this:

	var reply
	reply = prompt("What's your name?")
Then you can use the name later on.

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 much 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) {
	actions 
} else { 
	other_actions
}

If the condition is true, then the actions are performed, otherwise the other_actions are performed. Both groups of actions can be one or more statements. The braces surround the actions; you can omit them for an action that has only one 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 actions 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.

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) {
	actions
}

As long as the condition is true, then the actions will be repeated. As with if-else, the condition is surrounded by parentheses, the statements in the action part 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 will likely have to kill the browser.)

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; wrapping the computation up 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 fahr
	fahr = low
	while (fahr <= high) {
		document.write(fahr + "F is " + ftoc(fahr) + "C <br>")
		fahr = fahr + 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.



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 20 lines. If yours is getting a lot 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.

 

Program structure

You must put all of the logic for playing a single game in a separate function called newgame. 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 newgame. 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 newgame 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:

    <script>
        while (confirm("Want to guess my number?")) {
            newgame()
        }

        function newgame() {
            // statements to play one game go here
        }
    </script>
If you start with this template, you will have a much easier time.

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
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! You can 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.
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 now 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, and an if statement that compares the guess to the secret number. Look back at the discussion of control flow 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, 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 likely 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.

Another tip for this problem is to display the correct answer right away, until you know the program is working. It's hard to debug a program that generates a different random value each time it runs!

Inside your program text values must appear inside quotes (e.g., "What's your guess?"). The + sign is used to attach two text strings to form a new one (e.g., "Hi " + "There" is the same as "Hi There"). If you find yourself getting strings when you wanted numbers, recall the parseInt function.

Comments

Comments are annotations added by programmers but not looked at by Javascript when it is compiling or 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. In 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 or Mozilla, Opera, or Safari on a Mac 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

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 displays the right answer with document.write.
  • The user should then be asked about another game with confirm. OK means yes, Cancel means no.
  • 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, copy your lab5.html file to your public_html directory on Unix if you have not already done so.

    Send email to cos109@princeton.edu with the subject Lab 5 and your name. Please also mail us the file lab5.html as part of the mail message (not an attachment, just text in the body of the mail message).

    It is a very 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 in your Unix account, 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.