[system] / trunk / webwork-modperl / lib / WeBWorK / ContentGenerator / Problem.pm Repository:
ViewVC logotype

View of /trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/Problem.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 415 - (download) (as text) (annotate)
Wed Jun 26 13:33:59 2002 UTC (10 years, 10 months ago) by sh002i
File size: 11510 byte(s)
stuff i've been working on.
-sam

    1 package WeBWorK::ContentGenerator::Problem;
    2 use base qw(WeBWorK::ContentGenerator);
    3 
    4 use strict;
    5 use warnings;
    6 use Apache::Constants qw(:common);
    7 use WeBWorK::ContentGenerator;
    8 use WeBWorK::PG;
    9 
   10 # "Classic" form fields from processProblem8.pl
   11 #
   12 # user - user ID
   13 # key - session key
   14 # course - course name
   15 # probSetKey - USUALLY known as the PSVN
   16 # probNum - problem number a.k.a. ID a.k.a. name
   17 #
   18 # Mode - display mode (HTML, HTML_tth, or typeset or whatever it's called)
   19 # show_old_answers - whether or not student's old answers should be filled in
   20 # ShowAns - asks for correct answer to be shown -- only available for instructors
   21 # answer$i - student answers
   22 # showEdit - checks if the ShowEditor button should be shown and clicked
   23 # showSol - checks if the solution button ishould be shown and clicked
   24 #
   25 # source - contains modified problem source when called from the web-based problem editor
   26 # seed - contains problem seed when called from the web-based problem editor
   27 # readSourceFromHTMLQ - if true, problem is read from 'source' instead of file
   28 # action - submit button clicked to invoke script (alledgedly)
   29 #   'Save updated version'
   30 #   'Read problem from disk'
   31 #   'Submit Answers'
   32 #   'Preview Answers'
   33 #   'Preview Again'
   34 # probFileName - name of the PG file being edited
   35 # languageType - afaik, always set to 'pg'
   36 
   37 sub title {
   38   my ($self, $problem_set, $problem) = @_;
   39   my $r = $self->{r};
   40   my $user = $r->param('user');
   41   return "Problem $problem of problem set $problem_set for $user";
   42 }
   43 
   44 sub body {
   45   my ($self, $problem_set, $problem) = @_;
   46 
   47   # we have to call init_translator like this:
   48   my $pt = WeBWorK::PG->new($courseEnv, $userName, $setName, $problemNumber, $formData);
   49 
   50   #
   51 
   52   # ----- this is not a place of honor -----
   53 
   54   # Run the problem (output the html text) but also store it within the object.
   55   # The correct answers are also calculated and stored within the object
   56   $pt ->translate();
   57 
   58   # print problem output
   59   print "Problem goes here<p>\n";
   60   print "Problem output <br>\n";
   61   print "<HR>";
   62   print ${$pt->r_text()};
   63   print "<HR>";
   64   print "<p>End of problem output<br>";
   65 
   66 
   67   # print source code
   68   print "Source code<pre>\n";
   69   print $SOURCE1;
   70   print "</pre>End source code<p>";
   71 
   72   # The format for the output is described here.  We'll need a local variable
   73   # to handle the warnings.  From within the problem the warning command
   74   # has been slaved to the __WARNINGS__  routine which is defined in Global.
   75   # We'll need to provide an alternate mechanism.
   76   # The base64 encoding is only needed for xml transmission.
   77   print "<hr>";
   78   print "Warnings output<br>";
   79   my $WARNINGS = "Let this be a warning:";
   80 
   81   print $WARNINGS;
   82 
   83   # Install the standard problem grader.  See gage/xmlrpc/daemon.pm or processProblem8 for detailed
   84   # code on how to choose which problem grader to install, depending on courseEnvironment and problem data.
   85   # See also PG.pl which provides for problem by problem overrides.
   86   $pt->rf_problem_grader($pt->rf_std_problem_grader);
   87 
   88   # creates and stores a hash of answer results inside the object: $rh_answer_results
   89   $pt -> process_answers($rh->{envir}->{inputs_ref});
   90 
   91 
   92   # THE UPDATE AND GRADING LOGIC COULD USE AN OVERHAUL.  IT WAS SOMEWHAT CONSTRAINED
   93   # BY LEGACY CONDITIONS IN THE ORIGINAL PROCESSPROBLEM8.  IT'S NOT BAD
   94   # BUT IT COULD PROBABLY BE MADE A LITTLE MORE STRAIGHT FORWARD.
   95   #
   96   # updates the problem state stored by the translator object from the problemEnvironment data
   97 
   98   # $pt->rh_problem_state({ recorded_score      => $rh->{problem_state}->{recorded_score},
   99   #             num_of_correct_ans    => $rh->{problem_state}->{num_of_correct_ans} ,
  100   #             num_of_incorrect_ans  => $rh->{problem_state}->{num_of_incorrect_ans}
  101   #           } );
  102 
  103   # grade the problem (and update the problem state again.)
  104   #
  105   # Define an entry order -- the default is the order they are received from the browser.
  106   # (Which as I understand it is NOT guaranteed to be the Left->Right Up-> Down order we're
  107   # used to in the West.
  108 
  109   my %PG_FLAGS = $pt->h_flags;
  110     my $ra_answer_entry_order = ( defined($PG_FLAGS{ANSWER_ENTRY_ORDER}) ) ?
  111                 $PG_FLAGS{ANSWER_ENTRY_ORDER} : [ keys %{$pt->rh_evaluated_answers} ] ;
  112   # Decide whether any answers were submitted.
  113     my  $answers_submitted = 0;
  114       $answers_submitted = 1 if defined( $rh->{answer_form_submitted} ) and 1 == $rh->{answer_form_submitted};
  115   # If there are answers, grade them
  116     my ($rh_problem_result,$rh_problem_state) = $pt->grade_problem( answers_submitted => $answers_submitted,
  117                                    ANSWER_ENTRY_ORDER => $ra_answer_entry_order
  118                                    );       # grades the problem.
  119 
  120   # Output format expected by Webwork.pm (and I believe processProblem8, but check.)
  121   my $out = {
  122           text            => ${$pt ->r_text()}, #  encode_base64( ${$pt ->r_text()}  ),
  123           header_text         => $pt->r_header,     # encode_base64( ${ $pt->r_header } ),
  124           answers           => $pt->rh_evaluated_answers,
  125           errors                => $pt-> errors(),
  126           WARNINGS            => $WARNINGS,          #encode_base64($WARNINGS ),
  127           problem_result        => $rh_problem_result,
  128           problem_state       => $rh_problem_state,
  129           PG_flag           => \%PG_FLAGS
  130          };
  131 
  132   # Debugging printout of environment tables
  133   print "<P>Request item<P>\n\n";
  134   print "<TABLE border=\"3\">";
  135   print $self->print_form_data('<tr><td>','</td><td>','</td></tr>');
  136   print "</table>\n";
  137   print "path info <br>\n";
  138   print $r->path_info();
  139   print "<P>\n\ncourseEnvironment<P>\n\n";
  140   print pretty_print_rh($courseEnvironment);
  141   print "<P>\n\nproblemEnvironment<P>\n\n";
  142   print pretty_print_rh($problemEnvir_rh);
  143 
  144   "";
  145 }
  146 
  147 sub pretty_print_rh {
  148     my $r_input = shift;
  149     my $out = '';
  150     if ( not ref($r_input) ) {
  151       $out = $r_input;    # not a reference
  152     } elsif (is_hash_ref($r_input)) {
  153       local($^W) = 0;
  154     $out .= "<TABLE border = \"2\" cellpadding = \"3\" BGCOLOR = \"#FFFFFF\">";
  155     foreach my $key (sort keys %$r_input ) {
  156       $out .= "<tr><TD> $key</TD><TD>=&gt;</td><td>&nbsp;".pretty_print_rh($r_input->{$key}) . "</td></tr>";
  157     }
  158     $out .="</table>";
  159   } elsif (is_array_ref($r_input) ) {
  160     my @array = @$r_input;
  161     $out .= "( " ;
  162     while (@array) {
  163       $out .= pretty_print_rh(shift @array) . " , ";
  164     }
  165     $out .= " )";
  166   } elsif (ref($r_input) eq 'CODE') {
  167     $out = "$r_input";
  168   } else {
  169     $out = $r_input;
  170   }
  171     $out;
  172 }
  173 
  174 sub is_hash_ref {
  175   my $in =shift;
  176   my $save_SIG_die_trap = $SIG{__DIE__};
  177     $SIG{__DIE__} = sub {CORE::die(@_) };
  178   my $out = eval{  %{   $in  }  };
  179   $out = ($@ eq '') ? 1 : 0;
  180   $@='';
  181   $SIG{__DIE__} = $save_SIG_die_trap;
  182   $out;
  183 }
  184 sub is_array_ref {
  185   my $in =shift;
  186   my $save_SIG_die_trap = $SIG{__DIE__};
  187     $SIG{__DIE__} = sub {CORE::die(@_) };
  188   my $out = eval{  @{   $in  }  };
  189   $out = ($@ eq '') ? 1 : 0;
  190   $@='';
  191   $SIG{__DIE__} = $save_SIG_die_trap;
  192   $out;
  193 }
  194 
  195 1;
  196 
  197 __END__
  198 
  199 my $foo =0;
  200 
  201 # The warning mechanism.  This needs to be turned into an object of its own
  202 ###############
  203 ## Error message routines cribbed from CGI
  204 ###############
  205 
  206 BEGIN {    #error message routines cribbed from CGI
  207 
  208   my $CarpLevel = 0;  # How many extra package levels to skip on carp.
  209   my $MaxEvalLen = 0; # How much eval '...text...' to show. 0 = all.
  210 
  211   sub longmess {
  212     my $error = shift;
  213     my $mess = "";
  214     my $i = 1 + $CarpLevel;
  215     my ($pack,$file,$line,$sub,$eval,$require);
  216 
  217     while (($pack,$file,$line,$sub,undef,undef,$eval,$require) = caller($i++)) {
  218       if ($error =~ m/\n$/) {
  219         $mess .= $error;
  220       }
  221       else {
  222         if (defined $eval) {
  223           if ($require) {
  224             $sub = "require $eval";
  225           }
  226           else {
  227             $eval =~ s/[\\\']/\\$&/g;
  228             if ($MaxEvalLen && length($eval) > $MaxEvalLen) {
  229               substr($eval,$MaxEvalLen) = '...';
  230             }
  231             $sub = "eval '$eval'";
  232           }
  233         }
  234         elsif ($sub eq '(eval)') {
  235           $sub = 'eval {...}';
  236         }
  237 
  238         $mess .= "\t$sub " if $error eq "called";
  239         $mess .= "$error at $file line $line\n";
  240       }
  241 
  242       $error = "called";
  243     }
  244 
  245     $mess || $error;
  246   }
  247 }
  248 ###############
  249 ### Our error messages for giving maximum feedback to the user for errors within problems.
  250 ###############
  251 BEGIN {
  252   sub PG_floating_point_exception_handler {       # 1st argument is signal name
  253     my($sig) = @_;
  254     print "Content-type: text/html\n\n<H4>There was a floating point arithmetic error (exception SIG$sig )</H4>--perhaps
  255     you divided by zero or took the square root of a negative number?
  256     <BR>\n Use the back button to return to the previous page and recheck your entries.<BR>\n";
  257     exit(0);
  258   }
  259 
  260   $SIG{'FPE'}  = \&PG_floating_point_exception_handler;
  261 #!/usr/bin/perl  -w
  262   sub PG_warnings_handler {
  263     my @input = @_;
  264     my $msg_string = longmess(@_);
  265     my @msg_array = split("\n",$msg_string);
  266     my $out_string = '';
  267 
  268     # Extra stack information is provided in this next block
  269     # If the warning message does NOT end in \n then a line
  270     # number is appended (see Perl manual about warn function)
  271     # The presence of the line number is detected below and extra
  272     # stack information is added.
  273     # To suppress the line number and the extra stack information
  274     # add \n to the end of a warn message (in .pl files.  In .pg
  275     # files add ~~n instead
  276 
  277     if ($input[$#input]=~/line \d*\.\s*$/) {
  278       $out_string .= "##More details: <BR>\n----";
  279       foreach my $line (@msg_array) {
  280         chomp($line);
  281         next unless $line =~/\w+\:\:/;
  282         $out_string .= "----" .$line . "<BR>\n";
  283       }
  284     }
  285 
  286     $Global::WARNINGS .="*  " . join("<BR>",@input) . "<BR>\n" . $out_string .
  287                         "<BR>\n--------------------------------------<BR>\n<BR>\n";
  288     $Global::background_plain_url = $Global::background_warn_url;
  289     $Global::bg_color = '#FF99CC';  #for warnings -- this change may come too late
  290   }
  291 
  292   $SIG{__WARN__}=\&PG_warnings_handler;
  293 
  294   $SIG{__DIE__} = sub {
  295       my $message = longmess(@_);
  296       $message =~ s/\n/<BR>\n/;
  297       my ($package, $filename, $line) = caller();
  298       # use standard die for errors eminating from XML::Parser::Expat
  299       # it uses a trapped eval which sometimes fails -- apparently on purpose
  300       # and the error is handled by Expat itself.  We don't want
  301       # to interfer with that.
  302 
  303       if ($package eq 'XML::Parser::Expat') {
  304         die @_;
  305       }
  306       #print  "$package $filename $line \n";
  307     print
  308     "Content-type: text/html\r\n\r\n <h4>Software error</h4> <p>\n\n$message\n<p>\n
  309     Please inform the webwork meister.<p>\n
  310     In addition to the error message above the following warnings were detected:
  311     <HR>
  312     $Global::WARNINGS;
  313     <HR>
  314     It's sometimes hard to tell exactly what has gone wrong since the
  315     full error message may have been sent to
  316     standard error instead of to standard out.
  317     <p> To debug  you can
  318     <ul>
  319     <li> guess what went wrong and try to fix it.
  320     <li> call the offending script directly from the command line
  321     of unix
  322     <li> enable the debugging features by redefining
  323     \$cgiURL in Global.pm and checking the redirection scripts in
  324     system/cgi. This will force the standard error to be placed
  325     in the standard out pipe as well.
  326     <li> Run tail -f error_log <br>
  327     from the unix command line to see error messages from the webserver.
  328     The standard error output is being placed in the error_log file for the apache
  329     web server.  To run this command you have to be in the directory containing the
  330     error_log or enter the full path name of the error_log. <p>
  331     In a standard apache installation, this file is at /usr/local/apache/logs/error_log<p>
  332     In a RedHat Linux installation, this file is at /var/log/httpd/error_log<p>
  333     At Rochester this file is at /ww/logs/error_log.
  334     </ul>
  335     Good luck.<p>\n" ;
  336   };
  337 
  338 
  339 
  340 }

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9