Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

The third 'if'

by danield (Novice)
on Jan 25, 2004 at 23:58 UTC ( [id://324034]=perlquestion: print w/replies, xml ) Need Help??

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

Hello all, I do have a file with this content:
------------- Summary Log (generated: Tue Apr 1 22:02:29 MST 2003) ------------- ZIP file: file_01.zip Detail log file: TA01Apr2003-01.zip.LOG PDF statements generated: 162 Impressions: 880 Hierarchy updates: 66 Movements performed: 19 Statements loaded: 162 Hierarchy errors: 0 Movement errors: 0 Statement errors: 0 ----------------- END Summary Log -----------------

and I do have this perl script:
#!usr/bin/perl -w use strict; use Fcntl qw[:flock]; my $impressions = 0; my $iofile = '/other/scripts/daniel/input/c07_impressions_io.info'; open (IO, $iofile) || die("Could not open file 1!"); while (<IO> ) { chop; my ($FH, $output, $file2check, $month, $year) = split (/\s+/, $_) +; open OUT, ">> $output"; chdir $FH or die "$!"; while (glob $file2check) { open FH, $_ or die $!; flock FH, LOCK_SH or die $!; while (<FH> ) { chomp; if ( / Summary Log \(generated:/ ) { print "Found Sumary Log, checking the month and year.\n"; my($emptyspce, $summary, $log, $generated, $day_word, $monthfi +le, $day_number, $time, $timezone, $yearfile ) = split(/\s+/, $_); if ( $monthfile eq $month and $yearfile eq $year){ print "File has $yearfile and $monthfile in it. Now Looking fo +r Impressions.\n"; if ( /Impressions:/ ) { print "Found Impressions, now splitting.\n"; my($text, $value) = split(/:/, $_); print $impressions += $value if ($value =~ /\d+/) +; print "\n"; } } } } close FH or die $!; } } print OUT 'Total impressions: ', $impressions or die $!;

When I run the script, it produces this output:
Found Sumary Log, checking the month and year. Found Sumary Log, checking the month and year. File has 2003) and Nov in it. Now Looking for Impressions. Found Sumary Log, checking the month and year. File has 2003) and Nov in it. Now Looking for Impressions. Found Sumary Log, checking the month and year. File has 2003) and Nov in it. Now Looking for Impressions.

The script should basically open a file, then check if it has 'Nov' and '2003)' in it.
If yes, the script then should check if there is a line with 'Impressions:' and if impressions has assigned a numeric value, it should then sum together the number of all impressions for the given month and year.
However, the script unable to find impressions. I had a simplier version of the same script and the portion of the code responsible for dealing with impressions did work. Now it does not work, and I have not changet that piece of code. Please, can anybody advice? Thank you for your time. danield

Replies are listed 'Best First'.
Re: The third 'if'
by Zaxo (Archbishop) on Jan 26, 2004 at 01:28 UTC

    Some helpful indentation would point out troubles with your code.

    Nested magical while loops will walk on each other's $_. I don't think that is hurting you here, but it will someday.

    You have a logic bug, your code says,

    while ( lines_to_read() ) { if ( the_line_is_the_right_header()) { if ( the_line_also_has_impressions) { # impression things } } }
    No line satisfies both conditions. You need to last out of the inner loop if the header is wrong. If the header is right keep saying next until you find "Impressions:" or run out of lines.

    Your impression handling code treats a string with leading spaces (from split /:/) as a number. That will always evaluate to zero. [ysth++ is correct. I still think:] split /:\s*/ will work better.

    Update: Here is the whole loop in pseudocode with last and next applied to fix the logic,

    while (files_to_read()) { next unless the_line_is_the_right_header(); while ( lines_to_read() ) { next unless the_line_has_impressions(); # impression things last; # no need to look further in this file } }

    After Compline,
    Zaxo

      Leading and trailing spaces are silently ignored in string->numeric conversion (except for the special "0 but true"). So "  3   " == 3, with no warnings.
      Hello Zaxo, Unfortunatelly I don't know how to implement 'last' or 'next', could you please be more specific?
      In meantime I have tested a suggestion of a different person so the code now looks like:
      #!usr/bin/perl -w #use strict; use Fcntl qw[:flock]; my $impressions = 0; my $iofile = '/other/scripts/daniel/input/c07_impressions_io.info'; open (IO, $iofile) || die("Could not open file 1!"); while (<IO>) { chop; my ($FH, $output, $file2check, $month, $year) = split (/\s+/, $_ +); open OUT, ">> $output"; chdir $FH or die "$!"; while (glob $file2check) { open FH, $_ or die $!; flock FH, LOCK_SH or die $!; while (<FH>) { chomp; if ( / Summary Log \(generated:/ ) { print "Found Sumary Log, checking the month and year.\n"; my($emptyspce, $summary, $log, $generated, $day_word, $monthfi +le, $day_number, $time, $timezone, $yearfile) = split(/\s+/, $_); print "The current file has $monthfile and $yearfile\n"; print "And I am looging for $month and $year\n"; if ( $monthfile eq $month and $yearfile eq $year){ print "File has $yearfile and $monthfile in it. Now Looking fo +r Impressions.\n"; my $found = 0; until ($found) { my $line = <FH>; if ($line =~ /Impressions:/ ) { $found++; print "Found Impressions, now splitting.\n"; my($text, $value) = split(/:\s*/, $_); print $impressions += $value if ($value =~ /\d+/); print "\n"; } } } } } close FH or die $!; } } print OUT 'Total impressions: ', $impressions or die $!;

      And the output I am getting now is:
      Found Impressions, now splitting. Argument "Sat Nov 1 00" isn't numeric in add at c07c_imp.pl line 39, +<FH> chunk 13. 0 Found Sumary Log, checking the month and year. The current file has Nov and 2003) And I am looging for Nov and 2003) File has 2003) and Nov in it. Now Looking for Impressions. Found Impressions, now splitting. Argument "Sat Nov 1 00" isn't numeric in add at c07c_imp.pl line 39, +<FH> chunk 13. 0 Found Sumary Log, checking the month and year. The current file has Nov and 2003) And I am looging for Nov and 2003) File has 2003) and Nov in it. Now Looking for Impressions. Found Impressions, now splitting. Argument "Sat Nov 1 00" isn't numeric in add at c07c_imp.pl line 39, +<FH> chunk 13.
        I think your line 38 should be my($text, $value) = split(/:\s*/, $line); instead of my($text, $value) = split(/:\s*/, $_);. It goes back to what Zaxo said about $_ haunting you. :)

        Your match in line 39 will be true if there is any digit in $value, if you want for only digits try /^\d+$/ instead, but in your case (where you know $value will have a number in it) you don't actually need that if statement.

Re: The third 'if'
by arden (Curate) on Jan 26, 2004 at 16:19 UTC
    Maybe I'm missing one of those special shortcuts in perl (I certainly don't claim to know even 1/3 of all of them), but I don't see where you are attempting to read in the next line before testing if ( /Impressions:/ )

    As an aside, I'll have to strongly agree with Zaxo that your formatting (at least as posted here) really needs some help for readability! Somebody++ cleaned it up.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-04-19 20:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found