From: dpvc v. a. <we...@ma...> - 2005-09-24 00:47:27
|
Log Message: ----------- Added ability to have answers that are empty strings. String("") now will produce a valid string object regardless of the Context's defined string values. (You can prevent this using Context()->flags->set(allowEmptyStrings=>0); if you wish). String("")->cmp will produce an answer checker for an empty string (it removes the blank checker that WW installs). Modified Files: -------------- pg/lib: Parser.pm Value.pm pg/lib/Parser: String.pm pg/lib/Value: AnswerChecker.pm String.pm Revision Data ------------- Index: Value.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Value.pm,v retrieving revision 1.47 retrieving revision 1.48 diff -Llib/Value.pm -Llib/Value.pm -u -r1.47 -r1.48 --- lib/Value.pm +++ lib/Value.pm @@ -24,8 +24,9 @@ # ijk => 0, # print vectors as <...> # - # word to use for infinity + # For strings: # + allowEmptyStrings => 1, infiniteWord => 'infinity', # # For intervals and unions: @@ -174,7 +175,7 @@ # sub makeValue { my $x = shift; my %params = (showError => 0, makeFormula => 1, @_); - return $x if (ref($x) && ref($x) ne 'ARRAY') || $x eq ''; + return $x if ref($x) && ref($x) ne 'ARRAY'; return Value::Real->make($x) if matchNumber($x); if (matchInfinite($x)) { my $I = Value::Infinity->new(); @@ -182,7 +183,8 @@ return $I; } return Value::String->make($x) - if (!$Parser::installed || $$Value::context->{strings}{$x}); + if !$Parser::installed || $$Value::context->{strings}{$x} || + ($x eq '' && $$Value::context->{flags}{allowEmptyStrings}); return $x if !$params{makeFormula}; Value::Error("String constant '%s' is not defined in this context",$x) if $params{showError}; @@ -256,6 +258,7 @@ elsif (ref($value)) {return 'unknown'} elsif (defined($strings->{$value})) {return 'String'} elsif (Value::isNumber($value)) {return 'Number'} + elsif ($value eq '' && $equation->{context}{flags}{allowEmptyStrings}) {return 'String'} return 'unknown'; } Index: Parser.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser.pm,v retrieving revision 1.30 retrieving revision 1.31 diff -Llib/Parser.pm -Llib/Parser.pm -u -r1.30 -r1.31 --- lib/Parser.pm +++ lib/Parser.pm @@ -39,7 +39,10 @@ my $tree = $string; $tree = $tree->{tree} if exists $tree->{tree}; $math->{tree} = $tree->copy($math); } elsif (Value::isValue($string)) { - $math->{tree} = $math->{context}{parser}{Value}->new($math,$string); + $math->{tree} = $context->{parser}{Value}->new($math,$string); + } elsif ($string eq '' && $context->{flags}{allowEmptyStrings}) { + $math->{string} = ""; + $math->{tree} = $context->{parser}{Value}->new($math,""); } else { $math->{string} = $string; $math->tokenize; Index: String.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser/String.pm,v retrieving revision 1.10 retrieving revision 1.11 diff -Llib/Parser/String.pm -Llib/Parser/String.pm -u -r1.10 -r1.11 --- lib/Parser/String.pm +++ lib/Parser/String.pm @@ -19,7 +19,7 @@ my $def = $equation->{context}{strings}{$value}; unless ($def) { $def = $equation->{context}{strings}{uc($value)}; - $def = undef if $def->{caseSensitive} && $value ne uc($value); + $def = {} if $def->{caseSensitive} && $value ne uc($value); } $value = $def->{alias}, $def = $equation->{context}{strings}{$value} while defined($def->{alias}); Index: AnswerChecker.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Value/AnswerChecker.pm,v retrieving revision 1.65 retrieving revision 1.66 diff -Llib/Value/AnswerChecker.pm -Llib/Value/AnswerChecker.pm -u -r1.65 -r1.66 --- lib/Value/AnswerChecker.pm +++ lib/Value/AnswerChecker.pm @@ -617,6 +617,25 @@ return $typeMatch->typeMatch($other,$ans); } +# +# Remove the blank-check prefilter when the string is empty, +# and add a filter that removes leading and trailing whitespace. +# +sub cmp { + my $self = shift; + my $cmp = $self->SUPER::cmp(@_); + if ($self->value =~ m/^\s*$/) { + $cmp->install_pre_filter('erase'); + $cmp->install_pre_filter(sub { + my $ans = shift; + $ans->{student_ans} =~ s/^\s+//g; + $ans->{student_ans} =~ s/\s+$//g; + return $ans; + }); + } + return $cmp; +} + ############################################################# package Value::Point; Index: String.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Value/String.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -Llib/Value/String.pm -Llib/Value/String.pm -u -r1.7 -r1.8 --- lib/Value/String.pm +++ lib/Value/String.pm @@ -21,7 +21,8 @@ my $self = shift; my $class = ref($self) || $self; my $x = join('',@_); my $s = bless {data => [$x]}, $class; - if ($Parser::installed) { + if ($Parser::installed && + !($x eq '' && $$Value::context->flag('allowEmptyStrings'))) { my $strings = $$Value::context->{strings}; if (!$strings->{$x}) { my $X = $strings->{uc($x)}; |