Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

comparison of character

by Anonymous Monk
on Jul 16, 2013 at 11:09 UTC ( #1044550=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello

I have a case in my code , where I am asking user to input either Y or N and if they enter something else I want them to re enter , so I have written a while loop such that

print "Do you wish to update (Y/N)?\n"; my $choice = <>; chomp $choice; while ($choice ne "Y" || $choice ne "y" || $choice ne "N" || $choice +ne "n")

but eve if I press Yor N , the flow enters this while loop . so I cant can't understand why ?

Comment on comparison of character
Download Code
Re: comparison of character
by hippo (Deacon) on Jul 16, 2013 at 11:14 UTC

    Just amend your code to display the value of $choice so you can see what it really is. Do this just before you test it. eg.

    print "The value of \$choice is '$choice'\n"; while ($choice ne ...
Re: comparison of character
by roboticus (Canon) on Jul 16, 2013 at 11:14 UTC

    Think about it a bit more: If the user enters 'X', it enters the while loop because 'X' ne 'Y', right?

    If the user enters 'Y' then the first bit of your conditional fails ('Y' eq 'Y') so it continues to the next bit--but 'Y' ne 'y' so the conditional is satisfied anyway.

    Any character you enter will satisfy one of the parts of your while condition. I suggest you think about your logic AND change the conditional to make it do what you want. ;^)

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: comparison of character
by moritz (Cardinal) on Jul 16, 2013 at 11:15 UTC

    Your loop misses a body (with curly braces).

    $choice ne "Y" || $choice ne "y"

    if $choice is Y, then $choice ne 'y' is true, and the whole condition is true. Or more general, if one of the branches is false, all the other branches are true, and the condition as a whole is true again.

    You probably want to use while ($choice !~ /[yn]/i) { ... }, or while (!($choice eq 'y' || $choice eq ...)) { }.

Re: comparison of character
by choroba (Abbot) on Jul 16, 2013 at 11:16 UTC
    If you enter "Y", then $choice ne "N", so the OR clause is true and the while loop continues. You should have used && instead of ||.

    Moreover, you can include the first reading of the input into the loop as well:

    print "Do you wish to update (Y/N)?\n"; my $choice = q(); while ('y' ne lc $choice and 'n' ne lc $choice) { chomp($choice = <>); }
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: comparison of character
by Anonymous Monk on Jul 16, 2013 at 11:21 UTC
      AND IM SLEEPY WRONG FOOL

      probably because you used || instead of or its (...) || (...) ... or ... or ... or ...

      As already pointed out by others, it should really be a logical and, not a logical or.

        As already pointed out by others, it should really be a logical and, not a logical or.

        AND IM SLEEPY WRONG FOOL 20min ago, not every foolish post needs multiple followups :)

      No. According to perlop, eq has a higher precedence than || and or, so, in this case, either one will do the same thing.

      I tend to use || for logical tests (X || Y) and or for flow control (STMT or die...).

      Update: clarified word choice a bit.

      --MidLifeXis

Re: comparison of character
by rjt (Deacon) on Jul 16, 2013 at 11:39 UTC

    A couple other points to ponder:

    print "Do you wish to update (Y/N)?\n";

    You likely added the \n to ensure the prompt prints for the user. See $| to print without buffering, so you don't need the trailing newline:

    $| = 1; print "Do you wish to update (Y/N)? ";

    The overall structure leaves a bit to be desired. What about something more along these lines?

    $| = 1; my $choice; do { print "Do you wish to update (Y/N)? "; $choice = lc <>; chomp $choice; } until ($choice =~ /^[yn]$/i); say "You picked `$choice'";

    This will repeat the prompt if the input is invalid, and normalizes the input by converting it to lowercase, to simplify your code later in the program.

Re: comparison of character
by BillKSmith (Chaplain) on Jul 16, 2013 at 15:05 UTC
    I recommend that you use a module to prompt. Under ActiveState, use ActiveState::Prompt. It has a function called 'yes' whic does what you want. On other platforms, use IO::Prompt::Hooked. The documentation uses your case as an example of prompt with validation.
    Bill
Re: comparison of character
by davido (Archbishop) on Jul 16, 2013 at 15:57 UTC

    If it's homework, by all means, figure out the logic. If not:

    use IO::Prompt::Hooked; my $choice = prompt( message => 'Do you wish to update? (Y/N):', validate => qr/^[YN]$/i, );

    Or if you want to provide extra help upon receiving invalid input:

    my $choice = prompt( message => 'Do you wish to update? (Y/N):', validate => qr/^[YN]$/i, error => "Response must be 'Y' or 'N'.\n\n", );

    ...or if you want to add a default...

    my $choice = prompt( message => 'Do you wish to update? (Y/N):', default => 'N', validate => qr/^[YN]$/i, error => "Response must be 'Y' or 'N'.\n\n", );

    Dave

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (13)
As of 2014-07-22 18:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (125 votes), past polls