[system] / trunk / pg / macros / parserFormulaUpToConstant.pl Repository:
ViewVC logotype

Diff of /trunk/pg/macros/parserFormulaUpToConstant.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5914 Revision 5917
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: pg/macros/parserFormulaUpToConstant.pl,v 1.17 2008/09/16 03:01:17 dpvc Exp $ 4# $CVSHeader: pg/macros/parserFormulaUpToConstant.pl,v 1.18 2008/09/16 03:23:54 dpvc Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 6# This program is free software; you can redistribute it and/or modify it under
7# the terms of either: (a) the GNU General Public License as published by the 7# the terms of either: (a) the GNU General Public License as published by the
8# Free Software Foundation; either version 2, or (at your option) any later 8# Free Software Foundation; either version 2, or (at your option) any later
9# version, or (b) the "Artistic License" which comes with this package. 9# version, or (b) the "Artistic License" which comes with this package.
175 $r = $r->substitute($r->{constant}=>$l->{constant}) unless $r->{constant} eq $l->{constant}; 175 $r = $r->substitute($r->{constant}=>$l->{constant}) unless $r->{constant} eq $l->{constant};
176 # 176 #
177 # Compare with adaptive parameters to see if $l + n0 C = $r for some n0. 177 # Compare with adaptive parameters to see if $l + n0 C = $r for some n0.
178 # 178 #
179 my $adapt = $l->adapt; 179 my $adapt = $l->adapt;
180 $main::{_cmp_} = sub {return $adapt == $r}; # a closure to access local variables 180 my $equal = $adapt->cmp_compare($r,{});
181 my $equal = main::PG_restricted_eval('&{$main::{_cmp_}}'); # prevents errors with large adaptive parameters
182 delete $main::{_cmp_}; # remove temprary function
183 $self->{adapt} = $self->{adapt}->inherit($adapt); # save the adapted value's flags 181 $self->{adapt} = $self->{adapt}->inherit($adapt); # save the adapted value's flags
184 return -1 unless $equal; 182 return -1 unless $equal;
185 # 183 #
186 # Check that n0 is non-zero (i.e., there is a multiple of C in the student answer) 184 # Check that n0 is non-zero (i.e., there is a multiple of C in the student answer)
187 # (remember: return value of 0 is equal, and non-zero is unequal) 185 # (remember: return value of 0 is equal, and non-zero is unequal)
206 my $self = shift; 204 my $self = shift;
207 my $f = shift->inherit($self); 205 my $f = shift->inherit($self);
208 delete $f->{adapt}; delete $f->{constant}; 206 delete $f->{adapt}; delete $f->{constant};
209 foreach my $id ('test_points','test_at') { 207 foreach my $id ('test_points','test_at') {
210 if (defined $f->{$id}) { 208 if (defined $f->{$id}) {
211 $f->{$id} = $f->{$id}->value if Value::isValue($f->{$id}); 209 $f->{$id} = [$f->{$id}->value] if Value::isValue($f->{$id});
212 $f->{$id} = [$f->{$id}] unless ref($f->{$id}) eq 'ARRAY'; 210 $f->{$id} = [$f->{$id}] unless ref($f->{$id}) eq 'ARRAY';
213 $f->{$id} = [map {[$_]} @{$f->{$id}}] unless ref($f->{$id}[0]) eq 'ARRAY'; 211 $f->{$id} = [map {
212 (Value::isValue($_) ? [$_->value] :
213 (ref($_) eq 'ARRAY'? $_ : [$_]))
214 } @{$f->{$id}}];
214 $f->{$id} = $self->addConstants($f->{$id}); 215 $f->{$id} = $self->addConstants($f->{$id});
215 } 216 }
216 } 217 }
217 return $f; 218 return $f;
218} 219}
225 my $self = shift; my $points = shift; 226 my $self = shift; my $points = shift;
226 my @names = $self->context->variables->variables; 227 my @names = $self->context->variables->variables;
227 my $variables = $self->context->{variables}; 228 my $variables = $self->context->{variables};
228 my $Points = []; 229 my $Points = [];
229 foreach my $p (@{$points}) { 230 foreach my $p (@{$points}) {
231 if (scalar(@{$p}) == scalar(@names)) {
232 push (@{$Points},$p);
233 } else {
230 my @P = (.1) x scalar(@names); my $j = 0; 234 my @P = (.1) x scalar(@names); my $j = 0;
231 foreach my $i (0..scalar(@names)-1) { 235 foreach my $i (0..scalar(@names)-1) {
232 if (!$variables->{$names[$i]}{arbitraryConstant}) { 236 if (!$variables->{$names[$i]}{arbitraryConstant}) {
233 $P[$i] = $p->[$j] if defined $p->[$j]; $j++; 237 $P[$i] = $p->[$j] if defined $p->[$j]; $j++;
238 }
234 } 239 }
240 push (@{$Points}, \@P);
235 } 241 }
236 push (@{$Points}, \@P);
237 } 242 }
238 return $Points; 243 return $Points;
239} 244}
240 245
241################################################## 246##################################################
278# 283#
279# Add useful messages, if the author requested them 284# Add useful messages, if the author requested them
280# 285#
281sub cmp_postprocess { 286sub cmp_postprocess {
282 my $self = shift; my $ans = shift; 287 my $self = shift; my $ans = shift;
283 $self->SUPER::cmp_postprocess($ans); 288 $self->SUPER::cmp_postprocess($ans,@_);
284 return unless $ans->{score} == 0 && !$ans->{isPreview}; 289 return unless $ans->{score} == 0 && !$ans->{isPreview};
285 return if $ans->{ans_message} || !$self->getFlag("showHints"); 290 return if $ans->{ans_message} || !$self->getFlag("showHints");
286 my $student = $ans->{student_value}; 291 my $student = $ans->{student_value};
287 my $result = $ans->{correct_value} <=> $student; # compare encodes the reason in the result 292 $main::{_cmp_} = sub {return $ans->{correct_value} <=> $student}; # compare encodes the reason in the result
293 my $result = main::PG_restricted_eval('&{$main::{_cmp_}}');
294 delete $main::{_cmp_};
288 $self->cmp_Error($ans,"Note: there is always more than one posibility") if $result == 2 || $result == 3; 295 $self->cmp_Error($ans,"Note: there is always more than one posibility") if $result == 2 || $result == 3;
289 if ($result == 3) { 296 if ($result == 3) {
290 my $context = $self->context; 297 my $context = $self->context;
291 $context->flags->set(no_parameters=>0); 298 $context->flags->set(no_parameters=>0);
292 $context->variables->add(x00=>'Real'); 299 $context->variables->add(x00=>'Real');
293 my $correct = $self->removeConstant+"n01+n00x00"; # must use both parameters 300 my $correct = $self->removeConstant+"n01+n00x00"; # must use both parameters
294 $main::{_cmp_} = sub {return $correct == $student+"x00"}; # a closure to access local variables 301 $result = 1 if $correct->cmp_compare($student+"x00",{});
295 $result = 1 if main::PG_restricted_eval('&{$main::{_cmp_}}'); # prevents domain errors (and other errors)
296 delete $main::{_cmp_}; # remove temprary function
297 $context->variables->remove('x00'); 302 $context->variables->remove('x00');
298 $context->flags->set(no_parameters=>1); 303 $context->flags->set(no_parameters=>1);
299 } 304 }
300 $self->cmp_Error($ans,"Your answer is not the most general solution") if $result == 1; 305 $self->cmp_Error($ans,"Your answer is not the most general solution") if $result == 1;
301 $self->cmp_Error($ans,"Your formula should be linear in the constant '$student->{constant}'") 306 $self->cmp_Error($ans,"Your formula should be linear in the constant '$student->{constant}'")

Legend:
Removed from v.5914  
changed lines
  Added in v.5917

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9