| … | |
… | |
| 272 | formatting will be used; this will show 'arbitrary' precision |
272 | formatting will be used; this will show 'arbitrary' precision |
| 273 | floating points. |
273 | floating points. |
| 274 | |
274 | |
| 275 | Default Values (As of 7/24/2000) (Option -- Variable Name -- Value) |
275 | Default Values (As of 7/24/2000) (Option -- Variable Name -- Value) |
| 276 | |
276 | |
| 277 | Format -- $numFormatDefault -- "%0.5f#" |
277 | Format -- $numFormatDefault -- "%0.5f#" |
| 278 | Relative Tolerance -- $numRelPercentTolDefault -- .1 |
278 | Relative Tolerance -- $numRelPercentTolDefault -- .1 |
| 279 | Absolute Tolerance -- $numAbsTolDefault -- .001 |
279 | Absolute Tolerance -- $numAbsTolDefault -- .001 |
| 280 | Zero Level -- $numZeroLevelDefault -- 1E-14 |
280 | Zero Level -- $numZeroLevelDefault -- 1E-14 |
| 281 | Zero Level Tolerance -- $numZeroLevelTolDefault -- 1E-12 |
281 | Zero Level Tolerance -- $numZeroLevelTolDefault -- 1E-12 |
| 282 | |
282 | |
| 283 | =cut |
283 | =cut |
| 284 | |
284 | |
| 285 | |
285 | |
| … | |
… | |
| 291 | |
291 | |
| 292 | ANS( num_cmp( answer or answer_array_ref, options_hash ) ); |
292 | ANS( num_cmp( answer or answer_array_ref, options_hash ) ); |
| 293 | |
293 | |
| 294 | 1. the correct answer, or a reference to an array of correct answers |
294 | 1. the correct answer, or a reference to an array of correct answers |
| 295 | 2. a hash with the following keys (all optional): |
295 | 2. a hash with the following keys (all optional): |
| 296 | mode -- 'std' (default) (allows any expression evaluating to a number) |
296 | mode -- 'std' (default) (allows any expression evaluating to |
|
|
297 | a number) |
| 297 | 'strict' (only numbers are allowed) |
298 | 'strict' (only numbers are allowed) |
| 298 | 'frac' (fractions are allowed) |
299 | 'frac' (fractions are allowed) |
| 299 | 'arith' (arithmetic expressions allowed) |
300 | 'arith' (arithmetic expressions allowed) |
| 300 | format -- '%0.5f#' (default); defines formatting for the correct answer |
301 | format -- '%0.5f#' (default); defines formatting for the |
|
|
302 | correct answer |
| 301 | tol -- an absolute tolerance, or |
303 | tol -- an absolute tolerance, or |
| 302 | relTol -- a relative tolerance |
304 | relTol -- a relative tolerance |
| 303 | units -- the units to use for the answer(s) |
305 | units -- the units to use for the answer(s) |
| 304 | strings -- a reference to an array of strings which are valid |
306 | strings -- a reference to an array of strings which are valid |
| 305 | answers (works like std_num_str_cmp() ) |
307 | answers (works like std_num_str_cmp() ) |
| 306 | zeroLevel -- if the correct answer is this close to zero, then zeroLevelTol applies |
308 | zeroLevel -- if the correct answer is this close to zero, |
|
|
309 | then zeroLevelTol applies |
| 307 | zeroLevelTol -- absolute tolerance to allow when answer is close to zero |
310 | zeroLevelTol -- absolute tolerance to allow when answer is close |
|
|
311 | to zero |
| 308 | |
312 | |
| 309 | debug -- if set to 1, provides verbose listing of hash entries throughout fliters. |
313 | debug -- if set to 1, provides verbose listing of |
|
|
314 | hash entries throughout fliters. |
| 310 | |
315 | |
| 311 | Returns an answer evaluator, or (if given a reference to an array of |
316 | Returns an answer evaluator, or (if given a reference to an array of |
| 312 | answers), a list of answer evaluators. Note that a reference to an array of |
317 | answers), a list of answer evaluators. Note that a reference to an array of |
| 313 | answers results is just a shortcut to writing a separate cum_cmp() for each |
318 | answers results is just a shortcut for writing a separate <code>num_cmp()</code> for each |
| 314 | answer. It does not mean that any of those answers are considered correct |
319 | answer. |
| 315 | for one question. |
|
|
| 316 | |
320 | |
| 317 | EXAMPLES: |
321 | EXAMPLES: |
| 318 | |
322 | |
| 319 | num_cmp( 5 ) -- correct answer is 5, using defaults for all options |
323 | num_cmp( 5 ) -- correct answer is 5, using defaults |
|
|
324 | for all options |
| 320 | num_cmp( [5,6,7] ) -- correct answers are 5, 6, and 7, using defaults for all options |
325 | num_cmp( [5,6,7] ) -- correct answers are 5, 6, and 7, |
|
|
326 | using defaults for all options |
| 321 | num_cmp( 5, mode => 'strict' ) -- correct answer is 5, mode is strict |
327 | num_cmp( 5, mode => 'strict' ) -- correct answer is 5, mode is strict |
| 322 | num_cmp( [5,6], relTol => 5 ) -- correct answers are 5 and 6, both with 5% relative tolerance |
328 | num_cmp( [5,6], relTol => 5 ) -- correct answers are 5 and 6, |
| 323 | num_cmp( 6, strings => ["Inf", "Minf", "NaN"] ) -- correct answer is 6, "Inf", "Minf", and "NaN" |
329 | both with 5% relative tolerance |
| 324 | recognized as valid answers |
330 | num_cmp( 6, strings => ["Inf", "Minf", "NaN"] ) |
|
|
331 | -- correct answer is 6, "Inf", "Minf", |
|
|
332 | and "NaN" recognized as valid, but |
|
|
333 | incorrect answers. |
| 325 | |
334 | |
| 326 | =cut |
335 | =cut |
| 327 | |
336 | |
| 328 | sub num_cmp { |
337 | sub num_cmp { |
| 329 | my $correctAnswer = shift @_; |
338 | my $correctAnswer = shift @_; |
| … | |
… | |
| 647 | num_cmp(\@answerList, %options); |
656 | num_cmp(\@answerList, %options); |
| 648 | } |
657 | } |
| 649 | |
658 | |
| 650 | sub frac_num_cmp { # only allow fractions and numbers as submitted answer |
659 | sub frac_num_cmp { # only allow fractions and numbers as submitted answer |
| 651 | |
660 | |
| 652 | my ( $correctAnswer, $relPercentTol, $format, $zeroLevel, $zeroLevelTol ) = @_; |
661 | my ( $correctAnswer, $relPercentTol, $format, $zeroLevel, $zeroLevelTol ) = @_; |
| 653 | |
662 | |
| 654 | my %options = ( 'tolerance' => $relPercentTol, |
663 | my %options = ( 'tolerance' => $relPercentTol, |
| 655 | 'format' => $format, |
664 | 'format' => $format, |
| 656 | 'zeroLevel' => $zeroLevel, |
665 | 'zeroLevel' => $zeroLevel, |
| 657 | 'zeroLevelTol' => $zeroLevelTol |
666 | 'zeroLevelTol' => $zeroLevelTol |
| 658 | ); |
667 | ); |
| 659 | |
668 | |
| 660 | set_default_options( \%options, |
669 | set_default_options( \%options, |
| 661 | 'tolType' => 'relative', |
670 | 'tolType' => 'relative', |
| 662 | 'tolerance' => $relPercentTol, |
671 | 'tolerance' => $relPercentTol, |
| 663 | 'mode' => 'frac', |
672 | 'mode' => 'frac', |
| 664 | 'format' => $numFormatDefault, |
673 | 'format' => $numFormatDefault, |
| 665 | 'zeroLevel' => $numZeroLevelDefault, |
674 | 'zeroLevel' => $numZeroLevelDefault, |
| 666 | 'zeroLevelTol' => $numZeroLevelTolDefault, |
675 | 'zeroLevelTol' => $numZeroLevelTolDefault, |
| 667 | 'relTol' => $numRelPercentTolDefault, |
676 | 'relTol' => $numRelPercentTolDefault, |
| 668 | 'debug' => 0, |
677 | 'debug' => 0, |
| 669 | ); |
678 | ); |
| 670 | |
679 | |
| 671 | num_cmp([$correctAnswer], %options); |
680 | num_cmp([$correctAnswer], %options); |
| 672 | } |
681 | } |
| 673 | |
682 | |
| 674 | ## See std_num_cmp_list for usage |
683 | ## See std_num_cmp_list for usage |
| 675 | sub frac_num_cmp_list { |
684 | sub frac_num_cmp_list { |
| 676 | my ( $relPercentTol, $format, @answerList ) = @_; |
685 | my ( $relPercentTol, $format, @answerList ) = @_; |
| 677 | |
686 | |
| 678 | my %options = ( 'tolerance' => $relPercentTol, |
687 | my %options = ( 'tolerance' => $relPercentTol, |
| 679 | 'format' => $format |
688 | 'format' => $format |
| 680 | ); |
689 | ); |
| 681 | |
690 | |
| 682 | set_default_options( \%options, |
691 | set_default_options( \%options, |
| 683 | 'tolType' => 'relative', |
692 | 'tolType' => 'relative', |
| 684 | 'tolerance' => $relPercentTol, |
693 | 'tolerance' => $relPercentTol, |
| 685 | 'mode' => 'frac', |
694 | 'mode' => 'frac', |
| 686 | 'format' => $numFormatDefault, |
695 | 'format' => $numFormatDefault, |
| 687 | 'zeroLevel' => $numZeroLevelDefault, |
696 | 'zeroLevel' => $numZeroLevelDefault, |
| 688 | 'zeroLevelTol' => $numZeroLevelTolDefault, |
697 | 'zeroLevelTol' => $numZeroLevelTolDefault, |
| 689 | 'relTol' => $numRelPercentTolDefault, |
698 | 'relTol' => $numRelPercentTolDefault, |
| 690 | 'debug' => 0, |
699 | 'debug' => 0, |
| 691 | ); |
700 | ); |
| 692 | |
701 | |
| 693 | num_cmp(\@answerList, %options); |
702 | num_cmp(\@answerList, %options); |
| 694 | } |
703 | } |
| 695 | |
704 | |
| 696 | sub frac_num_cmp_abs { # only allow fraction expressions as submitted answer with absolute tolerance |
705 | sub frac_num_cmp_abs { # only allow fraction expressions as submitted answer with absolute tolerance |
| 697 | my ( $correctAnswer, $absTol, $format ) = @_; |
706 | my ( $correctAnswer, $absTol, $format ) = @_; |
| 698 | |
707 | |
| 699 | my %options = ( 'tolerance' => $absTol, |
708 | my %options = ( 'tolerance' => $absTol, |
| 700 | 'format' => $format |
709 | 'format' => $format |
| 701 | ); |
710 | ); |
| 702 | |
711 | |
| 703 | set_default_options (\%options, |
712 | set_default_options (\%options, |
| 704 | 'tolType' => 'absolute', |
713 | 'tolType' => 'absolute', |
| 705 | 'tolerance' => $absTol, |
714 | 'tolerance' => $absTol, |
| 706 | 'mode' => 'frac', |
715 | 'mode' => 'frac', |
| 707 | 'format' => $numFormatDefault, |
716 | 'format' => $numFormatDefault, |
| 708 | 'zeroLevel' => 0, |
717 | 'zeroLevel' => 0, |
| 709 | 'zeroLevelTol' => 0, |
718 | 'zeroLevelTol' => 0, |
| 710 | 'debug' => 0, |
719 | 'debug' => 0, |
| 711 | ); |
720 | ); |
| 712 | |
721 | |
| 713 | num_cmp([$correctAnswer], %options); |
722 | num_cmp([$correctAnswer], %options); |
| 714 | } |
723 | } |
| 715 | |
724 | |
| 716 | ## See std_num_cmp_list for usage |
725 | ## See std_num_cmp_list for usage |