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.
In lab08, we saw how we can:
<form>
element to allow the user to enter values and press a button<input type="button" value="Calculate" onclick="calculate();" />
onclick
is both the name of an HTML attribute, and also an event handler calculate();
is both the value of an HTML attribute, and also a JavaScript function call<script>
element that pulls in another function definition from an external file We'll need these concepts from lab08 for this lab:
So, please review lab08 before starting, and refer to it anytime you get stuck.
In this lab, we'll:
pizzaCalc.html
file from lab08 to make sure that it validates at http://validator.w3.org 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.
By now, you should be comfortable with how to do this. But if you need a refresher, see step 1 of lab06.
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.
lab08
directoryCopy all of the files from your ~/public_html/cisc103/lab08
directory into your new ~/public_html/cisc103/lab09
By now, you should be comfortable with how to do this. But if you need a refresher, see step 1 of lab06.
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.
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.
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:
xmlns
attribute on this tag tells us what XML Namespace (xmlns) is being used—i.e. how to interpret the rest of the tags in the document.
xml:lang
and lang
tags tell us that this page is written in English (en). This may help with things such as search engine optimization (SEO).Typically, you just "copy and paste" this line—I will not expect you to memorize it for an exam.
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:
<form>
tag, required attribute action
not specifiedHere's why, and how to fix it.
<form>
open tag requires an attribute called action
. action
attribute is only used with server-side technologies such as PHP<form>
with <form action="">
, and this problem should go awayIf 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.
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.
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.
// test 1
actual
, expected
and diff
if (diff < tolerance)
and the part of the code that follows it.
tolerance
is defined, and read the comment.
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.
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.
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.
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.
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.
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.
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!
Writing a stub is fun, because:
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.
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.
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);
radius
, and assigns it the value of diameter
divided by twoMath.PI
, multiplies it by radius
times radius
, and stores the results in the local variable areaOfOnePizza
. This is the JavaScript version of area = πr2 howMany
times areaOfOnePizza.
That represents the total area of all the pizzas. The value that comes after return
is the value that is produced by the function as the answer.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.
Here is one more example, just to be sure you have the idea.
Convert Fahrenheit to Celsius
// FtoC: function to convert celsius to fahrenheit // consumes: fTemp, number, temperature in Fahrenheit // produces: cTemp, number, temperature in celsius
See: testFtoC.js
// 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 }
> 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()
>
// 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); }
> js js> load("FtoC.js") js> load("testFtoC.js") js> testFtoC() test 1 passed test 2 passed js>
js> FtoC(212) 100 js> FtoC(32) 0 js> FtoC(-40) -40 js>
Your problem statement is:
Convert Celsius to Fahrenheit
Look at this test script, and review how it works.
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.
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:
js>
prompt) You'll submit this script on WebCT later in this lab.
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!
Make a script file called lab09_step6e.txt
containing the following steps:
js>
prompt) CtoF()
CtoF()
function. You'll submit this script on WebCT later in this lab.
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
http://validator.w3.org/check?uri=referer
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!
step | what we're looking for | points |
---|---|---|
step2 |
|
20 |
step 6b |
|
20 |
step 6c |
|
10 |
step 6d |
|
20 |
step 6e |
|
10 |
step 7 |
|
50 |
step 8 |
|
10 |
overall following of directions | student should follow the directions given | 10 |
Total |