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

View of /trunk/pg/lib/Parser/Variable.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2687 - (download) (as text) (annotate)
Fri Aug 27 00:28:27 2004 UTC (15 years, 3 months ago) by dpvc
File size: 3386 byte(s)
Added ability to have linear adaptive parameters in the function
answer checker.  It only works for real-valued functions, though.
To use a parameter, use

       Context()->variables->add(a=>'Parameter');

and then use 'a' as a variable within your answer.  The student will
not be allowed to enter the parameter, but the professor will.

Note that the correct answer will show the full professor's answer,
including the parameters, even though the student can't type it.  Is
this the right behaviour?

    1 #########################################################################
    2 #
    3 #  Implements named variables
    4 #
    5 package Parser::Variable;
    6 use strict; use vars qw(@ISA);
    7 @ISA = qw(Parser::Item);
    8 
    9 $Parser::class->{Variable} = 'Parser::Variable';
   10 
   11 #
   12 #  Error if the variable is not declared in the current context.
   13 #  Record the variable in the equation's list of variables.
   14 #
   15 sub new {
   16   my $self = shift; my $class = ref($self) || $self;
   17   my $equation = shift;
   18   my ($name,$ref) = @_;
   19   unless ($equation->{context}{variables}{$name}) {
   20     my $string = substr($equation->{string},$ref->[2]);
   21     if ($string =~ m/^([a-z][a-z]+)/i) {
   22       $ref->[3] = $ref->[2]+length($1);
   23       $equation->Error("'$1' is not defined in this context",$ref);
   24     }
   25     $equation->Error("Variable '$name' is not defined in this context",$ref);
   26   }
   27   $equation->Error("Variable '$name' is not defined in this context",$ref)
   28     if $equation->{context}{variables}{$name}{parameter} &&
   29        $equation->{context}{flags}{no_parameters};
   30   $equation->{variables}{$name} = 1;
   31   my $def = $equation->{context}{variables}{$name};
   32   bless {
   33     name => $name, def => $def, type => $def->{type},
   34     ref => $ref, equation => $equation
   35   }, $class;
   36 }
   37 
   38 #
   39 #  Replace the variable with its value, if one was given
   40 #
   41 sub reduce {
   42   my $self = shift; my $equation = $self->{equation};
   43   my $value = $equation->{values}{$self->{name}};
   44   $self = $equation->{context}{parser}{Value}->new($equation,[$value])
   45     if defined($value);
   46   return $self;
   47 }
   48 
   49 #
   50 #  Substitute a variable's value, if there is one
   51 #
   52 sub substitute {
   53   my $self = shift; my $equation = $self->{equation};
   54   my $value = $equation->{values}{$self->{name}};
   55   $self = $equation->{context}{parser}{Value}->new($equation,[$value])
   56     if defined($value);
   57   return $self;
   58 }
   59 
   60 #
   61 #  Replace the variable with its value, if one was given
   62 #
   63 sub eval {
   64   my $self = shift;
   65   my $value = $self->{equation}{values}{$self->{name}};
   66   return $value if defined($value);
   67   $self->Error("No value given for variable '$self->{name}'");
   68 }
   69 
   70 #
   71 #  Add the variable name to the equation's list of variables
   72 #    unless the variable has been assigned a value
   73 #
   74 sub getVariables {
   75   my $self = shift; my $variables = $self->{equation}{variables};
   76   return {} if defined($self->{equation}{values}{$self->{name}});
   77   return {$self->{name} => 1};
   78 }
   79 
   80 #
   81 #  Copy the variable, and add the name to the new equation's list
   82 #
   83 sub copy {
   84   my $self = shift;
   85   $self = $self->SUPER::copy(@_);
   86   my $variables = $self->{equation}{variables};
   87   $variables->{$self->{name}} = 1
   88     unless defined($self->{equation}{values}{$self->{name}});
   89   return $self;
   90 }
   91 
   92 #
   93 #  Return the variable's name or value
   94 #
   95 sub string {
   96   my $self = shift;
   97   my $value = $self->{equation}{values}{$self->{name}};
   98   return $value if defined($value);
   99   return $self->{name};
  100 }
  101 #
  102 #  Make a subscripted variable name if it ends in numbers
  103 #
  104 sub TeX {
  105   my $self = shift; my $name = $self->{name};
  106   my $value = $self->{equation}{values}{$name};
  107   return $value if defined($value);
  108   $name = $1.'_{'.$2.'}' if ($name =~ m/^(\D+)(\d+)$/);
  109   return $name;
  110 }
  111 #
  112 #  Make a variable reference
  113 #
  114 sub perl {
  115   my $self = shift;
  116   my $value = $self->{equation}{values}{$self->{name}};
  117   return $value if defined($value);
  118   return '$'.$self->{name};
  119 }
  120 
  121 #########################################################################
  122 
  123 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9