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

I am trying to write a very simple program that asks the user a question and displays a response depending if they get the answer right or not. The code below does this fine but I want it to loop back to the question again if they get the answer wrong. Any help much appreciated as this is my first attempt at any Perl (as you can probably tell from the basic coding!)

#!/usr/bin/perl #define a variable to store the number of planets $noplanets = 9; #displays the question to the user print "How many planets are there?"; #sets the variable $planets to whatever is input by the user and rem +oves the line break chomp ($planets=<>); #checks to see if the user has input any incorrect answer if ($planets ne $noplanets){ #tells the program to display the text in quotation marks print "Sorry thats not right, try again\n"; #tells the program where the end of the if statement is } #tells the program what to display if the answer is not incorrect else { print "Well done there are indeed $noplanets planets in the + solar system"; #ends the else statement }

Replies are listed 'Best First'.
Re: Help using a while loop with STDIN
by GrandFather (Saint) on Feb 07, 2012 at 20:39 UTC

    First off, always use strictures (use strict; use warnings;). If you had perl would have told you that there are only 8 planets (well, maybe not - it may have told you there are 767 known planets).

    Rewriting your code using strictures, a while loop and making a couple of fixes (and cleaning out the comments) we get:

    #!/usr/bin/perl use strict; use warnings; my $kSolarPlanets = 8; print "How many planets are there? "; while (defined(my $planets = <>)) { chomp $planets; if ($planets == $kSolarPlanets) { print "Well done there are indeed $kSolarPlanets planets in th +e solar system"; last; } print "Sorry that's not right, try again: "; }

    Note the use of == for the numeric equality check instead of eq which performs a string equality check. 8 == 8.0 is true but 8 eq 8.0 is false.

    Please don't clutter your code with comments that describe the exciting new language features you have just learned. They don't help the compiler and they don't help you. They do make it almost impossible to actually see the code!

    Don't put multiple statements on one line (I'm looking at you else line) because the statements after the first tend to disappear.

    Actually the real reason to use strictures is to pick up a range of trivial to make errors (like typos) that can lead to really hard to find bugs. Strict won't actually check that your planets constant is the correct number :(.

    True laziness is hard work
Re: Help using a while loop with STDIN
by Riales (Hermit) on Feb 07, 2012 at 20:35 UTC
    I think what you're looking for is a while loop. You can wrap your prompt/check in a while loop that always loops until a correct answer is submitted.
Re: Help using a while loop with STDIN
by kcott (Archbishop) on Feb 07, 2012 at 20:59 UTC

    As GrandFather said in the CB, you need while, next and last.

    You should also add use strict; and use warnings; to the top of all your scripts. Without going into any great detail here, these will basically let you know if you've done something wrong.

    You also need to know that Perl uses different operators for comparing strings and numbers (see perlop for details). Note how I put the 9 in quotes so that the ne operator is comparing a string with a string (you were comparing a string with a number).

    Finally, as a matter of style, you've used far too many comments. Your code seemed to get rather lost amongst them and, in this instance, I don't see any that actually add anything helpful.

    Putting all that together, you might end up with something like:

    use strict; use warnings; my $planet_count = "9"; while (1) { print "How many planets are there? "; chomp(my $planet_guess = <>); if ($planet_guess ne $planet_count) { print "Sorry that's not right, try again.\n"; next; } else { print "Well done! There are indeed $planet_count planets in th +e solar system.\n"; last; } }

    Example output:

    How many planets are there? 3 Sorry that's not right, try again. How many planets are there? 6 Sorry that's not right, try again. How many planets are there? 9 Well done! There are indeed 9 planets in the solar system.

    P.S. I think Pluto got demoted to planetoid (or something), so there's only 8 planets now. :-)

    -- Ken

      If you have a flow control statement (next, last, return, exit, ...) at the end of an if block, you don't need to follow the block with an else block which saves a level of indentation for the following code. I tend to call the technique "early exit". Be warned however that some purists frown on the technique claiming that "things should only have one exit point". I use the technique a lot because I think it tends to clean up code something wonderful.

      On a related note, if you change the sense of your if you don't need the next. For the resulting code see my earlier reply to the OP.

      Note that you have duplicated the OP's error in using ne in place of ==. On a related note you shouldn't quote the 9 in the assignment to $planet_count - a count is generally a number not a string after all.

      True laziness is hard work