Guys I am writing a program in perl to loop through an array of integers read in from a file line by line, then notice patterns of numbers in each line and output triples(3 of the same numbers occuring consecutively), pairs(only two of the same numbers occuring consecutively) and straights (three numbers occuring consecutively,each proceeding 1 more than the last).
I keep getting this error however:

Now sorted: 
1 1 1 3 3 3 4 4 4 7 7 7 9 9 Vulnerable   Triples: 4 Pairs: 1 Straights: 0
2 2 2 3 4 5 6 6 6 7 7 7 8 9 Vulnerable   Triples: 3 Pairs: 0 Straights: 4
1 2 2 3 3 3 4 5 6 7 8 9 9 9 Vulnerable   Triples: 2 Pairs: 1 Straights: 5
1 2 3 3 4 5 5 5 6 7 8 9 9 9 Vulnerable   Triples: 2 Pairs: 1 Straights: 5
1 2 3 3 4 4 4 5 6 7 7 8 9   Immune
1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 9 Immune

Gene Analysis complete. 4 vulnerable cases found - Eliminate Immediately!

Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric ne (!=) at main.pl line 98.
Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric eq (==) at main.pl line 98.
Use of uninitialized value within @nums in subtraction (-) at main.pl line 106.
Use of uninitialized value within @nums in subtraction (-) at main.pl line 106.
Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric eq (==) at main.pl line 98.
Use of uninitialized value within @nums in subtraction (-) at main.pl line 106.
Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric ne (!=) at main.pl line 98.
Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric eq (==) at main.pl line 98.
Use of uninitialized value within @nums in subtraction (-) at main.pl line 106.
Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric ne (!=) at main.pl line 98.
Use of uninitialized value in numeric eq (==) at main.pl line 90.
Use of uninitialized value in numeric eq (==) at main.pl line 98.
Use of uninitialized value within @nums in subtraction (-) at main.pl line 106.

I have spent days trying to solve this. Please let me know what I may be doing incorrectly?! Below is the snippet of code that is not working for me.

foreach $line(@lines)
{ 
  chomp $line;
  @nums = split / /, $line; 
  #print "this is nums: @nums\n";
  @snums = sort { $a <=> $b } @nums;
  #print "this is @snums\n";
  $size = @snums;
  $pairs = 0;
  $straights = 0;
  $triples = 0;

  #if not equal to 14 characters output vulnerable
  if($size == 1)
  {
    $susceptibility = "";
  }
  elsif($size != 14 && $size != 1)
  {
    $susceptibility = "Immune";
    print "@snums"."\t".$susceptibility."\n";
  }
  elsif($size == 14)
  {
    $i = 0;
    #check for gene combinations
    #while($i <= $#snums)
    for $i(0..$#snums)
    {
      #Check for triples
      if(($snums[$i] == $snums[$i+1]) && ($snums[$i] == $snums[$i+2]
      ))
      {
        $triples ++;
      }
      #Check for pairs
      if(($nums[$i] == $nums[$i+1]) && ($nums[$i] != $nums[$i+2])
      && ($nums[$i] != $nums[$i-1]))
      {
        $pairs ++;
      }
      #Check for straights
      if(($nums[$i] == ($nums[($i+1)]-1)) && ($nums[$i+1] == 
      ($nums[($i+2)]-1)))
      {
        $straights ++;
      }
    }
 $susceptibility = "Vulnerable";
 $infected ++;
 print "@nums"."\t".$susceptibility."\t"." Triples: $triples"." Pairs: $pairs"." Straights: $straights"."\n";
  }
 }

Dani AI

Generated

The warnings come from reading past the ends (and before the start) of the arrays and from mixing the sorted array with the unsorted one. Indexes like $snums[$i+1], $snums[$i+2] and $nums[$i-1] will be undef at the ends and trigger the Use of uninitialized value messages — and using undef in arithmetic causes the subtraction warnings. Also split / / can produce empty fields if the line has extra spaces; normalize splitting with /\s+/.

Fixes that are safe and simple:

  • turn on use strict; use warnings; and declare my variables so scope/accidental reuse (the loop $i) cannot leak. (This aligns with pointing at initialization, but scoped my is better than globals.)
  • normalize tokens: my @nums = grep { length } split /\s+/, $line; then my @snums = sort { $a <=> $b } @nums;
  • never loop to the raw 0..$#snums if you then access $i+2. Either guard each access with defined(...) or loop for my $i (0 .. $#snums - 2) for checks that need a three-element window.

A more robust pattern: count equal-value runs for pairs/triples, and use a de-duplicated sorted list for straights. Example (conceptual):

# run-length count for pairs/triples
my $run = $snums[0]; my $count = 1;
for my $v (@snums[1..$#snums]) {
  if ($v == $run) { $count++ }
  else { $triples++ if $count == 3; $pairs++ if $count == 2; $run = $v; $count = 1 }
}
$triples++ if $count == 3; $pairs++ if $count == 2;

# unique sorted values for straights
my @uniq = do { my %seen; grep { !$seen{$_}++ } @snums };
for my $i (0 .. $#uniq - 2) {
  $straights++ if $uniq[$i]+1 == $uniq[$i+1] && $uniq[$i]+2 == $uniq[$i+2];
}

Quick debug tips: print Dumper(\@snums) or warn index and values inside the loop, and re-run with perl -cw / perl -Mstrict -Mwarnings to catch other issues. ’s hash-based approach is a good alternative; combine it with these boundary-safe checks and you should stop the warnings and get correct counts.

Recommended Answers

All 2 Replies

Hellop,

It is hard to tell with out all of the code but I am guessing that line 90 in your error messages is line 14 above. Do you initialize $size anywhere with something like:

my $size = 0;

Hi,
Is either you are working with MaddTechwf or you are the same person with a different username. Like I mentioned on his trends which is marked solved, there are better way of doing what he wants.
Moreover, except I don't understand his requirement, how are you getting your straight count?
Using the concept of what was posted, please check the modified script below:

use warnings;
use strict;

# check that a file is given on the CLI
die "USAGE: perlsscript.pl input_file.txt " unless defined $ARGV[0];

my %data_collector;
my $original_data;
my $result_for_display;

## open the file
open my $fh, '<', $ARGV[0] or die "can't open file: $!";
my $sample_size = <$fh>;

## test the sample size
$sample_size =
  ( $sample_size >= 1 && $sample_size <= 200_000 )
  ? $sample_size
  : "Invalid Sample Size\n";

while (<$fh>) {

    $original_data .= $_;     # get original data

    # call the subroutine get_stat & give it an Array ref of sorted data
    push @$result_for_display, get_stat( [ sort { $a <=> $b } (split) ] );
}

close $fh or die "can't close file: $!";  # close your file

# print out the sample size & original data looks
print "\nSample size = ", $sample_size, $/,
  "Here are the original Sample: ", $/,
  $original_data, $/;

# get_stat subroutine  
sub get_stat {

    my @data = @{ shift(@_) };

    if ( scalar @data != 14 ) {
        return join( ' ' => @data, "\t", "Immune" ), $/;
    }
    my %counter;
    my %present = (
        Tripples => 0,
        Pairs    => 0,
        Straight => 0,
    );
    $counter{$_}++ for @data;

    for ( keys %counter ) {
        $present{Tripples}++ if $counter{$_} == 3;
        $present{Pairs}++    if $counter{$_} == 2;
        $present{Straight}++ if $counter{$_} == 1;
    }

    return <<"VALUE";
@data\tVulnerable\tTripples: $present{Tripples} Pairs: $present{Pairs} Straight: $present{Straight}

VALUE

}

# print out your final report looks
print $_ for @$result_for_display;

Which will produce the following output:

Sample size = 6

Here are the original Sample: 
1 3 4 7 9 1 3 4 7 9 1 3 4 7
2 6 2 6 3 5 4 6 2 9 7 8 7 7
9 9 9 6 5 4 3 7 3 8 3 2 2 1
5 5 5 4 3 1 3 2 9 6 9 7 9 8
1 3 2 4 4 7 7 4 5 6 8 9 3
9 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5

1 1 1 3 3 3 4 4 4 7 7 7 9 9 Vulnerable  Tripples: 4 Pairs: 1 Straight: 0

2 2 2 3 4 5 6 6 6 7 7 7 8 9 Vulnerable  Tripples: 3 Pairs: 0 Straight: 5

1 2 2 3 3 3 4 5 6 7 8 9 9 9 Vulnerable  Tripples: 2 Pairs: 1 Straight: 6

1 2 3 3 4 5 5 5 6 7 8 9 9 9 Vulnerable  Tripples: 2 Pairs: 1 Straight: 6

1 2 3 3 4 4 4 5 6 7 7 8 9    Immune
1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 9      Immune
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.