average 3.0 → 3.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
+ [![Build Status](https://semaphoreci.com/api/v1/projects/fd96a25e-c843-44ff-8c43-1da486ca03a6/425376/badge.svg)](https://semaphoreci.com/fegoa89/average)
2
+
1
3
  # Average
2
4
 
3
- TODO: Write a gem description
5
+ Simple gem to calculate mean, median and mode from an array.
4
6
 
5
7
  ## Installation
6
8
 
@@ -18,7 +20,35 @@ Or install it yourself as:
18
20
 
19
21
  ## Usage
20
22
 
21
- TODO: Write usage instructions here
23
+ Get Median
24
+
25
+ $ [3, 4, 5, 2, 3, 1].mean
26
+ $ 3.0
27
+
28
+ Get Mode
29
+
30
+ $ [2,4,6,14,21,24,229,24,24,39].mode
31
+ $ 24
32
+
33
+ It gives back an array due that could be possible to have more than one mode in a array
34
+
35
+ $ [1, 2, 2, 2, 3, 3, 7, 7, 7, 9].mode
36
+ $ [2, 7]
37
+
38
+ But if you want to have only a unique mode, you can use 'unique_mode' method (Only for Ruby versions bigger than 1.8.7 -> http://apidock.com/ruby/v1_8_7_72/Enumerable/max_by).
39
+
40
+ $ [1, 2, 2, 2, 3, 3, 7, 7, 7, 9].unique_mode
41
+ $ 2
42
+
43
+ Get Median
44
+
45
+ $ [3,4,5].median
46
+ $ 4
47
+
48
+ All methods described aboved can handle an array of integers, floats, strings or a mixed array with all of them
49
+
50
+ $ [3, "4", 5, 2.0, 3, "1.0"].mean
51
+ $ 3.0
22
52
 
23
53
  ## Contributing
24
54
 
@@ -5,6 +5,5 @@ require "average/mode"
5
5
  require "average/average_helper"
6
6
  require "average/array_overrides"
7
7
 
8
- module Average
9
-
8
+ class Average
10
9
  end
@@ -1,5 +1,8 @@
1
- require 'average/mean'
2
- require 'average/median'
1
+ include Mean
2
+ include Mode
3
+ include Median
4
+ include AverageHelper
5
+
3
6
  class Array
4
7
  def mean
5
8
  get_mean(self)
@@ -12,4 +15,9 @@ class Array
12
15
  def median
13
16
  get_median(self)
14
17
  end
18
+
19
+ def unique_mode
20
+ get_unique_mode(self)
21
+ end
22
+
15
23
  end
@@ -1,43 +1,46 @@
1
- def valid_array?(array)
2
- # Valid if:
3
- # - the class of the parameter 'array' respond to Array
4
- # - the parameter 'Array' is not null or empty.
5
- # - The array given contains Integers, Floats, and Strings that could be turned to a valid digit.
6
- ( array.is_a?(Array) && !array.nil? && !array.empty? && array_contain_digits?(array) )
7
- end
1
+ module AverageHelper
2
+ def valid_array?(array)
3
+ # Valid if:
4
+ # - the class of the parameter 'array' respond to Array
5
+ # - the parameter 'Array' is not null or empty.
6
+ # - The array given contains Integers, Floats, and Strings that could be turned to a valid digit.
7
+ ( array.is_a?(Array) && !array.nil? && !array.empty? && array_contain_digits?(array) )
8
+ end
8
9
 
9
- def array_contain_digits?(array)
10
- # Go through all elements
11
- result = true
12
- array.each do |array_element|
13
- if not value_can_be_handled?(array_element)
14
- result = false
10
+ def array_contain_digits?(array)
11
+ # Go through all elements
12
+ result = true
13
+ array.each do |array_element|
14
+ if !value_can_be_handled?(array_element)
15
+ result = false
16
+ end
15
17
  end
18
+ result
16
19
  end
17
- result
18
- end
19
20
 
20
- def value_can_be_handled?(element)
21
- # Check if the elements of the array 'look like numbers'.
22
- element.is_a?(Integer) || element.is_a?(Float) || looks_like_a_digit?(element)
23
- end
21
+ def value_can_be_handled?(element)
22
+ # Check if the elements of the array 'look like numbers'.
23
+ element.is_a?(Integer) || element.is_a?(Float) || looks_like_a_digit?(element)
24
+ end
24
25
 
25
26
 
26
- def looks_like_a_digit?(digit)
27
- if digit.is_a?(String) && digit !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
28
- # is _not_ a string that could be turned to a digit
29
- false
30
- else
31
- # is a string that could be a digit
32
- true
27
+ def looks_like_a_digit?(digit)
28
+ if digit.is_a?(String) && digit !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
29
+ # is _not_ a string that could be turned to a digit
30
+ false
31
+ else
32
+ # is a string that could be a digit
33
+ true
34
+ end
33
35
  end
34
- end
35
36
 
36
- def clean_array(array)
37
- array.each_with_index do |val, index|
38
- if val.is_a?(String)
39
- val.include?('.') ? (array[index] = val.to_f) : (array[index] = val.to_i)
37
+ def clean_array(array)
38
+ array.each_with_index do |val, index|
39
+ if val.is_a?(String)
40
+ val.include?('.') ? (array[index] = val.to_f) : (array[index] = val.to_i)
41
+ end
40
42
  end
43
+ array
41
44
  end
42
- array
45
+
43
46
  end
@@ -1,5 +1,7 @@
1
- def get_mean(array)
2
- return if not valid_array?(array)
3
- array = clean_array(array)
4
- array.inject(0) { |sum, x| sum += x } / array.size.to_f
1
+ module Mean
2
+ def get_mean(array)
3
+ if valid_array?(array)
4
+ clean_array(array).inject(0) { |sum, x| sum += x } / array.size.to_f
5
+ end
6
+ end
5
7
  end
@@ -1,22 +1,24 @@
1
- def get_median(array)
2
- return if not valid_array?(array)
3
- array = clean_array(array)
4
- calculate_median(array)
5
- end
1
+ module Median
2
+ def get_median(array)
3
+ if valid_array?(array)
4
+ calculate_median(clean_array(array))
5
+ end
6
+ end
6
7
 
7
- def calculate_median(array)
8
- array.sort!
9
- if array.length.even?
10
- get_mean( middle_items_to_average(array) )
11
- else
12
- array[ array.length / 2.to_f ]
8
+ def calculate_median(array)
9
+ array.sort!
10
+ if array.length.even?
11
+ get_mean( middle_items_to_average(array) )
12
+ else
13
+ array[ array.length / 2.to_f ]
14
+ end
13
15
  end
14
- end
15
16
 
16
- def middle_item(array)
17
- array.size / 2
18
- end
17
+ def middle_item(array)
18
+ array.size / 2
19
+ end
19
20
 
20
- def middle_items_to_average(array)
21
- array[ middle_item(array) -1 .. middle_item(array) ]
21
+ def middle_items_to_average(array)
22
+ array[ middle_item(array) -1 .. middle_item(array) ]
23
+ end
22
24
  end
@@ -1,20 +1,33 @@
1
- def get_mode(array)
2
- return if not valid_array?(array)
3
- array = clean_array(array)
4
- result = repetition_hash(array)
5
- result[:hash_result].select { |key, value| value == result[:max_repetition] }.keys.collect { |float| float.to_i }
6
- end
1
+ module Mode
2
+ def get_mode(array)
3
+ if valid_array?(array)
4
+ result = repetition_hash( clean_array(array) )
5
+ if build_hash_result(result).count > 1
6
+ # It contains more than one mode
7
+ build_hash_result(result).keys.collect { |float| float.to_i }
8
+ else
9
+ # It contains only one mode
10
+ build_hash_result(result).keys.first
11
+ end
12
+ end
13
+ end
7
14
 
8
- def repetition_hash(array)
9
- return if !valid_array?(array)
10
- array = clean_array(array)
11
- result = array.inject({}) { |key, value| key[value] = array.count(value.to_f); key }
12
- { hash_result: result, max_repetition: result.values.max }
13
- end
15
+ def repetition_hash(array)
16
+ { hash_result: build_repetition_result(array), max_repetition: build_repetition_result(array).values.max }
17
+ end
14
18
 
15
- def unique_mode(array)
16
- # only for Ruby versions bigger than 1.8.7 -> http://apidock.com/ruby/v1_8_7_72/Enumerable/max_by
17
- return if !valid_array?(array)
18
- array = clean_array(array)
19
- array.max_by { |x| array.count(x) }
19
+ def build_hash_result(result)
20
+ result[:hash_result].select { |key, value| value == result[:max_repetition] }
21
+ end
22
+
23
+ def build_repetition_result(array)
24
+ array.inject({}) { |key, value| key[value] = array.count(value.to_f); key }
25
+ end
26
+
27
+ def get_unique_mode(array)
28
+ # only for Ruby versions bigger than 1.8.7 -> http://apidock.com/ruby/v1_8_7_72/Enumerable/max_by
29
+ if valid_array?(array)
30
+ clean_array(array).max_by { |x| clean_array(array).count(x) }
31
+ end
32
+ end
20
33
  end
@@ -1,3 +1,3 @@
1
- module Average
2
- VERSION = "3.0"
1
+ class Average
2
+ VERSION = "3.1"
3
3
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Average do
4
4
 
5
- let(:int_array) { [3,4,5] }
5
+ let(:int_array) { [3,4,5] }
6
6
 
7
7
  describe '.mean' do
8
8
  context 'should give back the same result as' do
@@ -28,4 +28,12 @@ describe Average do
28
28
  end
29
29
  end
30
30
 
31
+ describe '.unique_mode' do
32
+ context 'should give back the same result as ' do
33
+ it 'get_unique_mode([X,X,X,X])' do
34
+ expect(int_array.unique_mode).to eq(get_unique_mode(int_array))
35
+ end
36
+ end
37
+ end
38
+
31
39
  end
@@ -97,11 +97,11 @@ describe Average do
97
97
  end
98
98
 
99
99
  describe '#clean_array' do
100
- context 'with an array that contains valid that could be converted to a digit' do
100
+ context 'with an array that has a valid mixed-array structure' do
101
101
  it 'should return an array without string and with the correct numeric format' do
102
102
  expect(clean_array(valid_array)).to eq([3, 4.0, 5, 2, 0.3])
103
103
  end
104
104
  end
105
105
  end
106
106
 
107
- end
107
+ end
@@ -7,6 +7,8 @@ describe Average do
7
7
  let(:mode_array) { [1,1,2,2,3,4] }
8
8
 
9
9
  let(:mixed_array) { [3, 4.0, 5, 2.0, 3, 1.0] }
10
+ let(:array_with_two_modes) { [1, 2, 2, 2, 3, 3, 7, 7, 7, 9] }
11
+ let(:array_with_one_mode) { [2, 4, 6, 14, 21, 24, 229, 24, 24, 39] }
10
12
 
11
13
  describe '#get_mode' do
12
14
 
@@ -17,36 +19,36 @@ describe Average do
17
19
  end
18
20
 
19
21
  context 'with a empty array' do
20
- it 'should return a empty array' do
22
+ it 'should return nil' do
21
23
  expect(get_mode([])).to eq(nil)
22
24
  end
23
25
  end
24
26
 
25
27
  context 'with a nil object' do
26
- it 'should return a empty array' do
28
+ it 'should return a nil' do
27
29
  expect(get_mode([])).to eq(nil)
28
30
  end
29
31
  end
30
32
 
31
33
  end
32
34
 
33
- describe '#unique_mode' do
35
+ describe '#get_unique_mode' do
34
36
 
35
37
  context 'with a array of integers' do
36
38
  it 'should calculate the correct mode returning only one mode' do
37
- expect(unique_mode(mode_array)).to eq(1)
39
+ expect(get_unique_mode(mode_array)).to eq(1)
38
40
  end
39
41
  end
40
42
 
41
43
  context 'with a empty array' do
42
44
  it 'should return nil' do
43
- expect(unique_mode([])).to eq(nil)
45
+ expect(get_unique_mode([])).to eq(nil)
44
46
  end
45
47
  end
46
48
 
47
49
  context 'with a nil object' do
48
50
  it 'should return nil' do
49
- expect(unique_mode(nil)).to eq(nil)
51
+ expect(get_unique_mode(nil)).to eq(nil)
50
52
  end
51
53
  end
52
54
 
@@ -71,17 +73,26 @@ describe Average do
71
73
  end
72
74
 
73
75
  context 'with a empty array' do
74
- it 'should return nil' do
75
- expect(repetition_hash([])).to eql(nil)
76
+ it 'should return a hash with empty values' do
77
+ expect(repetition_hash([])).to eql({:hash_result=>{}, :max_repetition=>nil})
76
78
  end
77
79
  end
78
80
 
79
- context 'with a empty array' do
80
- it 'should return nil' do
81
- expect(repetition_hash(nil)).to eql(nil)
81
+ end
82
+
83
+ describe 'testing returned values' do
84
+
85
+ context 'with an array that has two modes' do
86
+ it 'should return an array with two values' do
87
+ expect(get_mode(array_with_two_modes)).to eq([2, 7])
82
88
  end
83
89
  end
84
90
 
91
+ context 'with an array that has one modes' do
92
+ it 'should return an array with two values' do
93
+ expect(get_mode(array_with_one_mode)).to eq(24)
94
+ end
95
+ end
85
96
  end
86
97
 
87
- end
98
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: average
3
3
  version: !ruby/object:Gem::Version
4
- version: '3.0'
4
+ version: '3.1'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-01 00:00:00.000000000 Z
12
+ date: 2015-11-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler