Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: For- loop increment not passing to inner block

by CountZero (Bishop)
on Mar 30, 2008 at 20:16 UTC ( [id://677379]=note: print w/replies, xml ) Need Help??


in reply to For- loop increment not passing to inner block

There are two problems with your code:
  1. Assuming SORTD is some form of file-handle, the first time you arrive at the while-loop ($i being equal to 0), the while-loop will totally exhaust the filehandle. All following calls to readline(SORTD) (when $i is incremented and the while-loop is entered again, will just return undef and the while-loop will not even start. Re-entering the loop does not reset the filehandle to the beginning of the file.
  2. The value of $i remains constant throughout each iteration of the for loop. So the while-loop will see the same value of $i for the whole of the file you are reading.
One more comment: it is more customary to write readline(SORTD) as <SORTD>

CountZero

A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Replies are listed 'Best First'.
Re^2: For- loop increment not passing to inner block
by Anonymous Monk on Mar 30, 2008 at 20:47 UTC
    Ah! Of course! I wasn't resetting the filehandle! (Must. . . have. . . coffee. . ) The filehandle SORTD refers a textfile like this:
    0912203749 0725284648 0608294149 0622424347 1219303436 1729313449 1015162331 . . .
    These are actually groupings of five 2-digit numbers. My goal was to traverse it by column, using i*2 as a starting index (that part, at least, works fine). I probably should have explained that at the outset but, silly me, I thought the issue was probably too simple to require further elaboration (I won't make that mistake again). Bountiful thanks, CountZero!
      I might not understand the overall task, but I would be inclined to invert the order of your two loops: the "while" loop over the file data should be the outer loop, and the "for" loop over columns in each line should be the inner loop.

      If the file in question is not very big (e.g. less than, say, 50 MB on typical desktop machines of the last few years), and you have some reason to prefer your current ordering of the loops, it would be better to read the whole file content into a memory-resident array first, then use a nested "for" loop over that array, rather than repeating your "while" loop over the file contents.

      The point is that file i/o is quite slow relative to memory-internal operations, so reading data from a file just once (rather than five times) just makes more sense.

      This is bread and butter stuff for Perl and there are many better ways to achieve what you are after. Some are likely to be outside your current comfort zone so sift through the following and see what you like the look of:

      use warnings; use strict; while (<DATA>) { chomp; my @numbers = unpack ("(a2)*", $_); print "unpacked: @numbers, "; @numbers = /(..)/g; print "matched: @numbers, "; @numbers = (); push @numbers, substr $_, 0, 2, '' while length $_; print "substr'd: @numbers\n"; } __DATA__ 0912203749 0725284648 0608294149 0622424347 1219303436 1729313449 1015162331

      Prints:

      unpacked: 09 12 20 37 49, matched: 09 12 20 37 49, substr'd: 09 12 20 +37 49 unpacked: 07 25 28 46 48, matched: 07 25 28 46 48, substr'd: 07 25 28 +46 48 unpacked: 06 08 29 41 49, matched: 06 08 29 41 49, substr'd: 06 08 29 +41 49 unpacked: 06 22 42 43 47, matched: 06 22 42 43 47, substr'd: 06 22 42 +43 47 unpacked: 12 19 30 34 36, matched: 12 19 30 34 36, substr'd: 12 19 30 +34 36 unpacked: 17 29 31 34 49, matched: 17 29 31 34 49, substr'd: 17 29 31 +34 49 unpacked: 10 15 16 23 31, matched: 10 15 16 23 31, substr'd: 10 15 16 +23 31

      Perl is environmentally friendly - it saves trees
        I got sidetracked, but finally got back to this and took a look at your ideas, Grandfather. I'm a little disconcerted that your examples are simply reading each row into an array, in different ways. Thanks for the stylistic tips, but I'm not sure how that's relevant to what I'm trying to do (aggregate individual columns for analysis), but I guess I explained it badly. No matter. My stupid error was caught by Count Zero, and my awkward approach works fine for now. I may re-implement it using an array of references (my original idea), but I was aiming for a quick-and-dirty solution (not to worry: it's neither for work or a homework assignment!) :) . Thanks again.
      Thanks for the tips all, particularly Grandfather. I can assure you that, to the extent I have a "comfort zone," it's simply habits and prejudices carrying over from other languages I've used. There may be more than one way to do it, but I have no interest in using a Stradavarius to pound nails. I'm always interested in a better way to do it, and if that requires learning new things, that's all the better. Thanks again!

Log In?
Username:
Password:

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

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

    No recent polls found