File:  [LON-CAPA] / loncom / homework / math_parser / CalcEnv.pm
Revision 1.3: download - view: text, annotated - select for diffs
Mon Mar 13 22:31:22 2023 UTC (21 months, 2 weeks ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_5_msu, version_2_11_4_msu, HEAD
- Add $Id$ line in comments for display of version.

# The LearningOnline Network with CAPA - LON-CAPA
# CalcEnv
#
# $Id: CalcEnv.pm,v 1.3 2023/03/13 22:31:22 raeburn Exp $
#
# Copyright (C) 2014 Michigan State University Board of Trustees
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

##
# Calculation environment, using either units or variables.
##
package Apache::math_parser::CalcEnv;

use strict;
use warnings;
use utf8;

use File::Slurp;

use aliased 'Apache::math_parser::Quantity';
use aliased 'Apache::math_parser::Units';

##
# Constructor
# @param {boolean} unit_mode
##
sub new {
    my ($class, $unit_mode) = @_;
    if (!defined $unit_mode) {
        $unit_mode = 0;
    }
    my $self = {
        _unit_mode => $unit_mode,
    };
    if ($self->{_unit_mode}) {
        $self->{_units} = Units->new();
    } else {
        $self->{_variables} = { }; # hash variable name -> quantity
    }
    my $constants_txt = read_file("$Apache::lonnet::perlvar{'lonTabDir'}/constants.json");
    $self->{_constants} = JSON::DWIW->new->from_json($constants_txt);
    $self->{_tolerance} = 0;
    bless $self, $class;
    return $self;
}

# Attribute helpers

##
# Unit mode ?
# @returns {boolean}
##
sub unit_mode {
    my $self = shift;
    return $self->{_unit_mode};
}

##
# Units
# @returns {Units}
##
sub units {
    my $self = shift;
    return $self->{_units};
}

##
# Variables
# @returns {Object.<string, Quantity>} hash variable name -> quantity
##
sub variables {
    my $self = shift;
    return $self->{_variables};
}

##
# The constants, read from constants.json.
# @returns {hash} A hash name -> hash with the keys value and units
##
sub constants {
    my $self = shift;
    return $self->{_constants};
}

##
# Tolerance
# @returns {string|float} tolerance
##
sub tolerance {
    my $self = shift;
    return $self->{_tolerance};
}


##
# Changes an existing unit or defines a new one.
# @param {string} symbol - name used in math expressions
# @param {string} convert - SI equivalent or using other units to help converting to SI
##
sub setUnit {
    my( $self, $symbol, $convert ) = @_;
    $self->units->{_derived}->{$symbol} = $convert;
}

##
# Changes an existing variable value or defines a new one.
# @param {string} symbol - name used in math expressions
# @param {float|Quantity} value - number value or Quantity
##
sub setVariable {
    my( $self, $symbol, $value ) = @_;
    if ($value->isa(Quantity)) {
        $self->variables->{$symbol} = $value;
    } else {
        $self->variables->{$symbol} = Quantity->new($value);
    }
}

##
# Defines the tolerance to use for = operations.
# @param {string|float} tolerance
##
sub setTolerance {
    my( $self, $tolerance ) = @_;
    $self->{_tolerance} = $tolerance;
}

##
# Returns a variable quantity or undef.
# @param {string} symbol - name used in math expressions
# @returns {Quantity}
##
sub getVariable {
    my( $self, $symbol ) = @_;
    return $self->variables->{$symbol};
}

##
# Returns a constant quantity or undef.
# @param {string} symbol - name used in math expressions
# @returns {Quantity}
##
sub getConstant {
    my( $self, $symbol ) = @_;
    my $cst = $self->constants->{$symbol};
    if (!defined $cst) {
        return undef;
    }
    return Quantity->new($cst->{"value"}, $cst->{"units"});
}

##
# Converts a unit name into a Quantity. Throws an exception if the unit is not known.
# @param {string} name - the unit name
# @returns {Quantity}
##
sub convertToSI {
    my ( $self, $name ) = @_;
    return $self->units->convertToSI($self, $name);
}


1;
__END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>