reptile7's JavaScript blog Monday, April 27, 2020

SC II
Blog Entry #409

OK, let's get back to our discussion of the CCC Super Calculator; we are at present ready to segue from structure to behavior by taking on the SC's JavaScript.

The supercalc.html `<script>` code comprises no fewer than twenty-five functions. A sprawling `getinput( )` function at the top of the script serves as a gateway to seventeen of those functions. Outside `getinput( )`'s jurisdiction are `more( )`, `calc( )`, `cleart( )`, `less( )`, `helppi( )`, `doit( )`, and `helpround( )` functions that are relevant to the Arithmetic and remainder parts of the calculator and that we will cover in today's post.

Arithmetic action

Suppose we want to add 9 and 7. We click the calculator's button

`<input type="button" value="  9  " onclick="more(9, document.mainform.total);">`

thereby calling a `more( )` function.

```function more(obj, where) {     if (where.value == "" || where.value == "0") { where.value = obj; }     else { where.value += obj; } }```

The number 9 and a `document.mainform.total` object reference for the total I/O text field

`<input type="text" name="total" size="20" value="0">`

are passed to the `more( )` function and are given the identifiers obj and where, respectively. If the `where.value` is the empty string* or the numeric string `"0"` - true in this case - then it is set to obj; if a non-0 value were already present in the where field, then obj would be appended to that value.
*The starting `"0"`, or any inputted value, can be backspaced to a blank.

• As for a standard calculator, the total.value is initialized to 0.
• Usually, the user display for a standard calculator is right-justified; Netscape 4.x won't `text-align:right;` the total field but modern browsers will.
• FYI, the default size for an `<input type="text">` is 20. If the SC had a lot of text boxes with a size="20" attribute, then I would delete those attributes, but just one? Leave it.

Clicking the and buttons similarly calls the `more( )` function and appends + and 7 characters to the 9 per `more( )`'s else clause.

To calculate and display the sum, we click the button

`<input type="button" value="  =  " onclick="calc(document.mainform.total, document.mainform.total);">`

thereby calling a `calc( )` function.

```function calc(obj, objw) {     if (objw.value == "") { objw.value = ''; }     objw.value = eval(obj.value); }```

The `calc( )` call strangely passes two `document.mainform.total` references to the `calc( )` function: the arguments argument is given an obj identifier and the arguments argument is given an objw identifier. The `calc( )` function `eval( )`s the `obj.value` and then parks the result in the objw field.

Prior to carrying out the sum, `calc( )` tests if the `objw.value` is an empty string: if true, then the `objw.value` is pointlessly reset to an empty string.

Is there any need to use two Text objects here? If there is, I don't see it. Moreover, `eval('')` returns undefined with all of the browsers on my computer: a blank should be converted to a 0 for this case. I would consequently rewrite the `calc( )` function as:

`function calc(obj) { if (! obj.value.length) obj.value = 0; obj.value = eval(obj.value); }`

I should lastly note that we can also get the sum by typing 9+7 in the total field and clicking the button as the total field is not readonly (the readonly attribute was standardized in HTML 4, which postdates the SC).

More arithmetic `more( )` buttons and the additive inverse button

Clicking the other digit buttons,
the decimal point button,
the other arithmetic operator buttons,
and the parentheses buttons
loads the corresponding characters into the total field via the `more( )` function as described above.

The additive inverse button is bound to a separate `negpos( )` function that we will discuss at a later point.

C/d

The button

`<input type="button" value=" PI " onclick="helppi( ); more('(' + Math.PI + ')', document.mainform.total);">`

also calls on `more( )` in order to load π into the total field although the details are a bit different. Clicking the button first calls a `helppi( )` function

```function helppi( ) {     if (document.mainform.mode.checked) { window.alert("PI is an easy function that just gives you PI. 3.14......"); } }```

that pops up a
PI is an easy function that just gives you PI. 3.14...... message
if the
Help radio button is checked, as is true initially.

```<b>Mode: <input name="mode" type="radio" checked>Help <input name="mode" type="radio">No Help <!-- No </b> is present in the source. -->```

Subsequently, a '(3.141592653589793)' string - yep, 15 fractional digits - is shipped off to `more( )`. I think the parentheses are there to prevent the π value from being appended to an already-present preceding number.

JavaScript (the browser's JavaScript engine) does not see 5(3.141592653589793) as a multiplication, however; you'll have to input an * symbol between the 5 and the (3.141592653589793) to calculate the circumference of a circle whose diameter is 5. In practice, `eval('5(3.141592653589793)')` throws a 5 is not a function TypeError.

My Casio fx-85v calculator outputs π to seven places past the decimal point (3.1415927), which is good enough for me, and therefore I would send `Math.PI.toFixed(7)` to `more( )` instead.

Clearing and backspacing

Clicking the SC's button calls a `cleart( )` function that clears the total field by resetting it to 0 à la a standard calculator.

```function cleart(obj) { obj.value = "0"; } <input type="button" value="  C  " onclick="cleart(document.mainform.total);">```

Clicking the SC's button calls a `less( )` function that backspaces the total.value; like a standard calculator's (clear entry) button, the button allows the user to delete the rightmost number of a larger expression without having to start over.

```function less(obj) { obj.value = obj.value.substring(0, obj.value.length - 1); } <input type="button" value=" <-- " onclick="less(document.mainform.total);">```

I don't like the button's label or location:
I'd relabel it (no dashed arrows, please)
and put it next to the clearing button as Saries's Rainbow Calculator does.
FWIW, my Casio fx-85v has a backspace button that will backspace an inputted value but not an outputted value, e.g., upon dividing 10 by 7, it won't backspace the 1.4285714 quotient; in contrast, the `less( )` function backspaces all total.values.

Twelve of the `getinput( )`-gated functions call on an external `doit( )` function to overwrite the total.value with a new obj value.

```function doit(obj, where) { // For all cases, where = document.mainform.total     where.value = obj; }```

The SC's button for rounding a non-integer to an integer also calls on the `doit( )` function.

`<input type="button" value="Round" onclick="helpround( ); doit(Math.round(document.mainform.total.value), document.mainform.total);">`

As shown above, the rounding is carried out by a `Math.round(document.mainform.total.value)` operation embedded in the `doit( )` call. The `round( )`ed output is passed to `doit( )` as the arguments `doit( )` argument and then is written to the total field.

Perhaps you are thinking, "The `cleart( )` and `less( )` functions have just one parameter. Why don't we send `document.mainform.total` to a dedicated `function roundValue(obj) { obj.value = Math.round(obj.value); }` function instead?" Well, that would be a more straightforward way to go, wouldn't it?

Prior to the `doit( )` call the button calls on a `helpround( )` function

```function helpround( ) {     if (document.mainform.mode.checked) { window.alert("Round is an easy function that simply rounds the number in the total textbox to the nearest whole number."); } }```

that pops up a
Round is an easy function that simply rounds the number in the total textbox to the nearest whole number message
if theHelp radio button is checked. The term "whole number" generally means 0 or a positive integer but not a negative integer (although some people use "whole number" and "integer" interchangeably), so we should probably change `whole number` to `integer` in the `alert( )` text as the `round( )` method duly rounds negative numbers as well as positive ones.
We'll go after the SC's exponentiation and trigonometry operations in the following entry.

Friday, April 03, 2020

Super Calc v2.3
Blog Entry #408

The next Calculators, Calendars, and Clocks item is a Super Calculator ("SC" hereafter), which went live at Java Goodies in September 1997 and was created by Tom Richardson, Jr. The SC code is posted here.

We've covered a JavaScript calculator twice previously.
(1) Blog Entries #74 and #75 go through Saries's Rainbow Calculator.
(2) Blog Entries #369, #370, and #371 go through Jamie Beyore's Another Great Science Calculator.
The SC is operations-wise similar to these calculators; it has some features that they don't have - e.g., it provides a memory facility and an extensive `alert( )`-based help system - and vice versa.

Super structural summary

Set the controls for the heart of the calculator

The SC includes 47 controls in total, they being
a name="total" I/O text field,
41 push buttons for the various input and operation keys plus a push button for an About feature near the bottom of the calculator,
two hidden fields for memory inputs, and
two radio buttons for turning its help system on and off, respectively.
These controls are accessed (and were rendered back in the day) via a containing name="mainform" form.

The mainform form content includes the tables and outro material described below, and is horizontally centered on the page by an unclosed `<center>` element. Here's a screen shot of the original supercalc.txtsupercalc.html display: Lay of the land

The SC display is laid out with six borderless tables.

`var tables = document.forms["mainform"].getElementsByTagName("table");`

The tables table holds the big Super Calc v2.3 heading and the Best used with Netscape Communicator 4.0 metatext.

The tables table holds the business end of the calculator in its entirety - everything between the Best used with Netscape Communicator 4.0 text and the button - and itself serves as a container for the tables-tables tables.

The tables table holds the Scientific Notation, Memory, and Special functions sections on the left-hand side.

Moving to the middle, the tables table holds the Mode radio buttons and the 0-defaultValued total field and the key whereas the tables table holds the ... keys.

Lastly, the tables table holds the Powers, Finding "x", Fractions, and Misc sections on the right-hand side.

I am normally lenient as regards leaving `<table>` markup in place for these old scripts, but it would clearly be stretching it to say that we are dealing with grids of data in this case: the tables can and should be exchanged for an equivalent set of divs.

The Super Calc v2.3 heading is actually coded with a font element:

```<font color="red" size="6"><b><center>Super Calc v2.3</b></font> <!-- Nope, there's no </center> tag here either. -->```

As it happens, the size="6" setting and an h1 element both give a 32px font-size, so we can more appropriately code the heading with:

```h1 { color: red; text-align: center; } <h1>Super Calc v2.3</h1>```

An h1 heading provides a `<p>`-like separation between the heading and the Best used with Netscape Communicator 4.0 text; as shown by the above screen shot, the font formulation puts the heading and the text in the same line box (Joe's /JSBook/supercalc.html demo inserts a `<br>` between them).

The Netscape Communicator 4.0 link points to an http://cgi.netscape.com/cgi-bin/upgrade.cgi resource, which is no longer live (you wouldn't expect it to be) although archived versions of it are still available, not that we want to be encouraging Netscape Communicator 4.0 use in this day and age, of course.

The tables table horizontally separates the tables table, the tables-tables tables, and the tables table via a cellspacing="20" attribute. If we give the tables table → div an id="calcDiv" and contain the tables-tables controls with a single div, then we can approximately reproduce the horizontal separation via a `#calcDiv div { display: inline-block; margin: 10px; }` styling.

The Scientific Notation, Memory, ... headings are not put in `<th>` cells but are simply `<b>`olded. Alternatively, we can legitimately mark up the headings with the label element:

```label { display: block; font-weight: bold; margin: 2px; } <div id="calcDiv"> <div> <label>Scientific Notation:<br /> <input type="button" value="Scie" onclick="getinput(scie);" /> <input type="button" value="UnScie" onclick="getinput(unscie);" /> </label> ...```

Outro

The SC display concludes with some 'fine print' - I'll call it that as it's wrapped in a `<font size="-50">` element whose size="-50" setting gives an x-small font-size.

The fine print's first line warns us:
Note: This script is NOT compatible with Microsoft's Internet Explorer 3.0

`<font color="red"><blink>Note: This script is NOT compatible with Microsoft's Internet Explorer 3.0</font></blink><br>`

We learned a couple of entries ago that IE 3.01 for the Mac won't act on onclick commands, which come up aplenty in the supercalc.html source; I have no idea what problem(s) may arise on the Windows side. The warning is reddened by a font element and is also marked up with a blink element (note that the font and blink elements are improperly nested), which does cause it to blink with the various versions of Netscape on my computer but is not supported by modern browsers. If this were a genuinely important message, then maybe we would blink it by toggling its visibility between visible and hidden, but it clearly isn't.

The fine print's second line asserts:
"[The SC is] the most powerful Web-based calculator in the world."
Perhaps this was true at the time of posting, and it's a boast that holds up surprisingly well today in that most modern-day JavaScript calculators do not venture beyond basic arithmetic - don't take my word for it, run a javascript calculator Google search and see for yourself.

The fine print's third and last line is a by Tom Richardson Jr. authorship credit. The Tom Richardson Jr. link points to an http://home.rmci.net/gooftroop resource, which is not available (if it ever was). The credit is approximately right-justified via 40 preceding spaces (36 &nbsp;s, 4 newlines).

Atop the fine print is an button that when clicked pops up an 'IP notice':
Super Calc v2.3(R) with new more compact Equasion+(R). Both Copyright(C) and authored by Tom Richardson Jr of Richardson Technologies(R)

`<input type="button" value="About" onclick="window.alert('Super Calc v2.3(R) with new more compact Equasion+(R). Both Copyright(C) and authored by Tom Richardson Jr of Richardson Technologies(R)');">`

• For an `alert( )` message or any other JavaScript string, an ® registered trademark symbol can be coded with \u00ae and a © copyright symbol can be coded with \u00a9.

Try it out:

Operational overview

Arithmetic
Like all calculators, the SC can add, subtract, multiply, and divide.
It has a additive inverse key but not a reciprocal key.
It doesn't have a percent key or a modulo key.

Exponentiation, square root, logarithm
The SC has and keys for squaring and cubing a number; moreover and more generally, it has an key for raising a number to the yth power.
It has a key for calculating the square root of a number; it doesn't have a key for calculating the yth root of a number.
It has a key for calculating the natural logarithm of a number; it doesn't have a key for calculating the common logarithm of a number.

Trigonometry
The SC has , , and keys for calculating the sine, cosine, and tangent of an angle in radians.

General
The SC has an key for `eval( )`uating an expression in the total field.
It has a key for clearing the total field and also a backspace key for deleting the total.value's rightmost character.
It has and parentheses keys that can be used to circumvent the MDAS (×/÷ over +/-) order of arithmetic operations.

Memory
The SC has and memory in (M+) keys and corresponding and memory recall (MR) keys and an memory clear key.

The remainder
The SC has a key for inputting π (3.14159...).
It has a key for rounding a number with a fractional part to the nearest integer.
Finally, it has , , , , and keys for operations that are, shall we say, 'off the beaten track' for a calculator - we'll detail them later.

Operational details

We'll do this next time.