CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
use of uninitialized value in numeric gt

 



mjw82
Novice

May 14, 2010, 8:30 PM

Post #1 of 14 (2736 views)
use of uninitialized value in numeric gt Can't Post

I keep getting many lines of that error when I run this. I'm trying to input two files each with numbers separated by commas, put them into arrays, and then compare the arrays and tally the results but it doesn't work.



use warnings;
use strict;

open (A, "in.txt");
open (B, "in2.txt");

my @A = split(/,/, <A>);
my @B = split(/,/, <B>);
my $counter = 0;
my $ascore = 0;
my $bscore = 0;

while () {

if ($A[$counter] > $B[$counter]) {
$ascore++;
} elsif ($A[$counter] < $B[$counter]) {
$bscore++;
}
$counter++;
if ($counter == 101) {
last;
}
}

print "$ascore - $bscore";


7stud
Enthusiast

May 15, 2010, 2:10 AM

Post #2 of 14 (2728 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

1) Search google for 'code tags'. Read the first 10 results and come back and post what you have learned.

4) Use the 3-arg form of open(), and use a variable instead of a bareword filehandle:


Code
open my $INFILE, '<', 'data.txt' 
or die "Couldn't open data.txt: $!";




5) Your <A> is in 'scalar context' because split() requires a scalar as the second argument. An array in scalar context returns the length of the array. So both @A and @B contain one element, the number of lines in each file.

That could easily be seen if you printed out the contents of each array, which is always a good idea when you get errors related to an array you are using.


(This post was edited by 7stud on May 15, 2010, 2:19 AM)


mjw82
Novice

May 15, 2010, 7:37 AM

Post #3 of 14 (2711 views)
Re: [7stud] use of uninitialized value in numeric gt [In reply to] Can't Post

This is what my input file looks like:

99,32,47,50,3,64,66,26,81,81,14,17,13,15,70,94,9,32,12,32,32,67,

I don't really get why the arrays show the number of lines in the file. How do I fix the script to do what I want?


mjw82
Novice

May 15, 2010, 7:45 AM

Post #4 of 14 (2710 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

I've changed the script to this but I still get the same error.

use warnings;
use strict;

my @A = ();
my @B = ();

open my $INFILE, '<', 'in.txt'
or die "Couldn't open data.txt: $!";

open my $INFILE2, '<', 'in2.txt'
or die "Couldn't open data.txt: $!";

foreach ($INFILE) {
push (@A, split(/,/, $_));
}
foreach ($INFILE2) {
push (@B, split(/,/, $_));
}

my $counter = 0;
my $ascore = 0;
my $bscore = 0;

while () {

if ($A[$counter] > $B[$counter]) {
$ascore++;
} elsif ($A[$counter] < $B[$counter]) {
$bscore++;
}
$counter++;
if ($counter == 101) {
last;
}

}

print "$ascore - $bscore";


BillKSmith
Veteran

May 15, 2010, 8:56 AM

Post #5 of 14 (2704 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

If I change your constant 101 to a 22 (the number of numbers in each input file), your original script works fine with the input file you provided. I have little doubt that it would have worked just as well with 101 input numbers on one line. We need to know more about the structure of your input files in order to help you read them correctly.
Good Luck,
Bill


mjw82
Novice

May 15, 2010, 9:07 AM

Post #6 of 14 (2702 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

Oh... ok that makes sense. But I was trying to figure out a way to read it if the file looks like this. It would be much more convenient for me. It was complaining about \n not being an integer. Also, is there a way to split on just whitespaces and not commas? Because I have to manually put the commas in there which is a hassle.

55, 32, 6, 45, 45,
2, 11, 53, 85, 70,
16, 67, 76, 70, 47,
6, 91, 80, 22, 94,
51, 90, 97, 22, 48,
99, 30, 40, 9, 74,
71, 20, 66, 83, 24,
30, 68, 1, 77, 73,
3, 39, 7, 23, 86,
5, 87, 38, 5, 88,
75, 52, 53, 35, 89,
77, 1, 11, 52, 62,
2, 31, 96, 99, 41,
88, 84, 37, 68, 95,
93, 18, 29, 73, 55,
99, 17, 35, 75, 50,
13, 49, 15, 44, 69,
3, 79, 78, 31, 30,
38, 77, 8, 22, 59,
7, 82, 6, 67, 65,


BillKSmith
Veteran

May 15, 2010, 12:45 PM

Post #7 of 14 (2687 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

Undefine $INPUT_RECORD_SEPARATOR ($\) to read the entire file as one 'line'.

Refer: perldoc perlvar

Change the pattern in the split to /\s+/ to split on white-space rather than commas.

refer: perldoc perlre for definition of \s

$/ = undef;
my @A = split(/\s+/, <A> );
my @B = split(/\s+/, <B> );

Change your termination condition to:

if ($counter == 100) {

You only have 100 input numbers.

Change your print statement to:

print "$ascore - $bscore = ", $ascore-$bscore, "\n";


Your probably did not intend the quotes.



The resulting code does work, but it is short of good practice in many ways. Other responders have made suggestions to improve the style.
Good Luck,
Bill


7stud
Enthusiast

May 15, 2010, 3:03 PM

Post #8 of 14 (2682 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post


Quote
I don't really get why the arrays show the number of lines in the file.


I was wrong. The line input operator <> returns one line when used in scalar context. So you are reading only one line of your file, which you split(), producing an array that contains way fewer elements than you think, and when the index values in your loop go beyond the end of the array, you get an error.


Quote
Also, is there a way to split on just whitespaces and not commas?


As a special case:


Code
split ' ', $string;


will remove all whitespace (spaces, tabs, newlines).


(This post was edited by 7stud on May 15, 2010, 3:15 PM)


7stud
Enthusiast

May 15, 2010, 7:28 PM

Post #9 of 14 (2674 views)
Re: [BillKSmith] use of uninitialized value in numeric gt [In reply to] Can't Post


Quote
Change your termination condition to:

if ($counter == 100) {


The whole loop is written poorly. Better:


Code
for my $i (0 .. $#a_array) { 

if ($a_numbers[$i] > $b_numbers[$i]) {
}
}



(This post was edited by 7stud on May 15, 2010, 9:55 PM)


mjw82
Novice

May 15, 2010, 8:57 PM

Post #10 of 14 (2666 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

Ok this is another question but, is there a way to put variables inside of variable names?

Like, I have $input but I want to change "input" to a variable $var, so it would be $$var.


7stud
Enthusiast

May 15, 2010, 9:56 PM

Post #11 of 14 (2663 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post


Quote
Ok this is another question but, is there a way to put variables inside of variable names?


There's never any need to do that, and you should never do that. Read about hashes.


(This post was edited by 7stud on May 15, 2010, 9:58 PM)


mjw82
Novice

May 16, 2010, 5:27 AM

Post #12 of 14 (2658 views)
Re: [7stud] use of uninitialized value in numeric gt [In reply to] Can't Post

I know about hashes but I don't know how they could help with this. What I actually want to do is make a subroutine &start and run it as &start (A, B) so I want A and B in the array @_ as @_[0] and @[1]. So then I went and substituted those into my subroutine variable names. The reason I'm doing this is so I can easily run &start with different variables like (C, D), etc.:

my $A = 0;
my $B = 0;
my $C = 0;
my $D = 0;
my $counter = 0;
my $ascore = 0;
my $bscore = 0;

sub start {
for $counter (0..99) {
if ($$_[0][$counter] > $$_[1][$counter]) {
$ascore++;
} elsif ($$_[0][$counter] < $$_[1][$counter]) {
$bscore++;
} elsif ($$_[0][$counter] == $$_[1][$counter]) {
$bscore++;
$ascore++;
}
}


(This post was edited by mjw82 on May 16, 2010, 5:28 AM)


FishMonger
Veteran / Moderator

May 16, 2010, 7:08 AM

Post #13 of 14 (2653 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post

What you're asking about is called symbolic references, which is a real bad idea to use and should be avoided.

http://www.perl.com/doc/FMTEYEWTK/style/slide24.html


7stud
Enthusiast

May 16, 2010, 8:38 PM

Post #14 of 14 (2608 views)
Re: [mjw82] use of uninitialized value in numeric gt [In reply to] Can't Post


---------

1) Search google for 'code tags'. Read the first 10 results and come back and post what you have learned.

If you post code without using code tags, then I won't answer any more of your questions. If you decide that's a good thing, then you know what to do.

-------------


2) Never use the notation: $_[0]. Instead, the first thing you should do inside a subroutine is assign the arguments to variables with common sense names (see example below).

3) You pass arrays to subroutines using references:


Code
use strict; 
use warnings;
use 5.010;

sub compare_arrays {
my($aref_1, $aref_2) = @_;
my @first_set_of_numbers = @$aref_1;
my @second_set_of_numbers = @$aref_2;

say "@first_set_of_numbers";
say "@second_set_of_numbers";

my($results_1, $results_2) = (10, 20);
return $results_1, $results_2;
}


my @a = (1, 2, 3);
my @b = (2, 3, 4);

my @results = compare_arrays(\@a, \@b);
say "@results";


--output:--
1 2 3
2 3 4
10 20


It sounds like you need to read perlreftut.


(This post was edited by 7stud on May 16, 2010, 9:01 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives