Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Newbie Errors - Uninitialized Values

by Anonymous Monk
on May 30, 2001 at 06:51 UTC ( #84151=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I've just started to learning perl and decided to write up a script to add vectors for my silly Physics class. I've gotten maybe halfway through it, and I am confounded by errors.

My program opens a file 'vectors' which contains 4 numbers, which are then assigned to variables using split(); The errors I am getting involve the use of unitialized variables so I think my use of split() is to blame.

Here's the script:

#!/usr/bin/perl -w $foo = 0; open (VECTORS, "vectors") or die print "Cannot open 'vectors' file: $! +\n"; while ($line = <VECTORS>) { if ($line =~ /\d/) { chomp $line; ($vectorA[$foo], $angleA[$foo], $vectorB[$foo], $angleB[$foo]) = s +plit " ", $line, 4; ++$foo; } } $max_vectors = $foo; for ($foo = 0; $foo <= $max_vectors; ++$foo) { $X[$foo] += ($vectorA[$foo] * cos($angleA[$foo])); $X[$foo] += ($vectorB[$foo] * cos($angleB[$foo])); } for ($foo = 0; $foo <= $max_vectors; ++$foo) { $Y[$foo] += ($vectorA[$foo] * sin($angleA[$foo])); $Y[$foo] += ($vectorB[$foo] * sin($angleB[$foo])); } # Must do more stuff here, ie. finish and convert to degrees after sin +() and cos() foreach $X (@X) { print "$X\n"; } print "\nblah\n\n"; foreach $Y (@Y) { print "$Y\n"; }
Here's the 'vectors' file I refer to:

Vector Addition File 9.8 0 10.878 115
Thanks for any help.

Replies are listed 'Best First'.
Re: Newbie Errors
by tachyon (Chancellor) on May 30, 2001 at 08:14 UTC

    Here is your code with some comments on errors, etc.

    I have added some debug prints so you can see what gives. This is alway a good start to debugging.

    First you are not opening the file "correctly" with a path and an I/O operator like < for read and > or >> for write.

    The uninitialised values arise because you increment $foo to a value one past the last element. In the exapmle the while fails after the first iteration. We have an array of length 1 ie only element '0' but $foo = 1. You use this value as a count of the number of elements and iterate from 0..1, thus using an uninit value.

    I could not resist cleaning up your code. See the final version. Of all the changes the split/\s+/,$line is one of the more important as now your data file can be "dirty" with multiple spaces between values and still work. Single space delimiters are fine provided no human hands ever touch the data file!

    hope this helps

    tachyon

    #!/usr/bin/perl -w $foo = 0; # not a good way to open a file, # should be open FOO, "<$path/$file" # also print after die not needed open (VECTORS, "vectors") or die print "Cannot open 'vectors' file: $! +\n"; while ($line = <VECTORS>) { if ($line =~ /\d/) { chomp $line; ($vectorA[$foo], $angleA[$foo], $vectorB[$foo], $angleB[$foo]) + = split " ", $line, 4; # debugging print print"file input $foo: $vectorA[$foo], $angleA[$foo], $vectorB +[$foo], $angleB[$foo]\n"; ++$foo; } } # this is wrong $foo is 1 as you incremented it # at the end of the loop, so when you hit the last # element you increment $foo 1 too much and set # $max_vector to 1 to0 much $max_vectors = $foo; # debugging print print "\$max_vectors: $max_vectors\n"; for ($foo = 0; $foo <= $max_vectors; ++$foo) { # debugging print print"\$foo $foo\n"; # this should be = for first assignment not += $X[$foo] += ($vectorA[$foo] * cos($angleA[$foo])); $X[$foo] += ($vectorB[$foo] * cos($angleB[$foo])); } # this is another loop just like the one above # why not put the two statements here with the two above? # and just have the one loop # this is also the longhand++ loop syntax for ($foo = 0; $foo <= $max_vectors; ++$foo) { # debugging print print"\$foo $foo\n"; # this should be = for first assignment not += $Y[$foo] += ($vectorA[$foo] * sin($angleA[$foo])); $Y[$foo] += ($vectorB[$foo] * sin($angleB[$foo])); } # Must do more stuff here, ie. finish and convert to degrees after sin +() and cos() foreach $X (@X) { print "$X\n"; } print "\nblah\n\n"; foreach $Y (@Y) { print "$Y\n"; } #!/usr/bin/perl -w use strict; my (@vectorA, @angleA, @vectorB, @angleB, @X, @Y); open (VECTORS, "<c:/vectors.txt") or die "Oops $!\n"; my $i = -1; while (my $line = <VECTORS>) { next unless $line =~ /\d/; $i++; ($vectorA[$i], $angleA[$i], $vectorB[$i], $angleB[$i]) = split/\s+ +/,$line; } die "Sorry, no data!\n" if $i == -1; my $max_vectors = $i; for (0..$max_vectors) { $X[$_] = ($vectorA[$_] * cos($angleA[$_])); $X[$_] += ($vectorB[$_] * cos($angleB[$_])); $Y[$_] = ($vectorA[$_] * sin($angleA[$_])); $Y[$_] += ($vectorB[$_] * sin($angleB[$_])); } # Must do more stuff here, ie. finish and convert to degrees after sin +() and cos() print "$_\n" for @X; print "\nblah\n\n"; print "$_\n" for @Y;
Re: Newbie Errors
by Sherlock (Deacon) on May 30, 2001 at 07:28 UTC
    If you look closely at your script, you'll notice that you read 1 line from your file (as expected). When you leave the loop to read from your file, $foo = 1. If you then look at each of your for loops below, they run from 0 to (and including) $max_vectors, which is equal to $foo, or 1. Therefore, those loops will each run twice, the first time, performing operations on $vectorA[0], $angleA[0], etc. and the next time on $vectorA[1], $angleA[1], etc. But since your loop to read in from file only executed once, only the values in $vectorA[0], $angleA[0], ... , are initialized. It's the second time through those for loops that is causing the uninitialized variable errors.

    You can solve this problem (only to see that it works) by adding this to the top of the script:
    # Initialize the variables that are causing problems $vectorA[1] = 0; $angleA[1] = 0; $vectorB[1] = 0; $angleB[1] = 0;
    I really doubt that this is what you want to do to initialize these variables - it's simply what I did to test my hypothesis of what was wrong.

    By the way, I added use strict; to the top of this script and got a whole bunch of errors. You might want to add that in and clean up a little before this script gets too unruly to deal with.

    Good Luck,
    - Sherlock

    Skepticism is the source of knowledge as much as knowledge is the source of skepticism.
Re: Newbie Errors
by chipmunk (Parson) on May 30, 2001 at 07:32 UTC
    In your for loops, you iterate from 0 to $max_vector. However, $max_vector is one greater than the index of the last value in @vectorA and the other arrays. Change <= $max_vector to < $max_vector and the warnings will go away.
Re: Newbie Errors
by Desdinova (Friar) on May 30, 2001 at 09:01 UTC
    The nodes above do a great job finding the errors. Just a very tiny thing to point out in this line
    open (VECTORS, "vectors") or die print "Cannot open 'vectors' file: $! + \n";
    The print statement after die is not really needed since this what dies does anyway.
    Just a little something to save you a few keystrokes
Re: Newbie Errors
by sierrathedog04 (Hermit) on May 30, 2001 at 14:29 UTC
    Since you're new to Perl, I thought I would mention that Perl comes with a built-in debugger. You can run the debugger to track line-by-line what your program is doing right or wrong.

    Simply type perl -d myprogram.pl to debug the perl script myprogram.pl. You can move from one line of your main program to the next by hitting the 'n' key. For more info type 'perldoc perldebtut' from the command line.

    For a long time I avoided using debug mode, but now I know that it is my friend.

Re: Newbie Errors
by cacharbe (Curate) on May 30, 2001 at 07:02 UTC
    copied, pasted, ran..no problem. What errors are you getting exactly. I didn't check the results for accuracy, but I didn't get any errors, so maybe you could be a little more verbose

    C-.

      When I run my script, I get this as output:
      Use of uninitialized value in cos at ./vectors.pl line 19, <VECTORS> l +ine 4. Use of uninitialized value in multiplication (*) at ./vectors.pl line +19, <VECTORS> line 4. Use of uninitialized value in cos at ./vectors.pl line 20, <VECTORS> l +ine 4. Use of uninitialized value in multiplication (*) at ./vectors.pl line +20, <VECTORS> line 4. Use of uninitialized value in sin at ./vectors.pl line 24, <VECTORS> l +ine 4. Use of uninitialized value in multiplication (*) at ./vectors.pl line +24, <VECTORS> line 4. Use of uninitialized value in sin at ./vectors.pl line 25, <VECTORS> l +ine 4. Use of uninitialized value in multiplication (*) at ./vectors.pl line +25, <VECTORS> line 4. 6.25584093881723 0 10.2844455635215 0
      If I leave out the '-w' option, the nasty messages go away but the useless zeros after meaningful input don't. I'll have to take a look at those in the morning.
        You should never simply take out -w or use strict; to get rid of an error or warning. by doing so, you haven't really gotten rid of the error, you've simply suppressed the message saying that there is such an error. Doing this is just asking for more errors and instability to crop up without you knowing it.

        - Sherlock

        Skepticism is the source of knowledge as much as knowledge is the source of skepticism.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://84151]
Approved by root
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2018-07-23 02:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?















    Results (459 votes). Check out past polls.

    Notices?