Re: unxpected sort warnings while using sort
by NetWallah (Canon) on Jul 22, 2015 at 23:06 UTC
|
local $/; # slurp mode
since you want individual numbers in separate array elements.
It is also a good idea to
chomp @data;
after reading it in.
<=> is the right operator for sorting numerics.
instead of "(my @num= shift)", use
my @sorted=sort {$a<=>$b} @_;
"Despite my privileged upbringing, I'm actually quite well-balanced. I have a chip on both shoulders." - John Nash
| [reply] [d/l] [select] |
|
|
made changes but no change in output
commented out slurp
made reable code by using @_ as used per subs
no sort and no change in message
open my $in, '<', 'numbers.txt' or die $!;
# local $/; # slurp mode
my @data = <$in>;
chomp @data;
close $in;
sort_num(@data);
my @new_sort=sort_num();
print "this is new sorted data ;",@new_sort;
sub sort_num{
my @sorted=sort {$a <=> $b}@_;
return @sorted;
}
Argument "2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1" isn'
+t numeric in sort at C:\Users\Alberto\Documents\NetBeansProjects\Perl
+Project\Perl Essentials\subroutines\ave_mode_median_range sub.pl line
+ 24.
this is new sorted data ;
| [reply] [d/l] [select] |
|
|
What is your data? The warning message
Argument "2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1" isn't numeric in sort at ...
shows that Perl still thinks it's a single string with a bunch of digits and spaces in it. sort will never sort this numerically — or any other way, since it's just a single-element list and so is already "sorted"!
Give a man a fish: <%-(-(-(-<
| [reply] [d/l] [select] |
|
|
2
3
3
3
5
7
8
12
...
If, instead, it looks like this:
2 3 3 3 5 7 8 12 ...
then you have a problem .. or rather, it needs to be handled differently in your code.
For the second case, you need:
my @data = split /\s+/,<$in>;
In addition, the way the "sort_num" is called has some issues in your code.
This is how it should be called:
my @new_sort = sort_num (@data);
And call it only ONCE.
"Despite my privileged upbringing, I'm actually quite well-balanced. I have a chip on both shoulders." - John Nash
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
|
| [reply] [d/l] |
Re: unxpected sort warnings while using sort
by AnomalousMonk (Archbishop) on Jul 23, 2015 at 03:53 UTC
|
If your data exists in a file as a single line of unsigned integers, then you need to extract these integers (digit groups) from the line to a list or array, perhaps after chomp-ing the line (although that may not be necessary if the line is just digits and whitespace with a newline at the end), and then numerically sort the list/array using the <=> comparator.
c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le
"my $line = '2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1';
dd $line;
;;
my @raw_numbers = $line =~ m{ \d+ }xmsg;
;;
my @sorted_numbers = sort { $a <=> $b } @raw_numbers;
dd \@sorted_numbers;
"
"2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1"
[1, 1, 2, 3, 3, 3, 3, 4, 5, 7, 8, 12, 12, 23, 25, 32, 33, 42, 43, 43,
+44, 55]
But again, what is your input data really like? You can see this with something like Data::Dumper::Dumper(), which should be available in any Perl installation, or Data::Dump::dd(), which I like, or even with individual print statements.
Give a man a fish: <%-(-(-(-<
| [reply] [d/l] [select] |
|
|
2 3 3 3 5 7 8 12 32 44 55 12 3 23 43 33 1 4 25 43 42 1
| [reply] [d/l] |
|
|
To be fair, Perl will usually just "do the right thing" for you with numbers inside strings.
But it can only read your mind so far. See:
my $var1 = "12345";
my $res1 = $var1 + 1;
print "Result 1: [$res1]\n";
Results in:
Result 1: [12346]
However:
my $var2 = "1 2 3 4 5";
my $res2 = $var2 + 1;
print "Result 2: [$res2]\n";
Results in:
Result 2: [2]
You see how Perl took the first number in the line and added 1 to it? But the rest of the line has been ignored, and thrown away.
If you want the rest of the numbers used, as noted throughout this thread, you have two choices:
- Process them in a way that uses them, such as the use of split, or;
- Put them on separate lines so file reading gets them separately.
| [reply] [d/l] [select] |
Re: unxpected sort warnings while using sort
by Laurent_R (Canon) on Jul 23, 2015 at 10:16 UTC
|
If the pieces of advice given to you so far are not sufficient to solve your issue, then you should really post a sample of your input file, so that we can know how to handle its contents.
| [reply] |
Re: unxpected sort warnings while using sort
by AnomalousMonk (Archbishop) on Jul 27, 2015 at 03:17 UTC
|
... I am updating the previous post ...
No, you deleted the previous post and replaced it with something quite different. In doing so, you rendered all previous replies incoherent, meaningless. Any future Seeker of Perl Wisdom who ventures down this path will find the signposts defaced and destroyed, the trail erased. Please don't do this again. A -- from me.
Update: Please note that it's perfectly acceptable to actually update, i.e., modify or expand, a post as long as the original material, to which replies may have been made, is preserved and a brief note is added saying what modifications or additions have been made.
Give a man a fish: <%-(-(-(-<
| [reply] [d/l] |
|
|
I am sorry I modified it
I thought the "update" button really did an update rather than delete but I guess not.
will learn from this and not delete any post in future
bummer, man, I wanna this to be used for someone else , if they had the same questions I do as I learn Perl.
again, I DO apologize for the error
| [reply] |
|
|
I wish I could double ++this post; once for the oft-needed chastisement against modifying nodes wholesale, and an additional one for the recursive reference when you edited a post about editing posts, thus showing one way to do it.
| [reply] [d/l] |
Re: unxpected sort warnings while using sort
by marinersk (Priest) on Jul 27, 2015 at 02:32 UTC
|
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.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
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];
}
| [reply] [d/l] [select] |
|
|
#!/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.
| [reply] [d/l] |
|
|
|
|