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

I am a beginner for perl. I am writting a program to check if the data in the same column have the same letter,if it finds different letter,then print column number and done for this column and go to compare another column. The table have hundards of columns and rows. so I use two loops, it does not work!
#!/usr/bin/perl -w use strict; open(FH, "table") or die "Can't open file to read!:$! \n"; my $i=2; for (my $i=2; $i<=682; $i++){ while (<FH>){ chomp; my @matrix=split; my $seed=$matrix[$i];#each time I compare one column; next until ($seed=~/[ACGTN-]/ && (!($seed =~ /\$seed/))) { print "P",$i," "; }#Line 23 } $i=$i+1; }until($i>682);#Line 29 close FH; exit;

syntax error at ./dwarfcmp line 23, near "}"
syntax error at ./dwarfcmp line 29, near "}"
Execution of aborted due to compilation errors.
I try more, it did not stop after it find the different letter,and it never can get out of the while loop too!
Please help! Thanks advance.

Edit kudra, 2002-05-30 Fixed code tags--wrap entire code in one set of code tags, not each line in code tags!

Replies are listed 'Best First'.
Re: How to control the loop
by cLive ;-) (Prior) on May 30, 2002 at 00:49 UTC
    Your English is a little confusing, but I can see three errors from a quick glance:
    next until ($seed=~/[ACGTN-]/ && (!($seed =~ /\$seed/))) { # should be: next unless ($seed=~/[ACGTN-]/ && (!($seed =~ /\$seed/)));
    And there's also a problem with the second half of that statement:
    (!($seed =~ /\$seed/)));
    That's always going to evaluate as true - assuming $seed is never '$seed' - ie you're looking to match a literal by escaping the $. And if you meant to interpolate it, it will always be false because $seed always matches $seed ??

    Please clarify. Also:

    $i=$i+1; }until($i>682);#Line 29
    Delete this - your initial for loop covers the condition.

    If you clarify what you are trying to do and supply some sample data input and expected output, that would help.

    cLive ;-)

    --
    seek(JOB,$$LA,0);

(MeowChow) Re: How to control the loop
by MeowChow (Vicar) on May 30, 2002 at 01:04 UTC
    I'm guessing you meant to do something like:
      
    #!/usr/bin/perl -w use strict; open(FH, "table") or die "Can't open file to read!: $!\n"; for my $i (2..682) { while (<FH>) { chomp; my @matrix = split; my $seed = $matrix[$i]; if ($seed !~ /[ACGTN-]/) { print "P$i "; last; } } seek FH, 0, 0; } close FH;
    This code assumes your file is too large to reasonably read into an array; if not, you should do so, instead of reading it over and over 682 times. Even if it is quite large, there are better ways to process it, if efficiency is of any concern.
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
Re: How to control the loop
by ChemBoy (Priest) on May 30, 2002 at 01:12 UTC

    You have a number of serious problems in this code, I'm afraid. I assume you succeeded in resolving those syntax errors at some point, since you say it never breaks out of the while loop, but since (as noted above) the code you posted does not compile, it's somewhat difficult to fix the logical errors.

    However, since cLive ;-) seems to have given you some good advice on the compile-time problems, I'll try to guess what other problems you're about to run into. As I understand it, what you're trying to do is this:

    for each column read each value in the column from the file perform a test on that value

    The problem with the approach you're taking is that you're trying to read the file 682 times. While there's not necessarily a problem with that, you haven't taken any measures to make it work--you're ending the first run through at the end of the file, and you stay there for the rest of the script (look at seek for how to get around that).

    If your table is merely in the range of 100s x 100s, though, I'd suggest instead reading the whole thing into memory: it's not necessarily scalable, but it's a heck of a lot easier to work with. Start with @lines = <FH>; just after you open it, and you can loop over it as many times as you like.

    Alternatively, you can try the slightly more memory-hogging routine of

    while (<FH>) { push @lines, [split]; }
    and using @lines as what passes in Perl for a 2D array. However, if that didn't make instant sense to you, you might want to avoid it. :-)



    If God had meant us to fly, he would *never* have given us the railroads.
        --Michael Flanders