How to convert a string "-" to an operator -?

D

Diandian Zhang

Hi, everyone,

I think the question is strange. But I really want get the value of
mathematical formal given in form of a string. For example from the
string "256 - 64", I want get the value (256 - 64). What I did was:

my $str = "256 - 64";
my @arr = split (/ /, $str);
my $value;

if (@arr[1] eq "-") {
$value = @arr[0] - @arr[2];
}
elsif (@arr[1] eq "+") {
$value = @arr[0] + @arr[2];
}
elsif (...) {
...;
}

Are there any better ways to solve the problem? Thanks!
 
P

Peter Wyzl

: Hi, everyone,
:
: I think the question is strange. But I really want get the value of
: mathematical formal given in form of a string. For example from the
: string "256 - 64", I want get the value (256 - 64). What I did was:

You could 'eval' the string:

$value = eval $str;

Read up on string eval.

P
 
J

Joe Smith

Diandian said:
$value = @arr[0] - @arr[2];

Put
use strict;
use warnings;
at the top of your code, and perl will tell you that
the above statement should be changed.
-Joe
 
B

Brian McCauley

Peter said:
: Hi, everyone,
:
: I think the question is strange. But I really want get the value of
: mathematical formal given in form of a string. For example from the
: string "256 - 64", I want get the value (256 - 64). What I did was:

You could 'eval' the string:

$value = eval $str;

Read up on string eval.

Don't just read "perldoc -f eval".

Be aware also that the person providing the string to your program will
be able to execute arbitray code (Perl code and external programs) as
the user-id under which the Perl script is running.

Think hard if this is acceptable to you now and likely to be accecptable
also in all contexts where your script may get run in future.
 
A

Arndt Jonasson

Brian McCauley said:
Don't just read "perldoc -f eval".

Be aware also that the person providing the string to your program
will be able to execute arbitray code (Perl code and external
programs) as the user-id under which the Perl script is running.

Think hard if this is acceptable to you now and likely to be
accecptable also in all contexts where your script may get run in
future.

Good warning.

If the purpose is to only evaluate numeric formulas, rejecting
everything that matches "[^0-9*/+- ()]" may be enough (including
period, perhaps, for floating-point numbers). But one still needs to
consider at least the cases of

1) division by zero;
2) bigger numbers than perl can handle (platform-dependent);
3) illegal syntax;

and whether it is exactly the Perl semantics that is wanted (do you want
the ** operator, for example).


If Perl's "eval" does not suffice, CPAN may help. Searching for
"arithmetic" pointed me to the module Math-Expression, for example.

Looking for "lex" and "parse" on CPAN may turn up tools for writing
a parser to do the task.
 
J

Joe Smith

s_g said:
Is there any function in perl to know the number of bits from the
beginning of the line to the current position?

The number of bits is not nearly as useful as the number of bytes
(or the number of characters; characters may be more than 8 bits).

Go look at the substr() and index() functions.
A more advanced way is to use @- and @+ with a pattern match.
-Joe
 
B

Brian McCauley

In the middle of an unrelated thread s_g wrote:

[ Please don't do that ]
My file contains :

Compared A B C D
Equivalent 2 24 56 2

Compared A C
Equivalent 2 4

Compared A B C
Equivalent 2 24 6

Compared C
Equivalent 5

I want to calculate the total number of C's.But, the position(column) of
C's get shifted.

Is there any function in perl to know the number of bits from the
beginning of the line to the current position?

You don't mean 'bits' you mean 'pieces' :)

Rather than having concept of 'current position' and work out which
piece the current position is in it it more natural to read line-wise
and split the data.

#!/usr/bin/perl
use strict;
use warnings;

my (%totals,@legend);

while(<>) {
my ($row_type,@cols) = split;
next unless $row_type;
if ( $row_type eq 'Compared' ) {
@legend = @cols;
} elsif ( $row_type eq 'Equivalent' ) {
for ( @legend ) {
$totals{$_} += shift @cols;
}
}
}

print "$totals{C}\n";
 
M

Michele Dondi

My file contains :

Compared A B C D
Equivalent 2 24 56 2 [snip]
I want to calculate the total number of C's.But, the position(column) of
C's get shifted.

If you can rely on the format of the input file as of the example
portion you've given, you may try something along the lines of:


#!/usr/bin/perl -ln

use strict;
use warnings;

next unless /^Compared/;
my @keys=split;
$_=<>;
my %hash; @hash{@keys}=split;
our $tot+=$hash{C};

END { print $tot };

__END__


Of course in a real app you'd explicitly write the loop and add error
checks appropriately.
Is there any function in perl to know the number of bits from the
beginning of the line to the current position?

No and I don't think that it would be relevant for your problem
however. Also, what do you mean with 'current position'? Are you
reading one charachter at a time?


HTH,
Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,297
Messages
2,571,536
Members
48,284
Latest member
alphabetsalphabets

Latest Threads

Top