We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

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

tian
tian asked
on
Medium Priority
165 Views
Last Modified: 2010-03-04
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.
Comment
Watch Question

Author

Commented:
Edited text of question
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
Are there any other operators besides + and / ?
Can any m's appear in more than one range?

Commented:
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?
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
If there's a non-compound metric and the user doesn't enter a corresponding value, should there be an error message?
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
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;
}

Commented:
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.
ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
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.

Commented:
\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";
  "";
 }
}

Commented:
Hmm, should have added  a "print "$m: $@" if $@; " like you did, forgot that part, but you got the idea.

Author

Commented:
Thank both of you. Please submit your solution as answer.I would like to close this question.

Commented:
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.

Author

Commented:
Ok,the second one
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.