in reply to Re: help with user selected hash operations?
in thread help with user selected hash operations?

oh, my gosh, this is more than i expected. thank you so much. T_T

i was hesitant to post the entire code because i thought it might be too long, but with little edits i've made so far, this is what i have:

#! /usr/bin/perl use strict; my %son_father; my $choice; my $name1; my $name2; my $name3; my $name4; my $newname; 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 (my $name1 = ucfirst lc <STDIN>); } if (exists $son_father{$name1}) { print "Duplicate name -- try again!\n"; } else { print "Add a father: "; chomp (my $add_dad = ucfirst lc <STDIN>); $son_father{$name1} = {$add_dad}; next; } if ($choice eq 'd') { print "Enter a male name: "; chomp (my $name2 = ucfirst lc <STDIN>); } if (exists $son_father{$name2}) { delete $son_father{$name2}; } else { print "Sorry, couldn't find you -- try again later!"; next; } if ($choice eq 'e') { print "Come back again -- goodbye!"; last; next; } if ($choice eq 'g'){ print "Enter a son's name: "; chomp (my $name4 = ucfirst lc <STDIN>); } if (exists $son_father{$name4}) { print "$son_father{$name4}\n"; next; } if ($choice eq 'o'){ my ($key, $value); foreach $value (sort keys %son_father){ print "$value\t$son_father{$value}\n"; next; } } if ($choice eq 'r'){ print "Enter a male name: "; chomp (my $name3 = ucfirst lc <STDIN>); if (exists $son_father{$name3}) { print "Enter a new father name: "; chomp ($newname = ucfirst lc <STDIN>); $son_father{$name3} = {$newname}; } else { print "Sorry, couldn't find you -- try again later!"; next; } } if ($choice ne 'a', $choice ne 'r', $choice ne 'o', $choice ne 'd' +, $choice ne 'e', $choice ne 'g') { print "Invalid choice, TRY AGAIN!\n"; next; } }

i can change my scalar variable names to make it easier to understand, these are just the names the professor asked us to use.

the problem i seem to be having is that the secondary STDINs seem to trigger the "invalid response", even with "next" as part of the code. along with that, if i do the "a" command first, the "duplicate name" prompt shows up in subsequent command loops... on top of that, i keep getting HASH(x) in place of the names i'm putting in for the secondary STDINs in the "a" and "r" commands. like this:

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 Make your choice: a Enter a male name: Bruce Duplicate name -- try again! Invalid choice, TRY AGAIN! 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 Make your choice: a Enter a male name: Phil Add a father: Justin 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 Make your choice: o Duplicate name -- try again! Bruce Richard Clark Jon Jeff Doug Phil HASH(0x6453d0) Robert Jason Thomas Evan Invalid choice, TRY AGAIN! 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 Make your choice: e Duplicate name -- try again! Come back again -- goodbye!

sorry, this is a lot. >_< i really do want to understand how to make this run perfectly, not just for my class, but just so i can use it again without getting this mixed up.

and thank you again for being so helpful. it makes me feel really welcome, despite how clueless i can be, haha.

EDIT: i forgot to mention - if i don't explicitly use "my (variable)" at the beginning of the code, i'm continuously told by my terminal AND my writing program that it isn't explicitly defined at all, regardless of if i used "my" within the chomp or not. i know i should be able to just use the "my" command within the STDIN perimeters, but no matter how i fiddle with it, it just tells me it's wrong!

Replies are listed 'Best First'.
Re^3: help with user selected hash operations?
by roboticus (Chancellor) on Oct 30, 2017 at 18:47 UTC

    lunette:

    You didn't quite get what kcott was telling you about your if statements and indentation. I've reformatted the code a little to hopefully help you see what he means:

    $ cat pm_1202351.pl #! /usr/bin/perl use strict; my %son_father; my $choice; my $name1; my $name2; my $name3; my $name4; my $newname; 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 (my $name1 = ucfirst lc <STDIN>); } if (exists $son_father{$name1}) { #46 print "Duplicate name -- try again!\n"; } else { print "Add a father: "; chomp (my $add_dad = ucfirst lc <STDIN>); $son_father{$name1} = {$add_dad}; next; } if ($choice eq 'd') { print "Enter a male name: "; chomp (my $name2 = ucfirst lc <STDIN>); } if (exists $son_father{$name2}) { #59 delete $son_father{$name2}; } else { print "Sorry, couldn't find you -- try again later!"; next; } if ($choice eq 'e') { print "Come back again -- goodbye!"; last; next; } if ($choice eq 'g'){ print "Enter a son's name: "; chomp (my $name4 = ucfirst lc <STDIN>); } if (exists $son_father{$name4}) { #76 print "$son_father{$name4}\n"; next; } if ($choice eq 'o'){ my ($key, $value); foreach $value (sort keys %son_father){ print "$value\t$son_father{$value}\n"; next; } } if ($choice eq 'r'){ print "Enter a male name: "; chomp (my $name3 = ucfirst lc <STDIN>); if (exists $son_father{$name3}) { print "Enter a new father name: "; chomp ($newname = ucfirst lc <STDIN>); $son_father{$name3} = {$newname}; } else { print "Sorry, couldn't find you -- try again later!"; next; } } if ($choice ne 'a', $choice ne 'r', $choice ne 'o', $choice ne 'd', +$choice ne 'e', $choice ne 'g') { print "Invalid choice, TRY AGAIN!\n"; next; } }

    Pay close attention to the lines marked 46, 59 and 76: You're intending them to be inside the prior if block, but it's hard to see that because your braces and indentation aren't consistent with each other.

    ...roboticus

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

      oh! i'm so sorry, the confusing indentations are a habit my professor has, and i just picked it up as i was going. it is a bit easier to read like this, haha. thank you!

        ... the confusing indentations are a habit my professor has ...

        Then you are being taught by a lunatic.


        Give a man a fish:  <%-{-{-{-<

Re^3: help with user selected hash operations?
by kcott (Archbishop) on Oct 31, 2017 at 05:33 UTC
    "oh, my gosh, this is more than i expected. thank you so much. T_T"

    You're very welcome.

    Some further responses came to mind as I was reading your reply; however, it appears they've already been covered, so there's no need for me to repeat them. As the update to your initial question indicates that your code is now "working perfectly", I'll assume that additional advice has clarified any outstanding issues.

    You've apologised a number of times for the length of what you've posted. There's really no need: I don't see anything that's excessively long. In general, avoid adding anything not directly related to the question, and keep the code that does demonstrate the problem to a minimum. You can wrap long tracts of code (or data, or output, or indeed anything else you want to post) in <spoiler>...</spoiler> or <readmore>...</readmore> tags: but don't overdo it though — presenting too little can be just as bad as presenting too much.

    "i forgot to mention - if i don't explicitly use "my (variable)" at the beginning of the code, i'm continuously told ... that it isn't explicitly defined at all, ..."

    I suspect that was related to your indentation/nesting problem:

    if (COND1) { my $var = ... } if (COND2) { # $var OUT-OF-SCOPE here }

    That code is really:

    if (COND1) { my $var = ... } if (COND2) { # $var OUT-OF-SCOPE here }

    But the code you needed/intended was:

    if (COND1) { my $var = ... if (COND2) { # $var IN SCOPE here } }

    If you're referring to something else, you'll need to post example code.

    — Ken

Re^3: help with user selected hash operations?
by AnomalousMonk (Archbishop) on Oct 30, 2017 at 18:39 UTC
    ... i keep getting HASH(x) in place of the names i'm putting in ...
    ... Phil HASH(0x6453d0) ...

    That's because:

    1. You still have statements like
          $son_father{$name1} = {$add_dad};
      which add an (incomplete) hash reference instead of a name; and
    2. You still do not have a
          use warnings;
      statement at the start of your script to enable Perl to tell you (update: or at least give you a hint) about stuff like this.

    I would add that you're also still using a weird indenting scheme that makes the inherent structure of your code very hard for me to follow; I hope it's easier for you, but I suspect not.


    Give a man a fish:  <%-{-{-{-<

      oh, shoot. i added "warnings" and "diagnostics" after posting this comment, my apologies... i'm still learning what's easiest for me in formatting, but i think i understand what everyone is saying re: indentations.

      an incomplete hash reference... i think i get it. i'll make sure to ask my professor about this. hashes are still brand new to me, so i'm getting easily frustrated when i really shouldn't be. thank you!

        an incomplete hash reference...

        The critical point is not that the  {$add_dad} "name" you are assigning in the
            $son_father{$name1} = {$add_dad};
        statement is an incomplete hash reference, it's that it is a hash reference at all. Please ask your professor about "anonymous hash and array constructors (or composers)". Please see Making References (item 3 in particular) in perlref.


        Give a man a fish:  <%-{-{-{-<

Re^3: help with user selected hash operations?
by poj (Abbot) on Oct 30, 2017 at 18:55 UTC

    If you indent this block

    if ($choice eq 'a'){ print "Enter a male name: "; chomp (my $name1 = ucfirst lc <STDIN>); } if (exists $son_father{$name1}) { print "Duplicate name -- try again!\n"; } else { print "Add a father: "; chomp (my $add_dad = ucfirst lc <STDIN>); $son_father{$name1} = {$add_dad}; next; }

    correctly you can see it is 2 blocks not 1

    if ($choice eq 'a'){ print "Enter a male name: "; chomp (my $name1 = ucfirst lc <STDIN>); } if (exists $son_father{$name1}) { print "Duplicate name -- try again!\n"; } else { print "Add a father: "; chomp (my $add_dad = ucfirst lc <STDIN>); $son_father{$name1} = {$add_dad}; next; }

    What you want is probably

    if ($choice eq 'a'){ print "Enter a male name: "; chomp (my $name = ucfirst lc <STDIN>); if (exists $son_father{$name}) { print "Duplicate name $name -- try again!\n"; } else { print "Add a father: "; chomp (my $add_dad = ucfirst lc <STDIN>); $son_father{$name} = $add_dad; print "$name added with father $add_dad\n"; } next; }
    poj

      i was told this last night by a friend on twitter! but for some reason when i tried to write this, the code insisted it wasn't correct. it works when you write it the way you've done it. i wonder why it told me i was wrong. thank you!