Annotation of loncom/homework/default_homework.lcpm, revision 1.39
1.25 albertel 1: # file name (temp): default_homework
1.1 harris41 2: # used by lonxml::xmlparse() as input variable $safeinit to Apache::run::run()
1.20 harris41 3: #
4: # Guy Albertelli
5: #
6: # 05/25/2001 H. K. Ng
1.24 ng 7: # 05/31/2001 H. K. Ng
1.20 harris41 8: #
1.25 albertel 9: #init some globals
1.38 albertel 10: $hidden::RANDOMINIT=0;
1.22 ng 11: $pi=atan2(1,1)*4;
12: $rad2deg=180.0/$pi;
13: $deg2rad=$pi/180.0;
1.3 albertel 14:
1.7 albertel 15: sub caparesponse_check {
1.36 albertel 16: #not properly used yet: calc
17: #not to be used: $ans_fmt
1.39 ! albertel 18: my ($answer,$type,$tol,$sig,$ans_fmt,$unit,$calc,$samples) =
! 19: eval $_[1].
! 20: ';return ($answer,$type,$tol,$sig,$ans_fmt,$unit,$calc,$samples);';
1.36 albertel 21:
1.10 albertel 22: my $tol_type=''; # gets it's value from whether tol has a % or not done
1.19 albertel 23: my $sig_lbound=''; #done
24: my $sig_ubound=''; #done
1.7 albertel 25: my ($response,$expr)=@_;
1.31 albertel 26:
1.32 albertel 27:
1.8 albertel 28: #type's definitons come from capaParser.h
1.31 albertel 29: my $message='';
1.32 albertel 30: #remove leading and trailing whitespace
31: if ($response=~ /^\s|\s$/) {
32: $response=~ s:^\s+|\s+$::g;
33: $message .="Removed ws now :$response:<br />";
34: } else {
35: $message .="no ws in :$response:<br />";
36: }
37:
1.8 albertel 38: if ($type eq '' ) {
1.31 albertel 39: $message .= "Didn't find a type :$type:$expr: defaulting<br />";
1.8 albertel 40: if ( $answer eq ($answer *1.0)) { $type = 2;
41: } else { $type = 3; }
42: } else {
43: if ($type eq 'cs') { $type = 4;
44: } elsif ($type eq 'ci') { $type = 3;
45: } elsif ($type eq 'mc') { $type = 5;
46: } elsif ($type eq 'fml') { $type = 8;
1.9 albertel 47: } elsif ($type eq 'subj') { $type = 7;
48: } else { return "ERROR: Unknown type of answer: $type" }
1.8 albertel 49: }
50:
1.39 ! albertel 51: my $points;
! 52: my $id_list;
! 53: #formula type setup the sample points
! 54: if ($type eq '8') {
! 55: ($id_list,$points)=split(/@/,$samples);
! 56: $message.="Found :$points: points<br />";
! 57: }
1.10 albertel 58: if ($tol eq '') {
59: $tol=0.0;
60: $tol_type=1; #TOL_ABSOLUTE
61: } else {
62: if ($tol =~ /%$/) {
1.12 albertel 63: chop $tol;
1.10 albertel 64: $tol_type=2; #TOL_PERCENTAGE
65: } else {
66: $tol_type=1; #TOL_ABSOLUTE
67: }
68: }
1.12 albertel 69:
70: if ($sig eq '') {
71: $sig_lbound = 0; #SIG_LB_DEFAULT
72: $sig_ubound =15; #SIG_UB_DEFAULT
73: } else {
74: ($sig_lbound,$sig_ubound) = split /,/,$sig;
75: }
1.7 albertel 76: my $result = &caparesponse_capa_check_answer($response,$answer,$type,
1.10 albertel 77: $tol_type,$tol,
1.7 albertel 78: $sig_lbound,$sig_ubound,
1.39 ! albertel 79: $ans_fmt,$unit,$calc,$id_list,
! 80: $points,$external::randomseed);
1.9 albertel 81:
82: if ($result == '1') { $result='EXACT_ANS'; }
83: elsif ($result == '2') { $result='APPROX_ANS'; }
84: elsif ($result == '3') { $result='SIG_FAIL'; }
85: elsif ($result == '4') { $result='UNIT_FAIL'; }
86: elsif ($result == '5') { $result='NO_UNIT'; }
87: elsif ($result == '6') { $result='UNIT_OK'; }
88: elsif ($result == '7') { $result='INCORRECT'; }
89: elsif ($result == '8') { $result='UNIT_NOTNEEDED'; }
90: elsif ($result == '9') { $result='ANS_CNT_NOT_MATCH'; }
91: elsif ($result =='10') { $result='SUB_RECORDED'; }
92: elsif ($result =='11') { $result='BAD_FORMULA'; }
93: elsif ($result =='12') { $result='WANTED_NUMERIC'; }
1.13 albertel 94: else {$result = "ERROR: Unknown Result:$result:$@:";}
1.9 albertel 95:
1.36 albertel 96: return "$result:<br />Error $error:<br />Answer $answer:<br />Response $response:<br /> type-$type|$tol|$tol_type|$sig:$sig_lbound:$sig_ubound|$unit|<br />$message$expr";
1.14 albertel 97: }
98:
1.37 albertel 99: sub get_array_args {
100: my ($expr,$arg)=@_;
1.30 albertel 101: # do these first, because who knows what varname the instructor might have used
102: # but it probably isn't $CAPARESPONSE_CHECK_LIST_answer
1.37 albertel 103: my $CAPARESPONSE_CHECK_LIST_answer = eval $expr.';return $'.$arg; #'
1.39 ! albertel 104: if ($CAPARESPONSE_CHECK_LIST_answer =~ /^\s*[\$\@]/) {
! 105: my (@list) = eval $CAPARESPONSE_CHECK_LIST_answer;
! 106: }
1.14 albertel 107: my $result='';
1.31 albertel 108: $result.="error:$@:<br />";
109: # if the eval fails just use what is in the answer exactly
110: if (!defined(@list) || !defined($list[0])) {
111: $result.="list zero is undefined<br />";
112: $list[0]=$CAPARESPONSE_CHECK_LIST_answer;
113: }
1.37 albertel 114: return @list;
115: }
116:
117: sub caparesponse_check_list {
118: my ($response,$expr)=@_;
119: my (@list) = &get_array_args($expr,'answer');
1.15 albertel 120: my $aresult='';
1.14 albertel 121: my $current_answer;
1.39 ! albertel 122: my $answers=join(':',@list);
! 123: $result.="Got response :$answers:<br />";
1.31 albertel 124: my @responselist;
1.32 albertel 125: my $type =eval $expr.';return $answer;';
1.31 albertel 126: if ($type ne '' && $#list > 0) {
127: (@responselist)=split /,/,$response;
128: } else {
129: (@responselist)=($response);
130: }
1.15 albertel 131: my $unit='';
1.31 albertel 132: $result.="Initial final response :$responselist['-1']:<br />";
133: if ($type eq '') {
134: #for numerical problems split off the unit
135: if ( $responselist['-1']=~ /(.*[^\s])\s+([^\s]+)/ ) {
136: $responselist['-1']=$1;
137: $unit=$2;
138: }
1.15 albertel 139: }
1.31 albertel 140: $result.="Final final response :$responselist['-1']:<br />";
141: $result.=":$#list: answers<br />";
1.14 albertel 142: $unit=~s/\s//;
143: my $i=0;
144: my $awards='';
145: for ($i=0; $i<@list;$i++) {
1.31 albertel 146: $result.="trying answer :$list[$i]:<br />";
1.19 albertel 147: if ($unit eq '') {
148: $aresult=&caparesponse_check($responselist[$i],
1.31 albertel 149: $expr.';my $answer=\''.$list[$i].'\';');
1.19 albertel 150: } else {
151: $aresult=&caparesponse_check($responselist[$i]." $unit",
1.31 albertel 152: $expr.';my $answer=\''.$list[$i].'\';');
1.19 albertel 153: }
1.15 albertel 154: my ($temp)=split /:/, $aresult;
1.14 albertel 155: $awards.="$temp,";
1.15 albertel 156: $result.=$aresult;
1.14 albertel 157: }
158: chop $awards;
1.17 albertel 159: return "$awards:<br />$result";
1.7 albertel 160: }
161:
1.4 albertel 162: sub tex {
163: if ( $external::target eq "tex" ) {
164: return @_[0];
165: } else {
166: return @_[1];
167: }
168: }
169:
1.24 ng 170: sub var_in_tex {
171: if ( $external::target eq "tex" ) {
172: return @_[0];
173: } else {
174: return "";
175: }
176: }
177:
1.4 albertel 178: sub web {
179: if ( $external::target eq "tex" ) {
180: return @_[1];
181: } else {
182: if ( $external::target eq "web") {
1.26 ng 183: return @_[2];
184: } else {
1.4 albertel 185: return @_[0];
186: }
187: }
188: }
189:
1.24 ng 190: sub html {
191: if ( $external::target eq "web" ) {
1.26 ng 192: return shift;
1.24 ng 193: }
194: }
195:
1.4 albertel 196: sub problem {
1.11 albertel 197: return '1';
1.4 albertel 198: }
199:
1.1 harris41 200: sub hinton {
201: return 0;
202: }
203:
204: sub random {
205: my ($start,$end,$step)=@_;
1.38 albertel 206: if ( ! $hidden::RANDOMINIT ) {
207: srand($external::randomseed);
208: $hidden::RANDOMINIT=1;
209: }
1.1 harris41 210: my $num=1+int(($end-$start)/$step);
211: my $result=$start + int(rand() * $num)*$step;
212: return $result;
213: }
214:
1.26 ng 215: sub random_normal {
216: my ($item_cnt,$seed,$av,$std_dev) = @_;
217: my @retArray;
218: &random_set_seed_from_phrase($seed);
219: @retArray=&math_random_normal($item_cnt,$av,$std_dev);
220: return @retArray;
221: }
222:
223: sub random_beta {
224: my ($item_cnt,$seed,$aa,$bb) = @_;
225: my @retArray;
226: &random_set_seed_from_phrase($seed);
227: @retArray=&math_random_beta($item_cnt,$aa,$bb);
228: return @retArray;
229: }
230:
231: sub random_gamma {
232: my ($item_cnt,$seed,$a,$r) = @_;
233: my @retArray;
234: &random_set_seed_from_phrase($seed);
235: @retArray=&math_random_gamma($item_cnt,$a,$r);
236: return @retArray;
237: }
238:
239: sub random_exponential {
240: my ($item_cnt,$seed,$av) = @_;
241: my @retArray;
242: &random_set_seed_from_phrase($seed);
243: @retArray=&math_random_exponential($item_cnt,$av);
244: return @retArray;
245: }
246:
247: sub random_poisson {
248: my ($item_cnt,$seed,$mu) = @_;
249: my @retArray;
250: &random_set_seed_from_phrase($seed);
251: @retArray=&math_random_poisson($item_cnt,$mu);
252: return @retArray;
253: }
254:
255: sub random_chi {
256: my ($item_cnt,$seed,$df) = @_;
257: my @retArray;
258: &random_set_seed_from_phrase($seed);
259: @retArray=&math_random_chi_square($item_cnt,$df);
260: return @retArray;
261: }
262:
263: sub random_noncentral_chi {
264: my ($item_cnt,$seed,$df,$nonc) = @_;
265: my @retArray;
266: &random_set_seed_from_phrase($seed);
267: @retArray=&math_random_noncentral_chi_square($item_cnt,$df,$nonc);
268: return @retArray;
269: }
270:
271: sub random_f {
272: my ($item_cnt,$seed,$dfn,$dfd) = @_;
273: my @retArray;
274: &random_set_seed_from_phrase($seed);
275: @retArray=&math_random_f($item_cnt,$dfn,$dfd);
276: return @retArray;
277: }
278:
279: sub random_noncentral_f {
280: my ($item_cnt,$seed,$dfn,$dfd,$nonc) = @_;
281: my @retArray;
282: &random_set_seed_from_phrase($seed);
283: @retArray=&math_random_noncentral_f($item_cnt,$dfn,$dfd,$nonc);
284: return @retArray;
285: }
286:
287: sub random_multivariate_normal {
1.33 ng 288: my ($item_cnt,$seed,$mean,$covar) = @_;
1.26 ng 289: &random_set_seed_from_phrase($seed);
1.33 ng 290: @retArray=&math_random_multivariate_normal($item_cnt,@$mean,@$covar);
1.26 ng 291: return @retArray;
292: }
293:
294: sub random_multinomial {
295: my ($item_cnt,$seed,@p) = @_;
296: my @retArray;
297: &random_set_seed_from_phrase($seed);
298: @retArray=&math_random_multinomial($item_cnt,@p);
299: return @retArray;
300: }
301:
302: sub random_permutation {
303: my ($seed,@inArray) = @_;
304: my @retArray;
305: &random_set_seed_from_phrase($seed);
306: @retArray=&math_random_permutation(@inArray);
307: return @retArray;
308: }
309:
310: sub random_uniform {
311: my ($item_cnt,$seed,$low,$high) = @_;
312: my @retArray;
313: &random_set_seed_from_phrase($seed);
314: @retArray=&math_random_uniform($item_cnt,$low,$high);
315: return @retArray;
316: }
317:
318: sub random_uniform_integer {
319: my ($item_cnt,$seed,$low,$high) = @_;
320: my @retArray;
321: &random_set_seed_from_phrase($seed);
322: @retArray=&math_random_uniform_integer($item_cnt,$low,$high);
323: return @retArray;
324: }
325:
326: sub random_binomial {
327: my ($item_cnt,$seed,$nt,$p) = @_;
328: my @retArray;
329: &random_set_seed_from_phrase($seed);
330: @retArray=&math_random_binomial($item_cnt,$nt,$p);
331: return @retArray;
332: }
333:
334: sub random_negative_binomial {
335: my ($item_cnt,$seed,$ne,$p) = @_;
336: my @retArray;
337: &random_set_seed_from_phrase($seed);
338: @retArray=&math_random_negative_binomial($item_cnt,$ne,$p);
339: return @retArray;
340: }
341:
1.23 ng 342: sub abs { abs(shift) }
343: sub sin { sin(shift) }
344: sub cos { cos(shift) }
345: sub exp { exp(shift) }
346: sub int { int(shift) }
347: sub log { log(shift) }
348: sub atan2 { atan2($_[0],$_[1]) }
349: sub sqrt { sqrt(shift) }
350:
1.1 harris41 351: sub tan { sin($_[0]) / cos($_[0]) }
1.21 harris41 352: #sub atan { atan2($_[0], 1); }
353: #sub acos { atan2(sqrt(1 - $_[0] * $_[0]), $_[0] ); }
354: #sub asin { atan2($_[0], sqrt(1- $_[0] * $_[0]) ); }
1.22 ng 355:
1.18 albertel 356: sub log10 { log($_[0])/log(10); }
1.22 ng 357:
1.20 harris41 358: sub factorial {
359: my $input = int(shift);
360: return "Error - unable to take factorial of an negative number ($input)" if $input < 0;
361: return "Error - factorial result is greater than system limit ($input)" if $input > 170;
362: return 1 if $input == 0;
363: my $result = 1;
364: for (my $i=2; $i<=$input; $i++) { $result *= $i }
365: return $result;
366: }
367:
368: sub sgn {
369: return -1 if $_[0] < 0;
370: return 0 if $_[0] == 0;
371: return 1 if $_[0] > 0;
372: }
373:
374: sub min {
375: my @sorted = sort { $a <=> $b || $a cmp $b } @_;
376: return shift @sorted;
377: }
378:
379: sub max {
380: my @sorted = sort { $a <=> $b || $a cmp $b } @_;
381: return pop @sorted;
382: }
1.1 harris41 383:
1.20 harris41 384: sub roundto {
385: my ($input,$n) = @_;
386: return sprintf('%.'.$n.'f',$input);
387: }
388:
389: sub to_string {
390: my ($input,$n) = @_;
1.26 ng 391: return sprintf($input) if $n eq "";
392: $n = '.'.$n if $n !~ /^\./;
1.20 harris41 393: return sprintf('%'.$n,$input) if $n ne "";
394: }
395:
396: sub sub_string {
397: my ($str,$start,$len) = @_;
398: return substr($str,$start-1,$len);
399: }
1.1 harris41 400:
401: sub pow {return $_[0] ** $_[1]; }
1.27 ng 402: sub ceil {return (($_[0]-int($_[0]))== 0.0) ? $_[0] : (($_[0] > 0) ? (int($_[0])+ 1) : int($_[0])); }
403: sub floor {return (($_[0]-int($_[0]))== 0.0) ? $_[0] : (($_[0] > 0) ? int($_[0]) : (int($_[0])-1)); }
404: #sub floor {return int($_[0]); }
1.1 harris41 405:
1.2 albertel 406: sub format {
407: my ($value,$fmt)=@_;
1.11 albertel 408: return sprintf('%.'.$fmt,$value);
1.2 albertel 409: }
1.5 albertel 410:
411: sub map {
1.27 ng 412: my ($phrase,$dest,$source)=@_;
413: my @seed = &random_seed_from_phrase($phrase);
414: &random_set_seed(@seed);
415: my $destct = scalar(@$dest);
1.28 ng 416: if (!$source) {
417: my @output;
418: my @idx = &math_random_permuted_index($destct);
419: my $ctr = 0;
420: while ($ctr < $destct) {
421: $output[$ctr] = $$dest[$idx[$ctr]];
1.27 ng 422: $ctr++;
1.28 ng 423: }
424: return @output;
1.27 ng 425: } else {
1.28 ng 426: my $num = scalar(@$source);
427: my @idx = &math_random_permuted_index($num);
428: my $ctr = 0;
429: my $tot = $num;
430: $tot = $destct if $destct < $num;
431: if (ref($$dest[0])) {
432: while ($ctr < $tot) {
433: ${$$dest[$ctr]} = $$source[$idx[$ctr]];
434: $ctr++;
435: }
436: } else {
437: while ($ctr < $tot) {
438: $$dest[$ctr] = $$source[$idx[$ctr]];
439: $ctr++;
440: }
441: }
1.27 ng 442: }
443: }
444:
445: sub rmap {
446: my ($phrase,$dest,$source)=@_;
447: my @seed = &random_seed_from_phrase($phrase);
448: &random_set_seed(@seed);
449: my $destct = scalar(@$dest);
1.28 ng 450: if (!$source) {
451: my @idx = &math_random_permuted_index($destct);
452: my $ctr = 0;
453: my @r_idx;
454: while ($ctr < $destct) {
455: $r_idx[$idx[$ctr]] = $ctr;
456: $ctr++;
457: }
458: my @output;
459: $ctr = 0;
460: while ($ctr < $destct) {
461: $output[$ctr] = $$dest[$r_idx[$ctr]];
1.27 ng 462: $ctr++;
1.28 ng 463: }
464: return @output;
1.27 ng 465: } else {
1.28 ng 466: my $num = scalar(@$source);
467: my @idx = &math_random_permuted_index($num);
468: my $ctr = 0;
469: my $tot = $num;
470: $tot = $destct if $destct < $num;
471: my @r_idx;
1.27 ng 472: while ($ctr < $tot) {
1.28 ng 473: $r_idx[$idx[$ctr]] = $ctr;
1.27 ng 474: $ctr++;
1.28 ng 475: }
476: $ctr = 0;
477: if (ref($$dest[0])) {
478: while ($ctr < $tot) {
479: ${$$dest[$ctr]} = $$source[$r_idx[$ctr]];
480: $ctr++;
481: }
482: } else {
483: while ($ctr < $tot) {
484: $$dest[$ctr] = $$source[$r_idx[$ctr]];
485: $ctr++;
486: }
487: }
1.6 albertel 488: }
1.5 albertel 489: }
1.22 ng 490:
1.23 ng 491: sub capa_id { return }
492:
493: sub problem { return }
494:
1.22 ng 495: sub name{
496: my $fullname = &EXT('environment.lastname').', '.&EXT('environment.firstname').' '.&EXT('environment.middlename');
497: $fullname = "" if $fullname eq ", ";
1.26 ng 498: $fullname =~ s/\%2d/-/g;
1.22 ng 499: return $fullname;
500: }
501:
502: sub student_number {
503: my $id = &EXT('environment.id');
504: $id = '' if $id eq "";
505: return $id;
506: }
507:
508: sub class {
509: my $course = &EXT('course.description');
510: $course = '' if $course eq "";
511: return $course;
512: }
513:
514: sub sec {
515: my $sec = &EXT('request.course.sec');
1.23 ng 516: $sec = '' if $sec eq "";
1.22 ng 517: return $sec;
518: }
519:
1.23 ng 520: sub open_date {
521: my @dc = split(/\s+/,localtime(&EXT('resource.0.opendate')));
1.24 ng 522: return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969);
523: my @hm = split(/:/,$dc[3]);
524: my $ampm = " am";
525: if ($hm[0] > 12) {
526: $hm[0]-=12;
527: $ampm = " pm";
528: }
529: return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm;
1.23 ng 530: }
531:
532: sub due_date {
533: my @dc = split(/\s+/,localtime(&EXT('resource.0.duedate')));
1.24 ng 534: return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969);
535: my @hm = split(/:/,$dc[3]);
536: my $ampm = " am";
537: if ($hm[0] > 12) {
538: $hm[0]-=12;
539: $ampm = " pm";
540: }
541: return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm;
542: # return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3];
1.23 ng 543: }
544:
545: sub answer_date {
546: my @dc = split(/\s+/,localtime(&EXT('resource.0.answerdate')));
1.24 ng 547: return '' if ($dc[0] eq "Wed" and $dc[2] == 31 and $dc[4] == 1969);
548: my @hm = split(/:/,$dc[3]);
549: my $ampm = " am";
550: if ($hm[0] > 12) {
551: $hm[0]-=12;
552: $ampm = " pm";
553: }
554: return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$hm[0].':'.$hm[1].$ampm;
555: # return $dc[0].', '.$dc[1].' '.$dc[2].', '.$dc[4].' at '.$dc[3];
556: }
557:
558: sub array_moments {
559: my @input=@_;
560: my (@output,$N);
561: $N=scalar (@input);
562: $output[0]=$N;
563: if ($N <= 1) {
564: $output[1]=$input[0];
1.28 ng 565: $output[1]="Input array not defined" if ($N == 0);
1.24 ng 566: $output[2]="variance undefined for N<=1";
567: $output[3]="skewness undefined for N<=1";
568: $output[4]="kurtosis undefined for N<=1";
569: return @output;
570: }
571: my $sum=0;
572: foreach my $line (@input) {
573: $sum+=$line;
574: }
575: $output[1] = $sum/$N;
576: my ($x,$sdev,$var,$skew,$kurt) = 0;
577: foreach my $line (@input) {
578: $x=$line-$output[1];
579: $var+=$x**2;
580: $skew+=$x**3;
581: $kurt+=$x**4;
582: }
583: $output[2]=$var/($N-1);
584: $sdev=sqrt($output[2]);
585: if ($sdev == 0) {
586: $output[3]="inf-variance=0";
587: $output[4]="inf-variance=0";
588: return @output;
589: }
590: $output[3]=$skew/($sdev**3*$N);
591: $output[4]=$kurt/($sdev**4*$N)-3;
592: return @output;
593: }
1.5 albertel 594:
595: sub choose {
596: my $num = $_[0];
597: return $_[$num];
598: }
1.23 ng 599:
600:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>