CISC103, Fall 2007

lab09: More on JavaScript with Forms


Review

HTML material from lab07

In lab07, we learned about DOCTYPEs, meta content-type tags, and HTML validation. You will need that understanding for this lab, so if you need to review lab07, do so before starting lab09.

JavaScript material from lab08

In lab08, we saw how we can:

We'll need these concepts from lab08 for this lab:

So, please review lab08 before starting, and refer to it anytime you get stuck.

Goals for lab09

In this lab, we'll:

Before doing this lab, you should have completed the following:


Detailed Instructions

Step 1: Create directories and copy files

Create two new subdirectories:

~/public_html/cisc103/lab09 for web content we create in this lab
~/cisc103/lab09 for files we create in this lab that do not go on the web

And copy all files

from /www/htdocs/CIS/103/pconrad/07F/labs/lab09  to ~/cisc103/lab09

Please note that you are copying files into your directory for files that do not go on the web.

As promised, I'm not spelling how to do this anymore.

By now, you should be comfortable with how to do this. But if you need a refresher, see step 1 of lab06.

Step 2: Validating the pizzaCalc.html file from lab08

In lab08, we included a <!DOCTYPE ... > declaration and <meta http-equiv="Content-Type" ... > element to enable us to validate the file as correct HTML. However, because the focus in lab08 was on the JavaScript, we didn't take the time to do the validation. We're going to fix that in this lab.

Step2a: Copy all of your files from your lab08 directory

Copy all of the files from your ~/public_html/cisc103/lab08 directory into your new ~/public_html/cisc103/lab09

As promised, I'm not spelling how to do this anymore.

By now, you should be comfortable with how to do this. But if you need a refresher, see step 1 of lab06.

Step2b: Make the pages readable

Do the chmod command necessary to make all the files under ~/public_html/cisc103/lab09 readable on the web at http://copland.udel.edu/~youruserid/cisc103/lab09.

Step2c: Change the DOCTYPE

Because we are using self-closing tags, we need to move to the DOCTYPE for XHTML 1.0 strict if we want our document to validate properly. (You can read about the differences between HTML and XHTML in Chapter of your Head First HTML with XHTML and CSS textbook.)

So, change the DOCTYPE to this one:

<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Typically you "copy and paste" this section—I will not expect you to memorize it.

Step2c: Change the <html> open tag

When using XHTML instead of HTML, the <html> open tag takes a slightly more complex form, with three additional attributes:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

Here's a brief explanation:

Typically, you just "copy and paste" this line—I will not expect you to memorize it for an exam.

Step2e: Validate the page at validator.w3.org

Now, visit the page http://validator.w3.org

Enter the URL of your new pizzaCalc.html page—now updated for XHTML 1.0 strict—and click to validate the page.

You will likely run into at least one validation error (shown below) —possibly more. If there are any validation errors, fix them—20 pts of this week's lab grade is having no validation errors.

The one validation error you are almost guaranteed to have is this one:

On the opening <form> tag, required attribute action not specified

Here's why, and how to fix it.

If there are other validation errors, use your knowledge of HTML to try to resolve them

Usually they are caused by simple things such as:

If you run across any problem that, after really looking at it carefully, you can't fix, you can bring it to your TA or instructor during lab, or office hours.

 

Step 3: testAreaOfPizza.js—a test script for testAreaOfPizza.js

There is nothing to turn in for Step 3. However, it introduces an important idea—the idea of a test script.

The work you do in step 6 will depend on whether you understand the material in this step.

So read it carefully, and use the JavaScript prompt and the files in your directory this week to follow along, trying out the commands as you see them. This will help your understanding, and help you be better prepared to do step 6.

Step 3a: Looking at the script testAreaOfPizza.js.

Change your working directory to your ~/cisc103/lab09 directory.

Type the Unix command to list out the file testAreaOfPizza.js. You'll see that it contains the following code:

// testAreaOfPizza.js   test script for areaOfPizza.js
// P. Conrad for CISC103, sect 99, 10/23/2007


// test the function areaOfPizza()

function testAreaOfPizza() {

  //=======================================
  // define the tolerance
  //=======================================

  // tolerance is "how far away from the expected value" the result
  // is allowed to be.  We have to have some tolerance because the
  // calculation involves pi, which is always a approximation.

  // We put "var" in front of a variable the first time it appears
  // in a function, to indicate that it should be a local variable

  var tolerance = 0.01;

  //===================
  //  Run the tests
  //===================

  //  Test 1

  var expected = 113.10;
  var actual = areaOfPizza(12);
  var diff = Math.abs(expected-actual);

  if (diff < tolerance)
    {
      print('test 1 passed');
    }
  else
    {
      print('test 1 failed');
      print("expected=" + expected);
      print("actual=" + actual);
    }
  //  Test 2

  expected = 201.06;
  actual = areaOfPizza(16);
  diff = Math.abs(expected-actual);

  if (diff < tolerance)
    {
      print('test 2 passed');
    }
  else
    {
      print('test 2 failed');
      print("expected=" + expected);
      print("actual=" + actual);
    }

} // function testAreaOfPizza

This function is what we refer to as a test script. It tests whether the function areaOfPizza() does what is it supposed to do.

Look at the code and try to understand how it works.

Step 3b: "Hands on" experience to help you understand the test script

To learn more about how this test script works, we'll actually run it.

First we need to copy the areaOfPizza.js file from your ~/public_html/cisc103/lab08 directory into your ~/cisc103/lab09 directory.

Once areaOfPizza.js is in your current directory, type js at the Unix prompt to go into the JavaScript command line interpreter.

At the js> prompt, type the command shown here to load areaOfPizza.js into the interpreter:

> js
js> load("areaOfPizza.js");
js>   

Then, type a command to show what the result is when you pass 12 in as the actual parameter to the areaOfPizza() function:

 

js> areaOfPizza(12)
113.09733552923255
js>

Notice that in the test script, the expected result to be 113.10. But, in practice, the actual result is 113.09733552923255. This is why we have a tolerance value. Any number involving pi, or square roots, or even division can result in numbers that cannot be represented exactly in binary.

We are familiar with this notion—as you probably know, 1/3 of 100% is often written as 33.33%. However, if you take that and multiply it by 3, you don't get 100%, but 99.99%. The slight inaccuracy is due to the fact that 1/3 cannot be expressed in the decimal number system.

This happens in binary also, which is why numbers represented by computer (other than integers) tend to be slightly inaccurate.

Step 3c: "Hands on" experience: running a test script

So, we can run the test script as follows:

> js
js> load("areaOfPizza.js");
js> load("testAreaOfPizza.js");
js> testAreaOfPizza()
test 1 passed
test 2 passed
js> quit()
>

The fact that the script prints "passed" means that areaOfPizza.js is doing what it is supposed to do.

Test-driven development

One way to define the behavior of what a JavaScript function is supposed to do is to write the test script first. This is called test-driven development.

Step 4: The process: Given a test script, write a JavaScript function

For Step 4 and Step 5, there is nothing to turn in. But it is important to review these steps in detail, since they are preparation for step 6.

Steps 4 and 5 walk you through two complete examples of how to approach solving a problem in JavaScript when you are given a test script.

In Step 6, you'll then be asked to do the same, but you will be on your own. So work through these examples carefully to see how we go about attacking and solving a problem.

Problem Statement

Given a number of pizzas (e.g. 3 pizzas) and the diameter of each pizza (e.g. 12 inches), compute the total area in square inches of all three pizzas.

To solve this problem, we'll develop a function called areaOfNPizzas(), which can be described as follows:

But first, we'll develop a test script.

Step 4a: A test script: testAreaOfNPizzas()

Here is a link to another test script called testAreaOfNPizzas.js Compare this test script with the one from step 3a.

testAreaOfNPizzas.js contains a function definition for testAreaOfNPizzas(), which is a function that tests the areaOfNPizzas() function described above.

Look at testAreaOfNPizzas() and find

Be prepared to be able to answer those questions on an upcoming exam or quiz.

Step 4b: A stub for areaOfNPizzas()

If we have a test script, and we want to test whether the test script itself is working, we can write something called a stub.

A stub is a simple function definition that does as little work as possible, and always returns the wrong answer—on purpose!

It it fun to write a stub.

Writing a stub is fun, because:

Why would we possibly want to do that?

Because stubs allow us to "test the test"

With a a stub that always returns the wrong answer, we can check that our test script is actually capable of detecting errors.

An example stub


Here is a stub for the areaOfNPizzas() function. It is stored in the file areaOfNPizzasStub.js

// areaOfNPizzasStub.js    P. Conrad for CISC103, sect 99, 10/23/2007
// return area of a bunch of pizzas // consumes: howMany, a number, the number of pizzas you have // diameter, a number, the diameter of each pizza // produces: the total area of all of those pizzas

function areaOfNPizzas(howMany, diameter) {
return -42; // stub for testing purposes
} // function areaOfNPizzas

We can see that this file contains a function for areaOfNPizzas() that takes the same parameters as the function that testAreaOfNPizzas() is expecting.

But, it doesn't actually compute the correct value. Instead, it just always returns -42—a number that could not possibly be the correct answer!

That way, we can check whether the test function works. Notice that when we load the stub definition and the test script, and then try running them, we get results that show us that the test script correctly detects the errors in the function definition. This is good!

js> load("areaOfNPizzasStub.js")
js> areaOfNPizzas(2,12) 
-42
js> load("testAreaOfNPizzas.js") 
js> testAreaOfNPizzas() 
test 1 failed
expected=226.2
actual=-42
test 2 failed
expected=603.18
actual=-42
js> 
  

In a later step, you'll be asked to write your own stub function to go with a test script.

Step 4c: Turning the stub for areaOfNPizzas() into a working function

The next step in development of a solution to the problem is to turn our stub into a working function.

Use a Unix command to make a copy of the file areaOfNPizzasStub.js, called areaOfNPizzas.js

Then, edit the file as follows:

First, change the first line to:

// areaOfNPizzas.js P. Conrad for CISC103, sect 99, 10/23/2007

Then, change the body of the function—the part inside the { }. Instead of return -42; we want the following lines of JavaScript, which will compute the correct answer. We use the value of the formal parameters howMany and diameter to compute the answer:

   // calculate the radius

var radius = diameter / 2; var areaOfOnePizza = Math.PI * radius * radius; return (howMany * areaOfOnePizza);

Now that the function contains the correct body, we can test it using our test script, as follows:

js> load("areaOfNPizzas.js")
js> load("testAreaOfNPizzas.js") 
js> testAreaOfNPizzas()
test 1 passed
test 2 passed
js> areaOfNPizzas(1,12)
113.09733552923255
js> areaOfNPizzas(2,12) 
226.1946710584651
js> areaOfNPizzas(2,14) 
307.8760800517997
js> 

We see that when we load the proper version of the function and run it, the tests pass. We can also test various other value of howMany and diameter by typing them in at the command line.

Step 5: FtoC: Another complete example of test-driven development of a JavaScript function

Here is one more example, just to be sure you have the idea.

Problem Statement:

Convert Fahrenheit to Celsius

Function specification

// FtoC: function to convert celsius to fahrenheit
//  consumes: fTemp, number, temperature in Fahrenheit
//  produces: cTemp, number, temperature in celsius

Test script

See: testFtoC.js

Stub function

// FtoC.js P.Conrad for CISC103, 10/24/2007

// function to convert celsius to fahrenheit // consumes: fTemp, number, temperature in Fahrenheit // produces: cTemp, number, temperature in celsius

function FtoC(fTemp) { return -4242; // stub for testing }

Output from running test script with stub function

> js
js> load("FtoCstub.js");
js> load("testFtoC.js");
js> testFtoC()
test 1 failed
expected=20
actual=-4242
test 2 failed
expected=30
actual=-4242
js> quit()
>

Correct function

// FtoC.js P.Conrad for CISC103, 10/24/2007

// function to convert celsius to fahrenheit // consumes: fTemp, number, temperature in Fahrenheit // produces: cTemp, number, temperature in celsius

function FtoC(fTemp) { return ((fTemp-32) * 5/9); }

Output from running test script with correct function

> js
js> load("FtoC.js")
js> load("testFtoC.js")
js> testFtoC()
test 1 passed
test 2 passed
js> 


Output from a few more interactive tests


js> FtoC(212)
100
js> FtoC(32)
0
js> FtoC(-40)
-40
js> 
   

 

Step 6: Your turn: Develop a function, given the test script

Your problem statement is:

Convert Celsius to Fahrenheit

Step 6a: Review the test script testCtoF.js

Look at this test script, and review how it works.

Step 6b: Write a stub called CtoFstub.js

Using the previous examples as a model, write a JavaScript file CtoFstub.js, containing a stub definition for CtoF()

At the JavaScript prompt, use your CtoFstub.js file to test the test script as illustrated in the earlier steps in this lab.

Step 6c: Prepare a script file lab09_step6.txt to document that the stub does its job

It has been a while since we made a "script" file to make a permanent record of something we do at the Unix or JavaScript prompts.

So refer back to the following for a refresher, because we are going to do that next.

Make a script file called lab09_step6c.txt containing the following steps:

  1. While inside the script file, start up the JavaScript command line interpreter (i.e. get to the js> prompt)
  2. Then type the commands to load the test script, and load your stub function definition.
  3. Type in a function call to the test script, to show that the tests in the test script fail.
  4. Type in the function call that quits the JavaScript prompt, and returns you to the Unix prompt
  5. Type in the Unix command that ends the script.

You'll submit this script on WebCT later in this lab.

Step 6d: Write a proper function definition in a file called CtoF.js

Using the previous examples as a model, write a JavaScript file CtoF.js, containing a proper definition for CtoF(). You may like to start either with your stub file, or with some other function definition file as your starting point, but be sure to modify not only the code, but all appropriate comments also!

Step 6e: Prepare a script file lab09_step6e.txt to document that the function definition is correct

Make a script file called lab09_step6e.txt containing the following steps:

  1. While inside the script file, start up the JavaScript command line interpreter (i.e. get to the js> prompt)
  2. Then type the commands to load the test script, and load your proper function definition for CtoF()
  3. Type in a function call to the test script, to show that the tests in the test script pass
  4. Type in two or three other function calls to your CtoF() function.
  5. Type in the function call that quits the JavaScript prompt, and returns you to the Unix prompt
  6. Type in the Unix command that ends the script.

You'll submit this script on WebCT later in this lab.

Step 7: Given a JavaScript function, make a web page to enable the calculation

Refer back to lab08, and to the notes from lecture about making a web page that performs a calculation using JavaScript.

Then, make a web page, CtoF.html, that uses your CtoF() function.

Make your web page available at the link http://copland.udel.edu/~youruserid/cisc103/lab09/CtoF.html

For full credit:

Step 8: Submit four files on WebCT

When you are finished with steps 2, 6 and 7, then submit your four files from step 6 on WebCT:

CtoFstub.js, lab08_step6c.txt, CtoF.js, lab08_step6e.txt

Don't submit on WebCT until your step 2 and 7 are done also, since your submission on WebCT is the signal to the TA that your lab is ready to be graded (all parts of it.)

Then you are finished!


Grading: 150 pts

step what we're looking for points
step2
  • http://copland.udel.edu/~youruserid/cisc103/lab09/pizzaCalc.html should
    validate as XHTML 1.0 strict with no errors (and still work properly, as it did in lab08)
    • -20 if page does not have XHTML 1.0 DOCTYPE at all
    • -15 if page has XHTML 1.0 doctype and proper html open tag, but does not validate as valid XHTML 1.0 strict
    • -10 if page validates as XHTML 1.0, but does not work properly (i.e. does not calculate)
20
step 6b
  • CtoFstub.js
    • -20 if you don't submit it at all on WebCT
    • 10 pts for style, 10 pts for correctness
    • Note that if you don't complete step 6c correctly, you may lose correctness points here as well since your instructor/TA will find it difficult or impossible to determine correctness
20
step 6c
  • lab09_step6c.txt script file
    • 10 pts for following directions and submitting this file
10
step 6d
  • CtoF.js
    • -20 if you don't submit it at all on WebCT
    • 10 pts for style, 10 pts for correctness
    • Note that if you don't complete step 6e correctly, you may lose correctness points here as well since your instructor/TA will find it difficult or impossible to determine correctness
20
step 6e
  • lab09_step6e.txt script file
    • 10 pts for following directions and submitting this file
10
step 7
  • File validates as XHTML (10 pts)
  • File has a link to allow it to be validated at XHTML (5 pts)
  • File contains a form with three required elements (9 pts)
    • place to put in celsius temp, place to read out fahrenheit temp, button to click to get the answer
  • Layout is reasonably attractive and neat (6 pts)
  • Calculation works correctly (20 pts)
    • This requires that the file contain a reference to an external JavaScript file CtoF.js
    • That file should also be readable on the web
    • There needs to be an event handler hooked up to the calculate button to do the calculation
50
step 8
  • student correctly submits required files via WebCT (not by email, or some other non-standard way)
  • all four required files must be submitted: CtoFstub.js, lab08_step6c.txt, CtoF.js, lab08_step6e.txt
10
overall following of directions student should follow the directions given 10
Total    

 

Due Date: Tue, Nov 6, 11:55pm


Copyright 2007, Phillip T. Conrad, CIS Dept., University of Delaware. Permission to copy for non-commercial, non-profit, educational purposes granted, provided appropriate credit is given; all other rights reserved