![]() ![]() | ![]() |
- response uses/understands new larger seed
1: # The LearningOnline Network with CAPA 2: # various response type definitons response definition 3: # 4: # $Id: response.pm,v 1.74 2003/04/30 21:23:45 albertel Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23: # 24: # /home/httpd/html/adm/gpl.txt 25: # 26: # http://www.lon-capa.org/ 27: # 28: # 11/23,11/24,11/28 Gerd Kortemeyer 29: # Guy Albertelli 30: # 08/04,08/07 Gerd Kortemeyer 31: 32: package Apache::response; 33: use strict; 34: 35: BEGIN { 36: &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse')); 37: } 38: 39: sub start_response { 40: my ($parstack,$safeeval)=@_; 41: my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval); 42: if ($id eq '') { $id = $Apache::lonxml::curdepth; } 43: if ($#Apache::inputtags::import > -1) { 44: &Apache::lonxml::debug("Turning :$id: into"); 45: $id = join('_',@Apache::inputtags::import).'_'.$id; 46: &Apache::lonxml::debug("New :$id:"); 47: } 48: push (@Apache::inputtags::response,$id); 49: push (@Apache::inputtags::responselist,$id); 50: @Apache::inputtags::inputlist=(); 51: return $id; 52: } 53: 54: sub end_response { 55: pop @Apache::inputtags::response; 56: @Apache::inputtags::inputlist=(); 57: return ''; 58: } 59: 60: sub start_hintresponse { 61: my ($parstack,$safeeval)=@_; 62: my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval); 63: if ($id eq '') { $id = $Apache::lonxml::curdepth; } 64: push (@Apache::inputtags::response,$id); 65: push (@Apache::inputtags::paramstack,[%Apache::inputtags::params]); 66: return $id; 67: } 68: 69: sub end_hintresponse { 70: pop @Apache::inputtags::response; 71: if (defined($Apache::inputtags::paramstack[-1])) { 72: %Apache::inputtags::params= 73: @{ pop(@Apache::inputtags::paramstack) }; 74: } 75: return ''; 76: } 77: 78: # used by response to set the non-safe space random number generator to something 79: # that is stable and unique based on the part number and response number 80: sub setrandomnumber { 81: my $rndseed; 82: if ($ENV{'request.state'} eq "construct") { 83: $rndseed=$ENV{'form.rndseed'}; 84: if (!$rndseed) { $rndseed=time; } 85: } else { 86: $rndseed=&Apache::lonnet::rndseed(); 87: } 88: &Apache::lonxml::debug("randseed $rndseed"); 89: # $rndseed=unpack("%32i",$rndseed); 90: my $rndmod=(&Apache::lonnet::numval($Apache::inputtags::part) << 10); 91: if (defined($Apache::inputtags::response['-1'])) { 92: $rndmod+=&Apache::lonnet::numval($Apache::inputtags::response[-1]); 93: } 94: if ($rndseed =~/,/) { 95: my ($num1,$num2)=split(/,/,$rndseed); 96: $num1+=$rndmod; 97: $num2+=$rndmod; 98: $rndseed="$num1,$num2"; 99: } else { 100: $rndseed+=$rndmod; 101: } 102: &Apache::lonnet::setup_random_from_rndseed($rndseed); 103: &Apache::lonxml::debug("randseed $rndseed"); 104: return ''; 105: } 106: 107: sub meta_parameter_write { 108: my ($name,$type,$default,$display)=@_; 109: my $partref=$Apache::inputtags::part; 110: my $result='<parameter part="'.$Apache::inputtags::part.'"'; 111: if (defined($Apache::inputtags::response[-1])) { 112: $result.= ' id="'.$Apache::inputtags::response[-1].'"'; 113: $partref.='_'.$Apache::inputtags::response[-1]; 114: } 115: $result.= ' name="'.$name.'"'. 116: ' type="'.$type.'"'. 117: ($default?' default="'.$default.'"':''). 118: ($display?' display="'.$display.' [Part: '.$partref.']"':'') 119: .'></parameter>' 120: ."\n"; 121: return $result; 122: } 123: 124: sub meta_package_write { 125: my $name=shift; 126: my $result = '<parameter part="'.$Apache::inputtags::part.'"'; 127: if(defined($Apache::inputtags::response[-1])) { 128: $result.= ' id="'.$Apache::inputtags::response[-1].'"'; 129: } 130: $result.=' package="'.$name.'"></parameter>'."\n"; 131: return $result; 132: } 133: 134: sub meta_stores_write { 135: my ($name,$type,$display)=@_; 136: my $partref=$Apache::inputtags::part; 137: my $result = '<stores part="'.$Apache::inputtags::part.'"'; 138: if (defined($Apache::inputtags::response[-1])) { 139: $result.= ' id="'.$Apache::inputtags::response[-1].'"'; 140: $partref.='_'.$Apache::inputtags::response[-1]; 141: } 142: $result.= ' name="'.$name.'"'. 143: ' type="'.$type.'"'. 144: ' display="'.$display.' [Part: '.$partref.']"'. 145: "></stores>\n"; 146: } 147: 148: sub mandatory_part_meta { 149: # 150: # Autogenerate metadata for mandatory 151: # input (from RAT or lonparmset) and 152: # output (to lonspreadsheet) 153: # of each part 154: # 155: return 156: # &meta_parameter_write('opendate','date_start','', 157: # 'Opening Date'). 158: # &meta_parameter_write('duedate','date_end','', 159: # 'Due Date'). 160: # &meta_parameter_write('answerdate','date_start','', 161: # 'Show Answer Date'). 162: # &meta_parameter_write('weight','int_zeropos','', 163: # 'Available Points'). 164: # &meta_parameter_write('maxtries','int_pos','', 165: # 'Maximum Number of Tries'). 166: &meta_package_write('part'). 167: &meta_stores_write('solved','string', 168: 'Problem Status'). 169: &meta_stores_write('tries','int_zeropos', 170: 'Number of Attempts'). 171: &meta_stores_write('awarded','float', 172: 'Partial Credit Factor'); 173: # 174: # Note: responseid-specific data 'submission' and 'awarddetail' 175: # not available to spreadsheet -> skip here 176: # 177: } 178: 179: sub check_for_previous { 180: my ($curresponse,$partid,$id) = @_; 181: my %previous; 182: $previous{'used'} = 0; 183: foreach my $key (sort(keys(%Apache::lonhomework::history))) { 184: if ($key =~ /resource\.$partid\.$id\.submission/) { 185: &Apache::lonxml::debug("Trying $key"); 186: my $pastresponse=$Apache::lonhomework::history{$key}; 187: if ($pastresponse eq $curresponse) { 188: $previous{'used'} = 1; 189: my $history; 190: if ( $key =~ /^(\d+):/ ) { 191: $history=$1; 192: $previous{'award'} = $Apache::lonhomework::history{"$history:resource.$partid.$id.awarddetail"}; 193: $previous{'last'}='0'; 194: push(@{ $previous{'version'} },$history); 195: } else { 196: $previous{'award'} = $Apache::lonhomework::history{"resource.$partid.$id.awarddetail"}; 197: $previous{'last'}='1'; 198: } 199: if (! $previous{'award'} ) { $previous{'award'} = 'UNKNOWN'; } 200: &Apache::lonxml::debug("got a match :$previous{'award'}:$previous{'used'}:"); 201: } 202: } 203: } 204: &Apache::lonhomework::showhash(%previous); 205: return %previous; 206: } 207: 208: sub handle_previous { 209: my ($previous,$ad)=@_; 210: if ($$previous{'used'} && ($$previous{'award'} eq $ad) ) { 211: if ($$previous{'last'}) { 212: push(@Apache::inputtags::previous,'PREVIOUSLY_LAST'); 213: } else { 214: push(@Apache::inputtags::previous,'PREVIOUSLY_USED'); 215: } 216: push(@Apache::inputtags::previous_version,$$previous{'version'}); 217: } 218: } 219: 220: sub view_or_modify { 221: my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); 222: my $myself=0; 223: if ( ($name eq $ENV{'user.name'}) && ($domain eq $ENV{'user.domain'}) ) { 224: $myself=1; 225: } 226: my $vgr=&Apache::lonnet::allowed('vgr',$courseid); 227: my $mgr=&Apache::lonnet::allowed('vgr',$courseid); 228: if ($mgr) { return "M"; } 229: if ($vgr) { return "V"; } 230: if ($myself) { return "V"; } 231: return ''; 232: } 233: 234: sub start_dataresponse { 235: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; 236: my $id = &Apache::response::start_response($parstack,$safeeval); 237: my $result; 238: if ($target eq 'web') { 239: $result = $token->[2]->{'display'}.':'; 240: } elsif ($target eq 'meta') { 241: $result = &Apache::response::meta_stores_write($token->[2]->{'name'}, 242: $token->[2]->{'type'}, 243: $token->[2]->{'display'}); 244: $result .= &Apache::response::meta_package_write('dataresponse'); 245: } 246: return $result; 247: } 248: 249: sub end_dataresponse { 250: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; 251: my $result; 252: if ( $target eq 'web' ) { 253: } elsif ($target eq 'grade' ) { 254: if ( defined $ENV{'form.submitted'}) { 255: my ($symb,$courseid,$domain,$name)=&Apache::lonxml::whichuser(); 256: my $allowed=&Apache::lonnet::allowed('mgr',$courseid); 257: if ($allowed) { 258: &Apache::response::setup_params('dataresponse'); 259: my $partid = $Apache::inputtags::part; 260: my $id = $Apache::inputtags::response['-1']; 261: my $response = $ENV{'form.HWVAL_'.$id}; 262: my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval); 263: if ( $response =~ /[^\s]/) { 264: $Apache::lonhomework::results{"resource.$partid.$id.$name"}=$response; 265: $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response; 266: $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}='SUBMITTED'; 267: } 268: } else { 269: $result='Not Permitted to change values.' 270: } 271: } 272: } 273: &Apache::response::end_response; 274: return $result; 275: } 276: 277: sub start_responseparam { 278: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; 279: my $result=''; 280: if ($target eq 'meta') { 281: $result = &meta_parameter_write($token->[2]->{'name'}, 282: $token->[2]->{'type'}, 283: $token->[2]->{'default'}, 284: $token->[2]->{'description'}); 285: } elsif ($target eq 'edit') { 286: $result.=&Apache::edit::tag_start($target,$token); 287: $result.=&Apache::edit::text_arg('Name:','name',$token). 288: &Apache::edit::text_arg('Type:','type',$token). 289: &Apache::edit::text_arg('Description:','description',$token). 290: &Apache::edit::text_arg('Default:','default',$token). 291: "</td></tr>"; 292: $result.=&Apache::edit::end_table; 293: } elsif ($target eq 'modified') { 294: my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval, 295: 'name','type','description', 296: 'default'); 297: if ($constructtag) { 298: $result = &Apache::edit::rebuild_tag($token); 299: $result.=&Apache::edit::handle_insert(); 300: } 301: } elsif ($target eq 'grade' || $target eq 'answer' || $target eq 'web' || 302: $target eq 'tex' || $target eq 'analyze' ) { 303: if ($ENV{'request.state'} eq 'construct') { 304: my $name =&Apache::lonxml::get_param('name',$parstack,$safeeval); 305: my $default=&Apache::lonxml::get_param('default',$parstack, 306: $safeeval); 307: if ($name) {$Apache::inputtags::params{$name}=$default;} 308: } 309: } 310: return $result; 311: } 312: 313: sub end_responseparam { 314: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; 315: if ($target eq 'edit') { return ('','no'); } 316: return ''; 317: } 318: 319: sub start_parameter { 320: my $result = &start_responseparam(@_); 321: return $result; 322: } 323: 324: sub end_parameter { 325: my $result = &end_responseparam(@_); 326: return $result; 327: } 328: 329: sub reset_params { 330: %Apache::inputtags::params=(); 331: } 332: 333: sub setup_params { 334: my ($tag) = @_; 335: 336: if ($ENV{'request.state'} eq 'construct') { return; } 337: my %paramlist=(); 338: foreach my $key (keys(%Apache::lonnet::packagetab)) { 339: if ($key =~ /^$tag/) { 340: my ($package,$name) = split(/&/,$key); 341: $paramlist{$name}=1; 342: } 343: } 344: foreach my $key (keys(%paramlist)) { 345: my $entry= 'resource.'.$Apache::inputtags::part; 346: if (defined($Apache::inputtags::response[-1])) { 347: $entry.='_'.$Apache::inputtags::response[-1]; 348: } 349: $entry.='.'.$key; 350: &Apache::lonxml::debug("looking for $entry"); 351: my $value = &Apache::lonnet::EXT("$entry"); 352: &Apache::lonxml::debug("$key has value :$value:"); 353: if ($value eq 'con_lost' || $value =~ /^error:/) { 354: &Apache::lonxml::debug("using nothing"); 355: $Apache::inputtags::params{$key}=''; 356: } else { 357: &Apache::lonxml::debug("using value"); 358: $Apache::inputtags::params{$key}=$value; 359: } 360: } 361: } 362: 363: sub answer_header { 364: my ($type) = @_; 365: my $result; 366: if ($type eq 'optionresponse' || $type eq 'radiobuttonresponse' ) { 367: $result = '<table border="1"><tr><th>Answer for Part:'. 368: $Apache::inputtags::part. '</th></tr><tr>'."\n"; 369: } else { 370: $result = '<table border="1"><tr><td>Answer for Part:'. 371: $Apache::inputtags::part. '</td>'."\n"; 372: } 373: return $result; 374: } 375: 376: sub answer_part { 377: my ($type,$answer) = @_; 378: my $result; 379: if ($type eq 'optionresponse' || $type eq 'radiobuttonresponse') { 380: $result = '<td>'.$answer.'</td>'; 381: } else { 382: $result = '<td>'.$answer.'</td>'; 383: } 384: return $result; 385: } 386: 387: sub answer_footer { 388: my ($type) = @_; 389: my $result; 390: if ($type eq 'optionresponse' || $type eq 'radiobuttonresponse') { 391: $result = '</tr></table>'; 392: } else { 393: $result = '</tr></table>'; 394: } 395: return $result; 396: } 397: 398: sub showallfoils { 399: my $return=0; 400: if (defined($ENV{'form.showallfoils'}) && 401: $ENV{'request.state'} eq 'construct') { 402: $return=1; 403: } 404: return $return; 405: } 406: 407: sub getresponse { 408: my ($temp)=@_; 409: my $formparm='form.HWVAL_'.$Apache::inputtags::response['-1']; 410: my $response; 411: if (!defined($temp)) { 412: $temp=1; 413: } else { 414: $formparm.=":$temp"; 415: } 416: my %let_to_num=('A'=>0,'B'=>1,'C'=>2,'D'=>3,'E'=>4,'F'=>5,'G'=>6,'H'=>7, 417: 'I'=>8,'J'=>9,'K'=>10,'L'=>11,'M'=>12,'N'=>13,'O'=>14, 418: 'P'=>15,'Q'=>16,'R'=>17,'S'=>18,'T'=>19,'U'=>20,'V'=>21, 419: 'W'=>22,'X'=>23,'Y'=>24,'Z'=>25); 420: if ($ENV{'form.submitted'} eq 'scantron') { 421: my $part = $Apache::inputtags::part; 422: my $id = $Apache::inputtags::response[-1]; 423: $response = $ENV{'scantron.'.($Apache::lonxml::counter+$temp-1). 424: '.answer'}; 425: # save bubbled letter for later 426: $Apache::lonhomework::results{"resource.$part.$id.scantron"}.= 427: $response; 428: $response = $let_to_num{$response}; 429: } else { 430: $response = $ENV{$formparm}; 431: } 432: return $response; 433: } 434: 435: sub repetition { 436: my $id = $Apache::inputtags::part; 437: my $weight = &Apache::lonnet::EXT("resource.$id.weight"); 438: my $repetition = int $weight/9; 439: if ($weight % 9 != 0) {$repetition++;} 440: return $repetition; 441: } 442: 443: sub scored_response { 444: my ($part,$id)=@_; 445: my $repetition=&repetition(); 446: my $score=0; 447: for (my $i=0;$i<$repetition;$i++) { 448: my $increase=&Apache::response::getresponse($i+1); 449: if ($increase ne '') { $score+=$increase+1; } 450: } 451: my $weight = &Apache::lonnet::EXT("resource.$part.weight"); 452: my $pcr=$score/$weight; 453: $Apache::lonhomework::results{"resource.$part.$id.awarded"}=$pcr; 454: $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}= 455: 'ASSIGNED_SCORE'; 456: return $repetition; 457: } 458: 459: 1; 460: __END__ 461: