Once again: Rolling Frame!

Discussion in 'Perl Misc' started by Marek, Feb 22, 2009.

  1. Marek

    Marek Guest

    Hello all!


    Once again thank you for all for your help with my "rolling frame" in
    the thread "restrict a hash to 15 pairs and iterate over it" some
    weeks ago! I learned a lot of all your suggestions!

    I need once more your help in creating a multi-level hash like
    follows:

    We read in the line numbers, we count the lines ***and*** I need to
    know, how many times these numbers occur in a frame of five lines ...

    So my hash should have these informations in pseudo Perl code:

    number @(line, line, line) => how many times (each number)

    How to transform the genius code of the suggestion from Tad J
    McClellan that the hash creation

    $nums{$_}++ for values
    %lines;

    contains meantime the line numbers?

    here the example code and best greetings to all

    marek


    #!/usr/bin/perl
    use warnings;
    use strict;
    use Data::Dumper;

    my $size = 5; # 5 instead of 15
    my $line = 0; # "line" counter
    my %lines; # buffer up $size lines

    while ( <DATA> ) {
    next if /\./; # skip dates
    chomp;
    $line++;

    $lines{$line} = $_;

    if ( keys %lines == $size ) {

    print Dumper \%lines; # for debugging

    # count what is in the buffer
    my %nums;
    $nums{$_}++ for values %lines;

    # display what is in the (counted) buffer
    foreach my $num ( sort { $a <=> $b } keys %nums ) {
    printf "%3d: %3d times\n", $num, $nums{$num};
    }
    print "---------\n";

    # maintain buffer size
    delete $lines{ $line - $size + 1};
    }

    }

    __DATA__
    01.01.98
    7
    31
    33
    14
    7
    7
    35
    16
    20
    20
    13
    55
    1
    1
    7
    7
    9
    20
    21
    20
    7
    20
    Marek, Feb 22, 2009
    #1
    1. Advertising

  2. Marek

    Guest

    On Sun, 22 Feb 2009 07:02:48 -0800 (PST), Marek <> wrote:

    >Hello all!
    >
    >
    >Once again thank you for all for your help with my "rolling frame" in
    >the thread "restrict a hash to 15 pairs and iterate over it" some
    >weeks ago! I learned a lot of all your suggestions!
    >
    >I need once more your help in creating a multi-level hash like
    >follows:
    >
    >We read in the line numbers, we count the lines ***and*** I need to
    >know, how many times these numbers occur in a frame of five lines ...
    >
    >So my hash should have these informations in pseudo Perl code:
    >
    > number @(line, line, line) => how many times (each number)
    >
    >How to transform the genius code of the suggestion from Tad J
    >McClellan that the hash creation
    >
    > $nums{$_}++ for values
    >%lines;
    >
    >contains meantime the line numbers?
    >
    >here the example code and best greetings to all
    >
    >marek
    >
    >
    >#!/usr/bin/perl
    >use warnings;
    >use strict;
    >use Data::Dumper;
    >
    >my $size = 5; # 5 instead of 15
    >my $line = 0; # "line" counter
    >my %lines; # buffer up $size lines
    >
    >while ( <DATA> ) {
    > next if /\./; # skip dates
    > chomp;
    > $line++;
    >
    > $lines{$line} = $_;
    >
    > if ( keys %lines == $size ) {
    >
    > print Dumper \%lines; # for debugging
    >
    > # count what is in the buffer
    > my %nums;
    > $nums{$_}++ for values %lines;
    >
    > # display what is in the (counted) buffer
    > foreach my $num ( sort { $a <=> $b } keys %nums ) {
    > printf "%3d: %3d times\n", $num, $nums{$num};
    > }
    > print "---------\n";
    >
    > # maintain buffer size
    > delete $lines{ $line - $size + 1};
    > }
    >
    >}
    >
    >__DATA__
    >01.01.98
    >7
    >31
    >33
    >14
    >7
    >7
    >35
    >16
    >20
    >20
    >13
    >55
    >1
    >1
    >7
    >7
    >9
    >20
    >21
    >20
    >7
    >20


    This probably works.
    -sln

    ----------------------------------------

    use warnings;
    use strict;
    use Data::Dumper;

    my $size = 5; # 5 instead of 15
    my $line = 0; # "line" counter
    my %lines; # buffer up $size lines

    while ( <DATA> ) {
    next if /\./; # skip dates
    chomp;
    $line++;

    $lines{$line} = $_;

    if ( keys %lines == $size ) {

    print Dumper \%lines; # for debugging

    # get line's for each number, %nums = nbr=>[line,line,,], nbr=>
    my %nums;

    for (sort { $a <=> $b } keys %lines) {
    my $nbr = $lines{$_};
    push @{$nums{$nbr}}, $_;
    }

    print Dumper \%nums; # for debugging

    # display what is in the (counted) buffer
    foreach my $nbr ( sort { $a <=> $b } keys %nums ) {
    my $aref = $nums{$nbr};
    printf "%3d: %3d times, lines (%s)\n", $nbr, scalar(@$aref), join ',',@$aref;
    }
    print "---------\n";

    # maintain buffer size
    delete $lines{ $line - $size + 1};
    }

    }
    , Feb 22, 2009
    #2
    1. Advertising

  3. Marek

    Marek Guest

    sln Thank you! Great help!


    Best greetings marek
    Marek, Feb 23, 2009
    #3
  4. Marek

    Guest

    On Sun, 22 Feb 2009 18:34:43 GMT, wrote:

    >On Sun, 22 Feb 2009 07:02:48 -0800 (PST), Marek <> wrote:
    >
    >>Hello all!
    >>
    >>
    >>Once again thank you for all for your help with my "rolling frame" in
    >>the thread "restrict a hash to 15 pairs and iterate over it" some
    >>weeks ago! I learned a lot of all your suggestions!
    >>
    >>I need once more your help in creating a multi-level hash like
    >>follows:
    >>
    >>We read in the line numbers, we count the lines ***and*** I need to
    >>know, how many times these numbers occur in a frame of five lines ...
    >>
    >>So my hash should have these informations in pseudo Perl code:
    >>
    >> number @(line, line, line) => how many times (each number)
    >>
    >>How to transform the genius code of the suggestion from Tad J
    >>McClellan that the hash creation
    >>
    >> $nums{$_}++ for values
    >>%lines;
    >>
    >>contains meantime the line numbers?
    >>
    >>here the example code and best greetings to all
    >>
    >>marek
    >>

    [snip]

    Your welcome. Since I save code fragments in a local folder,
    thought this will give you more bang for the buck since you
    don't have to generate new %nums hash each time the frame advances.
    This reduces overhead quite a bit.

    Good luck!
    -sln
    -----------------------------------------------
    ## frame2.pl
    ##
    use warnings;
    use strict;
    use Data::Dumper;

    my $size = 5; # 5 instead of 15 (for test).
    my $line = 0; # "line" counter.
    my %Lines; # Line buffer, up to $size lines: line => number.
    my %Nums; # Number buffer, less than or equal to $size: number => [line,line,line]

    my ($nbr,$nbr_count,$aref,$off_frame_nbr);

    while ( <DATA> )
    {
    # Get digits
    /^\s*(\d+)\s*$/;
    next if (!defined $1);

    $nbr = $1;

    $line++;
    $Lines{ $line} = $nbr;
    unshift @{$Nums{ $nbr}}, $line; # prepend line to array

    if ( keys %Lines == $size )
    {
    # print Dumper \%Lines; # for debugging
    # print Dumper \%Nums; # for debugging
    print "\nFrame ".($line-$size+1)."-$line\n";

    # Display/check whats in the Numbs buffer
    foreach $nbr ( sort { $a <=> $b } keys %Nums )
    {
    $aref = $Nums{ $nbr};
    $nbr_count = @$aref;
    # .... here can check if $nbr_count is excessive
    # ....
    printf "%3d: %3d times at lines (%s)\n", $nbr, $nbr_count, join(',', reverse @$aref);
    }
    print "---------\n";

    # Deplete line going out of frame
    $off_frame_nbr = $Lines{ $line - $size + 1};
    pop @{$Nums{ $off_frame_nbr}};
    delete $Nums{ $off_frame_nbr} if (!@{$Nums{ $off_frame_nbr}});

    # Maintain buffer size
    delete $Lines{ $line - $size + 1};
    }
    }

    __DATA__
    01.01.98
    7
    31
    33
    14
    7
    7
    35
    16
    20
    20
    13
    55
    1
    1
    7
    7
    9
    20
    21
    20
    7
    20
    0
    0
    0
    , Feb 24, 2009
    #4
  5. Marek

    Marek Guest

    On Feb 24, 2:24 am, wrote:

    > snip


    Wow! This is great art! I am admiring such code, like a painting of
    Ilya Repin or ( because you are from Netherlands :) Salomon van
    Ruysdael. I will need weeks to fully understand, what is exactly going
    on in your solution.

    I know, the codex of honour in this group is to suggest first an own
    attempt of code, before asking for help. But: Dear Master sln! I dare
    not to ask a supplemental question. If you have no time, please simply
    don't answer. I don't want to abuse your witness and ***art***. But
    certainly I have a next big problem: How to work with these double
    numbers, once they occur? If there appears a double number, for
    example the 7 in line 5, I would like to see, whether it appears for a
    third time in a frame of five steps later.

    Thank you again


    marek
    Marek, Feb 24, 2009
    #5
  6. Marek

    Guest

    On Mon, 23 Feb 2009 22:30:42 -0800 (PST), Marek <> wrote:

    >On Feb 24, 2:24 am, wrote:
    >
    >> snip

    >
    >Wow! This is great art! I am admiring such code, like a painting of
    >Ilya Repin or ( because you are from Netherlands :) Salomon van
    >Ruysdael. I will need weeks to fully understand, what is exactly going
    >on in your solution.
    >
    >I know, the codex of honour in this group is to suggest first an own
    >attempt of code, before asking for help. But: Dear Master sln! I dare
    >not to ask a supplemental question. If you have no time, please simply
    >don't answer. I don't want to abuse your witness and ***art***. But
    >certainly I have a next big problem: How to work with these double
    >numbers, once they occur? If there appears a double number, for
    >example the 7 in line 5, I would like to see, whether it appears for a
    >third time in a frame of five steps later.
    >
    >Thank you again
    >
    >
    >marek


    Play with $Frame, $subframe and $suboffset variables and ramp stuff.
    Frame can be as large as you want, even larger than all your data.
    Make it large enough to encapsulate the numeric searches you need.
    This is really 2 subroutines. A third might be able to do number
    processing with regular expressions, letting you define more specific
    numeric traffic.

    There is no need though, to do while() unless you either have a very
    large file or are streaming real-time data. The same results can be had
    by mapping (line/number) pairs into an array, the primary sort by number,
    secondary by line. Then you can process the #line's withing the encolsing
    #number's. Same thing.

    Btw, I'm not from Europe.

    Regards,
    -sln

    ----------------------------------------------------
    ## frame3.pl
    ##
    use warnings;
    use strict;

    # Variables that control buffer manipulation ...
    my %Lines; # Line buffer, up to $frame lines: line => number.
    my %Nums; # Number buffer, less than or equal to $frame: number => [line,line,line]
    my $Frame = 20; # Frame size, can be many times larger than Subframe
    my $line = 0; # "line" counter.

    # Virtual frame variable (used for rampdown and data printing)
    my $vframe = $Frame;

    # Variables to control number matching ...
    my $rampup = 0; # 1 = process frame before it fills (no match, for debug only), 0 = wait for full frame
    my $rampdown = 1; # 1 = process last full frame until its empty (RECOMMENDED), 0 = do not process last frame
    my $subframe = 3; # Subframe size to check for number after double (can be 1 .. # for different effects)
    my $suboffset= 2; # Suboffset from 'double' where Subframe starts, 'double' is on Frame boundry (0 .. # for effects)
    my $firstdouble = 1; # 1 = force first sequential double found (22)22222
    # 0 = force last double found 22222(22), offset should be greater than 2
    # Misc ...
    my ($data,$nbr,$nbr_count,$aref,$off_frame_nbr);


    print <<"EOINF";

    ===========================
    Frame size $Frame
    Subframe size $subframe
    Suboffset $suboffset
    Rampup $rampup
    Rampdown $rampdown
    First double $firstdouble
    ===========================
    EOINF


    while ( defined ($data = <DATA>) || ($rampdown && keys %Lines))
    {
    # Get digits
    if (defined $data) {
    $data =~ /^\s*(\d+)\s*$/;
    next if (!defined $1);
    $nbr = $1;
    $line++;
    $Lines{ $line} = $nbr;
    unshift @{$Nums{ $nbr}}, $line; # prepend line to array
    } else {
    --$vframe;
    $vframe = $line if ($vframe > $line);
    }

    if ( $rampup || ($vframe != $Frame) || keys %Lines == $vframe )
    {
    ## Display/check whats in the Numbs buffer
    if ( keys %Lines ) { print "\nFrame ".($line < $vframe ? 1: $line-$vframe+1)."-$line\n" }
    foreach $nbr ( sort { $a <=> $b } keys %Nums )
    {
    $aref = $Nums{ $nbr};
    $nbr_count = @$aref;
    my @ln_array = reverse @$aref;

    printf "%3d: %3d times at lines (%s)\n", $nbr, $nbr_count, join(',', @ln_array);

    # -------------------------------------------------------------------------------------
    # Check if number is seen within a subframe at suboffset past finding its 'double'.
    # Detection of 'double' is on a frame boundry only.
    # --------------
    my ($cur,$prev,$offset,$check_subframe) = (0,-1,0,0);

    foreach $cur (@ln_array)
    {
    if ( !($check_subframe && $firstdouble) && $cur == ($prev + 1)) {
    $offset = $prev + $suboffset;
    $check_subframe = 1;
    # ---
    # Force detection on frame boundry (full frame or ramp down frame).
    last if (($line - $vframe + 1) != ($offset - $suboffset));
    }
    if ($check_subframe && $cur >= $offset && $cur < ($offset + $subframe) ) {
    print "\t\$\$ >> Found #($nbr) !! Sequence \@ " . ($offset - $suboffset) .
    ", subframe = " . $offset ."-". ($offset + $subframe - 1) .
    ", line = $cur\n";
    last;
    }
    $prev = $cur;
    }
    }
    print "---------\n";

    ## Handle buffers
    if ( keys %Lines == $vframe || !defined $data)
    {
    # Deplete line going out of frame
    $off_frame_nbr = $Lines{ $line - $vframe + 1};
    pop @{$Nums{ $off_frame_nbr}};
    delete $Nums{ $off_frame_nbr} if (!@{$Nums{ $off_frame_nbr}});

    # Maintain Line buffer size
    delete $Lines{ $line - $vframe + 1};
    }
    }
    }

    __DATA__
    01.01.98
    7
    7
    7
    31
    7
    33
    14
    77
    7
    35
    26
    20
    20
    7
    7
    7
    23
    55
    2
    2
    2
    2
    2
    2
    2
    2
    2
    2
    2
    2
    2
    2
    2
    21
    2
    20
    7
    20
    0
    2
    0
    , Mar 1, 2009
    #6
  7. Marek

    Marek Guest

    On Mar 1, 2:12 am, wrote:

    > snip


    Thank you sln for your great code. I discovered it only two days ago
    and I tried to thank you by email. But I was not "intelligent" enough
    to complete your email address right.

    I got through your code and I am amazed! I would like to code like
    you, but I am still a beginner.

    Could you send me your email-address? I have a question to you ...


    Best greetings from Munich


    marek
    Marek, Mar 8, 2009
    #7
  8. Marek

    Guest

    On Sun, 8 Mar 2009 09:37:33 -0700 (PDT), Marek <> wrote:

    >On Mar 1, 2:12 am, wrote:
    >
    >> snip

    >
    >Thank you sln for your great code. I discovered it only two days ago
    >and I tried to thank you by email. But I was not "intelligent" enough
    >to complete your email address right.
    >
    >I got through your code and I am amazed! I would like to code like
    >you, but I am still a beginner.
    >
    >Could you send me your email-address? I have a question to you ...
    >
    >
    >Best greetings from Munich
    >
    >
    >marek


    I set up a temporary email:


    -sln
    , Mar 10, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ante Perkovic

    Once again: validating the datagrid

    Ante Perkovic, Jun 25, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    880
    Ante Perkovic
    Jun 25, 2003
  2. =?Utf-8?B?TWF1cml6aW8gUG9sZXR0bw==?=

    Once logon, the web application returs to login page again

    =?Utf-8?B?TWF1cml6aW8gUG9sZXR0bw==?=, Mar 24, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    318
    Patrick.O.Ige
    Mar 25, 2006
  3. Spendius
    Replies:
    8
    Views:
    5,536
    Spendius
    Oct 22, 2003
  4. Gancy
    Replies:
    4
    Views:
    163
    Rasto Levrinc
    Feb 3, 2005
  5. Marek

    rolling frame (3)

    Marek, Mar 24, 2009, in forum: Perl Misc
    Replies:
    3
    Views:
    111
    Marek
    Mar 25, 2009
Loading...

Share This Page