#!/applic/nir/sun4/bin/perl -- -*- C -*- # GradeForthQuiz.pl # By Kevin McFadden (kevin@sherman.pas.rochester.edu) May 1995 # This perl cgi script serves two purposes: to learn cgi programming # in perl and to grade my Introduction To FORTH Quiz # (URL:http://sherman.pas.rochester.edu/~kevin/Dspsys/forth.html). # This script also demonstrates how to handle the main types of HTML-2.0 # buttons and such. # LIST OF VARIABLES IN QUIZ.HTML # FILL_THIS_IN # This program uses Steve Brenner's cgi-lib.pl library to handle the # input. @INC=("/applic/nir/sun4/WWW/cgi-bin"); require '/applic/nir/sun4/lib/perl/cgi-lib.pl'; # Answers... $total_questions = 23; $total_correct = 0; %answers = (N_Loop, "50", Loop_Exit, "abort", Line_With_Error, "20", Dup_Match, "( n1 -- n1 n1 )", TwoDup_Match, "( n1 n2 -- n1 n2 n1 n2 )", Swap_Match, "( n1 n2 -- n2 n1 )", Rot_Match, "( n1 n2 n3 -- n2 n3 n1 )", Over_Match, "( n1 n2 -- n1 n2 n1 )", Divide_Op, "2", Mod_Op, "1", Float_Div_Op, "30.0", TwoTimes_TwoPlus_OnePlus_Op, "23", Or_Op, "11", And_Op, "2", Not_Op, "-90", LT_Op, "FALSE", GT_Op, "TRUE", Zero_Equals_Op, "FALSE", FLTE_Op, "TRUE", x3y10, "C", x7y7, "A", x9y8, "D", x0y0, "B"); $Loop_Exit2 = "abort\""; # Two valid answers... # The script... &ReadParse; # Get the user's input as an # associative array, keyed by variable # name. To use a form variable, just # use the name (e.g. Divide_Op). print &PrintHeader; print "\n"; print "\n"; print "Graded Forth Quiz\n"; print "\n"; print "\n"; print ""; print "Top: Dspsys Index \n"; print ""; print ""; print "Top: Quiz! \n"; print "
\n"; # Calculate Grade while (($key, $value) = each %answers) { # print $key, ": ", $in{$key}, "\t", $value, "
\n"; if ($in{$key} eq $value) { # print "correct
\n"; $total_correct++; } # else # { # print "****not correct
\n"; # } } $grade = $total_correct/$total_questions*100; print "

You answered $total_correct out of $total_questions for "; print "a grade of $grade.

\n"; # Give answers... print "\n"; print "

Here are the solutions...

\n"; print "\n"; ############################################################ # Question 1 ############################################################ print "
"; print "(1) How many times should the following loop execute?\n"; print "
     ok 50 25 5 */ 100 - 100 do get-data write-data loop
"; print "

\n"; if ( $in{'N_Loop'} eq $answers{'N_Loop'} ) { print "

$in{'N_Loop'} is the correct answer!

\n"; } else { print "

$in{'N_Loop'} is incorrect. The correct answer is ", "$answers{'N_Loop'}.\n"; print " Solution:

\n"; print "

";
    print "     50 25 5 */ 100 - 100 do ... loop\n";
    print "     1250 5 / 100 - 100 do ... loop\n";
    print "     250 100 - 100 do ... loop\n";
    print "     150 100 do ... loop\n";
    print "     do loop executes from 100 up to, but not including,
\n"; print " 150, so it loops 50 times.

\n"; } ############################################################ # Question 2 ############################################################ print "


"; print "(2) Should the loop in (1) fail to execute the expected "; print "number of times, which of the words introduced might have "; print "caused the loop to exit early?

\n"; if ( ($in{'Loop_Exit'} eq $answers{'Loop_Exit'}) || ($in{'Loop_Exit'} eq $Loop_Exit2) ) { print "

$in{'Loop_Exit'} is the correct answer!

\n"; } else { print "

$in{'Loop_Exit'} is incorrect. The correct answer is ", "$answers{'Loop_Exit'}.\n"; print " Solution:

\n"; print "

\n";
    print "     Remember, abort stops all execution and clears ";
    print "the stack.\n     Another valid answer would be $Loop_Exit2.";
    print "

\n"; } ############################################################ # Question 3 ############################################################ print "


"; print "(3) The following word will work properly except for one "; print "mistake. Which line contains the error?

\n"; if ( $in{'Line_With_Error'} eq $answers{'Line_With_Error'} ) { print "

$in{'Line_With_Error'} is the correct answer!

\n"; } else { print "

$in{'Line_With_Error'} is incorrect. The correct answer is "; print "$answers{'Line_With_Error'}.\n"; print " Solution:

\n"; print "

\n";

    print "          20     else    .\"col and row must each be less than ";
    print "10\!\" cr

\n"; print " Line $answers{'Line_With_Error'} is incorrect because "; print "a space was forgotten after .\"\n"; print " which occurs after the else.\n"; print "

\n"; } ############################################################ # Question 4 ############################################################ print "


"; print "(4) Match the stack notation with the appropriate word.

\n"; print "

"; if ( $in{'Dup_Match'} eq $answers{'Dup_Match'} ) { print "a) dup is $in{'Dup_Match'}. You are correct!.\n"; } else { print "a) dup is not $in{'Dup_Match'}.\n The correct answer is "; print "$answers{'Dup_Match'}.\n"; } if ( $in{'TwoDup_Match'} eq $answers{'TwoDup_Match'} ) { print "b) 2dup is $in{'TwoDup_Match'}. You are correct!.\n"; } else { print "b) 2dup is not $in{'TwoDup_Match'}.\n The correct answer is "; print "$answers{'TwoDup_Match'}.\n"; } if ( $in{'Swap_Match'} eq $answers{'Swap_Match'} ) { print "c) swap is $in{'Swap_Match'}. You are correct! \n"; } else { print "c) swap is not $in{'Swap_Match'}.\n The correct answer is "; print "$answers{'Swap_Match'}.\n"; } if ( $in{'Rot_Match'} eq $answers{'Rot_Match'} ) { print "d) rot is $in{'Rot_Match'}. You are correct!.\n"; } else { print "d) rot is not $in{'Rot_Match'}.\n The correct answer is "; print "$answers{'Rot_Match'}.\n"; } if ( $in{'Over_Match'} eq $answers{'Over_Match'} ) { print "e) over is $in{'Over_Match'}. You are correct!.\n"; } else { print "e) over is not $in{'Over_Match'}.\n The correct answer is "; print "$answers{'Over_Match'}.\n"; } print "

"; ############################################################ # Question 5 ############################################################ print "
"; print "(5) What is the result of each operation below?

\n"; if ( $in{'Divide_Op'} eq $answers{'Divide_Op'} ) { print "

a) \"7 3 /\" is $in{'Divide_Op'}. Correct!

\n"; } else { print "

a) \"7 3 /\" is not $in{'Divide_Op'}. The correct answer is "; print "$answers{'Divide_Op'}. Solution:

\n"; print "
";
    print "     7 / 3 = 2.33\n";
    print "           = 2 because Forth drops the fractional part.
\n"; } if ( $in{'Mod_Op'} eq $answers{'Mod_Op'} ) { print "

b) \"81 10 mod\" is $in{'Mod_Op'}. Correct!

\n"; } else { print "

b) \"81 10 mod\" is not $in{'Mod_Op'}. The correct answer is "; print "$answers{'Mod_Op'}. Solution:

\n"; print "
";
    print "     81 mod 10 = 8 1/10\n";
    print "               = 1 because mod returns the remainder.
\n"; } if ( $in{'Float_Div_Op'} eq $answers{'Float_Div_Op'} ) { print "

c) \"3.33e1 1.11e0 f/\" is $in{'Float_Div_Op'}. Correct!

\n"; } else { print "

c) \"3.33e1 1.11e0 f/\" is not $in{'Float_Div_Op'}. "; print "The correct answer is "; print "$answers{'Float_Div_Op'}. Solution:

\n"; print "
";
    print "     3.33e1 / 1.11e0\n";
    print "     33.3   / 1.11\n";
    print "                     = 30.0\n";
    print "\n";
    print "30 is technically correct, but the result is stored on the\n";
    print "floating point stack as 30.0\n
"; } if ($in{'TwoTimes_TwoPlus_OnePlus_Op'} eq $answers{'TwoTimes_TwoPlus_OnePlus_Op'} ) { print "

d) \"10 2* 2+ 1+\" is $in{'TwoTimes_TwoPlus_OnePlus_Op'}. "; print "Correct!

\n"; } else { print "

d) \"10 2* 2+ 1+\" is not $in{'TwoTimes_TwoPlus_OnePlus_Op'}. "; print "The correct answer is "; print "$answers{'TwoTimes_TwoPlus_OnePlus_Op'}. Solution:

\n"; print "
";
    print "     10 * 2 + 2 + 1 = 23
\n"; } if ( $in{'Or_Op'} eq $answers{'Or_Op'} ) { print "

e) \"10 3 or\" is $in{'Or_Op'}. Correct!

\n"; } else { print "

e) \"10 3 or\" is not $in{'Or_Op'}. The correct answer is "; print "$answers{'Or_Op'}. Solution:

\n"; print "
";
    print "     10 or 3 = 1010 or 11 in binary.\n";
    print "             = 1011\n";
    print "             = 11 in decimal. 
\n"; } if ( $in{'And_Op'} eq $answers{'And_Op'} ) { print "

f) \"10 3 and\" is $in{'And_Op'}. Correct!

\n"; } else { print "

f) \"10 3 and\" is not $in{'And_Op'}. The correct answer is "; print "$answers{'And_Op'}. Solution:

\n"; print "
";
    print "     10 3 and = 1010 and 0011 in binary.\n";
    print "              = 0010\n";
    print "              = 2 in decimal.
\n"; } if ( $in{'Not_Op'} eq $answers{'Not_Op'} ) { print "

g) \"89 not\" is $in{'Not_Op'}. Correct!

\n"; } else { print "

g) \"89 not\" is not $in{'Not_Op'}. The correct answer is "; print "$answers{'Not_Op'}. Solution:

\n"; print "
";
    print "     89 not =  -1 - 89 (The easy way to think of it.)\n";
    print "            =  -90\n";

    print "            =  1011001 not\n";
    print "            =  000000000000000000000000001011001 not\n";
    print "            =  111111111111111111111111110100110\n";
    print "               This is the computer's representation of -90\n";
    print "               because negative numbers are really just very\n";
    print "               large integers. ";
    print "Convert it to our representation of -90:\n";
    print "               Add up the zeroes and you get 89 ";
    print "(2^0+2^3+2^4+2^6).\n";
    print "               Since 111111111111111111111111111111111 is -1 ";
    print "in decimal,\n";
    print "               89 less than this is -90, or -1011010.
\n"; } ############################################################ # Question 6 ############################################################ print "
"; print "(6) Answer \"true\" or \"false\" for each of the following "; print "comparisons.

\n"; if ( $in{'LT_Op'} eq $answers{'LT_Op'} ) { print "

a) \"7 7 <\" is $in{'LT_Op'}. Correct!

\n"; } else { print "

a) \"7 7 <\" is not $in{'LT_Op'}. The correct answer is "; print "$answers{'LT_Op'}.

\n"; } if ( $in{'GT_Op'} eq $answers{'GT_Op'} ) { print "

b) \"76 33 >\" is $in{'GT_Op'}. Correct!

\n"; } else { print "

b) \"76 33 >\" is not $in{'GT_Op'}. The correct answer is "; print "$answers{'GT_Op'}.

\n"; } if ( $in{'Zero_Equals_Op'} eq $answers{'Zero_Equals_Op'} ) { print "

c) \"0 3 0=\" is $in{'Zero_Equals_Op'}. Correct!

\n"; } else { print "

c) \"0 3 0=\" is not $in{'Zero_Equals_Op'}. The correct answer is "; print "$answers{'Zero_Equals_Op'}.

\n"; } if ( $in{'FLTE_Op'} eq $answers{'FLTE_Op'} ) { print "

d) \"3e1 5e1 f<=\" is $in{'FLTE_Op'}. Correct!

\n"; } else { print "

d) \"3e1 5e1 f<=\" is not $in{'FLTE_Op'}. The correct answer is "; print "$answers{'FLTE_Op'}.

\n"; } ############################################################ # Question 7 ############################################################ print "
"; print "(7) For each value of x and y, which code block will be "; print "executed?

\n"; print "

";
print "    : if-then-else-fun  ( x y -- )  \ Do stuff based on x and y.\n";
print "        2dup =\n";
print "        if\n";
print "            over 0>\n";
print "            over 0> and\n";
print "            if\n";
print "                [Code Block A]\n";
print "            else\n";
print "                [Code Block B]\n";
print "            then\n";
print "        else\n";
print "            1+ -\n";
print "            if\n";
print "                [Code Block C]\n";
print "            else\n";
print "                [Code Block D]\n";
print "            then\n";
print "        then  ;\n";
print "
"; if ( $in{'x3y10'} eq $answers{'x3y10'} ) { print "

a) $in{'x3y10'} is the correct answer!

\n"; } else { print "

a) $in{'x3y10'} is incorrect. The correct answer is "; print "$answers{'x3y10'}. Solution:

\n"; print "
";
    print "                         ( 3 10 )\n";
    print "     2dup =              ( 3 10 0 )\n";
    print "     if                  ( 3 10 ) Go to else.\n";
    print "     1+ -                ( 7 )\n";
    print "     if                  ( )\n";
    print "     Code Block C
\n"; } if ( $in{'x7y7'} eq $answers{'x7y7'} ) { print "

b) $in{'x7y7'} is the correct answer!

\n"; } else { print "

b) $in{'x7y7'} is incorrect. The correct answer is "; print "$answers{'x7y7'}. Solution:

\n"; print "
";
    print "                         ( 7 7 )\n";
    print "     2dup =              ( 7 7 -1 )\n";
    print "     if                  ( 7 7 ) Continue with if.\n";
    print "     over 0>             ( 7 7 -1 )\n";
    print "     over 0>             ( 7 7 -1 -1 )\n";
    print "     and                 ( 7 7 -1 )\n";
    print "     if                  ( 7 7 )\n";
    print "     Code Block A
\n"; } if ( $in{'x9y8'} eq $answers{'x9y8'} ) { print "

c) $in{'x9y8'} is the correct answer!

\n"; } else { print "

c) $in{'x9y8'} is incorrect. The correct answer is "; print "$answers{'x9y8'}. Solution:

\n"; print "
";
    print "                         ( 9 8 )\n";
    print "     2dup =              ( 9 8 0 )\n";
    print "     if                  ( 9 8 ) Go to else.\n";
    print "     1+ -                ( 0 )\n";
    print "     if                  ( ) Go to else.\n";
    print "     Code Block D.
\n"; } if ( $in{'x0y0'} eq $answers{'x0y0'} ) { print "

d) $in{'x0y0'} is the correct answer!

\n"; } else { print "

d) $in{'x0y0'} is incorrect. The correct answer is "; print "$answers{'x0y0'}. Solution:

\n"; print "
";
    print "                         ( 0 0 )\n";
    print "     2dup =              ( 0 0 -1 )\n";
    print "     if                  ( 0 0 ) Continue with if.\n";
    print "     over 0>             ( 0 0 -1 )\n";
    print "     over 0>             ( 0 0 -1 -1 )\n";
    print "     and                 ( 0 0 0 )\n";
    print "     if                  ( 7 7 ) Go to else.\n";
    print "     Code Block B
\n"; } print "
"; print ""; print "Top: Dspsys Index "; print ""; print ""; print "Top: Quiz! \n"; print "\n"; print "\n";