[system] / trunk / pg / lib / Value / AnswerChecker.pm Repository:
ViewVC logotype

Diff of /trunk/pg/lib/Value/AnswerChecker.pm

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

Revision 3496 Revision 3497
19 19
20sub cmp_defaults {( 20sub cmp_defaults {(
21 showTypeWarnings => 1, 21 showTypeWarnings => 1,
22 showEqualErrors => 1, 22 showEqualErrors => 1,
23 ignoreStrings => 1, 23 ignoreStrings => 1,
24 studentsMustReduceUnions => 1,
25 showUnionReduceWarnings => 1,
24)} 26)}
25 27
26sub cmp { 28sub cmp {
27 my $self = shift; 29 my $self = shift;
28 my $ans = new AnswerEvaluator; 30 my $ans = new AnswerEvaluator;
60 StringifyAsTeX => 0, # reset this, just in case. 62 StringifyAsTeX => 0, # reset this, just in case.
61 no_parameters => 1, # don't let students enter parameters 63 no_parameters => 1, # don't let students enter parameters
62 showExtraParens => 1, # make student answer painfully unambiguous 64 showExtraParens => 1, # make student answer painfully unambiguous
63 reduceConstants => 0, # don't combine student constants 65 reduceConstants => 0, # don't combine student constants
64 reduceConstantFunctions => 0, # don't reduce constant functions 66 reduceConstantFunctions => 0, # don't reduce constant functions
67 ($ans->{studentsMustReduceUnions} ?
68 (reduceUnions => 0, reduceSets => 0,
69 reduceUnionsForComparison => $ans->{showUnionReduceWarnings},
70 reduceSetsForComparison => $ans->{showUnionReduceWarnings}) :
71 (reduceUnions => 1, reduceSets => 1,
72 reduceUnionsForComparison => 1, reduceSetsForComparison => 1)),
65 ($ans->{requireParenMatch}? (): ignoreEndpointTypes => 1), # for Intervals 73 ($ans->{requireParenMatch}? (): ignoreEndpointTypes => 1), # for Intervals
66 $self->cmp_contextFlags($ans), # any additional ones from the object itself 74 $self->cmp_contextFlags($ans), # any additional ones from the object itself
67 ); 75 );
68 my $inputs = $self->getPG('$inputs_ref',{action=>""}); 76 my $inputs = $self->getPG('$inputs_ref',{action=>""});
69 $ans->{isPreview} = $inputs->{previewAnswers} || ($inputs->{action} =~ m/^Preview/); 77 $ans->{isPreview} = $inputs->{previewAnswers} || ($inputs->{action} =~ m/^Preview/);
232# 240#
233sub cmp_postprocess {} 241sub cmp_postprocess {}
234sub cmp_contextFlags {return ()} 242sub cmp_contextFlags {return ()}
235 243
236# 244#
245# For reducing Unions, Sets and Intervals
246#
247sub cmp_checkUnionReduce {
248 my $self = shift; my $ans = shift;
249 return unless $ans->{studentsMustReduceUnions} &&
250 $ans->{showUnionReduceWarnings} &&
251 !$ans->{isPreview};
252 my $student = $ans->{student_value};
253 return unless defined($student) && !Value::isFormula($student);
254 if ($student->type eq 'Union' && $student->length >= 2) {
255 my $reduced = $student->reduce;
256 return "Your union can be written in a simpler form"
257 unless $reduced->type eq 'Union' && $reduced->length == $student->length;
258 my @R = $reduced->value; my @S = sort {$a <=> $b} $student->value;
259 foreach my $i (0..$#R) {
260 return "Your union can be written in a simpler form"
261 unless $R[$i] == $S[$i];
262 }
263 } elsif ($student->type eq 'Set') {
264 my $reduced = $student->reduce;
265 return "Your set must have no redundant elements"
266 unless $reduced->length == $student->length;
267 }
268 return;
269}
270
271#
237# create answer rules of various types 272# create answer rules of various types
238# 273#
239sub ans_rule {shift; pgCall('ans_rule',@_)} 274sub ans_rule {shift; pgCall('ans_rule',@_)}
240sub named_ans_rule {shift; pgCall('NAMED_ANS_RULE',@_)} 275sub named_ans_rule {shift; pgCall('NAMED_ANS_RULE',@_)}
241sub named_ans_rule_extension {shift; pgCall('NAMED_ANS_RULE_EXTENSION',@_)} 276sub named_ans_rule_extension {shift; pgCall('NAMED_ANS_RULE_EXTENSION',@_)}
777 if $other->type =~ m/^(Point|List)$/; 812 if $other->type =~ m/^(Point|List)$/;
778 $other->type =~ m/^(Interval|Union|Set)$/; 813 $other->type =~ m/^(Interval|Union|Set)$/;
779} 814}
780 815
781# 816#
817# Check for unreduced unions and sets
818#
819sub cmp_equal {
820 my $self = shift; my $ans = shift;
821 my $error = $self->cmp_checkUnionReduce($ans);
822 if ($error) {$self->cmp_Error($ans,$error); return}
823 $self->SUPER::cmp_equal($ans);
824}
825
826#
782# Check for wrong enpoints and wrong type of endpoints 827# Check for wrong enpoints and wrong type of endpoints
783# 828#
784sub cmp_postprocess { 829sub cmp_postprocess {
785 my $self = shift; my $ans = shift; 830 my $self = shift; my $ans = shift;
786 return unless $ans->{score} == 0 && !$ans->{isPreview}; 831 return unless $ans->{score} == 0 && !$ans->{isPreview};
830)} 875)}
831 876
832# 877#
833# Use the list checker if the student answer is a set 878# Use the list checker if the student answer is a set
834# otherwise use the standard compare (to get better 879# otherwise use the standard compare (to get better
835# error messages 880# error messages). But check for unreduced unions
881# and sets first.
836# 882#
837sub cmp_equal { 883sub cmp_equal {
838 my ($self,$ans) = @_; 884 my ($self,$ans) = @_;
885 my $error = $self->cmp_checkUnionReduce($ans);
886 if ($error) {$self->cmp_Error($ans,$error); return}
839 Value::List::cmp_equal(@_) if $ans->{student_value}->type eq 'Set'; 887 return Value::List::cmp_equal(@_) if $ans->{student_value}->type eq 'Set';
840 Value::cmp_equal(@_); 888 $self->SUPER::cmp_equal($ans);
841} 889}
842 890
843############################################################# 891#############################################################
844 892
845package Value::Union; 893package Value::Union;
865 list_type => 'an interval, set or union', 913 list_type => 'an interval, set or union',
866 short_type => 'a union', 914 short_type => 'a union',
867 entry_type => 'an interval or set', 915 entry_type => 'an interval or set',
868)} 916)}
869 917
870sub cmp_equal {Value::List::cmp_equal(@_)} 918#
919# Check for unreduced sets and unions
920#
921sub cmp_equal {
922 my $self = shift; my $ans = shift;
923 my $error = $self->cmp_checkUnionReduce($ans);
924 if ($error) {$self->cmp_Error($ans,$error); return}
925 Value::List::cmp_equal($self,$ans);
926}
871 927
872############################################################# 928#############################################################
873 929
874package Value::List; 930package Value::List;
875 931
904# Handle removal of outermost parens in correct answer. 960# Handle removal of outermost parens in correct answer.
905# 961#
906sub cmp { 962sub cmp {
907 my $self = shift; 963 my $self = shift;
908 my $cmp = $self->SUPER::cmp(@_); 964 my $cmp = $self->SUPER::cmp(@_);
965 $cmp->{rh_ans}{showUnionReduceWarnings} = 0;
909 if ($cmp->{rh_ans}{removeParens}) { 966 if ($cmp->{rh_ans}{removeParens}) {
910 $self->{open} = $self->{close} = ''; 967 $self->{open} = $self->{close} = '';
911 $cmp->ans_hash(correct_ans => $self->stringify) 968 $cmp->ans_hash(correct_ans => $self->stringify)
912 unless defined($self->{correct_ans}); 969 unless defined($self->{correct_ans});
913 } 970 }
1005 $value =~ s/ or /s or /; # fix "interval or union" 1062 $value =~ s/ or /s or /; # fix "interval or union"
1006 push(@errors,"There should be more ${value}s in your $stype") 1063 push(@errors,"There should be more ${value}s in your $stype")
1007 if ($score < $maxscore && $score == $m); 1064 if ($score < $maxscore && $score == $m);
1008 push(@errors,"There should be fewer ${value}s in your $stype") 1065 push(@errors,"There should be fewer ${value}s in your $stype")
1009 if ($score < $maxscore && $score == $M && !$showHints); 1066 if ($score < $maxscore && $score == $M && !$showHints);
1067 }
1068
1069 #
1070 # If all the entries are in error, don't give individual messages
1071 #
1072 if ($score == 0) {
1073 my $i = 0;
1074 while ($i <= $#errors) {
1075 if ($errors[$i++] =~ m/^Your .* is incorrect$/)
1076 {splice(@errors,--$i,1)}
1077 }
1010 } 1078 }
1011 1079
1012 # 1080 #
1013 # Finalize the score 1081 # Finalize the score
1014 # 1082 #
1210 1278
1211 # 1279 #
1212 # Use the list checker if the formula is a list or union 1280 # Use the list checker if the formula is a list or union
1213 # Otherwise use the normal checker 1281 # Otherwise use the normal checker
1214 # 1282 #
1215 if ($self->type =~ m/^(List|Union)$/) { 1283 if ($self->type =~ m/^(List|Union|Set)$/) {
1216 Value::List::cmp_equal($self,$ans); 1284 Value::List::cmp_equal($self,$ans);
1217 } else { 1285 } else {
1218 $self->SUPER::cmp_equal($ans); 1286 $self->SUPER::cmp_equal($ans);
1219 } 1287 }
1220} 1288}

Legend:
Removed from v.3496  
changed lines
  Added in v.3497

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9