您的位置:寻梦网首页编程乐园CGI编程Zhanshou's CGI Tutorial

On Line Test


Online Test is not new for us. In fact, many important tests such as GRE, GMAT can be taken on line instead of paper work. On line test is safety and fast. No hard copies need to be sent from one place to another place. What we need to do is just to put the test on the line at the test starting time. Once the testers submit their answers, they can know their final score immediately. Professors should be happy about this. I believe they'd rather do some useful research work than grade over hundreds of annoying student tests.

HTML FORM

Here is the online test HTML FORM. I do not want to talk more about it here, any question you can reference the HTML FORM in the previous topic.

<html><body>
<center><h1>On Line Test</h1>
<hr>
<form method=POST action="cgi-bin/onlineTest.pl">
<table>
<tr><td bgcolor="yellowgreen"> Your  Name:</td><td>  <INPUT NAME="name" TYPE="TEXT" SIZE="20" MAXLENGTH="30"></td>  
    <td bgcolor="yellowgreen"> SSN:</td><td>  <INPUT NAME="ssn" TYPE="TEXT" SIZE="20" MAXLENGTH="30"></td></tr>
</table></center>
<hr width="50%">
Select the correct answer for the following questions. Question 1 to 4 has only one correct
answer while question 5 may have servral correcrt answers. Each question carries 20 point. For 
question 5 , if you select partial correct answer, you will get partial point. But if you select even
one incorrect answer, you will get nothing.
<ol>
<li>Where is the home for Java programming language?
  <ul>
  <li><input type="radio" name="home" value="A"> Microsoft Inc. 
  <li><input type="radio" name="home" value="B"> Sun Microsystem
  <li><input type="radio" name="home" value="C"> Netscape Inc.
  <li><input type="radio" name="home" value="D"> Borland Inc.
 </ul>
<li>Which of the following is the first graphical Web browser:
  <ul>
 <li> <input type="radio" name="browser" value="A"> Netscape
 <li> <input type="radio" name="browser" value="B"> Internet explorer 
 <li> <input type="radio" name="browser" value="C"> Hotjava
 <li> <input type="radio" name="browser" value="D"> Mosaic
 </ul>
<li> Who is the designer of Mosaic?<br>
   <select name="designer">
   <option selected value=""> Get your choice
   <option value="A"">Bill Gate
   <option value="B">Jame Gosling
   <option value="C">Marc Andreeson
   <option Value="D">Matthew Wright
</select>
<li> What is CGI?
 <ul>
 <li> <input type="radio" name="CGI" value="A"> A program
 <li> <input type="radio" name="CGI" value="B"> A computer Language 
 <li> <input type="radio" name="CGI" value="C"> A collection of protocol
 <li> <input type="radio" name="CGI" value="D"> None of above
 </ul>
<li>Which of the language(s) is(are) object-oriented?
<ol>
<li><input type="checkbox" name="Java" value="Y"> Java
<li><input type="checkbox" name="Fortran" value="Y"> Fortran
<li><input type="checkbox" name="Smalltalk" value="Y"> Smalltalk
<li><input type="checkbox" name="C" value="Y">C
</ol> 
</ol>
<hr>
<center>      <INPUT TYPE="SUBMIT" VALUE="Submit">        <INPUT TYPE="RESET"></center></form>
</body></html>

onlineTest.pl

Here is the CGI program, note that the red number is not part of the program, I add them just for my convenience to explain.

(1)
 #!/usr/local/bin/perl
 ########################################################################
 #  onlineTest.pl
 #  11/26/97 by Zhanshou Yu
 #  Any comments please send to :
 #  zhanshou@hotmail.com
 ######################################################################## 
(2)
 #Get the system date
 $date=`/usr/bin/date`;
 chop($date);         #chop the last enter character
(3)
 #get the input data from the form. Here I use POST method 
 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
(4)
 #Split the name-value pairs.
 @pairs=split(/&/,$buffer);

 #for each name=value pair, seperate them.
 foreach $pair(@pairs){
    ($name,$value)=split(/=/,$pair);  #split name=value to name value
    $value=~tr/+/ /;                  #substitute plus sign with space sign
    $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; #decode hexdecimal to character
    $FORM{$name}=$value;
 }
(5)
 # print html header 
 print" Content-type:text/html\n\n";
(6)
 # Check whether you fill out Your Name field and SSN field, if not , ask you back to fill out them.
 &missing_field('Your Name') unless ($FORM{'name'});
 &missing_field('SSN') unless ($FORM{'ssn'}); 
(7)
 #print html head, title, your name, SSN, your IP address and submit date. 
 print "<html><head><Title>Online Test Final Score</Title></head>";
 print "<center><h1> Online Test Final Result</h1></center>";
 print"<center><h4><table><tr><td> Your Name :</td> <td bgcolor=yellowgreen>$FORM{'name'}</td>";
 print"<td>SSN:</td><td bgcolor=yellowgreen> $FORM{'ssn'}</td></tr>";
 print"<tr><td>You are from :</td><td bgcolor=yellowgreen>$ENV{'REMOTE_ADDR'}</td>";
 print "<td>Submit date:</td><td bgcolor=yellowgreen> $date </td></tr></table></h4></center>";
 print "<p> Here is the result for each answer:";
 print "<ol>"; 
(8)
 #Initial the $score to 0
 $score=0;
(9)
 #########Analyze the Question No.1.#########################

 # if answer is B (which stands for Sun Microsystem), add 20 points.
 # else print wrong answer.
 if($FORM{'home'} eq 'B') {
  $score=$score+20;
 print "<li> Correct.\n";
 }
 else {print "<li> Wrong";}  
(10)
 #########Analyze the Question No.2.#########################

 # if answer is D (which stands for Mosaic), add 20 points.
 # else print wrong answer.
 if($FORM{'browser'} eq 'D') {
  $score=$score+20;
  print "<li> Correct.\n";
 }
 else {print "<li> Wrong";}  
(11)
 #########Analyze the Question No.3#########################

 # if answer is C (which stands for Marc Andreeson), add 20 points.
 # else print wrong answer.
 if($FORM{'designer'} eq 'C') {
 $score=$score+20;
 print "<li> Correct.\n";
 }
 else {print "<li> Wrong";}  
(12)
 #########Analyze the Question No.4#########################

 # if answer is C , add 20 points.
 # else print wrong answer.
 if($FORM{'CGI'} eq 'C') {
  $score=$score+20;
  print "<li> Correct.\n";
 }
 else {print "<li> Wrong";}  

 (13)
 #########Analyze the Question No.5#########################

 # If select either FORTRAN or C, then wrong.
 # Else if select either Smalltalk or Java, get 10 points
 # Else select both Smalltalk and Java , get 20 points.
 $flag=0;
 if(($FORM{'Fortran'} ne 'Y') && ($FORM{'C'} ne 'Y')) {
    if(($FORM{'Java'} eq 'Y')&&($FORM{'Smalltalk'} eq 'Y')) {
     $score=$score+20;
     $flag=2;
     }
    elsif(($FORM{'Java'} eq 'Y')||($FORM{'Smalltalk'} eq 'Y')) {
     $score=$score+10;
     $flag=1;
  }
 }
 if($flag==2){   print "<li> Correct.\n";}
 elsif($flag==1){
    print "<li> Partial correct.\n";
 }
 else {print "<li> Wrong";}  
 print "</ol>";
(14)
 #Print total score
 print "<p><h4>Your total score <font color=#228b22>$score/100</font>.";
 if($score<=40){ print " You are not so good, you still need  study hard !";}
 elsif($score<=80){ print " You are good. But if you study harder, you will be better.";}
 else { print " You are terrific. You really know a lot about computer science.";}
 
 print "</h4></body></html>";

(15)
 #missing_field subrountine. If mission field, print out error message.
 sub missing_field {
  local($variable)=@_;
  print "<html><head><Title>Online Test Sumission Error</Title></head>";
  print "<center><h1> Online Test Submission Error!</h1></center>";
  print "<center> <TABLE  width=\"50%\">";
  print" <TR><TD bgcolor=#007000 align=center><FONT color=#00FF9F>";
  print" You did not fill the <i>$variable </i>field.\n";
  print" Please <a href=\"http://www.cba.uh.edu/CGITutorial/online.html\">Go Back</a> to the form and fill out it. Thank you.\n";
  print "</FONT></TD></TR> </TABLE></center>";
  exit;
 }

Program Analysis

Let's take a close look at each part:
  • (1):
     #!/usr/local/bin/perl
    invokes the perl interpreter to execute this program, this line can not be omitted in Unix system.

  • (2) Get the system date:

    /usr/bin/date is a shell command that returns the current date and time. The chop($date) function delete the last character (newline character) from the $date string.

  • (3).
     read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
    Read the input data from user. Here we use POST method. Remember for POST method the input data is read from standard input file(STDIN), different from GET method where we us "QUERY_STRING" environment variable to receive input data.

  • (4) Input data parsing and decoding.

    Recall in previous Encoding Scheme topic, we mentioned that before input data were sent to the server, they need to be encoded. So after we receive the input data, the first step we need to do is to decode them. We know that the received data in the format of :

          name1=value1&name2=value2&name3=value3...
    First split the name=value pairs into an string array @pairs.:
          @pairs=split(/&/,$buffer);
    Now @pairs=(name1=value1,name2=value2,name3=value3)

    Then we need to separate names and values

          ($name,$value)=split(/=/,$pair);

    Next substitute plus sign with space sign:

          $value=~tr/+/ /;

    Translate hexdecimal to character

          $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;

    Finally associate each name with value:

          $FORM{$name}=$value;

  • (5). Print the html header :
           print" Content-type:text/html\n\n";
    which tell the server that this is a html file instead other MIME type files. Note the two new line characters following the context-type, they can not be ignored.

  • (6). For each field in the form, we can specify it either required or optical. Some fields must be filled out, while others whether filled out or not are both acceptable. In this example we specify the Your Name and the SSN fields are the required fields. So We need to check them first. If they were filled out, you can submit your query otherwise go back and fill out the required fields. This is why we need the following statements:
      &missing_field('Your Name') unless ($FORM{'name'});
      &missing_field('SSN') unless ($FORM{'ssn'}); 
    
    Here missing_field is a subroutine that inform you that you didn't fill out some fields.

  • ( 7) is nothing but print out html head, title, your name, SSN, your IP address and submit date.

  • ( 8). Before grade the test, we need to initialize the total score to 0:
    $score=0;

  • ( 9)Analyze the first question:
    if($FORM{'home'} eq 'B') {
      $score=$score+20;
     print "<li> Correct.\n";
     }
     else {print "<li> Wrong";} 
    
    If the answer is 'B', which stands for Sun Microsystem, then add 20 points to the total score and print out the correct message. Other wise, print wrong messge.

    Part (10), (11), (12), (13) are similar to part (9).

  • (14) :
    print "<p><h4>Your total score <font color=#228b22>$score/100</font>.";
    if($score<=40){ print " You are not so good, you still need  study hard !";}
    elsif($score<=80){ print " You are good. But if you study harder, you will be better.";}
    else { print " You are terrific. You really know a lot about computer science.";}
    
    Print out the total score and comment : if your score is no more than 40, print the message "You are not so good, you still need study hard !"; if your score is between 40 and 80, the message is " You are good. But if you study harder, you will be better."; if you get more than 80 points, the comment is "You are terrific. You really know a lot about computer science.".

  • (15) is a subroutine to print out error message if you missing some required fields.

Previous Page Table of Content Next Page