in reply to help with user selected hash operations?

Since you have attempted something .. here is corrected/working code for you to enhance/complete the missing options(r,x).

I have added the "o" option, so you can check results at each step.

#! /usr/bin/perl use strict; my %son_father; my $choice; my $name1; my $add_dad; %son_father = (Jeff => "Doug", Thomas => "Evan", Robert => "Jason", Bruce => "Richard", Clark => "Jon") ; my $menu = <<MENU; SON_FATHER Hash Operations a- Add a son-father pair d- Delete a son-father pair e- exit the program g- Get a father o- Output the hash neatly r- Replace a father x- get a grand father MENU while (1) { # display the menu print $menu, "\n\n"; # get the user choice print "Make your choice: "; chomp($choice = lc <STDIN>); # fulfill the user request if ($choice eq 'a'){ print "Enter a male name: "; chomp ($name1 = <STDIN>); if (exists $son_father{$name1}) { print "Duplicate name -- try again!\n"; next; } print "Add a father: "; chomp ($add_dad = <STDIN>); $son_father{$name1} = $add_dad; print "Added\n"; next; # <<<<< added } if ($choice eq 'd') { print "Enter a male name: "; chomp ($name1 = <STDIN>); if (exists $son_father{$name1}) { delete $son_father{$name1}; print "Deleted.\n"; } else { print "Sorry, couldn't find '$name1' -- try again later!" +; } next; } if ($choice eq 'o') { print "$_\t=> $son_father{$_}\n" for sort keys %son_father; next; } if ($choice eq 'e') { print "Come back again -- goodbye!"; exit; }else { print "Invalid choice, TRY AGAIN!\n"; } }
Significant changes:
* Added "next" statements to return to top of the loop after an option completes
* Changed "if" statements to enclose subordinate input (Asking for names)
* Corrected the "Add Father" assignment .. removing extra {}, which made it a hashref.
* Remove "lc" for Name inputs to allow correct case names.
* Added the "o" option.

                All power corrupts, but we need electricity.

Replies are listed 'Best First'.
Re^2: help with user selected hash operations?
by lunette (Acolyte) on Oct 30, 2017 at 08:01 UTC

    i've definitely solved the repetition problem! i'm not sure i can /see/ what "next;" is doing, but it does seem to be helping! haha.

    i think my confusion now is, after doing all the other steps i can, i'm still not positive how to make the final if statement work: it's meant to be, "if user inputs none of the menu options, the invalid message appears". when i had it set to "if ($choice ne 'a'...'e')" then print the error message, but it seems like it's taking the input for $name1, etc, as an invalid input, too.

    } if ($choice eq 'r'){ print "Enter a male name: "; chomp (my $name3 = lc <STDIN>); if (exists $son_father{$name3}) { print "Enter a new father name: "; chomp ($newname = <STDIN>); $son_father{$name3} = {$newname}; } else { print "Sorry, couldn't find you -- try again later!"; next; } } if ($choice ne 'a', 'r', 'o', 'd', 'e') { print "Invalid choice, TRY AGAIN!\n"; } }

    i'm going to try and ask my professor about this more tomorrow, but i'm wondering if i'm just missing something obvious. will it read /every/ non-$choice standin as false if i write the if statement like this? is there any way to fix that? i thought assigning each standin a different variable would keep it separate from the if statement...

    i'm definitely feeling less anxious after getting some help, but i'm getting pretty delirious after working on this for seven hours, hahah. sorry for being a bit incoherent.

    oh, gosh, i forgot to say thank you. that's the problem with staying up until 4am. thank you so much!

      if ($choice ne 'a', 'r', 'o', 'd', 'e') { print "Invalid choice, TRY AGAIN!\n"; }
      No, conditions don't work that way. You cannot have a list of options on the right hand side of an eq.
      Possible solutions:
      # Very explicit: if ($choice ne 'a' && $choice ne 'r' && $choice ne 'o' && $choice ne ' +d' && $choice ne 'e') { print "Invalid choice, TRY AGAIN!\n"; } # Testing if the element is in a List of options: unless ( grep { $_ eq $choice } ('a', 'r', 'o', 'd','e') ) { print "Invalid choice, TRY AGAIN!\n"; } # Testing if the element matches a regular expression: unless ( $choice =~ /^(a|r|o|d|e)$/ ) { print "Invalid choice, TRY AGAIN!\n"; }


      holli

      You can lead your users to water, but alas, you cannot drown them.
        You can also use a character class in a regex:
        unless ($choice =~ /^[arode]$/) {

        Also, some people prefer List::Util::none to negated grep:

        use List::Util qw{ none }; if (none { $_ eq $choice } qw( a r o d e )) {
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        okay, i thought it was something like that. the problem with working on code so long is after a while you just throw stuff at the wall and see what sticks.

        and thank you! i was trying to understand the "unless" condition last night but i think my brain was just scrambled. that makes sense!

      i'm not sure i can /see/ what "next;" is doing
      for ( 1 .. 3 ) { print "The father\n"; print "The son\n"; next; print "But no holy ghost\n"; }
      Do you see it now? You do really need to understand the core concepts, like loops, if's and most importantly true/false. If you don't: this happens. I'm all for learning by example - this is the natural way our brain works - but you need examples of one core concept at a time.


      holli

      You can lead your users to water, but alas, you cannot drown them.
        yes!! this is very easy to understand, thank you!! i understand now.

      In addition to the other excellent advice you have received, I will offer a diagnostic tool which is as useful as it is simple: don't just say something's wrong, say in what way it is wrong. ie. instead of

      print "Invalid choice, TRY AGAIN!\n";

      do this:

      print "Invalid choice ($choice), should be one of a, r, o, d or e. TRY + AGAIN!\n";

      This will let you know either that your condition is badly written (as it was) or if $choice is not being correctly set.

      For other handy tips, do peruse the Basic debugging checklist.