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

I have a basic script which parses and processes a set of .tmp input files:

my $extension = '.txt'; my @files = glob("*.tmp"); for my $file (@files) { open IN, '<', $file or die "$!"; $file =~ s/\..*//; my $outfile = $file.$extension; open OUT, '>', $outfile or die "$!"; while (<IN>) { next unless $. > 45; chomp $_; our(@F) = split(' ', $_, 0); @array = split(m[[:,/]+], $F[9], 0); $check = index($F[4],','); if ($check == '-1') { $ratio = $array[3] / $array[4]; print OUT "$F[0]\t$F[1]\t$F[3]\t$F[4]\t$ratio\t$array[4]\n +"; } elsif ($check > 0) { @allele = split(',', $F[4]); $ratio1 = $array[3] / $array[5]; $ratio2 = $array[4] / $array[5]; print OUT "$F[0]\t$F[1]\t$F[3]\t$allele[0]\t$ratio1\t$arra +y[5]\n$F[0]\t$F[1]\t$F[3]\t$allele[1]\t$ratio2\t$array[5]\n"; } } }

However upon running it, I am receiving the error:

Illegal division by zero at /file/pathway/script.pl line 15 <IN> line 37864

Why is this occurring and how can it be fixed?

Line 37864 is the final line+1 in the first input file (i.e. it's attempting to process an empty line), so I have a feeling that it is due to the fact that in a couple of instances I am splitting one input line into two output lines (see Line 22) and this is offsetting $. but I am not sure.

Replies are listed 'Best First'.
Re: Illegal division by zero error
by davido (Cardinal) on Feb 01, 2016 at 16:31 UTC

    Your script executes line 15 if index($F[4],','); returns -1, which means if the comma isn't found. There are two obvious situations where the comma would not be found: (1) The input data has at least ten fields but there is no comma in the tenth field, or (2) The input data doesn't have ten fields. The second situation can happen, as an example, if your script encounters an empty line. Essentially, you're not handling blank lines or lines that don't conform to expectations. Even in a really sanitary data set, a blank line will often occur at the end of the file. If every line of the input ends with a \n, then the last useful data line also has a newline at the end, leaving an empty line after it. Solve the problem by skipping empty lines. Right after your chomp, put a sanity check: next unless length $_;


    Dave

      Thanks. I had not considered that the IF criteria could be met in more than one way. I have included the recommended next unless length $_; after the chomp $_; however the same error is still returned. I've also tried next if (/^\s+$/); to no avail.

        Then the next step is to put a print statement immediately before line 15 (line 16 now that you added the next unless length line). Print the raw line, and also some of the variables holding various splits and matches. Verify that things look like you expect them to. That will help you to spot the case that you're not handling correctly.


        Dave

Re: Illegal division by zero error
by Corion (Patriarch) on Feb 01, 2016 at 16:28 UTC

    Have you inspected line 15 in your code? Is there a division happening in line 15?

    What steps have you taken to verify that the divisor in line 15 is not zero? Have you printed it out?

      Yes, line 15 is a division:

      $ratio = $array[3] / $array[4];

      The division it is attempting is essentially "zero" because it's attempting to process an empty line after the end of the file.

      I am not sure what is actually the issue - although I think it may be the issue I specified in the OP - if so, i'm not entirely sure how to compensate for the splitting of lines. I did try to essentially offset $. myself by subtracting '1' from it everytime the elseif loop criteria is met but the error is still returned.

        So you have ascertained that the error happens because you enter that block of code but $array[4] contains a value that Perl interprets as zero.

        Maybe you don't want to enter that block if $array[4] contains a value that Perl interprets as zero? Maybe you want to prevent processing invalid lines that leave invalid values in @F?

        You have not shown examples of valid and problematic lines, so we can only guess and trace the path of execution backwards from where the error happens. If you tell us what you want to avoid, or for what kind of lines the error happens, maybe we can better find a solution with you.

        Maybe you want to skip processing empty lines?