Re: Calculating statistical median
by kwaping (Priest) on Jul 13, 2005 at 14:43 UTC
|
| [reply] |
|
|
| [reply] [d/l] |
Re: Calculating statistical median
by tlm (Prior) on Jul 14, 2005 at 01:39 UTC
|
For something this simple, I prefer to code it. With List::Util::sum and POSIX::ceil:
sub median {
sum( ( sort { $a <=> $b } @_ )[ int( $#_/2 ), ceil( $#_/2 ) ] )/2;
}
print median( 1..4 ), "\n";
print median( 1..5 ), "\n";
__END__
2.5
3
| [reply] [d/l] |
|
|
What's the advantage of coding it yourself in this specific situation? Other than for fun, which I completely understand.
I'm asking because I normally code things myself instead of using available modules for one of two reasons: to learn how to do it (aka for fun), or to avoid the overhead of loading a module. In your example, you're loading two modules instead of the single one I suggested. Plus, you obviously already know how to do this operation, so it can't be a learning exercise. So I'm baffled.
I am not implying anything, I'm just truly curious as to why. :)
| [reply] |
|
|
The principal reason in this case is that I try to minimize the number of non-core modules that my code uses, since each non-core module introduces one more potential obstacle, however small it may be, for someone else using my code. I.e., I'd never use a non-core module just to import a simple one-line function. More generally, I weigh the tradeoff between coding something myself and introducing a non-core dependency. The bigger and more complex the candidate module (i.e. the more potentially difficult its installation by some other user), the more I am willing to code myself.
But I don't want to overstate this point! When I speak in this context about "coding something myself" I am usually referring to a small bit of functionality that I may be able to implement in only a few lines of code. Of course, this also assumes that I feel confident in coding something myself; there are many problem areas that I don't understand well enough and am glad to use modules written by others, even if my needs could have been met with only a few lines by an expert.
One other reason why I may code something myself is if I find the documentation for a module so poor that I suspect that the apparent time saving of using the module instead of coding it myself will be lost trying to make up for the bad documentation (e.g. by wading through the source).
A third reason is that sometimes the available CPAN alternative is not good for some reason (usually speed).
But again, just to be clear, even with all these considerations, I end up using plenty of modules, both core and non-core.
| [reply] |
|
|
|
|
This is not a statistical median: a median of array of integers must be integer
| [reply] |
|
|
| [reply] |
Re: Calculating statistical median
by trammell (Priest) on Jul 13, 2005 at 16:46 UTC
|
| [reply] |
Re: Calculating statistical median
by Anonymous Monk on Jul 13, 2005 at 16:11 UTC
|
#!/usr/bin/perl -w
use strict;
my @array = qw/1 2 3 4 9/;
print median(@array);
sub median
{
my @vals = sort {$a <=> $b} @_;
my $len = @vals;
if($len%2) #odd?
{
return $vals[int($len/2)];
}
else #even
{
return ($vals[int($len/2)-1] + $vals[int($len/2)])/2;
}
}
| [reply] [d/l] |
|
|
This is the only sample here that returns correct median. Thanx guy.
| [reply] |
Re: Calculating statistical median
by monkey_boy (Priest) on Jul 13, 2005 at 15:39 UTC
|
| [reply] |
|
|
| [reply] |
Re: Calculating statistical median
by dirac (Beadle) on Jul 13, 2005 at 15:18 UTC
|
sub mean {
my ($arrayref) = @_;
my $result;
foreach (@$arrayref) { $result += $_ }
return $result / @$arrayref;
}
my @points = qw(1 2 3 4);
print mean \@points;
| [reply] [d/l] |
|
|
| [reply] |
|
|
Hi.
Is there a special reason for the array reference? Versus this?
sub mean {
my $result;
foreach (@_) { $result += $_ }
return $result / @_;
}
my @points = qw(1 2 3 4);
print mean @points;
| [reply] [d/l] |
|
|
Copying an array or hash into @_ takes time.
Passing arrays and hashes by reference is
straightforward.
See Benchmark
If you want median:
sub median { $_[0]->[ @{$_[0]} / 2 ] }
my @points = 0..100;
print median(\@points), "\n";
| [reply] [d/l] |
|
|
|
|
|
|
|
|
| A reply falls below the community's threshold of quality. You may see it by logging in. |