bkoski-array_stats 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-01-21
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/array_stats.rb
7
+ lib/array_stats/array_stats.rb
8
+ lib/array_stats/array.rb
9
+ lib/array_stats/float.rb
10
+ script/console
11
+ script/destroy
12
+ script/generate
13
+ test/test_array_stats.rb
14
+ test/test_float_extensions.rb
15
+ test/test_helper.rb
data/PostInstall.txt ADDED
@@ -0,0 +1 @@
1
+ For more information on array_stats, see http://github.com/bkoski/array_stats
data/README.rdoc ADDED
@@ -0,0 +1,67 @@
1
+ = array_stats
2
+
3
+ * http://github.com/bkoski/array_stats
4
+
5
+ == DESCRIPTION:
6
+
7
+ Simple statistics for ruby arrays -- mean, median, sum, and percentile. For more complex
8
+ applications, you should consider NArray[http://narray.rubyforge.org/].
9
+
10
+ == SYNOPSIS:
11
+
12
+ Adds convenient methods to grab stats from a Ruby array, including:
13
+ * mean
14
+ * median
15
+ * sum
16
+ * percentile
17
+
18
+ Percentile calculations are based on the NIST formula[http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm] for percentiles.
19
+
20
+ == EXAMPLE:
21
+
22
+ require 'array_stats'
23
+
24
+ puts [1,3,5,7].mean
25
+ > 4
26
+
27
+ puts [1,2,3,4].sum
28
+ > 10
29
+
30
+ puts [1,2,3,4,5].median
31
+ > 3
32
+
33
+ puts [1,2,3,4,5].percentile(50)
34
+ > 3
35
+
36
+ == REQUIREMENTS:
37
+
38
+ * FIX (list of requirements)
39
+
40
+ == INSTALL:
41
+
42
+ * <tt>sudo gem install bkoski-array_stats --source http://gems.github.com</tt>
43
+
44
+ == LICENSE:
45
+
46
+ (The MIT License)
47
+
48
+ Copyright (c) 2009 Ben Koski
49
+
50
+ Permission is hereby granted, free of charge, to any person obtaining
51
+ a copy of this software and associated documentation files (the
52
+ 'Software'), to deal in the Software without restriction, including
53
+ without limitation the rights to use, copy, modify, merge, publish,
54
+ distribute, sublicense, and/or sell copies of the Software, and to
55
+ permit persons to whom the Software is furnished to do so, subject to
56
+ the following conditions:
57
+
58
+ The above copyright notice and this permission notice shall be
59
+ included in all copies or substantial portions of the Software.
60
+
61
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
62
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
63
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
64
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
65
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
66
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
67
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/array_stats'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('array_stats', ArrayStats::VERSION) do |p|
7
+ p.developer('Ben Koski', 'gems@benkoski.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ # p.extra_deps = [
12
+ # ['activesupport','>= 2.0.2'],
13
+ # ]
14
+ # p.extra_dev_deps = [
15
+ # ['newgem', ">= #{::Newgem::VERSION}"]
16
+ # ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
@@ -0,0 +1,11 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module ArrayStats
5
+ VERSION = '0.5.0'
6
+ end
7
+
8
+ require "#{File.dirname(__FILE__)}/array_stats/float"
9
+ require "#{File.dirname(__FILE__)}/array_stats/array_stats"
10
+ require "#{File.dirname(__FILE__)}/array_stats/array"
11
+
@@ -0,0 +1,3 @@
1
+ class Array
2
+ include ArrayStats
3
+ end
@@ -0,0 +1,43 @@
1
+ module ArrayStats
2
+
3
+ # Returns the sum of all elements in the array; 0 if array is empty
4
+ def sum
5
+ self.inject(0) {|sum, sample| sum += sample}
6
+ end
7
+
8
+ # Returns the mean of all elements in array; nil if array is empty
9
+ def mean
10
+ if self.length == 0
11
+ nil
12
+ else
13
+ self.sum / self.length
14
+ end
15
+ end
16
+
17
+ # Returns the median for the array; nil if array is empty
18
+ def median
19
+ percentile(50)
20
+ end
21
+
22
+ # Returns the percentile value for percentile _p_; nil if array is empty.
23
+ #
24
+ # _p_ should be expressed as an integer; <tt>percentile(90)</tt> returns the 90th percentile of the array.
25
+ #
26
+ # Algorithm from NIST[http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm]
27
+ def percentile p
28
+ sorted_array = self.sort
29
+ rank = (p.to_f / 100) * (self.length + 1)
30
+
31
+ if self.length == 0
32
+ return nil
33
+ elsif rank.fractional_part?
34
+ sample_0 = sorted_array[rank.truncate - 1]
35
+ sample_1 = sorted_array[rank.truncate]
36
+
37
+ return (rank.fractional_part * (sample_1 - sample_0)) + sample_0
38
+ else
39
+ return sorted_array[rank - 1]
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,13 @@
1
+ class Float
2
+
3
+ # Returns true if a float has a fractional part; i.e. <tt>f == f.to_i</tt>
4
+ def fractional_part?
5
+ fractional_part != 0.0
6
+ end
7
+
8
+ # Returns the fractional part of a float. For example, <tt>(6.67).fractional_part == 0.67</tt>
9
+ def fractional_part
10
+ (self - self.truncate).abs
11
+ end
12
+
13
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/array_stats.rb'}"
9
+ puts "Loading array_stats gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,71 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestArrayStats < Test::Unit::TestCase
4
+
5
+ context "median" do
6
+ should "return the middle of the set if array length is odd" do
7
+ assert_equal 15, [1,2,15,22,38].median
8
+ end
9
+
10
+ should "return the average of the middle of the set if array length is even" do
11
+ assert_equal 10, [1,6,14,22].median
12
+ end
13
+
14
+ should "return nil if the array is empty" do
15
+ assert_nil [].median
16
+ end
17
+
18
+ should "sort an array before deriving the median" do
19
+ assert_equal 20, [1,20,50,60,10].median
20
+ end
21
+ end
22
+
23
+ context "percentile" do
24
+ should "choose the number at a particular rank if array divides cleanly" do
25
+ assert_equal 36, [12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48].percentile(65)
26
+ end
27
+
28
+ should "interpolate according to algorithm if array does not divide cleanly" do
29
+ assert_equal 5.5, [3,5,7,8,9,11,13,15].percentile(25)
30
+ assert_equal 95.1981, [95.1772,95.1567,95.1937,95.1959,95.1442,95.0610,95.1591,95.1195,95.1065,95.0925,95.1990,95.1682].percentile(90).round_to(0.0001)
31
+ end
32
+
33
+ should "return nil if the array is empty" do
34
+ assert_nil [].percentile(30)
35
+ end
36
+ end
37
+
38
+ context "sum" do
39
+ should "return the sum of all elements in the array" do
40
+ assert_equal 12, [2,4,6].sum
41
+ end
42
+
43
+ should "return an integer if all elements are ints" do
44
+ assert_kind_of Integer, [2,4,6].sum
45
+ end
46
+
47
+ should "return a float if at least some of the elements are floats" do
48
+ assert_kind_of Float, [2.5,3.5,6].sum
49
+ end
50
+
51
+ should "return 0 if the array is empty" do
52
+ assert_equal 0, [].sum
53
+ end
54
+ end
55
+
56
+ context "mean" do
57
+ should "return the mean for the array " do
58
+ assert_equal 7, [2,4,6,8,10,12].mean
59
+ assert_equal 25, [48,29,26,19,3].mean
60
+ end
61
+
62
+ should "return nil if the array is empty" do
63
+ assert_nil [].mean
64
+ end
65
+ end
66
+
67
+
68
+
69
+ end
70
+
71
+
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestFloatExtensions < Test::Unit::TestCase
4
+
5
+ context "fractional_part?" do
6
+ should "return true for a number with a fractional part" do
7
+ n = 1.249
8
+ assert n.fractional_part?
9
+ end
10
+
11
+ should "return true for a number without a fractional part" do
12
+ n = 1.0
13
+ assert !n.fractional_part?
14
+ end
15
+ end
16
+
17
+ context "fractional_part" do
18
+ should "return the decimal parts for a number" do
19
+ n = 12.2456
20
+ assert_in_delta 0.2456, n.fractional_part, 0.00000001
21
+ end
22
+
23
+ should "retrun the decimal parts, even if they are 0" do
24
+ n = 12.0
25
+ assert_equal 0.0, n.fractional_part
26
+ end
27
+
28
+ should "retrun the decimal as a positive number, even if the original float is negative" do
29
+ n = -12.2399
30
+ assert_in_delta 0.2399, n.fractional_part, 0.00000001
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/array_stats'
4
+ require 'shoulda'
5
+ require 'facets'
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bkoski-array_stats
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Koski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-22 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.0
23
+ version:
24
+ description: Simple statistics for ruby arrays -- mean, median, sum, and percentile. For more complex applications, you should consider NArray[http://narray.rubyforge.org/].
25
+ email:
26
+ - gems@benkoski.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - PostInstall.txt
35
+ - README.rdoc
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - PostInstall.txt
40
+ - README.rdoc
41
+ - Rakefile
42
+ - lib/array_stats.rb
43
+ - lib/array_stats/array_stats.rb
44
+ - lib/array_stats/array.rb
45
+ - lib/array_stats/float.rb
46
+ - script/console
47
+ - script/destroy
48
+ - script/generate
49
+ - test/test_array_stats.rb
50
+ - test/test_float_extensions.rb
51
+ - test/test_helper.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/bkoski/array_stats
54
+ post_install_message: PostInstall.txt
55
+ rdoc_options:
56
+ - --main
57
+ - README.rdoc
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project: array_stats
75
+ rubygems_version: 1.2.0
76
+ signing_key:
77
+ specification_version: 2
78
+ summary: Simple statistics for ruby arrays -- mean, median, sum, and percentile
79
+ test_files:
80
+ - test/test_array_stats.rb
81
+ - test/test_float_extensions.rb
82
+ - test/test_helper.rb