Solved

Automated quiz grader

Posted on 1997-05-10
3
979 Views
Last Modified: 2013-12-25
I have a free online boating safety course at
<http://tcmall.com/nauticalknowhow>. Unfortunately or fortunately, in four months online I have gotten over 70,000 page access and I am getting 200+ ten question review exams daily. Currently the exams are on a form with radio buttons and upon submission of the form the students answers are emailed to me and I must grade and respond by email back to
the student. The question is, is their something already available in JavaScript or CGI close to what I need or can one of the experts help me fill my needs. Any one who assists will get full credit. The following are my requirements:

1. Check to see that the student has made at least a 70% on the 10 question exam. This is required before they can continue.

2. If yes, show the student the numbers he got correct, his/her grade and the answers to the questions he got incorrect.

3. If no, show the student a message of what questions he/she got wrong but do not show the answers. Simply direct them back to the material and ask them to resubmit.

4. I also need a record of this forwarded to me or somehow stored in a dbase or flat text file that I can access.

5. I also need to have the ability of randomizing the questions so someone who gets all the correct answers cannot pass them around the net to others who have not taken the exam.

Any assistance you could provide would be greatly appreciated. I would make sure to give you credit for any help possible. This is a service that we developed to be free to the user and we'd like to keep it that way, but without automation and or sponsors we may not be able to. This is just a "sideline" or at least I thought it was going to be.

Thanks,

Capt Matt

0
Comment
Question by:captmatt
  • 2
3 Comments
 
LVL 3

Accepted Solution

by:
RM032397 earned 100 total points
ID: 1854187
I have a a small demo that may be of interest
http://www.catalog.co.uk/demo/game/quizobj.htm

It shows how to create questions with feedback and scoring using only javascript.

For the security you would have to have people register to take the exam and access the page, or the could have multiple goes. This would require cgi server scripting.

Questions could be plugged in by accessing different question sets in separate files, using an additional, invisible, frame.

Adding the grading would be easy as the total marks are caluculated. You then set marking standards to allocate the grade.

The results can then be attached to a form and sunbmitted to your server which can then email to you (formmail.cgi) or add to a database if you have a script for that.

A lot depends on just how formal this examination has to be.
I think it would be hard to set up something un-hackable.

0
 

Expert Comment

by:avramov
ID: 1854188
I have emailed you a prototype page based on your chapter 3 quiz
0
 
LVL 3

Expert Comment

by:RM032397
ID: 1854189
Since you have a problem with the emailed demos, here they are, so anyone can get them!
=========================================================
Frameset file chquiz.htm
=========================
<HTML><HEAD>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="Author" content="Moonraker Productions, Inc.">
<meta name="Classification"
content="Boating Safety, Boating Education, Navigation">
<meta name="Description"
content="Nautical Know How, Basic Boating Safety Certification Course, Chapter III review exam.">
<meta name="KeyWords"
content="Basic Boating Safety Course, Boating Education, Boating Safety, Boating, Sailing, Power BoatingSailing, Boat Maintenance, Boat Repairs">
<title>Chapter Three Review Questions</title>

<SCRIPT LANGUAGE="JavaScript">
<!--
// Copyright Rodney Myers mailto:rmyers@patrol.i-way.co.uk
// Commercial use without permission prohibited
/*
A script for generating a multi-choice questionnaire with feedback
for each answer, scoring for each answer,
flexibility on the number of questions and the number of answers,
scoring with feedback, all in one file using two frames.

*/

// Global variables
var Number_of_Questions = null // defined in subframe qq file
var Score = 0

var clientname  = ""
var clientemail = ""
var clientnote  = ""

// set up var in which to create a new array named Quiz
var Quiz    =  null
// and array Mark to contain feedback on answers given
var ANSWERS =  null    // new makeArray(Number_of_Questions)

// Question objects in Quiz array

function Question(Question_Text,Answers,Feedback,Scores,Correct) {
  this.Question_Text = Question_Text
  this.Answers       = Answers
  this.Feedback      = Feedback
  this.Scores        = Scores
  this.Correct       = Correct
}


function StoreAnswer(RBValue){
// value contains Q number
// and Answer given as string separated with ";"
var X = parser(RBValue,";")
ANSWERS[parseInt(X[1]) ] = parseInt(X[2])
}

function doButtons(Win) {
var There= Win.document
There.open()
There.write("<FORM NAME='BFORM'>")
There.write("<INPUT TYPE='BUTTON' VALUE='Quiz Re-set' onClick='parent.doDisplay(parent.Display)'>")
There.write("<INPUT TYPE='BUTTON' VALUE='Marks' onClick='parent.doFeedback(parent.Display)'>")
There.write("<INPUT TYPE='BUTTON' VALUE='View Source' onClick='window.location = \"view-source:\" + window.location.href'>")
There.write("</FORM>")
There.close()
}

function doDisplay(Win) {
var There= Win.document
There.open()
There.write('<body bgcolor="#FFFFFF" text="#000000" link="#0000EE" vlink="#551A8B" alink="#FF0000">')
doDisplayFormTop(There)
for (var i = 1 ; i <= Number_of_Questions ; i++ )
     { DoQuestion(i,There) }
doDisplayFormBottom(There)
There.close()
}

function doDisplayFormTop(There){
There.writeln('<form action="/cgi-bin/cgiemail/mailtemp.txt" name="chtest" method="POST">')
There.writeln('<input type="hidden" name="success" value="http://www.tcmall.com/nauticalknowhow/boating/thanks.htm"><input ')
There.writeln('type="hidden" name="chapter" value="Chapter 3">')
There.writeln('<NOBR><font color="#000080">Please enter your name:</font>')
There.writeln('<input type="text" size="50" name="Name" value="',clientname,'"></nobr><BR>')
There.writeln('<NOBR><font color="#000080">and your email address:</font> <input ')
There.writeln('type="text" size="50" name="required_email" value="',clientemail,'"></nobr><br>')
There.writeln('<br><font color="#000080"><p align="center">From the answers below, select the one you think is correct.</font></p>')
}

function doDisplayFormBottom(There){
There.writeln('<p><font color="#000080"><b>Before you submit your answers for grading, ')
There.writeln('please help us out by telling us how you heard about the course:</b></font></p>')
There.writeln('<div align="center"><center><table border="0">')
There.writeln('    <tr>')
There.writeln('        <td colspan="3"><font color="#000080">Please tell us')
There.writeln('        how you heard about the course and give us your')
There.writeln('        comments or submit questions.</font><br>')
There.writeln('        <textarea name="Comments" rows="5" cols="50"')
There.writeln('        wrap="physical">',clientnote,'</textarea></td>')
There.writeln('    </tr>')
There.writeln('</table>')
There.writeln('</center></div><p><input type="button" value="Tell me my grade!" onClick="top.doFeedback(window)">')
There.writeln('</form>')
}


function DoQuestion(Q,There) {
doQtxt(Q,There)
var Answers = parser(Quiz[Q].Answers ,";")
var l = Answers.length
There.write("<BLOCKQUOTE>")
for (var i = 1 ; i <= l ; i++ )
  {
  doRButton(Q,i,There)
  There.write(Answers[i])
  There.write("<BR>")
  }
There.write("<BR></BLOCKQUOTE>")
}

function doQtxt(Q,There){
There.write("<BR><font color='#000080'><b>Question ",Q,". ",Quiz[Q].Question_Text,"</b></font>")
}

function doRButton(Q,A,There){
var V = Q + ";" + A
There.write('<INPUT TYPE="radio" NAME="',
            'ans',Q,'" VALUE="',V,
            '" onClick="parent.StoreAnswer(this.value)" align="left">')
}



function doFeedback(Win) {
var There    = Win.document
var Answers  = null ; var Feedback= null
var Scores   = null ; var l       = null
var A = null // answer given
var C = null // Correct answer
Score = 0

// store the non-answer values from forms
clientname  = There.chtest.Name.value    
clientemail = There.chtest.required_email.value
clientnote  = There.chtest.Comments.value    

There.open()
There.write('<body bgcolor="#FFFFFF" text="#FF000" link="#0000EE">')
for (var Q = 1 ; Q <= Number_of_Questions ; Q++ )
     { A = ANSWERS[Q]       // index of answer given
       C = Quiz[Q].Correct  //          correct answer
       Answers  = parser(Quiz[Q].Answers ,";")
       Feedback = parser(Quiz[Q].Feedback,";")
       Scores   = parser(Quiz[Q].Scores  ,";")
       doQtxt(Q,There)
       There.write("<BLOCKQUOTE>")
       There.write("Correct Answer : ",Answers[C], " scores ",Scores[C],"<BR>");
       
       if ((ANSWERS[Q] > 0) && (A != C )) // NOT Correct Answer
          {There.write("Your answer : ",Answers[A].bold()," scores ",Scores[A],"<BR>")
           There.write(Feedback[A],"<BR>")
           Score += parseInt(Scores[A])
          }
      else if (A==C) Score += parseInt(Scores[C])
      if (ANSWERS[Q] == 0)
      There.write("NO ANSWER GIVEN<BR>");
      There.write("</BLOCKQUOTE>")

}
var s1 = "TOTAL SCORE: "
var s2 = "YOUR GRADE : "
There.write("<BR>",s1.fixed(),Score)
There.write("<BR>",s2.fixed(),grade(Score).bold(),"<BR>")
There.writeln('<form>')
There.writeln('<input type="reset" value="Let me try again!" onClick="top.goAgain(window)"></p>')
There.writeln('</form>')
There.close()
}

function goAgain(Win) {
for (var i = 0 ; i <=Number_of_Questions ; i++ ) { ANSWERS[i]=0}
doDisplay(Win)

}

function grade(Score){
var Ret = null
if (Score == 10)   Ret = "A++"
if (Score ==  9)   Ret = "A+"
if (Score ==  8)   Ret = "A"
if (Score ==  7)   Ret = "B+"
if (Score ==  6)   Ret = "B"
if (Score ==  5)   Ret = "C"
if (Score ==  4)   Ret = "D"
if (Score ==  3)   Ret = "E"
if (Score ==  2)   Ret = "F"
if (Score ==  1)   Ret = "F-"
if (Score ==  0)   Ret = "F--"
return (Ret)
}

function blankFrame(Win){
var There    = Win.document
There.open()
There.write('<body bgcolor="#FFFFFF"></BODY>')
There.close()
}


// Functions from McComb's Javascript Sourcebook (Wiley)
function makeArray (NumElements) {
var Count; this.length=NumElements; for (var Count = 1 ; Count <= NumElements ; Count++)
     this[Count] = 0;  return (this); }

function parser (InString, Sep)  { // From JavaScript Sourcebook by Gordon McComb pub.Wiley
var NumSeps=1; InString = "" + InString
for (Count=1; Count < InString.length; Count++)  { if (InString.charAt(Count)==Sep) NumSeps++ }
parse = new makeArray (NumSeps); Start=0; Count=1; ParseMark=0; LoopCtrl=1;
while (LoopCtrl==1)  {ParseMark = InString.indexOf(Sep, ParseMark); TestMark=ParseMark+0;
if ((TestMark==0) || (TestMark==-1))
   {parse[Count]= InString.substring (Start, InString.length);LoopCtrl=0;break}
    parse[Count] = InString.substring (Start, ParseMark);
    Start=ParseMark+1;ParseMark=Start;Count++;}
parse[0]=Count;return (parse)}

//--end-->
</SCRIPT>
</HEAD>
<FRAMESET ROWS = 50%,50%,* FRAMEBORDER="0" FRAMESPACING="0" BORDER="0" BORDERCOLOR="#ffffff">
<FRAME SRC="ch3qtop.htm"                          NAME="Intro" >
<FRAME SRC="javascript:parent.blankFrame(window)" NAME="Display" >
<FRAME SRC="ch3qq.htm"                            NAME="Questions" >
</FRAMESET>
<NOFRAMES><BODY><H3>FRAMES and JavaScript capable browser required.</H3>
</BODY></NOFRAMES>
</HTML>
=================================================
ch3qtop.htm is based on your page header and loads into top frame
=================================================================
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>

<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="Author" content="Moonraker Productions, Inc.">
<meta name="Classification"
content="Boating Safety, Boating Education, Navigation">
<meta name="Description"
content="Nautical Know How, Basic Boating Safety Certification Course, Chapter III review exam.">
<meta name="KeyWords"
content="Basic Boating Safety Course, Boating Education, Boating Safety, Boating, Sailing, Power BoatingSailing, Boat Maintenance, Boat Repairs">
<meta name="GENERATOR" content="Microsoft FrontPage 2.0">
<title>Chapter Three Review Questions</title>
</head>

<body bgcolor="#FFFFFF" text="#000000" link="#0000EE" vlink="#551A8B" alink="#FF0000">
<div align="center"><center>

<table border="0" cellpadding="0" cellspacing="0">
    <tr>
        <td><p align="center"><img src="nkhsm.gif" width="273"
        height="42"></p>
        </td>
    </tr>
    <tr>
        <td><p align="center"><img src="bsc.gif" width="310"
        height="30"><br>
        <a href="../index.htm"><img src="hpbut.gif" border="0"
        width="117" height="17"></a><a href="BoatTOC.htm"><img
        src="tocbut.gif" border="0" width="155" height="17"></a><a
        href="3_9.htm"><img src="ppbut.gif" border="0"
        width="135" height="17"></a><a href="4_1.htm"><img
        src="npbut.gif" border="0" width="109" height="17"></a></p>
        </td>
    </tr>
    <tr>
        <td align="center" colspan="2"><font color="#0000FF"><b>Boating
        Basics Review Questions<img src="vspacer.GIF" width="10"
        height="10"></b>Chapter III - The Boat</font></td>
    </tr>
</table>
</center></div>

<p><font color="#000080">Following are questions that relate to
Chapter III, The Boat, which you hopefully have just completed.
If you would like to track your progress please complete the form
with your name and email address and the results will be returned
to you. To answer each question simply click the button beside
the answer you think is correct and when you have finished click
on the &quot;Tell me my grade!&quot; button at the end of the
exam. You can change your answers at any time or you may clear
the exam entirely by clicking on the &quot;Let me try
again!&quot; button. </font><font color="#FF0000">Good Luck!</font></p>

<p align="center"><font size="2"><i>Copyright 1996/97 Moonraker
Productions, Inc.<br>
</i></font><a href="mailto:nauticalknowhow@tcmall.com"><font
size="2">moonraker@tcmall.com</font></a></p>

</body>
</html>
======================================
ch3qq.htm loads into an invisible frame and has the question data
NOTE since I don't know the subject I made the first answer of each set the "correct" one and I have explained in email how to edit the last part of the data. See function question{} to see how data is arranged.
========================================
<SCRIPT LANGUAGE="JavaScript">
<!--
top.Number_of_Questions =    10

// create new array named Quiz
top.Quiz    = new top.makeArray(top.Number_of_Questions)
top.ANSWERS = new top.makeArray(top.Number_of_Questions)

top.Quiz[ 1] = new top.Question('If something is "abeam to port" it is:','straight out from the middle of the boat, on the left side;straight out from the middle of the boat, on the right side;behind you to the right;in front of you to the left','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 2] = new top.Question('Something on the starboard side is:','on the side with the star;on top of the boat;on the bottom of the boat;on the right side looking forward','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 3] = new top.Question('A "Class A" boat is:','very fast;less than 16 feet in length;26 feet in length or more;over 65 feet in length','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 4] = new top.Question('You measure the length overall (LOA) of a boat:','from stem to stern along the side;from front to back over the top;along the centerline from the outside of the hull aft to the outside of the hull forward;from back to front where the water touches','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 5] = new top.Question('Displacement vessels:','have a small underwater profile;must have a mast;are very fast boats;are designed to move through the water with a minimum of propulsion','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 6] = new top.Question('Most small utility boats:','plane easily;are flat-bottom;may be unstable;all of the above','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 7] = new top.Question('Most small boats are powered by:','inboard engines;outboard engines;inboard/outboard engines;jet drives','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 8] = new top.Question('A boat\'s capacity plate tells you:','how much the boat weighs;the boat\'s top speed;the maximum horsepower recommended for the boat;the number of life jackets required','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[ 9] = new top.Question('The most common cause of boat breakdowns is:','lack of fuel;low on oil;low on water;corrosion','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)

top.Quiz[10] = new top.Question('The first thing you should look for after starting your engine is:','smoke;water from the discharge to indicate that the cooling system is working;sparks;fumes','Feedback for answer 1;Feedback for answer 2;Feedback for answer 3;Feedback for answer 4',"1;0;0;0",1)


// The positioning of this ensures that all data is in place before any attempt is made to display the questions.
top.doDisplay(top.Display)

//-->
</SCRIPT>

I do not advise any attempt to edit these files except with a text editor. eg Notepad.

0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
Deprecated and Headed for the Dustbin By now, you have probably heard that some PHP features, while convenient, can also cause PHP security problems.  This article discusses one of those, called register_globals.  It is a thing you do not want.  …
This video teaches users how to migrate an existing Wordpress website to a new domain.
The viewer will learn how to dynamically set the form action using jQuery.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now