Monday, June 13, 2016

The Key to the Operation, Part 1

Blog Entry #369

In today's post we tuck into "Another Great Science Calculator", the next Calendars, Clocks, and Calculators (CCC) script. Authored by Jamie Beyore in 1997, the Another Great Science Calculator script codes a desktop calculator via which the user can carry out various mathematical operations, which we will detail in the discussion below.

**Visualizing the calculator**

The javagoodies.com/scicalc.txt document holding the Another Great Science Calculator script code is still live as of this writing but the script's demo page shows...

*nothing*. As it happens, two incorrectly formulated HTML comments stand in our way.

`<!-- In the document head: -->`

<!-- The Following Program Was ... (C) 1997 --- //>

<!-- In the document body: -->

<!-- Start Calculator Display --//>

HTML comments should end with a

`-->`

character sequence. The head comment contains three alien pre-`>`

characters (the two slashes and the space that precedes them) and the body comment contains two alien pre-`>`

characters (the two slashes); removing these characters brings the display to life.This is just an image, not the actual calculator - I'll roll out a functioning demo in due course.

**Structure notes**

Jamie's calculator is laid out with four tables. Table #1 holds the Jamie's Calculator heading and the display/input field.

`<table border="1" valgin="middle" algin="center">`

<tr><td bgcolor="yellow" align="center">Jamie's Calculator</td></tr>

<tr><td bgcolor="lightgrey" align="center"><input type="text" name="expr" size="35" action="calculate(this.form);"></td></tr>

</table>

• Misspellings notwithstanding, the table element does not have a valign attribute whereas its align attribute is deprecated. An align="center" setting would horizontally center the table on the page, however; in practice, all of the calculator tables are horizontally centered by a center element (whose required

`</center>`

tag is missing).• "lightgrey" is now a standard, W3C-approved color keyword: its #rrggbb value is #d3d3d3. The bgcolor="lightgrey" setting colors only a 1px cellpadding rectangle, which even the sharpest-eyed observers are unlikely to notice.

• The action attribute is valid for only the form element: it has a %URI; data type and is not used to call functions.

Tables #2-4 frame the calculator's operator and operand keys.

Table #2 holds the → row of keys.

Table #3 holds the → row of keys.

Table #4 holds the remainder.

The tables #2-4 code is pretty conventional and doesn't contain any red flags (for some keys the onclick setting contains an unnecessary line break but this doesn't cause any problems) so I won't burden you with it.

Could we code the whole shebang as a single table, maybe put the table #1 content in a thead element and/or code the Jamie's Calculator heading as a caption element? Yep, we could do that.

A form element (whose required

`</form>`

tag is missing) consolidates the tables and their controls.`<body bgcolor="red" valink="yellow" alink="yellow" link="yellow">`

<center>

<form>

...table/input code...

Although there aren't any links in the scicalc.html code, let me lastly point out that the valink in the

`<body>`

tag should be vlink.**Operation types**

We can organize the calculator operations into four categories:

(A) arithmetic

(E) exponential

(L) logarithmic

(T) trigonometric

(A) For an arithmetic calculation, the user enters an expression containing numbers and one or more operators - e.g., 3 * (5 - 7) / 9 - into the expr field and then clicks the key to display the answer.

(E,L,T) For exponential, logarithmic, and trigonometric calculations, the user enters a number into the expr field and then clicks the applicable operator key to display the answer.

Exception: The reciprocal key, which performs an arithmetic (division) operation, is like the (E,L,T) keys.

**Operands and their inputs**

The 0-9 digit keys call on an enter( ) function to enter their corresponding digits into the expr field, e.g.:

`<head>`

<script language="javascript">

...

function enter(arg, string) { arg.expr.value += string; }

`<td><input type="button" value=" 7 " onclick="enter(this.form, 7);"></td>`

Clicking the key calls enter( ) and passes thereto this.form and 7, which are respectively given arg and string identifiers; subsequently, enter( ) appends string to the value of the arg.expr field.

Inputting a decimal point is a bit different, and is problematic.

`var decimalsign = " . ";`

`<td><input type="button" value=" . " onclick="enter(this.form, decimalsign);"></td>`

The script's script element features a top-level section in which a space-dot-space string is assigned to a decimalsign variable; clicking the key appends decimalsign to the arg.expr.value as detailed above. As you would surmise, the spaces in decimalsign shouldn't be there, and they prevent the calculator from carrying out calculations on decimalsign-containing inputs, e.g., pressing returns NaN and not 10. Having said this, I should note that the expr field is an ordinary text input in which we can type values via a computer keyboard, and we do also have the option of inputting an unadorned . character via a . keyboard key. Still, we really ought to get rid of those decimalsign spaces, wouldn't you say?

The key does not convert a number to its additive inverse but instead inputs a negativesign for the purpose of entering a negative number.

`// Right after the decimalsign declaration:`

var negativesign = " -";

`<td><input type="button" value=" neg " onclick="enter(this.form, negativesign);"></td>`

**Arithmetic**

The +, -, *, and / arithmetic operators are also variabilized

`// Just before the decimalsign declaration:`

var plussign = " + ";

var minussign = " - ";

var multiplysign = " * ";

var dividesign = " / ";

and are enter( )ed into the expr field à la the operand characters.

```
<td><input type="button" value=" + " onclick="enter(this.form, plussign);">
<input type="button" value=" - " onclick="enter(this.form, minussign);"></td> ...
```

Left and right parenthesis (( and )) characters are similarly available for overriding the multiplication/division-over-addition/subtraction order of operations.

`var leftbracket = " (";`

var rightbracket = ") ";

```
<td><input type="button" value=" ( " onclick="enter(this.form, leftbracket);"></td>
<td><input type="button" value=" ) " onclick="enter(this.form, rightbracket);"></td>
```

Arithmetic expressions are evaluated by a calculate( ) function.

`function calculate(arg) { arg.expr.value = eval(arg.expr.value); }`

`<td><input type="button" value=" = " onclick="calculate(this.form);"></td>`

This is a case that really does require the eval( ) function, or at least I can't think of any other way to do what we want to do here.

Multiplicative inverse

A separate inverse( ) function handles the operation.

`function inverse(form) { form.expr.value = 1 / form.expr.value; }`

`<td><input type="button" value=" 1 / X " onclick="inverse(this.form);"></td>`

We'll continue our deconstruction of the calculator's functionality in the following entry.

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)