Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

generalisation of a script

by steph_bow (Pilgrim)
on Nov 25, 2008 at 17:11 UTC ( [id://725886]=perlquestion: print w/replies, xml ) Need Help??

steph_bow has asked for the wisdom of the Perl Monks concerning the following question:

Hello Dear Monks

I have made a script that works but I would like to generalise it. Could you give me some advice ? Thanks. The aim of the code is to equally redistribute the times of aircraft departures.

here is the input file

11:10 A1 11:30 E4 11:30 Z4 11:50 H5 12:02 H6 12:25 B2 12:25 A8 12:30 F3 12:30 E7 12:50 E15 12:55 E16

Here is the output

11:00 A1 11:20 E4 11:40 Z4 11:59 H5 12:00 H6 12:10 B2 12:20 A8 12:30 F3 12:40 E7 12:50 E15 12:59 E16

here is my code

use strict; use diagnostics; my $infile = $ARGV[0]; open my $INFILE, q{<}, $infile or die; my $outfile = "sliced_"."$infile"; open my $OUTFILE, q{>}, $outfile or die; sub convert_time_in_mn { my ($ref_time)=@_; my @tab = split(":",$ref_time); #$value=$tab[0].$tab[1]; my $value=($tab[0]*60)+$tab[1]; return $value; } my @slice_11_12_flights; my @slice_12_13_flights; while(my $line = <$INFILE>){ $line =~ s/\s+$//; my $time = substr($line , 0, 5); my $time_mn = convert_time_in_mn($time); print STDOUT "time_mn is ${time_mn}\n"; $line = "$line\n"; if (${time_mn} <= 719){ push @slice_11_12_flights, $line; } else{ push @slice_12_13_flights, $line; } } my $nb_11_12 = @slice_11_12_flights; my $nb_12_13 = @slice_12_13_flights; # the interval number should be equal to the number of elements minus +one my $NB_11_12 = $nb_11_12 -1; my $NB_12_13 = $nb_12_13 -1; # mean nb of seconds between two planes in the same slice my $inter_sec_11_12 = 3600/$NB_11_12; my $inter_sec_12_13 = 3600/$NB_12_13; my $time_11_12 = 0; my $time_12_13 = 0; my @minutes; foreach my $i(0..$NB_11_12){ my $sec = $i * $inter_sec_11_12; print STDOUT "sec is $sec\n"; my $min = int($sec/60); # in order to avoid confusion if ($min == 60){ $min = 59; } if ($min =~ /^(\d)$/){ $min = "0"."$1"; } my $time = join ":", "11", "$min"; print STDOUT "time is $time\n"; my $slice = $slice_11_12_flights[$i]; print STDOUT "slice is $slice\n"; my $former_time = substr($slice , 0, 5); $slice =~ s/$former_time/$time/; print $OUTFILE "$slice"; } foreach my $i(0..$NB_12_13){ my $sec = $i * $inter_sec_12_13; print STDOUT "sec is $sec\n"; my $min = int($sec/60); # in order to avoid confusion if ($min == 60){ $min = 59; } if ($min =~ /^(\d)$/){ $min = "0"."$1"; } my $time = join ":", "12", "$min"; print STDOUT "time is $time\n"; my $slice = $slice_12_13_flights[$i]; print STDOUT "slice is $slice\n"; my $former_time = substr($slice , 0, 5); $slice =~ s/$former_time/$time/; print $OUTFILE "$slice"; }

Replies are listed 'Best First'.
Re: generalisation of a script
by BrowserUk (Patriarch) on Nov 25, 2008 at 17:46 UTC

    It's not clear to me what you mean by "generalise", but this simplifies it a little, and appears to produce similar output for the test case:

    #! perl -slw use strict; use Data::Dump qw[ pp ]; my %in; m[(\d\d):\d\d (.+)$] and push @{ $in{ $1 } }, $2 while <DATA>; for my $hr ( sort{ $a <=> $b } keys %in ) { my $n = $#{ $in{ $hr } }; my $step = 60 / $n; my $min = 0; for my $flight ( @{ $in{ $hr } } ) { printf( "%02d:%02d %s\n", $hr, int( $min ), $flight ); $min += $step; $min = 59 if $min > 59; } } __DATA__ 11:10 A1 11:30 E4 11:30 Z4 11:50 H5 12:02 H6 12:25 B2 12:25 A8 12:30 F3 12:30 E7 12:50 E15 12:55 E16

    Produces:

    C:\test>725886.pl 11:00 A1 11:20 E4 11:40 Z4 11:59 H5 12:00 H6 12:10 B2 12:20 A8 12:30 F3 12:40 E7 12:50 E15 12:59 E16

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Thanks a lot BrowserUK

      When I wrote "generalise", I wanted to find another way than to define @slice_11_12_flights, @slice_12_13_flights, ...

Re: generalisation of a script
by jwkrahn (Abbot) on Nov 25, 2008 at 18:48 UTC

    Perhaps you want something like this:

    #!/usr/bin/perl use warnings; use strict; my $infile = $ARGV[ 0 ]; my $outfile = "sliced_$infile"; open my $INFILE, '<', $infile or die "Cannot open '$infile' $!"; open my $OUTFILE, '>', $outfile or die "Cannot open '$outfile' $!"; my %flights; while ( <$INFILE> ) { my ( $hour, $rest ) = /(\d+):\d+(.+)/; push @{ $flights{ $hour } }, $rest; } for my $hour ( keys %flights ) { my $interval = 60 / @{ $flights{ $hour } }; for my $i ( 0 .. $#{ $flights{ $hour } } ) { printf $OUTFILE "%02d:%02d%s\n", $hour, $i * $interval, $fligh +ts{ $hour }[ 0 ]; } } __END__

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://725886]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-04-26 01:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found