Find the answer to your Linux question:
Results 1 to 2 of 2
I am working on a perl script that reads in a log file. The log file has the general form of: Code: (12-Nov-2012, 13:25:17) -- Foo Bar From this, I ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Oct 2012
    Posts
    26

    Average and Standard Deviation in Perl


    I am working on a perl script that reads in a log file. The log file has the general form of:

    Code:
    (12-Nov-2012, 13:25:17) -- Foo Bar
    From this, I calculate the time between events. However, I cannot seem to figure out how to calculate the mean and standard deviation. Here is my code:

    Code:
    use strict;
    use warnings;
    use Time::Interval;
    
    my (at)records;
    my $total_time = 0;
    
    while (<>) {
    
            ## Ignore lines that don't begin with (
            next unless /^\(/;
    
            ## Capture date/time/comment
            /^\(([^,]+),\s+([^\)]+)\)\s+--\s+(.+)/;
    
            ## Create an array of arrays (AoA)
            push (at)records, [ "$1 $2", $3 ];
    }
    
    print "Date/Time\tRun-Time\tComments\n";
    
    # Process records 0 - n-1 (since the last record's duration can't be calculated)
    for ( 0 .. (at)records - 2 ) {
    
            ## Calculate the time difference between n and n+1
            my $data = getInterval( $records[$_]->[0], $records[ $_ + 1 ]->[0] );
    
            ## Format the duration
            my $duration = sprintf '%02d:%02d:%02d',
              $data->{hours}, $data->{minutes}, $data->{seconds};
    
            print "$records[$_]->[0]\t$duration\t$records[$_]->[1]\n";
    }
    NB: in the code I had to replace the "at sign" due to having fewer than 15 posts with (at).
    Any advice?

  2. #2
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    Hi,

    If I were you, I'd convert the date/time strings to seconds since the Epoch, in order to do math on them. You can use the Time::Local perl module to do this. The value you are after should match up with the output of this command (given a certain date/time string):

    Code:
    date +%s --date="12-Nov-2012 13:25:17"
    Once you have numbers, instead of dates, to calculate the mean, it is a simple matter of:

    Code:
    my $mean = ($seconds1 + $seconds2 ) / 2;
    or if there are more than 2 date/times, add them all up and divide by N.

    I've never calculated standard deviation before, but there is perl solution here.

    modified for you, it might look like:
    Code:
    my $mean = whateveryoucalculatedearlier
    my $sqsum = 0;
    my @seconds = ($seconds1 $seconds2 $secondsN);
    for (@seconds) {
        $sqsum += ( $_ ** 2 );
    } 
    $sqsum /= $#seconds + 1;
    $sqsum -= ( $mean ** 2 );
    my $stdev = sqrt($sqsum);
    Now that you have your mean and standard dev in epochal seconds, convert them back using the perl built-in localtime function.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •