?
Solved

Performing math on perl variables...

Posted on 2003-03-03
8
Medium Priority
?
338 Views
Last Modified: 2012-06-27
I have perl code that opens a flat data file and
reads in two colmuns of numbers.  The code to do
this is as follows:

open(infile,'<my.dat');
#example of data being read in:
#                        lmbhux03:GBL_CPU_TOTAL_UTIL  lmbhux03:GBL_CPU_IDLE_UTIL

#01/01/03 09:00 Wed             88.600                       11.390
#01/02/03 09:00 Thu             44.880                       55.100

seek(infile,80,0); #mv pointer 80 bytes from 0 to start 1st true record.
$rec_count=0;
$byte_count=0;
while(<infile>){
   read(infile,$date,8);
   print "date=$date\n";

   seek(infile,23,1); #mv pointer 80 bytes from the last pointer
   read(infile,$time1,6);
$t1=$time+12.0;          #t1 is not working!!!
   print ("time1= ***$time1*** - > $time1 + 12=$t1\n");

   seek(infile,40,1); #mv pointer 80 bytes from the last pointer
}
close(infile);

As you can see in the above, the variable "t1" is not
working.  Is this because it is floating point data?

Please advise.
0
Comment
Question by:afsac
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 22

Expert Comment

by:grg99
ID: 8058385
You should be doing something like fscanf to extract your variables.  Something like:

float Time1, Time2;  char Date[10], Time[10], Day[10];

fscanf( infile, "%s %s %s %f %f", Date, Time, Day, &Time1, &Time2 );

0
 
LVL 22

Expert Comment

by:grg99
ID: 8058402
Sorry!  Thought this was the C group!

in Perl:

$Line = <INFILE>;

if( /(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+$/ ) {
$date = $1;  $time1 = $4; $time2 = $5;
}

0
 
LVL 20

Expert Comment

by:jmcg
ID: 8058665
Yes, it does look like you're trying to coerce Perl into looking like C.

The other thing that I'm suspicious of is the intermingled seeks and reads with byte counts. Do you have fixed-length records that you're dealing with? No line terminations? In that case, I'd still prefer to read in an entire record from the file at a time and parse the record contents separately.

Even if everything else you're doing was correct, your attempt to add 12.0 to a string containing a time representation is not going to do what you want. The time as you have it contains a leading space and a colon separating the hours from the minutes. This will have to be interpreted before it can be used in arithmetic.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:afsac
ID: 8059163
Please notice the example of the data file i'm reading
in.  It is not time, but a number. I tried reading
the entire record, and then parcing it out, but the
math didn't work their either.

I basically want to read the numbers in, and keep
a total of each as read then devide by the number of
records read in.  

Thank you for your quick response.
0
 
LVL 20

Expert Comment

by:jmcg
ID: 8060200
Sorry, I overlooked the seek by 23 bytes.

If you have a value in a scalar that looks like an integer or a floating point number, Perl will let you do arithmetic on it. If it doesn't look like a number, Perl will still let you do arithmetic with it, but it will treat the string as if it contained the value 0.

A leading space is sufficient to mess things up.

I'd approach this problem somewhat like this:

#! /usr/bin/env perl

open(infile,'<my.dat');

#example of data being read in:
#                        lmbhux03:GBL_CPU_TOTAL_UTIL  lmbhux03:GBL_CPU_IDLE_UTIL

#01/01/03 09:00 Wed             88.600                       11.390
#01/02/03 09:00 Thu             44.880                       55.100

$rec_count=0;

while(<infile>){
  @f = split;
  next unless @f == 5;

  $date = $f[0];
  print "date=$date\n";

  $time = $f[3];
  $t1=$time+12.0;
  print ("time1= ***$time1*** - > $time1 + 12=$t1\n");

  $accum += $t1;
  $rec_count++;
}
close(infile);

print "avg=", $accum/$rec_count;
0
 
LVL 26

Accepted Solution

by:
wilcoxon earned 200 total points
ID: 8060216
This should do what you're asking.

open(infile,'<my.dat');
#example of data being read in:
#                        lmbhux03:GBL_CPU_TOTAL_UTIL lmbhux03:GBL_CPU_IDLE_UTIL

#01/01/03 09:00 Wed             88.600                       11.390
#01/02/03 09:00 Thu             44.880                       55.100

my ($sum1, $sum2, $count) = (0,0,0);
while (<infile>) {
    chomp;
    next unless /([\d\/]+)\s+([\d:]+)\s+(\w+)\s+([\d\.]+)\s+([\d\.]+)\s*$/;
    my ($date, $time, $wday, $num1, $num2) = ($1, $2, $3, $4, $5);
    # $time will have hh:mm so will need further parsing if you want to modify it
    # but you had said it was the numbers you want tracked
    print "date=$date\ntime = "
    $sum1 += $num1;
    $sum2 += $num2;
    $count++;
}

print "avg1 = ", $sum1/$count, "\navg2 = ", $sum2/$count, "\n";
0
 

Author Comment

by:afsac
ID: 8064483
This worked the best, but I have one more quick question.
Now that I have it working i'm getting a number like
45.64, how do I use perl to round this number up to 46?

Thank you!
0
 
LVL 20

Expert Comment

by:jmcg
ID: 8065020
$x = 45.64;
$y = sprintf "%4.0f", $x;
print $y,"\n";

0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question