--- loncom/homework/response.pm 2005/06/29 19:20:10 1.122
+++ loncom/homework/response.pm 2006/03/08 22:17:17 1.137
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# various response type definitons response definition
#
-# $Id: response.pm,v 1.122 2005/06/29 19:20:10 albertel Exp $
+# $Id: response.pm,v 1.137 2006/03/08 22:17:17 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -32,13 +32,12 @@ use Apache::lonlocal;
use Apache::lonnet;
BEGIN {
- &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse'));
+ &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse','customresponse'));
}
sub start_response {
my ($parstack,$safeeval)=@_;
- my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);
- if ($id eq '') { $id = $Apache::lonxml::curdepth; }
+ my $id = &Apache::lonxml::get_id($parstack,$safeeval);
if ($#Apache::inputtags::import > -1) {
&Apache::lonxml::debug("Turning :$id: into");
$id = join('_',@Apache::inputtags::import).'_'.$id;
@@ -69,16 +68,15 @@ sub end_response {
sub start_hintresponse {
my ($parstack,$safeeval)=@_;
- my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);
- if ($id eq '') { $id = $Apache::lonxml::curdepth; }
- push (@Apache::inputtags::response,$id);
- push (@Apache::inputtags::responselist,$id);
+ my $id = &Apache::lonxml::get_id($parstack,$safeeval);
+ push (@Apache::inputtags::hint,$id);
+ push (@Apache::inputtags::hintlist,$id);
push (@Apache::inputtags::paramstack,[%Apache::inputtags::params]);
return $id;
}
sub end_hintresponse {
- pop @Apache::inputtags::response;
+ pop @Apache::inputtags::hint;
if (defined($Apache::inputtags::paramstack[-1])) {
%Apache::inputtags::params=
@{ pop(@Apache::inputtags::paramstack) };
@@ -94,9 +92,9 @@ sub pushrandomnumber {
# do nothing
} else {
my @seed=&Math::Random::random_get_seed();
- push (@randomseeds,\@seed);
+ push(@randomseeds,\@seed);
}
- &Apache::response::setrandomnumber();
+ &Apache::response::setrandomnumber(@_);
}
sub poprandomnumber {
my $rand_alg=&Apache::lonnet::get_rand_alg();
@@ -113,13 +111,14 @@ sub poprandomnumber {
}
sub setrandomnumber {
+ my ($ignore_id2) = @_;
my $rndseed;
$rndseed=&Apache::structuretags::setup_rndseed();
if (!defined($rndseed)) { $rndseed=&Apache::lonnet::rndseed(); }
&Apache::lonxml::debug("randseed $rndseed");
# $rndseed=unpack("%32i",$rndseed);
my $rand_alg=&Apache::lonnet::get_rand_alg();
- my $rndmod;
+ my ($rndmod,$rndmod2);
my ($id1,$id2,$shift_amt);
if ($Apache::lonhomework::parsing_a_problem) {
@@ -130,7 +129,7 @@ sub setrandomnumber {
$shift_amt=scalar(@Apache::inputtags::responselist);
} elsif ($Apache::lonhomework::parsing_a_task) {
$id1=$Apache::bridgetask::dimension;
- if (defined($Apache::bridgetask::instance[-1])) {
+ if (!$ignore_id2 && defined($Apache::bridgetask::instance[-1])) {
$id2=$Apache::bridgetask::instance[-1];
}
$shift_amt=scalar(@Apache::bridgetask::instance);
@@ -143,19 +142,22 @@ sub setrandomnumber {
} elsif ($rand_alg eq '64bit3') {
$rndmod=(&Apache::lonnet::numval2($id1) << 10);
if (defined($id2)) { $rndmod+=&Apache::lonnet::numval2($id2); }
- } else {
+ } elsif ($rand_alg eq '64bit4') {
my $shift=(4*$shift_amt)%30;
$rndmod=(&Apache::lonnet::numval3($id1) << (($shift+15)%30));
if (defined($id2)) {
$rndmod+=(&Apache::lonnet::numval3($id2) << $shift );
}
+ } else {
+ ($rndmod,$rndmod2)=&Apache::lonnet::digest("$id1,$id2");
}
+
if ($rndseed =~/([,:])/) {
my $char=$1;
use integer;
my ($num1,$num2)=split(/\Q$char\E/,$rndseed);
$num1+=$rndmod;
- $num2+=$rndmod;
+ $num2+= ((defined($rndmod2)) ? $rndmod2 : $rndmod);
if($Apache::lonnet::_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
$rndseed=$num1.$char.$num2;
} else {
@@ -358,6 +360,106 @@ sub end_dataresponse {
return $result;
}
+sub start_customresponse {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
+ my $id = &Apache::response::start_response($parstack,$safeeval);
+ push(@Apache::lonxml::namespace,'customresponse');
+ my $result;
+ undef($Apache::response::custom_answer);
+ &Apache::lonxml::register('Apache::response',('answer'));
+ if ($target eq 'web') {
+ if ( &Apache::response::show_answer() ) {
+ my $answer = &Apache::lonxml::get_param('answerdisplay',$parstack,
+ $safeeval);
+ $Apache::inputtags::answertxt{$id}=$answer;
+ }
+ } elsif ($target eq 'edit') {
+ $result.=&Apache::edit::tag_start($target,$token);
+ $result.=&Apache::edit::text_arg('String to display for answer:',
+ 'answerdisplay',$token);
+ $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
+ } elsif ($target eq 'modified') {
+ my $constructtag;
+ $constructtag=&Apache::edit::get_new_args($token,$parstack,
+ $safeeval,'answerdisplay');
+ if ($constructtag) {
+ $result = &Apache::edit::rebuild_tag($token);
+ $result.=&Apache::edit::handle_insert();
+ }
+ } elsif ($target eq 'answer' || $target eq 'grade') {
+ &Apache::response::reset_params();
+ } elsif ($target eq 'meta') {
+ $result .= &Apache::response::meta_package_write('customresponse');
+ }
+ return $result;
+}
+
+sub end_customresponse {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
+ my $result;
+ my $part=$Apache::inputtags::part;
+ my $id=$Apache::inputtags::response[-1];
+ if ( $target eq 'grade' && &Apache::response::submitted() ) {
+ my $response = &Apache::response::getresponse();
+ if ( $response =~ /[^\s]/ &&
+ $Apache::response::custom_answer_type eq 'loncapa/perl') {
+ if (!$Apache::lonxml::default_homework_loaded) {
+ &Apache::lonxml::default_homework_load($safeeval);
+ }
+ my %previous = &Apache::response::check_for_previous($response,
+ $part,$id);
+ $Apache::lonhomework::results{"resource.$part.$id.submission"}=
+ $response;
+ my $error;
+ ${$safeeval->varglob('LONCAPA::customresponse_submission')}=
+ $response;
+
+ my $award = &Apache::run::run('{ my $submission=$LONCAPA::customresponse_submission;'.$Apache::response::custom_answer.'}',$safeeval);
+ if (!&Apache::inputtags::valid_award($award)) {
+ $error = $award;
+ $award = 'ERROR';
+ }
+ &Apache::response::handle_previous(\%previous,$award);
+ $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=
+ $award;
+ if ($error) {
+ $Apache::lonhomework::results{"resource.$part.$id.awardmsg"}=
+ $error;
+ }
+ }
+ }
+ pop(@Apache::lonxml::namespace);
+ &Apache::lonxml::deregister('Apache::response',('answer'));
+ &Apache::response::end_response();
+ return $result;
+}
+
+sub start_answer {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
+ my $result;
+ $Apache::response::custom_answer=
+ &Apache::lonxml::get_all_text_unbalanced("/answer",$parser);
+ $Apache::response::custom_answer_type=
+ lc(&Apache::lonxml::get_param('type',$parstack,$safeeval));
+ $Apache::response::custom_answer_type =~ s/\s+//g;
+ if ($target eq "edit" ) {
+ $result=&Apache::edit::tag_start($target,$token,'Answer algorithm');
+ $result.=&Apache::edit::editfield($token->[1],
+ $Apache::response::custom_answer,
+ '',80,4);
+ } elsif ( $target eq "modified" ) {
+ $result=$token->[4].&Apache::edit::modifiedfield('/answer',$parser);
+ }
+ return $result;
+}
+
+sub end_answer {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
+ if ($target eq 'edit' ) {
+ return &Apache::edit::end_table();
+ }
+}
+
sub decide_package {
my ($tagstack)=@_;
my $package;
@@ -488,15 +590,30 @@ sub setup_params {
}
}
+{
+ my @answer_bits;
+
sub answer_header {
- my ($type) = @_;
+ my ($type,$increment) = @_;
my $result;
if ($env{'form.answer_output_mode'} eq 'tex') {
- $result = ' \vskip 0 mm \begin{tabular}{|c|}\hline Answer for Part: \verb|'.
- $Apache::inputtags::part.'| \\\\ \hline ';
+ undef(@answer_bits);
+ my $bit;
+ if ($Apache::lonhomework::type eq 'exam') {
+ $bit = ($Apache::lonxml::counter+$increment).') ';
+ } else {
+ $bit .= ' Answer for Part: \verb|'.
+ $Apache::inputtags::part.'| ';
+ }
+ push(@answer_bits,$bit);
} else {
- $result = '
Answer for Part:'.
- $Apache::inputtags::part. ' | '."\n";
+ $result = '';
+ if ($Apache::lonhomework::type eq 'exam') {
+ $result .= ''.$Apache::lonxml::counter+$increment. ') | ';
+ } else {
+ $result .= 'Answer for Part:'.$Apache::inputtags::part.' | ';
+ }
+ $result .= "\n";
}
return $result;
}
@@ -505,7 +622,17 @@ sub answer_part {
my ($type,$answer) = @_;
my $result;
if ($env{'form.answer_output_mode'} eq 'tex') {
- $result = ' \verb|'.$answer.'|\\\\ \hline ';
+ my $to_use='|';
+ foreach my $value (32..126) {
+ my $char=pack('c',$value);
+ if ($answer !~ /\Q$char\E/) {
+ $to_use=$char;
+ last;
+ }
+ }
+ if ($answer ne '') {
+ push(@answer_bits,'\verb'.$to_use.$answer.$to_use);
+ }
} else {
$result = ''.$answer.' | ';
}
@@ -516,13 +643,18 @@ sub answer_footer {
my ($type) = @_;
my $result;
if ($env{'form.answer_output_mode'} eq 'tex') {
- $result = ' \end{tabular} \vskip 0 mm ';
+ my $columns = scalar(@answer_bits);
+ $result = ' \vskip 0 mm \noindent \begin{tabular}{|'.'c|'x$columns.'}\hline ';
+ $result .= join(' & ',@answer_bits);
+ $result .= ' \\\\ \\hline \end{tabular} \vskip 0 mm ';
} else {
$result = '
';
}
return $result;
}
+}
+
sub showallfoils {
if (defined($env{'form.showallfoils'})) {
my ($symb)=&Apache::lonxml::whichuser();
@@ -574,8 +706,8 @@ sub repetition {
my $id = $Apache::inputtags::part;
my $weight = &Apache::lonnet::EXT("resource.$id.weight");
if (!defined($weight) || ($weight eq '')) { $weight=1; }
- my $repetition = int $weight/9;
- if ($weight % 9 != 0) {$repetition++;}
+ my $repetition = int($weight/10);
+ if ($weight % 10 != 0) { $repetition++; }
return $repetition;
}
@@ -584,6 +716,7 @@ sub scored_response {
my $repetition=&repetition();
my $score=0;
for (my $i=0;$i<$repetition;$i++) {
+ # A is 1, B is 2, etc. (get response return 0-9 and then we add 1)
my $increase=&Apache::response::getresponse($i+1);
if ($increase ne '') { $score+=$increase+1; }
}
@@ -745,6 +878,29 @@ sub submitted {
return 0;
}
+sub add_to_gradingqueue {
+ my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
+ if ( $courseid eq ''
+ || $symb eq ''
+ || $env{'request.state'} eq 'construct'
+ || $Apache::lonhomework::type ne 'problem') {
+ return;
+ }
+
+ my %queue_info = ( 'type' => 'problem',
+ 'time' => time);
+
+ if (exists($Apache::lonhomework::history{"resource.0.checkedin.slot"})) {
+ $queue_info{'slot'}=
+ $Apache::lonhomework::history{"resource.0.checkedin.slot"};
+ }
+
+ my $result=&Apache::bridgetask::add_to_queue('gradingqueue',\%queue_info);
+ if ($result ne 'ok') {
+ &Apache::lonxml::error("add_to_queue said $result");
+ }
+}
+
# basically undef and 0 (both false) mean that they still have work to do
# and all true values mean that they can't do any more work
#