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 numA ≥ numB.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 numA ≥ numB, 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 avar 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.
Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)