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

Aloha Monks,
I'm still struggling and learning, I do see progress but it is slow. I seek help with the following, it is almost what I want but I can not get the first (outside) loop to stop.

For brevity I'm posting the code that is my problem, I'm not sure to do that or paste everything, but hey I'm sure I'll find out. I will also take any advice that you wise ones wish to give. Mahalo
Joseph W. Guillaume

#$lines is how many big loops #I know there will be 5 lines of data in each loop $lines =scalar@data/5; #print "LINES $lines<p\/>"; #for ($i=1; $i<=$lines; $i++) { foreach ($lines) { for ($i=1; $i<=4; $i++) { $certification = shift(@data); print "Certification is $certification on "; $number = shift (@data); $month = $mon [$number-1]; print "$month"; $day = shift (@data); print " $day"; $year = shift(@data); print " $year"; $mo_yr = shift(@data); #print " $mo_yr"; print "<p\/><HR>"; } }

Replies are listed 'Best First'.
Re: Two loops
by thcsoft (Monk) on May 27, 2005 at 04:33 UTC
    foreach ($lines) doesn't make sense. try
    perl -e 'my $lines = 5; foreach ($lines) { print "foo\n"}'
    and watch 'foo' being printed exactly once. maybe you wanted to say foreach (@data)?

    language is a virus from outer space.
Re: Two loops
by monarch (Priest) on May 27, 2005 at 04:28 UTC
    The outside loop,
    foreach ( $lines ) {
    is calculated from:
    $lines =scalar@data/5;
    which, when re-written probably looks like this:
    $lines = scalar( @data ) / 5;

    Thus lines is a scalar value, there's only one of them, doesn't the outside loop execute only once?

    At least, when I try running:
    perl -e 'foreach (5) { print "Hello\n" }'
    I only get one loop.

Re: Two loops
by djohnston (Monk) on May 27, 2005 at 06:52 UTC
    You don't need nested loops to do what (I think) you are attempting to do. Since you are shifting information out of the @data array within the loop anyway, you would probably have more luck using a single while loop. Sort-of like this:
    while(@data){ my $certification = shift(@data); # etc.. blah blah print "<p\/><HR>"; }
Re: Two loops
by holli (Abbot) on May 27, 2005 at 04:27 UTC
    Your code looks somewhat screwed and makes not much sense to me. It seems you want to format a date.
    Please tell us what @data contains and what output you expect. I'm sure some monk will come up with a solution that fits into a single line.


    holli, /regexed monk/
      Aloha,
      I read all the data (from a file) into an array. There are 5 lines to each set. (I actually will only print 4) So I want to read 5 lines then increment then look and see if there is 5 more if there are read and print them, until I've exausted the file (which won't be too big). Somehow I get four lines, two with valid data and two more sets with only one line in each set and data that really looks weird.

      Mahalo, for your time. Joseph W. Guillaume

        I'm not sure I get what it is you're trying to do... However, to the extent that I think I know, try the following:
        for (1 .. int(scalar @data / 5)) { my $certification = shift(@data); my $number = shift(@data); my $month = $mon[$number - 1]; my $day = shift(@data); my $year = shift(@data); my $mo_yr = shift(@data); print "Certification is $certification on $month $day $year <p\/><H +R>\n"; }

        I'm guessing that there is a better way of doing this, but without knowing what the rest of the script is doing...

        --greg

Re: Two loops
by holli (Abbot) on May 27, 2005 at 15:16 UTC
    Given the sample data you have on loop362's scratchpad, I hacked this together. You can integrate it with the rest of your script.
    use strict; use warnings; my @mon = qw (January Feburary March April May June July August Septe +mber October November December); my @date = (); while ( <DATA> ) { chomp; if ( /^\D/ ) { print "$mon[$date[0]-1]-$date[1]-$date[2]\n" if @date; @date = (); print "certification is $_ on "; next; } unless ( /^\d\|/ ) { push @date, $_; } } print "$mon[$date[0]-1]-$date[1]-$date[2]\n"; __DATA__ Advanced Water Safety Course 1 21 2004 1|2004 Emergecy Vehile Operator Course 4 21 2004 4|2004

    Output:
    certification is Advanced Water Safety Course on January-21-2004 certification is Emergecy Vehile Operator Course on April-21-2004


    holli, /regexed monk/