This page contains automated test results for code from O'Reilly's Ruby Cookbook. If this code looks interesting or useful, you might want to buy the whole book.
| Taking Mean, Median, and Mode | ||
|---|---|---|
| Code | Expected | Actual |
def mean(array)
array.inject(0) { |sum, x| sum += x } / array.size.to_f
end
mean([1,2,3,4]) |
2.5 | 2.5 |
mean([100,100,100,100.1]) |
100.025 | 100.025 |
mean([-100, 100]) |
0.0 | 0.0 |
mean([3,3,3,3]) |
3.0 | 3.0 |
def median(array, already_sorted=false) return nil if array.empty? array = array.sort unless already_sorted m_pos = array.size / 2 return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos]) end median([1,2,3,4,5]) |
3 | 3 |
median([5,3,2,1,4]) |
3 | 3 |
median([1,2,3,4]) |
2.5 | 2.5 |
median([1,1,2,3,4]) |
2 | 2 |
median([2,3,-100,100]) |
2.5 | 2.5 |
median([1, 1, 10, 100, 1000]) |
10 | 10 |
def modes(array, find_all=true)
histogram = array.inject(Hash.new(0)) { |h, n| h[n] += 1; h }
modes = nil
histogram.each_pair do |item, times|
modes << item if modes && times == modes[0] and find_all
modes = [times, item] if (!modes && times>1) or (modes && times>modes[0])
end
return modes ? modes[1...modes.size] : modes
end
modes([1,2,3,4]) |
nil | nil |
modes([1,1,2,3,4]) |
[1] | [1] |
modes([1,1,2,2,3,4]) |
[1, 2] | [1, 2] |
modes([1,1,2,2,3,4,4]) |
[1, 2, 4] | [1, 2, 4] |
modes([1,1,2,2,3,4,4], false) |
[1] | [1] |
modes([1,1,2,2,3,4,4,4,4,4]) |
[4] | [4] |
def mean_without_float_conversion(array)
array.inject(0) { |x, sum| sum += x } / array.size
end
require 'rational'
numbers = [Rational(2,3), Rational(3,4), Rational(6,7)]
mean(numbers) |
0.757936507936508 | 0.757936507936508 |
mean_without_float_conversion(numbers) |
Rational(191, 252) | Rational(191, 252) |
mean([1, 100, 100000]) |
33367.0 | 33367.0 |
median([1, 100, 100000]) |
100 | 100 |
mean([1, 100, -1000000]) |
-333299.666666667 | -333299.666666667 |
median([1, 100, -1000000]) |
1 | 1 |
median(["a", "z", "b", "l", "m", "j", "b"]) |
"j" | "j" |
median(["a", "b", "c", "d"]) |
TypeError: String can't be coerced into Fixnum ... |
TypeError: String can't be coerced into Fixnum from (irb):2:in `+' from (irb):2:in `mean' from (irb):47:in `inject' from (irb):2:in `mean' from (irb):12:in `median' from (irb):47 |
def mean_and_standard_deviation(array)
m = mean(array)
variance = array.inject(0) { |variance, x| variance += (x - m) ** 2 }
return m, Math.sqrt(variance/(array.size-1))
end
#All the items in the list are close to the mean, so the standard
#deviation is low.
mean_and_standard_deviation([1,2,3,1,1,2,1]) |
[1.57142857142857, 0.786795792469443] | [1.57142857142857, 0.786795792469443] |
#The outlier increases the mean, but also increases the standard deviation. mean_and_standard_deviation([1,2,3,1,1,2,1000]) |
[144.285714285714, 377.33526837801] | [144.285714285714, 377.33526837801] |