#!/usr/local/bin/perl # check-box.cgi, version 1.0 written in Perl 5.0, last revision 8/15/96. # A PERL script that generates HTML pages containing either a # multiple-choice question or the corresponding response page # after the user submits an answer. The questions can have multiple # answers, ie choices 2,5, and 6 can be correct. Logs student response in a # datafile for grading purposes. # The script reads the question and response information from a text # data file of the form: # # The next two lines contain the page title and question topic that will be displayed at the top of the web page. # SEQ Question # Example 1 # # The next line contains the question. # Near-IR is a popular technique used in the following applications: # # The next x lines are for the x number of answers for the question. # Process control # Food analysis # Microscopy of metal surfaces # # The next 2 lines contain the sequential numbers of the correct answers and an optional explanation. # 1,2 # Near-IR is not useful for microscopy applications. # # The next four lines are dummy slots for features not implemented. # NA # NA # NA # NA # For more information see: # http://www.chem.vt.edu/chem-ed/CHP/scripts/perl/mccheck.html. # Program and concept by Ron Earp and Brian Tissue. # Copyright 1996 by Ronald L. Earp and Brian M. Tissue, all rights reserved. require "cgi-utils.pl"; # Automatically sets the path to the location to the script $script_location="http://"."$ENV{'SERVER_NAME'}"."$ENV{'SCRIPT_NAME'}"; $data_path="/disk2/script-data/mcquestions"; $roster_path="/disk2/script-data/rosters/"; &set_variables; &start_page; # Retrieve cgi variables being passed %parameters = &get_query; if (&open_file) { if ($parameters{'makeanswer'}) { # Display answer if if (&check_input) { if (&roll_search) { &display_question; &display_answers; &format_array; &grading; &display_gradeserver; } else { &search_error; } } else { &form_not_complete; } } # Display answer if else { # Display question if &display_question; &display_choices; } # Display question if } # Create end of HTML page. &end_page; # END OF MAIN SCRIPT. # BEGINNING OF SUBROUTINES. sub start_page { print ("Content-type: text/html\n\n"); print ("\n"); print "\n"; } sub set_variables { # Set variables for question responses. $incorrect_response="Your responses are incorrect."; $correct_response="Your response is correct."; $answer_tag=" *** Correct Answer *** "; # Set variables for the line positions of information in the data file. # Counting starts at 0 in the question file. $title1 = 1; $title2 = 2; $question = 4; $answers = 6; # These varibles describe the positions of the correct answer and explination # text relative to the last answer choice. $answerpos = 1; $explanationpos = 2; # This variable refers to the number of lines in the question data file # that are not displayed as poart of the question. $deadlines = 14; $index = 0; $fail = 0; } sub end_page { print ""; } sub file_error_message { print "

Error serving request


\n"; print "The filename: $qfile is incorrect or doesn't exist. All valid question data files end with a .qdf extension.\n"; print "Ask your instructor to check the question link.\n"; $fail = 1; } sub open_file { $qfile = "$data_path"."$parameters{'filename'}"; if (($qfile =~ /.qdf/) and open(QFILE, $qfile)) { @qarray = ; $qlength = @qarray; close(QFILE); return ("1"); } else { &file_error_message; return ("0"); } } sub display_question { print "",$qarray[$index + $title1],"\n"; print "

",$qarray[$index + $title1],"

\n"; print "

",$qarray[$index + $title2],"

\n"; print "
\n"; print "$qarray[$index + $question]

\n"; } sub display_choices { # Code to display the answers from the array. Backslash characters # are used to denote literals, such as @ or " within a string. print "

"; print "\n"; print " \n"; print " \n"; # Display answers for question. print "
    \n"; $maxcount = ($qlength - 14); $count = 0; while ($count < $maxcount) { $value = $count + 1; print "
  1. $qarray[$answers + $count] \n"; $count++; } print " \n"; print "
    \n"; # Put control here for checking of logging print "Class number: \n"; print "\n"; print "Student ID: \n"; print "\n"; print "

    \n"; print " \n"; print "

  2. \n"; print "
    \n"; } sub display_answers { print "
      \n"; $maxcount = ($qlength - $deadlines); print "
      \n"; @print_answers = split(/,/, $qarray[$answers + $maxcount + $answerpos]); $print_answer_length = @print_answers; for ($count = 0; $count < $maxcount; $count++) { $flag = 0; for ($search = 0; $search < $print_answer_length; $search++) { if (($print_answers[$search] - 1) == $count) { print "
    1. $qarray[$answers + $count] $answer_tag \n"; $flag = 1; } } if ($flag == 0) { print "
    2. $qarray[$answers + $count] \n"; } } print "
    3. \n"; print " \n"; print "
      \n"; print "You selected the following answers: "; for ($loop_control = 1; $loop_control <= $maxcount; $loop_control++) { print "$parameters{$loop_control} "; $user_answer_string = "$user_answer_string"."$parameters{$loop_control}"; } print "
      \n"; @answers = split(/,/, $qarray[$answers + $maxcount + $answerpos]); $answer_string = join("", @answers); $print_answer_string = join(" ", @answers); # Branching to provide output based on the users selection. if ($user_answer_string == $answer_string) { print "$correct_response
      \n"; $correct = 1; } else { print "$incorrect_response The correct answers are: $print_answer_string
      \n"; $correct = 0; } print "
      \n"; print $qarray[$answers + $maxcount + $explanationpos]; print "

      \n"; } sub form_not_complete { print "

      Error serving request


      \n"; print "You did not complete all sections of the question. You must provide an answer, \n"; print "class number, and student ID.

      \n"; print "Back to the question."; $fail = 1; } sub search_error { print "

      Error serving request


      \n"; print "Your student ID wasn't found in the class roll or the roll doesn't exist. Make sure that your \n"; print "class number and student ID were entered correctly.

      \n"; print "Back to the question."; $fail = 1; } sub write_error { print "

      Error serving request


      \n"; print "An error has occured writing to the grade log file. Your grade has not been logged. \n"; print "Please inform your instructor of this error.

      \n"; print "Back to the question.\n"; $fail = 1; } sub check_input { if (($parameters{'class'}) and ($parameters{'stid'})) { $id_length = length($parameters{'stid'}); if ($id_length != 9) { return("0") } else { return("1"); } } else { return("0"); } } sub format_array { @words = split(/\W/, $parameters{'filename'}); $word_length = @words; $qdf_name = $words[$wordlength - 2]; for ($loop_control = 0; $loop_control < $roster_length; $loop_control++) { chop ($roster[$loop_control]); } if ($roster[0] !~ /$qdf_name/) { $roster[0] = "$roster[0]" . ",$qdf_name"; for ($loop_control = 1; $loop_control < $roster_length; $loop_control++) { $roster[$loop_control] = "$roster[$loop_control]" . ",NA"; } } @student_data = split(/\W/, $roster[$student_pos]); $student_data_length = @student_data; @header = split(/\W/, $roster[0]); $header_length = @header; for ($loop_control = 0; $loop_control < $header_length; $loop_control++) { if ($header[$loop_control] =~ /$qdf_name/) { $replace_pos = $loop_control; } } } sub roll_search { $rosterfile = "$roster_path" . "$parameters{'class'}"; if (open(RFILE, $rosterfile)) { # if open file @roster = ; $roster_length = @roster; close(RFILE); for ($loop_control = 1; $loop_control < $roster_length; $loop_control++) { if ($roster[$loop_control] =~ /^$parameters{'stid'}/) { $student_pos = $loop_control; return("1"); } } } # if open file else { return("0"); } } sub check_time { return("1"); } sub grading { if ($student_data[$replace_pos] !~ /\d/) { if ($correct) { if (&check_time) { $student_data[$replace_pos] = "1"; print "Logging results to data file.

      \n"; } else { $student_data[$replace_pos] = "0.5"; print "Logging results to data file.

      \n"; } } else { $student_data[$replace_pos] = "0"; print "Logging results to data file.

      \n"; } for ($loop_control = 0; $loop_control < $student_data_length; $loop_control++) { if ($loop_control == 0) { $new_student_string = "$new_student_string" . "$student_data[$loop_control]"; } else { print "$student_data

      "; $new_student_string = "$new_student_string" . ",$student_data[$loop_control]"; } } $roster[$student_pos] = $new_student_string; &write_file; } else { print "You already have a grade for this question. No data logged.

      \n"; } } sub write_file { if (open(RFILE, ">$rosterfile")) { for ($loop_control = 0; $loop_control < $roster_length; $loop_control++) { print RFILE "$roster[$loop_control]\n"; } close(RFILE); } else { &write_error; } } sub display_gradeserver { print "

      Current grades:

      \n"; print "\n"; for ($loop_control = 0; $loop_control < $student_data_length; $loop_control++) { print "\n"; } print "
      $header[$loop_control]:
      $student_data[$loop_control]
      \n"; } # END OF SUBROUTINES # For testing purposes uncomment these lines # foreach $variable (sort keys %parameters) # { # print "$variable: $parameters{$variable}\n

      "; # }