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

Hello good monks!

I am finishing up an assignment that uses Markov chain algorithim to generate psuedo text. The problem is that while it is almost working, I am getting the followint message:

"Use of uninititiated value in join or string at (file location)"

I that this points to a scoping issue but I am not sure how to fix it. The code is below:

#!/opt/bin/perl -w use strict; use warnings; my %hash; my $hash; my $w1; my $w2; my @test; my $test; my @keysout; my $keysout; my $count; my $tot_counts; my $wordprecentage; my @feed; my $feed; while (<>) { # First fill the array @test with words foreach (split) { push(@test, $_); } @keysout = @test; $test = @test; #This will be useful in the next statment } my $cyc_count = 3; # set to stop the program runs out of nw or new wo +rds #First populate the data stucture while ( $cyc_count <= $test){ my $w1 = $test[0]; my $w2 = $test[1]; my $nw = $test[2]; $hash{$w1}{$w2}{total_counts}++; $hash{$w1}{$w2}{words}{$nw}++; $cyc_count++; shift(@test); } my $cyc_count2 = 3; #Make a three element long feed $keysout = @keysout; @feed = @keysout[0,1,2]; print " the Content of feed : @feed\n"; #now read values back out using an while($cyc_count2 <= $keysout){ ############## #PROBLEM likely with how I am handling these, ############## my $w1 = $feed[0]; my $w2 = $feed[1]; my $nw = $feed[2]; #retrieves a value from my @wordsList; #################### # PROBLEM HERE 'Use of uninitialized value' #################### for my $word ( keys %{ $hash{ $w1 }{ $w2 }{ words } } ) { push @wordsList, ( $nw ) x $hash{ $w1 }{ $w2 }{ words }{ $nw } +; } #print the words my $random_word = @wordsList[ rand( @wordsList ) ]; print "random word: $random_word\n"; #pushing $random_word on the end of @feed push (@feed, $random_word); #shifting one element off the left side shift(@feed); $cyc_count2++; print " "; }

My thanks to anyone who can suggest a way to fix this little problem.

-mox

Replies are listed 'Best First'.
Re: Scoping Problem? - 'Use of uninititiated value...'
by GrandFather (Saint) on Nov 01, 2006 at 03:00 UTC

    The issue seems to be that @feed can be set to bogus sequences of words. If the input stream is obtained from the following __DATA__ section:

    __DATA__ the quick brown fox brown fox jumps jumps the quick fox jumps

    then in the second itteration of the while($cyc_count2 <= $keysout){ loop @feed contains qw(quick brown brown) and the hash lookup fails because no such sequence existed in the original text.

    Fixing the issue is left as an exercise for the reader ;).


    DWIM is Perl's answer to Gödel
Re: Scoping Problem? - 'Use of uninititiated value...'
by dewey (Pilgrim) on Nov 01, 2006 at 05:37 UTC
    If I understand correctly, the generation loop (while($cyc_count2 <= keycount)) keeps track of the last few words using @feed and uses them to find a new word. The new word should be found using only the last two words, so @feed should only contain two values at any time, not three:
    @feed = @keysout[0,1]; ... while($cyc_count2 <= $keysout){ my $w1 = $feed[0]; my $w2 = $feed[1]; #no $nw needed! ...
    After this, the intent seems to be to generate a list of possible next words in which each word appears as many times as it follows these two words in the original text. I think this is the main bug, and the loop should read like this:
    for my $word ( keys %{ $hash{ $w1 }{ $w2 }{ words } } ){ push @wordsList, ($word) x $hash{ $w1 }{ $w2 }{ words }{ $word }; }
    This way, for each word that ever followed these two (according to the hash), that word is added the same number of times it was seen in this context in the original text.
    I don't think this will solve all of the problems with this code, but it's closer to what the code was meant to do.
    ~dewey

      Jackpot!

      Thank you for your response, this was extremely helpful!

      -mox
Re: Scoping Problem? - 'Use of uninititiated value...'
by Anonymous Monk on Nov 01, 2006 at 03:02 UTC
    $test = @test; #This will be useful in the next statment
    Nope: while ( $cyc_count <= @test){
    On second thought, if you are shifting @test, just write
    while( @test ){ ... shift @test; }
Re: Scoping Problem? - 'Use of uninititiated value...'
by holcapek (Sexton) on Nov 01, 2006 at 07:14 UTC
    It would be useful to use Data::Dumper and dump %hash with it. It may suggest if you have built %hash well (=as you wanted) or not (as you probably reference non-existing key).