| 1 | #!/usr/local/bin/webwork-perl |
1 | #!/usr/local/bin/perl |
| 2 | BEGIN{ |
2 | BEGIN{ |
| 3 | be_strict(); |
3 | be_strict(); |
| 4 | sub i(); |
4 | |
| 5 | } |
5 | } |
|
|
6 | # export functions from Complex1. |
| 6 | |
7 | |
| 7 | foreach my $f (@Complex1::EXPORT) { |
8 | foreach my $f (@Complex1::EXPORT) { |
| 8 | PG_restricted_eval("\*$f = \*Complex1::$f"); |
9 | #PG_restricted_eval("\*$f = \*Complex1::$f"); # this is too clever -- |
|
|
10 | # the original subroutines are destroyed |
|
|
11 | next if $f eq 'sqrt'; #exporting the square root caused conflicts with the standard version |
|
|
12 | # You can still use Complex1::sqrt to take square root of complex numbers |
|
|
13 | local($main::string) = qq{ |
|
|
14 | sub main::$f { |
|
|
15 | &Complex1::$f; |
|
|
16 | } |
|
|
17 | }; |
|
|
18 | PG_restricted_eval($main::string); |
| 9 | } |
19 | } |
| 10 | |
20 | |
| 11 | # You need to add |
21 | # You need to add |
| 12 | # sub i(); # to your problem or else to dangerousMacros.pl |
22 | # sub i(); # to your problem or else to dangerousMacros.pl |
| 13 | # in order to use expressions such as 1 +3*i; |
23 | # in order to use expressions such as 1 +3*i; |
| … | |
… | |
| 29 | } |
39 | } |
| 30 | sub cplx_cmp { |
40 | sub cplx_cmp { |
| 31 | my $correctAns = shift; |
41 | my $correctAns = shift; |
| 32 | my %options = @_; |
42 | my %options = @_; |
| 33 | $correctAns = cplx($correctAns,0) unless ref($correctAns) =~/Complex/; |
43 | $correctAns = cplx($correctAns,0) unless ref($correctAns) =~/Complex/; |
|
|
44 | assign_option_aliases( \%options, |
|
|
45 | 'reltol' => 'relTol', |
|
|
46 | ); |
| 34 | set_default_options(\%options, |
47 | set_default_options(\%options, |
| 35 | reltol => .01 |
48 | 'tolType' => (defined($options{tol}) ) ? 'absolute' : 'relative', |
|
|
49 | # default mode should be relative, to obtain this tol must not be defined |
|
|
50 | 'tol' => $main::numAbsTolDefault, |
|
|
51 | 'relTol' => $main::numRelPercentTolDefault, |
|
|
52 | 'zeroLevel' => $main::numZeroLevelDefault, |
|
|
53 | 'zeroLevelTol' => $main::numZeroLevelTolDefault, |
|
|
54 | 'format' => $main::numFormatDefault, |
|
|
55 | 'debug' => 0, |
|
|
56 | |
| 36 | ); |
57 | ); |
| 37 | my $tol = .01*$options{reltol}; |
58 | |
|
|
59 | |
| 38 | my $ans_eval = sub { |
60 | my $ans_eval = sub { |
| 39 | my $in = shift; |
61 | my $in = shift; |
| 40 | my $rh_ans = new AnswerHash; |
62 | my $rh_ans = new AnswerHash; |
|
|
63 | $rh_ans->{correct_ans} = $correctAns; |
|
|
64 | unless (defined($in) and $in =~/\S/ ) { #bail on empty answer |
|
|
65 | $rh_ans->{student_ans} = "error: empty"; |
|
|
66 | return $rh_ans; |
|
|
67 | } |
| 41 | my($PG_errors,$PG_errors_long); |
68 | my($PG_errors,$PG_errors_long); |
| 42 | $rh_ans->{correct_ans} = $correctAns; |
69 | |
| 43 | $rh_ans->input($in); |
70 | $rh_ans->input($in); |
|
|
71 | |
|
|
72 | $rh_ans->{student_ans}=math_constants($rh_ans->{student_ans}); |
|
|
73 | $rh_ans->{student_ans} =~ s/e\^/exp /g; #try to handle exponents |
| 44 | $rh_ans=check_syntax($rh_ans); |
74 | $rh_ans=check_syntax($rh_ans); |
| 45 | $rh_ans->{student_ans} =~ s/e\^/exp /g; #try to handle exponents |
|
|
| 46 | $rh_ans->{student_ans} =~ s/-\s*i/-1*i/g; #try to keep -i being recognized as a file reference |
75 | $rh_ans->{student_ans} =~ s/\bi\b/(i)/g; #try to keep -i being recognized as a file reference |
|
|
76 | # and recognized as a function whose output is an imaginary number |
|
|
77 | |
|
|
78 | |
|
|
79 | |
|
|
80 | warn $rh_ans->pretty_print() if defined($options{debug}) and $options{debug}==1; |
| 47 | ($in,$PG_errors,$PG_errors_long) = PG_restricted_eval($rh_ans->{student_ans}); |
81 | ($in,$PG_errors,$PG_errors_long) = PG_restricted_eval($rh_ans->{student_ans}); |
|
|
82 | $in = $in +0*i; # force the input to be complex |
| 48 | if ($PG_errors_long) { |
83 | if ($PG_errors_long) { |
| 49 | $rh_ans->{error}=1; |
84 | $rh_ans->{error}=1; |
| 50 | $rh_ans->{ans_message} = $PG_errors; |
85 | $rh_ans->{ans_message} = $PG_errors; |
| 51 | } else { |
86 | } else { |
| 52 | $in->display_format('cartesian') if ref($in) =~/Complex/; |
87 | $in->display_format('cartesian') if ref($in) =~/Complex/; |
| 53 | $rh_ans->{student_ans}="$in"; |
88 | $rh_ans->{student_ans}="$in"; |
|
|
89 | my $permitted_error; |
|
|
90 | if (defined($options{tolType}) && $options{tolType} eq 'absolute') { |
|
|
91 | $permitted_error = $options{tol}; |
|
|
92 | } elsif ( abs($correctAns) <= $options{zeroLevel}) { |
|
|
93 | $permitted_error = $options{zeroLevelTol}; ## want $tol to be non zero |
|
|
94 | } else { |
|
|
95 | $permitted_error = abs(.01*$options{relTol}*$correctAns); # relative tolerance is given in per cent |
|
|
96 | } |
| 54 | $rh_ans->{score} = (abs($in - $correctAns)<$tol*abs($correctAns) )? 1:0; |
97 | $rh_ans->{score} = (abs($in - $correctAns)<$permitted_error )? 1:0; |
| 55 | |
98 | |
| 56 | } |
99 | } |
|
|
100 | |
| 57 | $rh_ans; |
101 | $rh_ans; |
| 58 | }; |
102 | }; |
| 59 | $ans_eval; |
103 | $ans_eval; |
| 60 | } |
104 | } |
| 61 | |
105 | |