Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: unxpected sort warnings while using sort

by marinersk (Priest)
on Jul 27, 2015 at 02:32 UTC ( [id://1136403]=note: print w/replies, xml ) Need Help??


in reply to unxpected sort warnings while using sort

You really need to start learning to use the debugging tools you've chosen -- in thise case, Data::Dump.

I wrote my own data dumper so I apologize for using a nonstandard module here to demonstrate, but it gets the point across quite nicely. I made the following changes:

sub median_num{ my @sorted= @_; #using shift didn't work, why? format? &debug::debugdumplist("median_num(): \@sorted", \@sorted);

Notice in the results how median_num()receives two different types of structures:

D:\PerlMonks>shift3.pl Using a hash as a reference is deprecated at D:\PerlMonks\shift3.pl li +ne 54. median_num(): @sorted (S:/Steve/Perl/debug.pm:887): [ARRAY(0x2ae0c28)] [1] [1] [2] [3] [3] [3] [3] [4] [5] [7] [8] [12] [12] [23] [25] [32] [33] [42] [43] [43] [44] [55] mean : 18.3636363636364 length : 22 median_num(): @sorted (S:/Steve/Perl/debug.pm:887): [1] [1] [2] [3] [3] [3] [3] [4] [5] [7] [8] [12] [12] [23] [25] [32] [33] [42] [43] [43] [44] [55] this is median : 12 this will be middle num position : 11.5 this is length :22 Use of uninitialized value in concatenation (.) or string at D:\PerlMo +nks\shift3.pl line 29. 1 1 2 3 3 3 3 4 5 7 8 12 12 23 25 32 33 42 43 43 44 55 D:\PerlMonks>

Look closely at the first one; the @sortedarray contains another ARRAY; and that array then has scalar values in it. This is an array of arrays.

Look at the second one; no embedded ARRAY; @sortedsimply contains scalar values.

So I looked at the lines in your code which call median_num(), and lo and behold, you are not using the subroutine consistently:

my ($middle,$median)=median_num(@new_sort); median_num(\@sorted);

The first line calls median_num()with an array as its parameter list.

The second one calls it with a REFERENCE to an array. In Cterms, you've passed it by reference instead of by value

Betting this inconsistency has something to do with why shiftdidn't work.

Also, you might want to clean up your errors and warnings, but you probably knew that.

Replies are listed 'Best First'.
Re^2: unxpected sort warnings while using sort
by perlynewby (Scribe) on Jul 28, 2015 at 20:47 UTC

    the use of value and by reference was an exercise for me to learn how to do it.

Re^2: unxpected sort warnings while using sort
by perlynewby (Scribe) on Jul 30, 2015 at 00:15 UTC

    Monks

    I need help with my sub routine

    I cannot find a way to create a counter and test for the most duplicated number in the hash

    have tried on my own but not successful. Please help so I can see how to do this properly

    problem section below
    sub mode_num{ my %count=(); %opt = %{shift @_ } ; #creating hash #dump \%opt; #check data coming in.. #need to get integrate count as I format data into hash(next task + to make it reable) for (sort{$a <=> $b} %opt{NUMBERS}){ #dump \$opt{NUMBERS}++; $opt{NUMBERS}++; } our @keys= sort{$opt{NUMBERS}->{$b}<=>$opt{NUMBERS}->{$a}} key +s %opt{NUMBERS}; return $opt{NUMBERS}[0]; #some $keys[0] here but don't know proper +syntax...or correct method }
    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
    Complete code
    # will find ave, media, range,mode and mean use strict; use warnings; use autodie; use Data::Dump qw(dump); open my $in, '<', 'numbers.txt' or die $!; # local $/; # slurp mode my @data =split/\s+/,<$in>; close $in; my ($mean,$ref,@new_sort)= sort_num(@data); my $length=$$ref; #passing by ref example print "Input Data set : @new_sort\n"; print "Mean : $mean\n"; print "Lenght : $length\n"; my ($middle,$median)=median_num(@data); print "Median : $median\n"; print "Position of median number : $middle\n"; #using reference to build hash and find most duplicated num my ($hash_ref)=mode_num( {NUMBERS=>\@new_sort} ); #foreach my $k (keys %$hash_ref){ # for (0..$length){ # print " $hash_ref->{$k}[$_]"; #%hash->NUMBER=> i_number # } # } my ($mode_num)=alt_mode_num(@data); print "Mode : $mode_num\n"; # my sub practice with ref and hash_ref sub sort_num{ our @sorted=sort {$a <=> $b}@_; our $length = scalar (@sorted); our $add_div_elem =(eval join '+',@sorted)/$length; median_num(\@sorted); return $add_div_elem,\$length,@sorted; } sub median_num{ my @sorted= @_; #using shift didn't work, why? format? my $middle_one = eval ((scalar @sorted)+ 1)/2; my $median=$sorted[$middle_one]; return ( $middle_one, $median) } #passing by references sub mode_num{ my %count=(); %opt = %{shift @_ } ; #creating hash #dump \%opt; #check data coming in.. #need to get integrate count as I format data into hash(next task + to make it reable) for (sort{$a <=> $b} %opt{NUMBERS}){ #dump \$opt{NUMBERS}++; $opt{NUMBERS}++; } our @keys= sort{$opt{NUMBERS}->{$b}<=>$opt{NUMBERS}->{$a}} key +s %opt{NUMBERS}; return } #alternate to get most repeated num. need to know while using NUMBE +RS ref sub alt_mode_num{ my %count=(); for (sort{$a <=> $b} @_){ $count{$_}++; } my @key= sort{$count{$b}<=>$count{$a}} keys %count; return $key[0]; }
      #!/usr/bin/perl use warnings; use strict; sub most_duplicated { my @numbers = @_; my %count; ++$count{$_} for @numbers; my @most_duplicated; my $max_count = 0; for my $n (keys %count) { if ($count{$n} > $max_count) { @most_duplicated = ($n); $max_count = $count{$n} } elsif ($count{$n} == $max_count) { push @most_duplicated, $n; } } return ($max_count, \@most_duplicated) } 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 ($count, $most_duplicated) = most_duplicated(@data); print "@$most_duplicated occurred $count times.\n";

      It's also possible to avoid two loops and do all the work in one loop, but I think this way is more understandable.

      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        thank you this is great solution.

        can you replicate the counter and method to getting most duplicated using this function method

        sub mode_num{ my %count=(); %opt = %{shift @_ } ; #creating hash #dump \%opt; #check data coming in.. #need to get integrate count as I format data into hash(next task + to make it reable) for (sort{$a <=> $b} %opt{NUMBERS}){ #dump \$opt{NUMBERS}++; $opt{NUMBERS}++; } our @keys= sort{$opt{NUMBERS}->{$b}<=>$opt{NUMBERS}->{$a}} key +s %opt{NUMBERS}; return }

        now, I would like to use this method above so I can see how the loop/counter/finding most duplicated with a hash_ref works ($opt->{NUMBERS}[])

        It intrigued me to follow this method. Unfortunately, I haven't gotten a solution yet

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-04-24 22:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found