reptile7's JavaScript blog Wednesday, June 19, 2019

Approaching Quizmo, Part 2
Blog Entry #400

Welcome back to our ongoing deconstruction of the Java/JavaScript Goodies Math Check. In the previous post we walked through the checker's addition functionality and we now turn our attention to its subtraction, multiplication, and division code.

Subtract, multiply, divide

Clicking the rekenen form's , , and buttons calls `subtract( )`, `multiply( )`, and `divide( )` functions, respectively. The `subtract( )` and `multiply( )` functions are exactly like the `add( )` function except they've got - and * operators in place of the + operator; the `divide( )` function largely parallels the `add( )` function although it does feature some noteworthy differences.

Recall that the Math Check metatext includes a This page is best viewed with Netscape 3.0 line. With Navigator 3.04 on my iMac, `x / 0` for x 0 and `0 / 0` both return NaN; the former division returns Infinity with Netscape 4+ and all modern browsers. These divisions are legitimate but their usefulness leaves something to be desired vis-à-vis testing the user's division skills: the `divide( )` function staves them off by adding one to the `random( )` and `ranom( )` % remainders.

```numA = random(maxValue) + 1; numB = ranom(maxValue) + 1;```

The `divide( )` function subsequently carries out a numA / numB division for which the numA dividend is greater than or equal to the numB divisor; if a first `numA = random(maxValue) + 1;` is less than a first `numB = ranom(maxValue) + 1;`, then `divide( )` is re-called as many times as needed until numAnumB.

```if (numA < numB) { divide( ); } numC = numA / numB;```

The numC quotient is `round( )`-ed to the nearest integer; a following `alert( )` asks the user to follow suit.

```numC = Math.round(numC); window.alert("Please round your answer off ?\n.5 or higher one number up\n.4 or lower one number down");```

Each `divide( )`/`ans( )` run therefore displays four dialogs:

(1) `window.alert("Please round your answer...");`
(2) `window.prompt(numA + "/" + numB + " = ", 0);`
(3) `window.confirm("Do you want your browser to check your answer...");`
(4) `window.alert(...check response (answer is correct|wrong, try again later)...);`

If it takes three `divide( )` calls to obtain a numAnumB, then the user will be subjected to twelve dialogs for the same, ultimate `numA / numB` division, and we don't want that; this situation is easily cleaned up by placing a return statement after the `divide( )` re-call so as to end the current `divide( )` run.

`if (numA < numB) { divide( ); return; }`

Alternatively and preferably, we can lose the `divide( )` re-call and just exchange the numA and numB values via:

```if (numA < numB) {     var divisor = numA;     numA = numB;     numB = divisor; }```

Function consolidation

Do we really need separate `add( )`, `subtract( )`, `multiply( )`, and `divide( )` functions? Nah. Upon setting up a

`var opArray = ["+", "-", "*", "/"];`

operator string Array (N.B. a `var opArray = [+, -, *, /];` Array of non-stringified operators throws an expected expression, got ',' SyntaxError) the four functions can be formulated as a single `operate( )` function that is operator-differentiated by an opIndex parameter (0 for addition, 1 for subtraction, etc.) and whose operator characters are fetched by an opArray[opIndex] expression:

```function operate(opIndex) {     ...beginning maxValue, numA, and numB assignments...     if (opIndex == 3) { numA++; numB++; if (numA < numB) { ...numA↔numB exchange... } }     numC = eval(numA + opArray[opIndex] + numB);     if (opIndex == 3) { numC = Math.round(numC); window.alert("Please round your answer..."); }     Answer = window.prompt(numA + " " + opArray[opIndex] + " " + numB + " = ", 0);     if (window.confirm("Do you want your browser to check your answer to the problem " + numA + " " + opArray[opIndex] + " " + numB + "?")) ans( );     else window.alert("Please try again later!"); }```

Note that the numC = numA +|-|*|/ numB operations are merged via the somewhat-notorious `eval( )` function; if the use of `eval( )` here bothers you for whatever reason, you can write out the operations 'in longhand' instead per the original code:

```if (opIndex == 0) numC = numA + numB; if (opIndex == 1) numC = numA - numB; if (opIndex == 2) numC = numA * numB; if (opIndex == 3) numC = numA / numB;```

One last function

Clicking the button calls a `check( )` function that displays the user's correct and wrong tallies on an `alert( )` box.

```function check( ) {     window.alert("YOUR SCORE\n : " + correct + " correct\n : " + wrong + " incorrect"); }```

The user can problem-wise flit freely between
the add, subtract, multiply, and divide operations and
the A, B, and C difficulty levels
and `check( )` will score-wise keep track of it all.
In the next entry we'll revisit the random generation of numA and numB and then wrap things up with a refurbished demo.