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[0] argument is given an obj identifier and the arguments[1] 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[0].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.

Roundabout rounding

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[0] 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[0].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.

Comments: Post a Comment

<< Home

Powered by Blogger

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