class Mean

Allows calculation of arithmetic, geometric and harmonic means. Class methods allow the passing in of a data set. Alternatively an object can be created and elements can be added with push

Public Class Methods

arithmetic(data) click to toggle source

Calculate the arithmetic mean @param [Array<Numeric>] data the data values @return [Numeric, nil] the arithmetic mean or nil if there is no data

# File lib/means.rb, line 13
def Mean.arithmetic(data)
  data.sum / data.size unless data.empty?
end
geometric(data) click to toggle source

Calculate the geometric mean @param (see Mean.arithmetic) @return [Numeric, nil] the geometric mean or nil if there is no data or any elements are zero or negative

# File lib/means.rb, line 20
def Mean.geometric(data)
  data.reduce(:*) ** (1 / data.size) unless data.empty? or includes_zero_or_negative? data
end
harmonic(data) click to toggle source

Calculate the harmonic mean @param (see Mean.arithmetic) @return [Numeric, nil] the harmonic mean or nil if there is no data or any elements are zero or negative

# File lib/means.rb, line 27
def Mean.harmonic(data)
  data.size / data.reduce(0) {|sum, element| sum += (1 / element)} unless data.empty? or includes_zero_or_negative? data
end
new(params={}) click to toggle source

Remember the initial state.

If you are passing in an initial state:

arithmetic mean

needs `:sum` and `:count`

geometric mean

needs `:product` and `:count`

harmonic mean

needs `:sum_of_reciprocals` and `:count`

@param [Hash{Symbol => Numeric}] @raise if `:count` is negative @raise if `:sum_of_reciprocals` is negative @raise if `:product` is negative

# File lib/means.rb, line 41
def initialize(params={})
  check_params params
  assign_defaults params
end

Private Class Methods

includes_zero_or_negative?(data) click to toggle source
# File lib/means.rb, line 104
def self.includes_zero_or_negative? data
  data.any? {|element| zero_or_negative? element }
end
zero_or_negative?(element) click to toggle source
# File lib/means.rb, line 108
def self.zero_or_negative? element
  element <= 0
end

Public Instance Methods

arithmetic_mean() click to toggle source

Calculate the arithmetic mean @return [Numeric, nil] the arithmetic mean or nil if there is no data

# File lib/means.rb, line 62
def arithmetic_mean
  @sum / @count unless @count.zero?
end
geometric_mean() click to toggle source

Calculate the geometric mean @return [Numeric, nil] the geometric mean or nil if there is no data or any elements are zero or negative

# File lib/means.rb, line 68
def geometric_mean
  @product ** (1 / @count) unless @count.zero? or @includes_zero_or_negative
end
harmonic_mean() click to toggle source

Calculate the harmonic mean @return [Numeric, nil] the harmonic mean or nil if there is no data or any elements are zero or negative

# File lib/means.rb, line 74
def harmonic_mean
  @count / @sum_of_reciprocals unless @count.zero? or @includes_zero_or_negative
end
push(element) click to toggle source

Add element to the data set @param [Numeric] element the element to add

# File lib/means.rb, line 48
def push(element)
  @includes_zero_or_negative = true if Mean.zero_or_negative? element

  unless @includes_zero_or_negative
    @sum_of_reciprocals += (1 / element)
    @product *= element
  end

  @sum += element
  @count += 1
end

Private Instance Methods

assign_defaults(params) click to toggle source
# File lib/means.rb, line 87
def assign_defaults params
  defaults = {
    sum: 0,
    sum_of_reciprocals: 0,
    product: 1,
    count: 0
  }

  options = params.reverse_merge defaults

  @sum                       = options[:sum]
  @sum_of_reciprocals        = options[:sum_of_reciprocals]
  @product                   = options[:product]
  @count                     = options[:count]
  @includes_zero_or_negative = false
end
check_params(params) click to toggle source
# File lib/means.rb, line 80
def check_params params
  params.assert_valid_keys :count, :sum_of_reciprocals, :product, :sum
  raise_error_for_negative params, :count
  raise_error_for_negative params, :sum_of_reciprocals
  raise_error_for_negative params, :product
end
raise_error_for_negative(params, key) click to toggle source
# File lib/means.rb, line 112
def raise_error_for_negative params, key 
  raise %{cannot have negative "#{key.to_s}" of "#{params[key]}"} if params.has_key? key and params[key] < 0
end