Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Bowling Handicaps

by Andrew_Levenson (Hermit)
on Mar 10, 2006 at 14:28 UTC ( [id://535709]=perlquestion: print w/replies, xml ) Need Help??

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

Okay, this next one finds the averages of 4 Bowler's games, their handicaps, and the team handicap. I've read the warnings over and over and tried to fix it, but I can't. Any advice? (I realize that there is probably a much shorter way to write this, but right now i'm shooting for being able to do it as opposed to making it look nice.)
Everything works fine, save for the handicap and team handicap part.
use strict; use warnings; my $hand1; my $hand2; my $hand3; my $hand4; print "Please enter Bowler 1's 3 scores: \n::"; my $b11=<>; print "::"; my $b12=<>; print "::"; my $b13=<>; print "\n"; print "Please enter Bowler 2's 3 scores: \n::"; my $b21=<>; print "::"; my $b22=<>; print "::"; my $b23=<>; print "\n"; print "Please enter Bowler 3's 3 scores: \n::"; my $b31=<>; print "::"; my $b32=<>; print "::"; my $b33=<>; print "\n"; print "Please enter Bowler 4's 3 scores: \n::"; my $b41=<>; print "::"; my $b42=<>; print "::"; my $b43=<>; print "\n"; my $ave1= int(($b11+$b12+$b13)/3); if($ave1<=200){ my $hand1=int((200-$ave1)*(.85)); } if($ave1>=200){ my $hand1=0; } my $ave2= int(($b21+$b22+$b23)/3); if($ave2<=200){ my $hand2=int((200-$ave2)*(.85)); } if($ave2>=200){ my $hand2=0; } my $ave3= int(($b31+$b32+$b33)/3); if($ave3<=200){ my $hand3=int((200-$ave3)*(.85)); } if($ave3>=200){ my $hand3=0; } my $ave4= int(($b41+$b42+$b43)/3); if($ave4<=200){ my $hand4=int((200-$ave4)*(.85)); } if($ave4>=200){ my $hand4=0; } my $teamhand=$hand1 + $hand2 + $hand3 + $hand4; print "Bowler 1's Average Score: $ave1 Bowler 1's Handicap: $ha +nd1\n"; print "Bowler 2's Average Score: $ave2 Bowler 2's Handicap: $ha +nd2\n"; print "Bowler 3's Average Score: $ave3 Bowler 3's Handicap: $ha +nd3\n"; print "Bowler 4's Average Score: $ave4 Bowler 4's Handicap: $ha +nd4\n"; print "The team's handicap is: $teamhand ";
Thanks in advance.

Replies are listed 'Best First'.
Re: Bowling Handicaps
by ptum (Priest) on Mar 10, 2006 at 14:46 UTC

    Well, the main problem is that you declare a new instance of the handN variables inside your if{} blocks, and so the values of those variables die when they go out of scope (once the if block ends). Then you revert back to the previous (undefined) value of $hand1, $hand2, etc.

    Update: Notice also that the warnings you received were pretty good clues to the source of the problem:

    Use of uninitialized value in addition (+) at ./test.pl line N, <> lin +e M.
    The line in question was this line:
    my $teamhand=$hand1 + $hand2 + $hand3 + $hand4;

    So it is saying that you are adding up variables that you have never initialized. Sure enough, when you originally declared them, you didn't set them to zero or anything. But surely you updated their value along the way, didn't you? Ah, no, that's when I noticed the new 'my' declaration of each of the $hand1, $hand2, $hand3 and $hand4 variables.


    No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: Bowling Handicaps
by thundergnat (Deacon) on Mar 10, 2006 at 15:30 UTC

    As others have pointed out you've got problems with scopeing. This sort of thing just crys out for arrays and loops though.

    use strict; use warnings; my @bowlers; my $team_handicap; for my $bowler (1..4) { print 'Please enter Bowler ',$bowler,"'s 3 scores:\n"; for (0..2) { print '::'; my $score = <>; chomp $score; $bowlers[$bowler]{avg} += $score; } $bowlers[$bowler]{avg} = int ( $bowlers[$bowler]{avg} / 3 ); $bowlers[$bowler]{handicap} = ($bowlers[$bowler]{avg} >= 200) ? int( (200 - $bowlers[$bowler]{avg} ) * .85) : 0; $team_handicap += $bowlers[$bowler]{handicap}; } print "\n\n"; for my $bowler (1..4) { print 'Bowler ',$bowler,"'s Average Score: ",$bowlers[$bowler]{avg} +; print "\tBowler ",$bowler,"'s Handicap: ",$bowlers[$bowler]{handica +p},"\n"; } print "The team's handicap is: $team_handicap";
Re: Bowling Handicaps
by xdg (Monsignor) on Mar 10, 2006 at 14:48 UTC

    You repeat "my" for the $hand1-4 variables when you assign to them, but in the separate scope of each if statement. Thus, when you do the addition to $teamhand, you get the original, uninitialized $hand1-4 variables.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Bowling Handicaps
by eric256 (Parson) on Mar 10, 2006 at 17:13 UTC

    For kicks I converted this into Perl6. Below is a fairly direct transaltion, though I think i'm going to try a rewrite without looking at the p5 version to see what i end up with.

    #!/usr/bin/pugs my @bowlers; my $team_handicap; for (1..2) -> my $bowler { say "Please enter Bowler $bowler's scores:"; for (0..2) { print "Score $_:"; my $score = =$*IN; @bowlers[$bowler].<average> += $score; } @bowlers[$bowler].<average> = int(@bowlers[$bowler].<average> / 3); @bowlers[$bowler].<handicap> = int( (200 - @bowlers[$bowler].<averag +e> ) * .85); $team_handicap += @bowlers[$bowler].<handicap>; } say; for (1..2) -> $bowler { say "Bowler $bowler's Average Score:", @bowlers[$bowler].<average>, "\t Handicap: ", @bowlers[$bowler].<handicap>; } say; say "The team's handicap $team_handicap";

    You can see it is very similar to Perl5 though definitly not the same, comment, improvments are welcome. Or get a committer bit and update it yourself. Link to the live version: http://svn.perl.org/perl6/pugs/trunk/examples/games/bowling.p6


    ___________
    Eric Hodges

      for (1..2) -> my $bowler {

      for 1..2 -> my $bowler {

      say;

      Probably tries to print $_, which is undef. Expect a warning.

      Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      A slightly more perl6 ish version.

      #!/usr/bin/pugs #http://svn.perl.org/perl6/pugs/trunk/examples/games/bowling2.p6 use v6; print "How many bowlers are on your team?"; my $bowlers = =$*IN; print "How many games would you like to average?"; my $games = =$*IN; my @bowlers; for (1 .. $bowlers) { my $bowler; say "Enter scores for bowler $_:"; for (1.. $games) { print "game $_ score:"; my $score = =$*IN; $bowler<games>.push( $score ); } $bowler<id> = $_; $bowler<total> = [+] @{$bowler<games>}; $bowler<avg> = $bowler<total> / $games; $bowler<handicap> = int ( (200 - $bowler<avg>) * .8); @bowlers.push($bowler); } for @bowlers -> $bowler { say "Bowler $bowler<id>'s average is $bowler<avg>\tHandicap: $bowler +<handicap>"; } my $team_handicap = [+] @bowlers.map:{ $_.<handicap> }; say "Team handicap is: $team_handicap";

      ___________
      Eric Hodges
Re: Bowling Handicaps
by martin (Friar) on Mar 10, 2006 at 14:49 UTC
    I see way too many my declarations here. You should leave my out of your if blocks. my creates a new lexical variable, while what you want is to access one defined one level up.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://535709]
Approved by xdg
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2024-04-25 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found