Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Help fixing this piece of code

by 1nickt (Canon)
on Aug 01, 2015 at 22:11 UTC ( [id://1137134]=note: print w/replies, xml ) Need Help??


in reply to Help fixing this piece of code

I didn't try to run your code since it's not a complete working program. Here's one way to get what I think you want:

#!/usr/bin/perl use strict; use warnings; my %hash; %hash = map { $_ => ++$hash{ $_ } } (split ' ', <DATA>); for (sort { $hash{$b} <=> $hash{$a} } keys %hash) { print "$_ => $hash{ $_ }\n"; last; } __DATA__ 2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1 4 5 3 3 3
The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: Help fixing this piece of code
by perlynewby (Scribe) on Aug 02, 2015 at 00:58 UTC

    Yes, I have already found a way to get mode for the set of numbers in a couple of ways.

    my ($mode_num)=alt_mode_num(@data); print "Mode : $mode_num\n"; sub alt_mode_num{ my %count=(); for (sort{$a <=> $b} @_){ $count{$_}++; } my @key= sort{$count{$b}<=>$count{$a}} keys %count; #print " Key with highest value is $keys[0] \n"; return $key[0]; }

    BUT I saw this way of passing the values by ref in this forum and wanted to duplicated it but failed

    this is the model I used to try to get my mode sub to look like

    my @num =(1..10); my @words = qw(hello world inside); function( {NUMBERS=>\@num, WORDS=>\@words} ); exit; sub function { die "no parameter!\n" unless @_; my %opt = %{ shift @_ }; my @i_words = $opt{WORDS}; print "this r words", Dumper \@i_words; my @i_numbers = $opt{NUMBERS}; print Dumper \@i_numbers; }

    (one of my problemS) is getting a counter and a compare for highest value.

    I specifically wanted this so I can see how it is done properly when using this way

      Yes, I have already found a way to get mode for the set of numbers in a couple of ways.

      No need to sort the list before you populate the hash.

      (one of my problemS) is getting a counter and a compare for highest value.

      Well, yes, you'll still have to count the values per key, so you'll still need a hash in any reasonable solution. The clever stuff with a reference to the array only gets your data into your subroutine. The next steps: to sort it in order to find out the mode number, and to return the mode, are going to be the same however you get the data into the sub.

      But you still aren't using strict and warnings and using a dumper to help you develop your code, as roboticus suggested in one of the most generous posts I can remember. If you were, you would get as far as:

      #!/usr/bin/perl -w use strict; use Data::Dumper; my @data = ( qw/ 2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 +1 4 5 3 3 3 /); my $mode = mode( { NUMBERS => \@data } ); sub mode { my %opt = %{ shift @_ }; print Dumper \%opt; } __END__

      . . . and you would see the contents of %opt:

      $VAR1 = { 'NUMBERS' => [ '2', '3', '3', '3', '5', '7', '8', '12', '32', '44', '55', '12', '3', '23', '43', '33', '1', '4', '25', '43', '42', '1', '4', '5', '3', '3', '3' ] };

      It could be that viewing the data like that doesn't help you see what's going on (because of the complicated way of passing the argument to the sub) ... so you can try a simpler way:

      #!/usr/bin/perl -w use strict; use Data::Dumper; my @data = ( qw/ 2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 +1 4 5 3 3 3 /); my $mode = mode( { NUMBERS => \@data } ); sub mode { my %opt = %{ shift @_ }; while (my ($key, $val) = each %opt) { print "k:$key v:$val\n"; } } __END__

      This outputs:

      k:NUMBERS v:ARRAY(0x7fef9a82a168)

      So now you can see that your %opts hash has only one key=value pair, and your list of numbers is still encapsulated in a reference in the single value in the hash. Probably not what you want, since your next line,

      my @i_numbers = $opt{NUMBERS};

      is expecting the value of the hash element to be an array. It's not. It's a reference to an array. So in order to use it, you'd either have to dereference it as you extract it from the hash, or capture into a reference:

      my $i_numbers = $opt{NUMBERS}; # $i_numbers is an arrayref # or my @i_numbers = @{ $opt{NUMBERS} }; # dereference the arrayref as you +get it from the hash

      . . . but either way, you are right back where you would have been if you had just passed a simple array to the sub: you still have to build a lookup table, i.e. a hash, in order to be able to sort by how many occurrences of each number there are. Here's the complete program: you can see that it has a level of complexity that is not needed, because of referencing the array at the beginning:

      #!/usr/bin/perl -w use strict; use Data::Dumper; my @data = ( qw/ 2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 +1 4 5 3 3 3 /); my $mode = mode( { 'NUMBERS' => \@data } ); # I quote hash keys so I d +on't # mistake them for constan +ts # and use them as bareword +s. print "Mode : $mode\n"; sub mode { my %count = (); my %opt = %{ shift @_ }; for ( @{ $opt{'NUMBERS'} } ) { # no need to sort the array here $count{ $_ }++; } my @key = sort{ $count{$b} <=> $count{$a} } keys %count; return $key[0]; } __END__

      I hope this reply showed you four things:

      • A reference to a variable is not the same thing as the variable itself.
      • Sometimes taking a reference to a variable is a good thing (e.g., rather than making multiple copies of it), but sometimes it overcomplicates things.
      • You should always examine your data if your program is not doing what you expect.
      • When you get suggestions from the monks, you should try them out and most likely follow them!

      The way forward always starts with a minimal test.

        YES!

        the part that I could not understand was the hash_ref when I was expecting an array of the numbers and ,therefore, I could not even begin to reverse the hash into something I could use to see the most duplicated item

        I was stumped and could not see the light

        it is why I asked to have solved by you

        now, I know (understand) how to tackle these dereferencing or,at least, I understand what perl is returning in this case

        I always use the strict and warnings pragma and use Dump. always

        I may not understand what or how to solve the problems being told by these but I always use them

        I spent the last 2 days reading on and practicing hash_ref and dereferencing them since you nailed my question and problem.

Log In?
Username:
Password:

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

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

    No recent polls found