Perl - how to compute totals via hash request

S

shree

Dear Perl Gurus,

I have a tab delimited log file that contains data of system
downtimes. It has 4 fields namely ID, type of downtime (whether
planned or unplanned), date and duration of downtime (in secs). I'm
asked to compute totals for each month of each type. See input data
file provided and mocked output file.

Data File (does not contain header line)
ID Type Date DowntimeSecs
1 Planned 01/19/2003 5000
2 Unplanned 01/27/2003 900
3 Unplanned 01/29/2003 300
4 Unplanned 02/12/2003 3690
5 Planned 02/27/2003 1800
...
...
80 Planned 07/12/2003 6000
81 Unplanned 07/15/2003 8400

Hence, the needed output file should be like
MonthYear Planned Unplanned TotalDownTime
Jan2003 5000 1200 6200
Feb2003 1800 3690 5490
...
...

I started with the following code

my %count;
while(<DATA>) {
chomp;
my ($id, $type, $date, $downtime_secs) = split (/\t/, $_);
$count{$type} += $downtime_secs;
}

while (my ($key, $val) = each %count) {
print "$key, $val \n";
}
which outputs
Unplanned, 82000
Planned, 90000

How can I modify the above, to give my customer what they wanted. Also
if anyone can educate me to how to extract more detailed info as shown
below, I would greatly appreciate it. Thank you

MonthYear Planned Unplanned Total NoPlanned NoUnplanned NoOfTotal
Jan2003 5000 1200 6200 1 2 3
Feb2003 1800 3690 5490 1 1 2
...
...
 
C

ctcgag

Dear Perl Gurus,

I have a tab delimited log file that contains data of system
downtimes. It has 4 fields namely ID, type of downtime (whether
planned or unplanned), date and duration of downtime (in secs). I'm
asked to compute totals for each month of each type. See input data
file provided and mocked output file.

Data File (does not contain header line)
ID Type Date DowntimeSecs
1 Planned 01/19/2003 5000
2 Unplanned 01/27/2003 900
3 Unplanned 01/29/2003 300
4 Unplanned 02/12/2003 3690
5 Planned 02/27/2003 1800
..
..
80 Planned 07/12/2003 6000
81 Unplanned 07/15/2003 8400

Hence, the needed output file should be like
MonthYear Planned Unplanned TotalDownTime
Jan2003 5000 1200 6200
Feb2003 1800 3690 5490
..
..

I started with the following code

my %count;

%sum would be a better name than %count.
while(<DATA>) {
chomp;
my ($id, $type, $date, $downtime_secs) = split (/\t/, $_);

my ($id, $type, $mon, $day, $year, $downtime_secs) = split (/\t|\//, $_);
$count{$type} += $downtime_secs;

$count{$mon.$year}{$type} += $downtime_secs;
}

while (my ($key, $val) = each %count) {
print "$key, $val \n";

print "$key, $val->{Planned}, $val->{Unplanned}\n";
}
which outputs
Unplanned, 82000
Planned, 90000

How can I modify the above, to give my customer what they wanted.

The above should start you down the path...
Also
if anyone can educate me to how to extract more detailed info as shown
below, I would greatly appreciate it. Thank you

Keep two hashes, one named %sum and one named %count, and do the
obvious with thing with each.
MonthYear Planned Unplanned Total NoPlanned NoUnplanned NoOfTotal
Jan2003 5000 1200 6200 1 2 3
Feb2003 1800 3690 5490 1 1 2
..
..


Xho
 
T

Tad McClellan

shree said:
Hence, the needed output file should be like
MonthYear Planned Unplanned TotalDownTime
Jan2003 5000 1200 6200
Feb2003 1800 3690 5490

Also
if anyone can educate me to how to extract more detailed info as shown


Errr, you do not need to extract any more info, you are already
extracting it all.

below, I would greatly appreciate it. Thank you

MonthYear Planned Unplanned Total NoPlanned NoUnplanned NoOfTotal
Jan2003 5000 1200 6200 1 2 3
Feb2003 1800 3690 5490 1 1 2


Oh, you need to record something that you are already extracting,
plus perform some calculations based on those values.


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

my %count;
while ( <DATA> ) {
chomp;
my($id, $type, $date, $downtime_secs) = split;
(my $key = $date) =~ s#/\d+##;
$count{$key}{$type} += $downtime_secs;

$count{$key}{ substr $type, 0, 1 }++;
}

foreach my $key ( sort keys %count ) {
printf "%-15s %10d %10d %10d %3d %3d %3d\n", $key,
$count{$key}{Planned}, $count{$key}{Unplanned},
$count{$key}{Planned}+$count{$key}{Unplanned},
$count{$key}{P}, $count{$key}{U},
$count{$key}{P} + $count{$key}{U};
}


__DATA__
1 Planned 01/19/2003 5000
2 Unplanned 01/27/2003 900
3 Unplanned 01/29/2003 300
4 Unplanned 02/12/2003 3690
5 Planned 02/27/2003 1800
80 Planned 07/12/2003 6000
81 Unplanned 07/15/2003 8400
 
J

John W. Krahn

shree said:
I have a tab delimited log file that contains data of system
downtimes. It has 4 fields namely ID, type of downtime (whether
planned or unplanned), date and duration of downtime (in secs). I'm
asked to compute totals for each month of each type. See input data
file provided and mocked output file.

Data File (does not contain header line)
ID Type Date DowntimeSecs
1 Planned 01/19/2003 5000
2 Unplanned 01/27/2003 900
3 Unplanned 01/29/2003 300
4 Unplanned 02/12/2003 3690
5 Planned 02/27/2003 1800
..
..
80 Planned 07/12/2003 6000
81 Unplanned 07/15/2003 8400

Hence, the needed output file should be like
MonthYear Planned Unplanned TotalDownTime
Jan2003 5000 1200 6200
Feb2003 1800 3690 5490
..
..

I started with the following code

my %count;
while(<DATA>) {
chomp;
my ($id, $type, $date, $downtime_secs) = split (/\t/, $_);
$count{$type} += $downtime_secs;
}

while (my ($key, $val) = each %count) {
print "$key, $val \n";
}
which outputs
Unplanned, 82000
Planned, 90000

How can I modify the above, to give my customer what they wanted. Also
if anyone can educate me to how to extract more detailed info as shown
below, I would greatly appreciate it. Thank you

MonthYear Planned Unplanned Total NoPlanned NoUnplanned NoOfTotal
Jan2003 5000 1200 6200 1 2 3
Feb2003 1800 3690 5490 1 1 2

This works with the data provided:

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

my %count;
while ( <DATA> ) {
chomp;
my ( undef, $type, $date, $secs ) = split /\t/;
( my $mon = $date ) =~ s!(\d+)/\d+/(\d+)!$2$1!;
$count{ $mon }{ sec }{ $type } += $secs;
$count{ $mon }{ cnt }{ $type }++;
}

my @mons = ( undef, qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ) );
print " --------- Seconds --------- ---------- Count ----------\n";
print "MonthYear Planned Unplanned Total Planned Unplanned Total\n";
for my $key ( sort keys %count ) {
( my $mon = $key ) =~ s/(\d{4})(\d\d)/$mons[$2]$1/;
printf "%-9s %9d %9d %9d %9d %9d %9d\n", $mon,
@{$count{ $key }{ sec }}{ 'Planned', 'Unplanned' },
$count{ $key }{ sec }{ Planned } + $count{ $key }{ sec }{ Unplanned },
@{$count{ $key }{ cnt }}{ 'Planned', 'Unplanned' },
$count{ $key }{ cnt }{ Planned } + $count{ $key }{ cnt }{ Unplanned };
}

__DATA__
1 Planned 01/19/2003 5000
2 Unplanned 01/27/2003 900
3 Unplanned 01/29/2003 300
4 Unplanned 02/12/2003 3690
5 Planned 02/27/2003 1800
80 Planned 07/12/2003 6000
81 Unplanned 07/15/2003 8400



John
 

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
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top