locate an entry and related information in the file(modified)

Hello,
    Does any one have an good idea  to implement following question in perl effectively.
Suppose there is a file the format is:

    metrics         range
-----------------------------------
    m1              0-12
    m2+m3           0-56
    m4              0.2-13.4
    m6/m7           8 -56
    ....

the entry may be compound.What the user input is like:" (m3 3),(m1 19), (m4 23)(m2,23)..." and the program can locate those given input in the file and check if the given value is within range.(However,if program gets "m3 3",it should save this metric and its value and after geting m4 and its value,it then can calculate the value of (m2+m3) and then check the validity).
thanks in advance.
tianAsked:
Who is Participating?
 
alamoConnect With a Mentor Commented:
Thanks, tian. The answer is as posted in the comments below.
0
 
tianAuthor Commented:
Edited text of question
0
 
ozoCommented:
Are there any other operators besides + and / ?
Can any m's appear in more than one range?

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
alamoCommented:
I assume "after geting m4 and its value,it then can calculate the value of (m2+m3)" was a typo, and you meant "after gettingm2 and its value...".

If there is a coumpound metric and the user doesn't enter values for all the needed values, should there be an error message or does in that case the metric just not apply?
0
 
ozoCommented:
If there's a non-compound metric and the user doesn't enter a corresponding value, should there be an error message?
0
 
ozoCommented:
open(INPUT,"<user.input") or die "can't open user.input: $!";
{local $/=")";
 while( <INPUT> ){
   unless( ($m,$v) = /(\w+)\W+(\d+)/ ){
      warn $_; next;
   }
   $m{$m} = $v;
  }
}
open(METRICS,"<metric.file") or die "can't open metric.file: $!";
while( <METRICS> ){
  chomp;
  unless( ($m,$min,$max) = /(\S+)\s+(-?[^-]+)-(.*)/ ){
    warn $_;
    next;
  }
  ($e=$m)=~s/(\w+)/\$m{$1}/g;
  $error = '';
  {local $^W=1; local $SIG{__WARN__} = sub{ $error=$_[0]};
  $v = eval $e;
  }
  warn "$m: $error" if $error;
  warn "$m: $@" if $@;
  warn "$_: invalid\n" if $v<=$min || $max <= $v;
}

0
 
alamoCommented:
Very nicely done, ozo. I would have done it a bit differently, because I made some different assumptions reading the question (negative values are allowable, range endpoints are allowable, metrics where none of the values are present are allowable, and an affirmative message when a metric passed). It could well be none of those assumptions are true, though.
0
 
ozoCommented:
I thought I allowed negative values?  (though not negative exponents in range values)
Exact equality of floating point values is not to be trusted anyway, so I thought I'd let undefined 0 values end up invalid.
(although the user input values seem to be integers...
that may have been a bad assumption)
There's also potential for the eval to do nasty things if the right metrics are passed.

It may also be interesting to see how you would have done it with other assumptions.
0
 
alamoCommented:
\W+ when reading user.input gobbles a leading negative sign.

Here's my version, based on the assumptions above:

(all lines up to and including "$error = '';" are the same, I am replacing the rest of the program from there):

 $goodmetrics=0;
 ($e=$m)=~s/(\w+)/&checkmetric($1)/ge;
 if ($error) {
  print $error unless $goodmetrics==0;
 }
 else {
  $v = eval $e;
  if ($v >= $min && $v <= $max) {
   print "$m: Success\n";
  }
  else {
   print "$m: failed ($v)\n";
  }
 }
}

sub checkmetric {
 my $n = pop;
 if (exists $m{$n}) {
  $goodmetrics++;
  $m{$n};
 }
 else {
  $error .= "$m: Unknown metric '$n'\n";
  "";
 }
}
0
 
alamoCommented:
Hmm, should have added  a "print "$m: $@" if $@; " like you did, forgot that part, but you got the idea.
0
 
tianAuthor Commented:
Thank both of you. Please submit your solution as answer.I would like to close this question.
0
 
alamoCommented:
tian, only one of us can provide the "answer"... you need to pick one of us, or else post another question just to give the other points.
0
 
tianAuthor Commented:
Ok,the second one
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.