Lab 5: Programming with Javascript

Thu Oct 28 17:02:42 EDT 2004

By the end of this lab, you will:

You will also begin to develop some appreciation for how complex programming can be, how easy it is to make errors, and how frustrating it can be to find and fix them. Don't get too frustrated! Ask a lab assistant for advice, take a break, and try again. With luck, you'll also begin to find programming a bit of fun.
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 more than half of all 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 doing mathematical operations (computing a square root or generating an apparently random number, for example), or manipulating 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.


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 most of what we'll do in this lab is clumsy too. But this is enough to get started, and we can refine it later on.

Displaying things 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 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 we 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 we reverse these two parts, however, the output will also be reversed.

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

Input and Output with prompt

The function prompt pops up a dialog box with a prompt 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 declares a variable called reply that saves whatever comes back from prompt. It then calls prompt to get whatever you type and stores that in reply. Then it displays Type your name and whatever is stored in reply. (The operator + joins two strings of characters into one long string of characters. You'll find yourself using it a lot in this lab.)

The detailed behavior of prompt is a bit subtle: if you hit the OK button or if you just push Enter, it returns an empty string (that is, ""). If you hit the Cancel button, the string 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 initial prompt displays "undefined". You can get rid of this by saying prompt("Type your name", "").

This is enough for us to get through the rest of the basics; later on we'll see 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 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. For practice, change your program to say
	Your name is 'xxx'?  It's nice to meet you, xxx!
where xxx is the name typed by a user, by storing the result of prompt in a variable, then using that in an alert.

Quotes and quoting

If you need a literal string of characters in your program, like Hello, there, you enclose it either single ' or double " quotes. If the string contains one kind of quote, you can quote it with the other, as we did in the example above. If you inadvertently omit a quote or don't balance them properly, it's an error and the most common symptom is that your program just doesn't work.

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 value on right to variable on left (e.g., next_year = year + 1)
+ - * /
Arithmetic: add, subtract, multiply, divide
+
Strings: make a new string from the two operands
< <= > >=
Comparators: less than, less than or equals, greater than, greater than or equals
== !=
More comparators: 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 -- such as 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. Each of these statements is described below.

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 actions stand for 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. Make sure you understand how this piece of code works. How would you modify it to work with Celsius temperatures?

var temperature
temperature = prompt("What's the temperature?")
if (temperature > 212) {
	alert("boiling")
} else if (temperature < 32) {
	alert("freezing")
} else {
	alert("in between")
}

Indentation and Spacing

Notice that we've indented the actions in the if-else code here. This emphasizes the logical 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 for you to read. You should 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 requested.

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, we 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")
	fahr = fahr + 10
}
Try some variant of this code with a smaller range of values. Don't forget that when you use while, you have to 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 -- consult a TA for help.)

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 useful 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, we could write a function to do the 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:

function ftoc(fahr) {
	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 too.

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.

We could use ftoc in a loop like this:

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

Comments

Comments provide a means for adding explanatory text to your program 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 e_e_cummings, E_E_Cummings   // two different names



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. What is it?". A totally no-frills version is only about 10 lines of code, and you should be able to do something nicer in 20 to 25 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.

Ours pops up a prompt that says "Guess my number." When the user types a number, the program replies with "too high", "too low", or "right". It keeps looping until the user gets the right answer. It prints each guess on the current page, along with a "Congratulations" message when the right answer is obtained.

Yours should do at least as much, and you can make it more polished if you wish, though there's no real credit for doing so.

Generating a secret number

As you work on this, it's probably easiest to store your program in the file lab5.html in your public_html directory; that's where it has to be when you're done.

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. You should just 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.

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.

You should 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 loop that asks the user whether he or she wants to play a(nother) game, and if the answer is yes, calls newgame. If you write a separate function this way, you can cleanly separate 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 more than one game.

One Step at a Time

If this is your first Javascript program you are liable to make mistakes. This is not as bad as it sounds -- if you are methodical, finding the bugs (or debugging) will not be too hard. 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 alert 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. If you developed on Internet Explorer, try it out with Netscape or Mozilla or Opera, or Safari on a Mac. Enlist the help of friends 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 prompt asks if the user wants to play the game. OK means yes, Cancel means no.
  • When the program 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 should display the appropriate message ("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 should be prompted for another guess.
  • If the answer was right, that's the end of this game. The program should display the right answer with document.write.
  • The user should then be asked about another game. OK means yes, Cancel means no.
  • 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 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.

    Every year, several people lose their work because they have not followed these instructions or heeded these warnings. Please don't be one of this year's victims!