[system] / trunk / pg / lib / Parser / Legacy / NumberWithUnits.pm Repository:
ViewVC logotype

View of /trunk/pg/lib/Parser/Legacy/NumberWithUnits.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3347 - (download) (as text) (annotate)
Mon Jul 4 20:12:22 2005 UTC (14 years, 7 months ago) by dpvc
File size: 3393 byte(s)
This is an attempt at making the traditional answer checkers call the
new Parser in place of their original ones.  That is, if you follow
the instructions in the README file, then problems that use
std_num_cmp(), fun_cmp(), etc. will really be using the new Parser
instead of the original PGanswermacros.pl versions.

The old answer checkers are still available, and can be switched back
on a site-wide, course-wide, or problem-by-problem basis.  See the
README for details.

    1 ######################################################################
    2 #
    3 #  This is a Parser class that implements a number with units.
    4 #  It is a temporary version until the Parser can handle it
    5 #  directly.
    6 #
    7 
    8 package Parser::Legacy::NumberWithUnits;
    9 our @ISA = qw(Value::Real);
   10 
   11 sub new {
   12   my $self = shift; my $class = ref($self) || $self;
   13   my $num = shift; my $units = shift;
   14   Value::Error("You must provide a number") unless defined($num);
   15   ($num,$units) = $num =~ m/^(.*)\s+(\S*)$/ unless $units;
   16   Value::Error("You must provide units for your number")
   17     unless $units;
   18   $num = Value::makeValue($num);
   19   Value::Error("A number with units must be a constant, not ".lc(Value::showClass($num)))
   20     unless Value::isReal($num);
   21   my %Units = getUnits($units);
   22   Value::Error($Units{ERROR}) if ($Units{ERROR});
   23   $num->{units} = $units;
   24   $num->{units_ref} = \%Units;
   25   $num->{isValue} = 1;
   26   bless $num, $class;
   27 }
   28 
   29 #
   30 #  Add the units to the string value
   31 #
   32 sub string {
   33   my $self = shift;
   34   $self->SUPER::string . " " . $self->{units};
   35 }
   36 
   37 #
   38 #  Add the units to the TeX value
   39 #
   40 sub TeX {
   41   my $self = shift;
   42   $self->SUPER::TeX . '\ ' . TeXunits($self->{units});
   43 }
   44 
   45 
   46 sub cmp_class {'a Number with Units'};
   47 
   48 #
   49 #  Replace the cmp_parse with one that removes the units
   50 #  from the student answer and checks them.  The answer
   51 #  value is adjusted by the factors, and then checked.
   52 #  Finally, the units themselves are checked.
   53 #
   54 sub cmp_parse {
   55   my $self = shift; my $ans = shift;
   56   #
   57   #  Check that the units are defined and legal
   58   #
   59   my ($num,$units) = $ans->{student_ans} =~ m/^(.*)\s+(\S*)$/;
   60   unless (defined($num) && $units) {
   61     $self->cmp_Error($ans,"Your answer doesn't look like a number with units");
   62     return $ans;
   63   }
   64   my %Units = getUnits($units);
   65   if ($Units{ERROR}) {$self->cmp_Error($ans,$Units{ERROR}); return $ans}
   66   #
   67   #  Check the numeric part of the answer
   68   #   and adjust the answer strings
   69   #
   70   $ans->{correct_value} *= $self->{units_ref}{factor}/$Units{factor};
   71   $ans->{student_ans} = $num;
   72   $ans = $self->SUPER::cmp_parse($ans);
   73   $ans->{student_ans} .= " " . $units;
   74   $ans->{preview_text_string}  .= " ".$units;
   75   $ans->{preview_latex_string} .= '\ '.TeXunits($units);
   76   #
   77   #  If there is not already a message, check the units
   78   #
   79   return $ans unless $ans->{ans_message} eq '';
   80   foreach my $funit (keys %{$self->{units_ref}}) {
   81     next if $funit eq 'factor';
   82     next if $self->{units_ref}{$funit} == $Units{$funit};
   83     $self->cmp_Error($ans,"The units for your answer are not correct")
   84       unless $ans->{isPreview};
   85     $ans->score(0); last;
   86   }
   87   return $ans;
   88 }
   89 
   90 #
   91 #  Convert units to TeX format
   92 #  (fix superscripts, put terms in \rm,
   93 #   and make a \frac out of fractions)
   94 #
   95 sub TeXunits {
   96   my $units = shift;
   97   $units =~ s/\^\(?([-+]?\d+)\)?/^{$1}/g;
   98   $units =~ s/\*/\\,/g;
   99   return '{\rm '.$units.'}' unless $units =~ m!^(.*)/(.*)$!;
  100   my $displayMode = WeBWorK::PG::Translator::PG_restricted_eval(q!$main::displayMode!);
  101   return '\frac{'.$1.'}{'.$2.'}' if ($displayMode eq 'HTML_tth');
  102   return '\frac{\rm\mathstrut '.$1.'}{\rm\mathstrut '.$2.'}';
  103 }
  104 
  105 #
  106 #  Get the units hash and fix up the errors
  107 #
  108 sub getUnits {
  109   my $units = shift;
  110   my %Units = Units::evaluate_units($units);
  111   if ($Units{ERROR}) {
  112     $Units{ERROR} =~ s/ at ([^ ]+) line \d+(\n|.)*//;
  113     $Units{ERROR} =~ s/^UNIT ERROR:? *//;
  114   }
  115   return %Units;
  116 }
  117 
  118 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9