# Doing computations

On this page, you’ll learn how to do computations based on data users enter. We’ll review some of the things we did earlier, just to make sure you got it. Baby steps, baby steps.

You’ll learn:

• How to show and hide content in response to user clicks.
• How to change content using `text()`.
• How to show input fields to get data from users.
• How to do computations on the data users enter.
• How to delay showing the output area until computations are done.

Let’s roll!

## Computing the tip

When you go to a restaurant in the US, it’s customary to tip a server (a waitress or waiter) 15% of the bill. So if your meal cost \$30, the tip would be \$30 × 15% = \$4.50, and the total cost of the meal would be \$34.50.

Let’s write a Web page to do that computation. Please try it now. CC

The word “computation” sounds sort of scary. Kieran

Hmm, yes, I can see that. But all it means here is doing some arithmetic, multiplying and adding. Even better: the computer does the work! You don’t have to. CC

Hey, I like that!

Here’s my starting page. Everything except the computation.

```<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Tip</title>
<script type="text/javascript">
\$("#meal_cost").focus();
\$("#compute_tip").click(function(){
});
});
</script>
<body>
<h1>Tip Computer</h1>
<p>
Meal cost:
<input type="text" id="meal_cost">
<button type="button" id="compute_tip">Compute</button>
</p>
<p>Tip: <span id="tip"></span></p>
<p>Total: <span id="total_cost"></span></p>
</body>
</html>
```

Figure 1. Starting the tip computer

Please try the code so far.

Most of the code should be familiar. Line 20 creates a text field. Line 21 creates a button.

Line 23 creates an output area to show the tip. It introduces a new tag: `<span>`. `<span>` is an inline tag. It can be inserted right into the middle of some content. `<span>` lets us give an `id` to a spot on the page, so we can refer to that place in JavaScript code.

Line 24 is another output area. It also uses a `<span>` with, of course, a different `id`. Remember that `id`s should be unique within a page.

Let’s look at the JS.

```\$(document).ready(function() {
\$("#meal_cost").focus();
\$("#compute_tip").click(function(){
});
});
```

Figure 2. JavaScript from the first tip computer

Line 1 attaches some code to the `ready()` event. Lines 3 to 5 bind some code to the `compute_tip` button.

Line 2 sets the focus in the input field when the page loads. The user can start typing immediately. This makes the page more usable.

Now to do the computation. Here’s some JS (warning: there’s a bug):

```\$(document).ready(function() {
\$("#meal_cost").focus();
\$("#compute_tip").click(function(){
//Get the cost of the meal.
meal_cost = \$("#meal_cost").val();
//Compute the tip and total.
tip = meal_cost * 0.15;
total_cost = meal_cost + tip;
//Output the results.
\$("#tip").text(tip);
\$("#total_cost").text(total_cost);
});
});
```

Figure 3. Tip computer JS (broken)

Line 5 gets whatever the user types into the input field and puts it into the variable `meal_cost`.

Line 7 works out the tip amount. `*` means “multiply,” so the line reads:

Take the contents of the variable `meal_cost`, multiply it by 0.15, and put the result in the variable `tip`.

Line 8 takes the contents of the variable `meal_cost`, and adds the contents of the variable `tip`, putting the result into the variable `total_cost`. At least, that’s what the intent is.

Lines 10 and 11 show the results.

When I try the page, it works, partially. I type in 30 for the meal cost, click the button, and get this: Figure 4. Broken tip computer

What!? The tip is fine. 30 × 0.15 is 4.5. But the page says that 30 + 4.5 is 304.5! It should be 34.5! What the `!#`#@! is going on?

## Buggy bug the buggity bug bugster

Welcome to the Wonderful World of Bugs.

The problem is that `+` has two meanings in JavaScript. The meanings are:

• Append text together.

Earlier, we say code like this:

`"Hello " + user_name + "!"`

There’s that +. It meant:

Take the text “Hello “, append the contents of the variable `user_name`, and append the text “!”.

That’s what this line in Figure 3 is doing:

`total_cost = meal_cost + tip;`

JavaScript treats the contents of the variables `mean_cost` and `tip` as text rather than numbers. It’s taking the contents of the variable `mean_cost`, and appending the contents of the variable `tip`. So:

30 + 4.5 gives 304.5

This is stupid. Really stupid. That’s what computers are. Very, very, very stupid.

We want to tell JavaScript: “Dude, treat the contents of the variables `mean_cost` and `tip` as numbers.” Then it will add instead of appending.

You should always address a JavaScript program as “dude.”

Change the code to:

`total_cost = parseFloat(meal_cost) + parseFloat(tip);`

In computerese, a “float” is a kind of number. There are many kinds of numbers. For instance, an integer is a whole number. A float is a number that can have a fraction. The function `parseFloat()` tells JS to treat the stuff inside the `()` as a number that can have a fraction.

When you do this, the `+` becomes an add. Try it.

# Exercise: Low tip

Change the program so it only tips 12%. Think anyone will notice?

Can't find the 'comment' module! Was it selected?

# Exercise: Kilos to pounds

Write a page that will convert kilograms to pounds. There are 2.2 lbs per kilo. The page will look like this to start with: Figure 1. Page at start

The user types a number in and clicks the button: Figure 2. Output

Can't find the 'comment' module! Was it selected?

## Sharing the cost

Let’s change the program so that the bill is split evenly between more than one person. Please try this version.

Here’s the code:

```<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Tip</title>
<script type="text/javascript">
\$("#meal_cost").focus();
\$("#compute_tip").click(function(){
//Get the cost of the meal.
meal_cost = \$("#meal_cost").val();
//Get the number of diners.
humans = \$("#humans").val();
//Compute the tip and totals.
tip = meal_cost * 0.15;
total_cost = parseFloat(meal_cost) + parseFloat(tip);
cost_per_human = total_cost / humans;
//Output the results.
\$("#tip").text(tip);
\$("#total_cost").text(total_cost);
\$("#cost_per_human").text(cost_per_human);
});
});
</script>
<body>
<h1>Tip Computer</h1>
<p>
Meal cost:
<input type="text" id="meal_cost">
</p>
<p>
Number of humans:
<input type="text" id="humans">
</p>
<p>
<button type="button" id="compute_tip">Compute</button>
</p>
<p>Tip: <span id="tip"></span></p>
<p>Total: <span id="total_cost"></span></p>
<p>Cost per human: <span id="cost_per_human"></span></p>
</body>
</html>
```

Figure 5. Group tip computer

There’s a new input field (line 35). The code is roughly the same. The total cost is divided up in line 18. There isn’t a `parseFloat()` in line 18, because the `/` operator only means “division.” So while `+` has two meanings, `/` only has one.

# Exercise: Kilos and grams to pounds

Write a page that will convert kilograms and grams to pounds. There are 1,000 grams per kilo, and 2.2 lbs per kilo. Figure 1. Page at start

The user types numbers and clicks the button: Figure 2. Output

Hint: Use at least one `parseFloat()`.

Can't find the 'comment' module! Was it selected?

## Hiding the output area

When the page first loads, the output area looks a little strange. Just the headings, with no numbers.

It would be better if we could hide the output area at first, and show it after the user has entered the data and clicked the button.

Figure 6. Improving the interface

Let’s see how to do that. Please try the page.

We’ll change the HTML to this:

```<div id="output_area">
<p>Tip: <span id="tip"></span></p>
<p>Total: <span id="total_cost"></span></p>
<p>Cost per human: <span id="cost_per_human"></span></p>
</div>
```

Figure 7. Wrapping in a `<div>`

The output tags are wrapped in a new tag, `<div>`. Use `<div>` when you want to make a container, as we’ve done here. A container is a tag that has a bunch of other tags inside it.

If we do something to the `<div>`, we do something to all its contents as well. So, if we hide the `<div>`, we hide all of its contents. If we show the `<div>`, we show all its contents.

Here’s what we want to do:

• When the page loads, hide the `<div>`.
• When the user clicks the button, do the calculations, fill in the output fields, and then show the `<div>`.

Here’s the JavaScript for the page:

```\$(document).ready(function() {
\$("#output_area").hide();
\$("#meal_cost").focus();
\$("#compute_tip").click(function(){
...
//Output the results.
\$("#tip").text(tip);
\$("#total_cost").text(total_cost);
\$("#cost_per_human").text(cost_per_human);
//Show the output
\$("#output_area").show();
});
});
```

Figure 8. New JavaScript

I gave the `<div>` an `id` of `output_area`. We can use that in the code to identify the thing to hide and show.

This line…

`\$("#output_area").hide();`

...hides the `<div>`, including everything inside it. The line is inside `\$(document).ready()`, so it runs when the page is loaded.

This line…

`\$("#output_area").show();`

...shows the `<div>`, including everything inside it. The line is run after the output values are inserted into `total_cost` and `cost_per_human`.

W00f!

## A little animation

Let’s add some animation to the way the output area appears. You can try it.

Figure 9. A little animation

Pass a value to the `show()` function:

`\$("#output_area").show('medium');`

That’s it! Change the speed by giving `show()` different values, like `'fast'`, `'slow'`, and `3000`. The last one extends the effect over 3,000 milliseconds (3 seconds).

# Exercise: Kilos, grams, pounds, with animation

Write a page that will convert kilograms and grams to pounds. There are 1,000 grams per kilo, and 2.2 lbs per kilo. Figure 1. Page at start

No output area is shown.

The user types numbers and clicks the button: Figure 2. Output

The output appears with an animated effect.

Hint: Use at least one `parseFloat()`.

Can't find the 'comment' module! Was it selected?

## Summary

You learned:

• How to show and hide content in response to user clicks.
• How to change content using `text()`.
• How to show input fields to get data from users.
• How to do computations on the data users enter.
• How to delay showing the output area until computations are done.

## What’s next?

What happens when you make a mistake in your code? Time to talk about debugging.