Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: How to evaluate a mathematical formula that is stored in another file?

by hdb (Monsignor)
on Mar 20, 2018 at 11:22 UTC ( #1211303=note: print w/replies, xml ) Need Help??

in reply to How to evaluate a mathematical formula that is stored in another file?

From the first part of your code it looks like you are storing your variables and values in the %data hash in the form $data{"variable name"} = "value". In order to work, your formulae have to use those variables and values in the very same format.

I would think it be useful to see a couple of examples.

Update: Here is some basic code to get you started:

use strict; use warnings; my %data = ( x => 5, y => 7, z => 2 ); my @formulae = ( 'x + y', 'z + 3', 'x ** z', 'a + x', 'x /= y', 'x - x' ); for my $formula (@formulae) { print "Processing formula $formula\n\t"; my @error = (); while ($formula =~ s|([a-z]+)|$data{$1}//' '|e) { push @error, $1 unless exists $data{$1}; } if (@error) { print "Error: unknown variable(s) @error\n\n"; } else { my $result = eval($formula); if( defined $result) { print "Result: $formula = $result\n\n"; } else { print "Syntax error in $formula\n\n"; } } }

Replies are listed 'Best First'.
Re^2: How to evaluate a mathematical formula that is stored in another file?
by skooma (Novice) on Mar 22, 2018 at 10:06 UTC

    Thanks your code greatly helped me to get part of my results. But can you explain these two lines below? Thanks.

    while ($formula =~ s|([a-z]+)|$data{$1}//' '|e) { push @error, $1 unless exists $data{$1};

      In my simplistic example code I assumed that a variable name consists of lower case letters. The regular expression ([a-z]+) finds any consecutive sequence of (at least one) lower case letters. It is then replaced by $data{$1}//' ' where $1 stands for the found sequence. $data{$1} is the value assigned to that sequence ie the variable name. If it does not exist in the hash %data the expression //' ' ensures that a blank is used instead (also makes sure that no warning is issued).

      I have used s||| instead of the more common s/// to avoid confusion on the // operator.

      In the push statement I store the found sequence as in $1 in the array @error if %data did not contain a value for the variable. This is some kind of crude error handling and I can list the names of variables without values further below in the code.

      Again, this is only a simplistic example, and not the only way to look at your requirements. The evil eval is still not fully defused and one could create havoc with mischievous inputs in the values or formulae provided.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1211303]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2022-05-22 14:46 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (80 votes). Check out past polls.