FAQ
What would be the best way to omit any record when varible $dist is
null or not > 1 ?

I am not sure my attempt is correct with the ternary operator with
length function. It seems that $dist is just being assinged 0 when
the expression $dist is not > 1.

Any help is greatly appreciated.

Thank you,

Chris

#!/usr/bin/perl

use warnings;
use strict;
use POSIX;

my $filepath = sprintf("F:/Backup/MySQL/10072810.EVDOPCMD");
my $runTime = sprintf("C:/%s.txt",strftime("%y%m%d%H%M",localtime));
#my $fileDate = strftime("%y%m%d%H%",localtime);

open my $fh, '<', $filepath or die "ERROR opening $filepath: $!";
open my $out, '>', $runTime or die "ERROR opening $runTime: $!";

my %sum;

while (<$fh>){
next unless /;/;
chomp;
my @data = split /;/;
my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
@data[31,32,38,44,45,46,47,261];

if( $cell >= 1 && $cell <= 900 && $sect >= 1 && $sect <= 6 ) {

my $carr =
( $cell <= 299 && $chan == 175 ) ? 2 :
( $cell >= 300 && $cell <= 599 && $chan == 75 ) ? 2 :
( $chan == 1025 ) ? 2 : 1 ;

$dist = sprintf "%.1f", ( length( $dist ) > 1 ) ? $dist/8/6.6/2 : 0;


for my $i (44..47) {
my $rlp = $data[$i];
$sum{$cell}{$sect}{$carr}{$dist} += $rlp if $rlp;
}
}
}

my @data;
my $lastDist = 0.0;
for my $cell ( sort keys %sum )
{
for my $sect ( sort keys %{$sum{$cell}} )
{
for my $carr ( sort keys %{$sum{$cell}{$sect}} )
{
$lastDist= 0.0;
for my $dist ( sort keys %{$sum{$cell}{$sect}{$carr}} )
{
for(my $i = $lastDist * 10; $i < $dist * 10; $i++)
{
push( @data, [ 0, $cell, $sect, $carr, sprintf("%0.2f",$i/10),]);
}
$lastDist=$dist+.1;
push( @data, [ $sum{$cell}{$sect}{$carr}{$dist}, $cell, $sect,
$carr, $dist,]);
}
}
}
}

for my $record ( sort {
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] ||
$a->[3] <=> $b->[3] ||
$a->[4] <=> $b->[4] } @data ) {
my( $val, $cell, $sect, $carr, $dist ) = @$record;
print $out "$cell\t $sect\t $carr\t $dist\t $val\n";
}
close $out;

Search Discussions

  • Rob Dixon at Sep 9, 2011 at 1:49 am

    On 08/09/2011 20:58, Chris Stinemetz wrote:
    What would be the best way to omit any record when varible $dist is
    null or not> 1 ?

    I am not sure my attempt is correct with the ternary operator with
    length function. It seems that $dist is just being assinged 0 when
    the expression $dist is not> 1.

    Any help is greatly appreciated.

    Thank you,

    Chris

    #!/usr/bin/perl

    use warnings;
    use strict;
    use POSIX;

    my $filepath = sprintf("F:/Backup/MySQL/10072810.EVDOPCMD");
    my $runTime = sprintf("C:/%s.txt",strftime("%y%m%d%H%M",localtime));
    #my $fileDate = strftime("%y%m%d%H%",localtime);

    open my $fh, '<', $filepath or die "ERROR opening $filepath: $!";
    open my $out, '>', $runTime or die "ERROR opening $runTime: $!";

    my %sum;

    while (<$fh>){
    next unless /;/;
    chomp;
    my @data = split /;/;
    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];

    if( $cell>= 1&& $cell<= 900&& $sect>= 1&& $sect<= 6 ) {

    my $carr =
    ( $cell<= 299&& $chan == 175 ) ? 2 :
    ( $cell>= 300&& $cell<= 599&& $chan == 75 ) ? 2 :
    ( $chan == 1025 ) ? 2 : 1 ;

    $dist = sprintf "%.1f", ( length( $dist )> 1 ) ? $dist/8/6.6/2 : 0;


    for my $i (44..47) {
    my $rlp = $data[$i];
    $sum{$cell}{$sect}{$carr}{$dist} += $rlp if $rlp;
    }
    }
    }

    my @data;
    my $lastDist = 0.0;
    for my $cell ( sort keys %sum )
    {
    for my $sect ( sort keys %{$sum{$cell}} )
    {
    for my $carr ( sort keys %{$sum{$cell}{$sect}} )
    {
    $lastDist= 0.0;
    for my $dist ( sort keys %{$sum{$cell}{$sect}{$carr}} )
    {
    for(my $i = $lastDist * 10; $i< $dist * 10; $i++)
    {
    push( @data, [ 0, $cell, $sect, $carr, sprintf("%0.2f",$i/10),]);
    }
    $lastDist=$dist+.1;
    push( @data, [ $sum{$cell}{$sect}{$carr}{$dist}, $cell, $sect,
    $carr, $dist,]);
    }
    }
    }
    }

    for my $record ( sort {
    $a->[1]<=> $b->[1] ||
    $a->[2]<=> $b->[2] ||
    $a->[3]<=> $b->[3] ||
    $a->[4]<=> $b->[4] } @data ) {
    my( $val, $cell, $sect, $carr, $dist ) = @$record;
    print $out "$cell\t $sect\t $carr\t $dist\t $val\n";
    }
    close $out;
    Hi Chris

    You write
    What would be the best way to omit any record when varible $dist is
    null or not> 1 ?
    But from your code, I assume you mean to omit records when the _length_
    of $dist isn't greater than one?

    I would make the check immediately $dest is assigned, and 'next' over
    the record in the same way as you do for those that contain no semicolon.

    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];

    next unless length $data > 1;

    and then later on, you know $dist is valid so there is no need for the
    test when you are reformatting it:

    $dist = sprintf "%.1f", $dist/8/6.6/2;

    HTH,

    Rob
  • Chris Stinemetz at Sep 9, 2011 at 8:54 am

    What would be the best way to omit any record when varible $dist is
    null or not>  1 ?
    But from your code, I assume you mean to omit records when the _length_
    of $dist isn't greater than one?

    I would make the check immediately $dest is assigned, and 'next' over
    the record in the same way as you do for those that contain no semicolon.

    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];

    next unless length $data > 1;

    and then later on, you know $dist is valid so there is no need for the
    test when you are reformatting it:

    $dist = sprintf "%.1f", $dist/8/6.6/2;

    HTH,

    Rob
    Thank you Rob. Your advise worked perfectly.
    One more question. Is it possible to combine the three next if
    statements below? So the code if doesn't take 3 lines?

    next if(length($dist) == 0);
    next if(length($cell) == 0);
    next if(length($sect) == 0);

    Thank you,

    Chris
  • Shlomi Fish at Sep 9, 2011 at 9:11 am
    Hi Chris,

    thanks for not top-posting. See below for my response.

    On Fri, 9 Sep 2011 03:54:14 -0500
    Chris Stinemetz wrote:
    What would be the best way to omit any record when varible $dist is
    null or not>  1 ?
    But from your code, I assume you mean to omit records when the _length_
    of $dist isn't greater than one?

    I would make the check immediately $dest is assigned, and 'next' over
    the record in the same way as you do for those that contain no semicolon.

    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];

    next unless length $data > 1;

    and then later on, you know $dist is valid so there is no need for the
    test when you are reformatting it:

    $dist = sprintf "%.1f", $dist/8/6.6/2;

    HTH,

    Rob
    Thank you Rob. Your advise worked perfectly.
    One more question. Is it possible to combine the three next if
    statements below? So the code if doesn't take 3 lines?

    next if(length($dist) == 0);
    next if(length($cell) == 0);
    next if(length($sect) == 0);
    Well, the naive way to do it would be to say:

    next if (!length($dist) or !length($cell) or !length($sect));

    There's a better way using List::MoreUtils :

    use List::MoreUtils qw(any);

    next if (any { !length($_) } $dist, $cell, $sect);

    Or:

    use List::MoreUtils qw(notall);

    next if (notall { length($_) } $dist, $cell, $sect);

    (Queue golfing.).

    Hope it helps.

    Regards,

    Shlomi Fish


    --
    -----------------------------------------------------------------
    Shlomi Fish http://www.shlomifish.org/
    What does "Zionism" mean? - http://shlom.in/def-zionism

    My opinions may seem crazy but they all make sense. Insane sense, but sense
    nonetheless.

    Please reply to list if it's a mailing list post - http://shlom.in/reply .
  • Paul Johnson at Sep 9, 2011 at 9:28 am

    On Fri, Sep 09, 2011 at 12:11:04PM +0300, Shlomi Fish wrote:

    next if (!length($dist) or !length($cell) or !length($sect));

    There's a better way using List::MoreUtils :
    For some definition of "better".

    See also De Morgan.

    --
    Paul Johnson - paul@pjcj.net
    http://www.pjcj.net
  • Shlomi Fish at Sep 9, 2011 at 9:37 am
    Hi,

    On Fri, 9 Sep 2011 11:28:19 +0200
    Paul Johnson wrote:
    On Fri, Sep 09, 2011 at 12:11:04PM +0300, Shlomi Fish wrote:

    next if (!length($dist) or !length($cell) or !length($sect));

    There's a better way using List::MoreUtils :
    For some definition of "better".
    Well, it is shorter and has less duplicate code/functionality. It also
    short-circuits like the Perl "or" and "and" operators.
    See also De Morgan.
    My notall { ... } refactoring makes use of this. See:

    http://en.wikipedia.org/wiki/De_Morgan%27s_laws

    Regards,

    Shlomi Fish

    --
    -----------------------------------------------------------------
    Shlomi Fish http://www.shlomifish.org/
    My Favourite FOSS - http://www.shlomifish.org/open-source/favourite/

    Judaism: God is all the shit, all the non‐shit and all the intermediate
    demi‐shits in between.

    Please reply to list if it's a mailing list post - http://shlom.in/reply .
  • Shawn H Corey at Sep 9, 2011 at 12:38 pm

    On 11-09-09 05:11 AM, Shlomi Fish wrote:
    next if (any { !length($_) } $dist, $cell, $sect);
    I would prefer:

    next if (any { length($_) == 0 } $dist, $cell, $sect);

    This makes it clearer as to exactly what condition is being tested, a
    zero-length string.


    --
    Just my 0.00000002 million dollars worth,
    Shawn

    Confusion is the first step of understanding.

    Programming is as much about organization and communication
    as it is about coding.

    The secret to great software: Fail early & often.

    Eliminate software piracy: use only FLOSS.

    "Make something worthwhile." -- Dear Hunter
  • Rob Dixon at Sep 9, 2011 at 3:43 pm

    On 09/09/2011 09:54, Chris Stinemetz wrote:
    What would be the best way to omit any record when varible $dist is
    null or not> 1 ?
    But from your code, I assume you mean to omit records when the _length_
    of $dist isn't greater than one?

    I would make the check immediately $dest is assigned, and 'next' over
    the record in the same way as you do for those that contain no semicolon.

    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];

    next unless length $data> 1;

    and then later on, you know $dist is valid so there is no need for the
    test when you are reformatting it:

    $dist = sprintf "%.1f", $dist/8/6.6/2;

    HTH,

    Rob
    Thank you Rob. Your advise worked perfectly.
    One more question. Is it possible to combine the three next if
    statements below? So the code if doesn't take 3 lines?

    next if(length($dist) == 0);
    next if(length($cell) == 0);
    next if(length($sect) == 0);
    If '0' is an invalid value for all three variables then you could write

    next unless $dist and $cell and $sect;

    or if you want to check only the length

    next unless length $dist and length $cell and length $sect;

    Rob
  • John W. Krahn at Sep 9, 2011 at 6:50 pm

    Chris Stinemetz wrote:
    What would be the best way to omit any record when varible $dist is
    null or not> 1 ?
    But from your code, I assume you mean to omit records when the _length_
    of $dist isn't greater than one?

    I would make the check immediately $dest is assigned, and 'next' over
    the record in the same way as you do for those that contain no semicolon.

    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];

    next unless length $data> 1;

    and then later on, you know $dist is valid so there is no need for the
    test when you are reformatting it:

    $dist = sprintf "%.1f", $dist/8/6.6/2;
    Thank you Rob. Your advise worked perfectly.
    One more question. Is it possible to combine the three next if
    statements below? So the code if doesn't take 3 lines?

    next if(length($dist) == 0);
    next if(length($cell) == 0);
    next if(length($sect) == 0);
    next unless length( $dist ) && length( $cell ) && length( $sect );

    And if you know that $dist or $cell or $sect will never contain the
    string "0" then you could write:

    next unless $dist && $cell && $sect;




    John
    --
    Any intelligent fool can make things bigger and
    more complex... It takes a touch of genius -
    and a lot of courage to move in the opposite
    direction. -- Albert Einstein
  • Mike McClain at Sep 9, 2011 at 4:32 pm
    Hi Chris,
    To debug your code simplify it as much as possible to include
    only the parts that aren't working right which means copy the file
    to a temporary working file (I usually call mine t.pl) and delete
    the stuff that's superflous. In your case that would be reading and
    writing files and the last 2 paragraphs starting with
    'my $lastDist = 0.0;' and 'for my $record ( sort {'.
    Put one line of your data at the end of your truncated file after
    the __DATA__ line and read it into a variable with a line like:
    my $record = <DATA>;
    On Thu, Sep 08, 2011 at 02:58:05PM -0500, Chris Stinemetz wrote:
    What would be the best way to omit any record when varible $dist is
    null or not > 1 ?

    I am not sure my attempt is correct with the ternary operator with
    length function. It seems that $dist is just being assinged 0 when
    the expression $dist is not > 1.

    Any help is greatly appreciated.

    Thank you,

    Chris

    #!/usr/bin/perl

    use warnings;
    use strict;
    use POSIX;

    my $filepath = sprintf("F:/Backup/MySQL/10072810.EVDOPCMD");
    Double quotes strings are interpolated but
    wastes clock cycles when uncalled for.
    Won't make a big difference here but done several times
    within a loop will add up.

    my $filepath = 'F:/Backup/MySQL/10072810.EVDOPCMD';
    my $runTime = sprintf("C:/%s.txt",strftime("%y%m%d%H%M",localtime));
    #my $fileDate = strftime("%y%m%d%H%",localtime);

    open my $fh, '<', $filepath or die "ERROR opening $filepath: $!";
    open my $out, '>', $runTime or die "ERROR opening $runTime: $!";

    my %sum;

    while (<$fh>){
    next unless /;/;
    chomp;
    my @data = split /;/;
    my($cell,$sect,$chan,$rlp1,$rlp2,$rlp3,$rlp4,$dist) =
    @data[31,32,38,44,45,46,47,261];
    <snip>

    The answer to your first question is here:
    next if( $dist <= 1 );

    You never use $rlp1,$rlp2,$rlp3,$rlp4 so are just wasting clock cycles
    by extracting them.
    my($cell,$sect,$chan,$dist) = (split /;/)[31,32,38,261];
    $dist = sprintf "%.1f", ( length( $dist ) > 1 ) ?
    $dist/8/6.6/2 : 0;

    This is the only place you assign to $dist so if you're not happy
    with the value here's where it needs fixing.
    1/8/6.6/2 = 0.0094696 = 1/105.6 and is a constant so take that
    calculation outside your loop as you gain nothing by calculating
    it again and again.
    <snip>

    Pushing your data into an array just so you can pull it back out
    seems a bit cumbersome to me.

    HTH,
    Mike
    --
    Satisfied user of Linux since 1997.
    O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedSep 8, '11 at 7:58p
activeSep 9, '11 at 6:50p
posts10
users7
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase