ruby-nuggets 0.6.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/.rspec +1 -0
  2. data/README +1 -1
  3. data/Rakefile +4 -4
  4. data/lib/nuggets/array/correlation.rb +5 -0
  5. data/lib/nuggets/array/correlation_mixin.rb +62 -0
  6. data/lib/nuggets/array/histogram.rb +5 -0
  7. data/lib/nuggets/array/histogram_mixin.rb +155 -0
  8. data/lib/nuggets/array/mean.rb +5 -0
  9. data/lib/nuggets/array/mean_mixin.rb +139 -0
  10. data/lib/nuggets/array/median.rb +5 -0
  11. data/lib/nuggets/array/median_mixin.rb +74 -0
  12. data/lib/nuggets/array/mode.rb +5 -0
  13. data/lib/nuggets/array/mode_mixin.rb +70 -0
  14. data/lib/nuggets/array/monotone.rb +5 -5
  15. data/lib/nuggets/array/only.rb +3 -2
  16. data/lib/nuggets/array/regression.rb +5 -0
  17. data/lib/nuggets/array/regression_mixin.rb +63 -0
  18. data/lib/nuggets/array/runiq_mixin.rb +1 -1
  19. data/lib/nuggets/array/standard_deviation_mixin.rb +5 -8
  20. data/lib/nuggets/array/variance_mixin.rb +30 -11
  21. data/lib/nuggets/enumerable/all_any_extended.rb +6 -6
  22. data/lib/nuggets/enumerable/minmax.rb +2 -2
  23. data/lib/nuggets/env/set_mixin.rb +4 -4
  24. data/lib/nuggets/env/user_home_mixin.rb +1 -1
  25. data/lib/nuggets/file/replace_mixin.rb +3 -3
  26. data/lib/nuggets/file/sub_mixin.rb +2 -2
  27. data/lib/nuggets/file/which_mixin.rb +15 -14
  28. data/lib/nuggets/hash/nest_mixin.rb +3 -3
  29. data/lib/nuggets/hash/only.rb +6 -4
  30. data/lib/nuggets/hash/unroll_mixin.rb +1 -1
  31. data/lib/nuggets/io/modes.rb +12 -12
  32. data/lib/nuggets/numeric/duration.rb +3 -3
  33. data/lib/nuggets/object/blank_mixin.rb +6 -6
  34. data/lib/nuggets/object/boolean_mixin.rb +3 -3
  35. data/lib/nuggets/object/singleton_class_mixin.rb +3 -3
  36. data/lib/nuggets/range/quantile_mixin.rb +1 -1
  37. data/lib/nuggets/statistics.rb +11 -0
  38. data/lib/nuggets/statistics_mixins.rb +11 -0
  39. data/lib/nuggets/string/case.rb +4 -4
  40. data/lib/nuggets/string/msub.rb +1 -1
  41. data/lib/nuggets/string/nsub.rb +2 -2
  42. data/lib/nuggets/string/sub_with_md.rb +2 -2
  43. data/lib/nuggets/tempfile/open.rb +1 -1
  44. data/lib/nuggets/uri/content_type_mixin.rb +1 -1
  45. data/lib/nuggets/uri/exist_mixin.rb +2 -2
  46. data/lib/nuggets/util/content_type.rb +1 -1
  47. data/lib/nuggets/util/i18n.rb +63 -63
  48. data/lib/nuggets/util/ruby.rb +7 -7
  49. data/lib/nuggets/version.rb +2 -2
  50. data/spec/nuggets/array/mean_spec.rb +127 -0
  51. data/spec/nuggets/array/median_spec.rb +79 -0
  52. data/spec/nuggets/array/mode_spec.rb +59 -0
  53. data/spec/nuggets/string/evaluate_spec.rb +2 -2
  54. metadata +29 -15
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/mode_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::ModeMixin
5
+ end
@@ -0,0 +1,70 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of ruby-nuggets, some extensions to the Ruby programming #
5
+ # language. #
6
+ # #
7
+ # Copyright (C) 2007-2011 Jens Wille #
8
+ # #
9
+ # Authors: #
10
+ # Jens Wille <jens.wille@uni-koeln.de> #
11
+ # #
12
+ # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
+ # under the terms of the GNU General Public License as published by the Free #
14
+ # Software Foundation; either version 3 of the License, or (at your option) #
15
+ # any later version. #
16
+ # #
17
+ # ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
20
+ # more details. #
21
+ # #
22
+ # You should have received a copy of the GNU General Public License along #
23
+ # with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
24
+ # #
25
+ ###############################################################################
26
+ #++
27
+
28
+ require 'nuggets/array/histogram_mixin'
29
+
30
+ module Nuggets
31
+ class Array
32
+ module ModeMixin
33
+
34
+ def self.included(base)
35
+ base.send :include, Nuggets::Array::HistogramMixin
36
+ end
37
+
38
+ # call-seq:
39
+ # array.mode => anObject
40
+ # array.mode(+true+) => anArray
41
+ #
42
+ # Returns the mode[http://en.wikipedia.org/wiki/Mode_%28statistics%29] of
43
+ # the values in _array_ (via #histogram).
44
+ #
45
+ # If parameter +true+ is passed, an Array of all modes is returned.
46
+ def mode(all = false, &block)
47
+ hist, modes = histogram(&block), []
48
+ freq = hist.values.max
49
+
50
+ hist.each { |key, value|
51
+ if value == freq
52
+ modes << key
53
+ break unless all
54
+ end
55
+ }
56
+
57
+ all ? modes : modes.first
58
+ end
59
+
60
+ # call-seq:
61
+ # array.modes => anArray
62
+ #
63
+ # Returns an Array of all modes of the values in _array_ (see #mode).
64
+ def modes(&block)
65
+ mode(true, &block)
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -28,7 +28,7 @@
28
28
  class Array
29
29
 
30
30
  # call-seq:
31
- # array.monotone?(operator) => true or false
31
+ # array.monotone?(operator) => +true+ or +false+
32
32
  #
33
33
  # Check whether _array_ is monotone according to +operator+.
34
34
  def monotone?(operator)
@@ -42,7 +42,7 @@ class Array
42
42
  alias_method :monotonic?, :monotone?
43
43
 
44
44
  # call-seq:
45
- # array.ascending? => true or false
45
+ # array.ascending? => +true+ or +false+
46
46
  #
47
47
  # Check whether _array_ is (strictly) ascending.
48
48
  def ascending?(strict = false)
@@ -51,7 +51,7 @@ class Array
51
51
  alias_method :increasing?, :ascending?
52
52
 
53
53
  # call-seq:
54
- # array.strictly_ascending? => true or false
54
+ # array.strictly_ascending? => +true+ or +false+
55
55
  #
56
56
  # Check whether _array_ is strictly ascending.
57
57
  def strictly_ascending?
@@ -60,7 +60,7 @@ class Array
60
60
  alias_method :strictly_increasing?, :strictly_ascending?
61
61
 
62
62
  # call-seq:
63
- # array.descending? => true or false
63
+ # array.descending? => +true+ or +false+
64
64
  #
65
65
  # Check whether _array_ is (strictly) descending.
66
66
  def descending?(strict = false)
@@ -69,7 +69,7 @@ class Array
69
69
  alias_method :decreasing?, :descending?
70
70
 
71
71
  # call-seq:
72
- # array.strictly_descending? => true or false
72
+ # array.strictly_descending? => +true+ or +false+
73
73
  #
74
74
  # Check whether _array_ is strictly descending.
75
75
  def strictly_descending?
@@ -28,10 +28,11 @@
28
28
  class Array
29
29
 
30
30
  # call-seq:
31
- # array.only(relax = true or false) => anObject
31
+ # array.only => anObject
32
+ # array.only(+true+) => anObject
32
33
  #
33
34
  # Returns the only element of _array_. Raises an IndexError if _array_'s
34
- # size is not 1, unless +relax+ is true.
35
+ # size is not 1, unless parameter +true+ is passed.
35
36
  #
36
37
  # Idea stolen from Gavin Sinclair's Ruby Extensions Project.
37
38
  def only(relax = size == 1)
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/regression_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::RegressionMixin
5
+ end
@@ -0,0 +1,63 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of ruby-nuggets, some extensions to the Ruby programming #
5
+ # language. #
6
+ # #
7
+ # Copyright (C) 2007-2011 Jens Wille #
8
+ # #
9
+ # Authors: #
10
+ # Jens Wille <jens.wille@uni-koeln.de> #
11
+ # #
12
+ # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
+ # under the terms of the GNU General Public License as published by the Free #
14
+ # Software Foundation; either version 3 of the License, or (at your option) #
15
+ # any later version. #
16
+ # #
17
+ # ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
20
+ # more details. #
21
+ # #
22
+ # You should have received a copy of the GNU General Public License along #
23
+ # with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
24
+ # #
25
+ ###############################################################################
26
+ #++
27
+
28
+ require 'nuggets/array/correlation_mixin'
29
+
30
+ module Nuggets
31
+ class Array
32
+ module RegressionMixin
33
+
34
+ def self.included(base)
35
+ base.send :include, Nuggets::Array::CorrelationMixin
36
+ end
37
+
38
+ # call-seq:
39
+ # array.linear_least_squares => anArray
40
+ #
41
+ # Calculates the {linear least squares regression}[http://en.wikipedia.org/wiki/Ordinary_least_squares]
42
+ # for the <tt>{x,y}</tt> pairs in _array_.
43
+ def linear_least_squares
44
+ sx, sy = 0.0, 0.0
45
+
46
+ return [] if empty?
47
+
48
+ each { |x, y|
49
+ sx += x
50
+ sy += y
51
+ }
52
+
53
+ b = corr * sy / sx
54
+ a = (sy - b * sx) / size.to_f
55
+
56
+ map { |x, _| [x, a + b * x] }
57
+ end
58
+
59
+ alias_method :llsq, :linear_least_squares
60
+
61
+ end
62
+ end
63
+ end
@@ -38,7 +38,7 @@ module Nuggets
38
38
  end
39
39
 
40
40
  # call-seq:
41
- # array.runiq! => an_array or nil
41
+ # array.runiq! => an_array or +nil+
42
42
  #
43
43
  # Reverse #uniq!.
44
44
  def runiq!
@@ -4,7 +4,7 @@
4
4
  # A component of ruby-nuggets, some extensions to the Ruby programming #
5
5
  # language. #
6
6
  # #
7
- # Copyright (C) 2007-2009 Jens Wille #
7
+ # Copyright (C) 2007-2011 Jens Wille #
8
8
  # #
9
9
  # Authors: #
10
10
  # Jens Wille <jens.wille@uni-koeln.de> #
@@ -38,13 +38,10 @@ module Nuggets
38
38
  # call-seq:
39
39
  # array.standard_deviation => aFloat
40
40
  #
41
- # Calculates the standard deviation of the items contained in _array_.
42
- def standard_deviation
43
- begin
44
- Math.sqrt(block_given? ? variance { |*a| yield(*a) } : variance)
45
- rescue Errno::EDOM
46
- 0.0
47
- end
41
+ # Calculates the {standard deviation}[http://en.wikipedia.org/wiki/Standard_deviation]
42
+ # of the values in _array_.
43
+ def standard_deviation(&block)
44
+ Math.sqrt(variance(&block))
48
45
  end
49
46
 
50
47
  alias_method :std, :standard_deviation
@@ -4,7 +4,7 @@
4
4
  # A component of ruby-nuggets, some extensions to the Ruby programming #
5
5
  # language. #
6
6
  # #
7
- # Copyright (C) 2007-2009 Jens Wille #
7
+ # Copyright (C) 2007-2011 Jens Wille #
8
8
  # #
9
9
  # Authors: #
10
10
  # Jens Wille <jens.wille@uni-koeln.de> #
@@ -32,27 +32,46 @@ module Nuggets
32
32
  # call-seq:
33
33
  # array.variance => aFloat
34
34
  #
35
- # Calculates the variance of the items in _array_.
36
- #
37
- # Based on <http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/>.
35
+ # Calculates the variance[http://en.wikipedia.org/wiki/Variance] of the
36
+ # values in _array_.
38
37
  def variance
39
- s, mean = 0.0, 0.0
38
+ sx, sq = 0.0, 0.0
40
39
 
41
- return s if empty?
40
+ return sx if empty?
42
41
 
43
- each_with_index { |x, n|
42
+ each { |x|
44
43
  x = yield x if block_given?
45
44
 
46
- delta = x - mean
47
- mean += delta / (n + 1)
48
- s += delta * (x - mean)
45
+ sx += x
46
+ sq += x ** 2
49
47
  }
50
48
 
51
- s / size
49
+ (sq - sx ** 2 / size) / size
52
50
  end
53
51
 
54
52
  alias_method :var, :variance
55
53
 
54
+ # call-seq:
55
+ # array.covariance => aFloat
56
+ #
57
+ # Calculates the covariance[http://en.wikipedia.org/wiki/Covariance] of the
58
+ # <tt>{x,y}</tt> pairs in _array_.
59
+ def covariance
60
+ sx, sy, sp = 0.0, 0.0, 0.0
61
+
62
+ return sx if empty?
63
+
64
+ each { |x, y|
65
+ sx += x
66
+ sy += y
67
+ sp += x * y
68
+ }
69
+
70
+ (sp - sx * sy / size) / size
71
+ end
72
+
73
+ alias_method :cov, :covariance
74
+
56
75
  end
57
76
  end
58
77
  end
@@ -31,23 +31,23 @@ module Enumerable
31
31
  alias_method :_nuggets_original_any?, :any?
32
32
 
33
33
  # call-seq:
34
- # enum.all?(obj[, operator]) => true or false
35
- # enum.all? { ... } => true or false
34
+ # enum.all?(obj[, operator]) => +true+ or +false+
35
+ # enum.all? { ... } => +true+ or +false+
36
36
  #
37
37
  # Adds the ability to pass an +object+ instead of a block, which will then
38
38
  # be tested against each item in _enum_ according to +operator+, defaulting
39
- # to :===.
39
+ # to <tt>:===</tt>.
40
40
  def all?(object = default = Object.new, operator = :===, &block)
41
41
  _nuggets_original_all?(&_block_for_all_any_extended(object, default, operator, &block))
42
42
  end
43
43
 
44
44
  # call-seq:
45
- # enum.any?(obj[, operator]) => true or false
46
- # enum.any? { ... } => true or false
45
+ # enum.any?(obj[, operator]) => +true+ or +false+
46
+ # enum.any? { ... } => +true+ or +false+
47
47
  #
48
48
  # Adds the ability to pass an +object+ instead of a block, which will then
49
49
  # be tested against each item in _enum_ according to +operator+, defaulting
50
- # to :===.
50
+ # to <tt>:===</tt>.
51
51
  def any?(object = default = Object.new, operator = :===, &block)
52
52
  _nuggets_original_any?(&_block_for_all_any_extended(object, default, operator, &block))
53
53
  end
@@ -85,7 +85,7 @@ module Enumerable
85
85
  # call-seq:
86
86
  # enum.max(what) => aValue
87
87
  #
88
- # Maximum #minmax. If +what+ is omitted, or nil, the original Enumerable#max
88
+ # Maximum #minmax. If +what+ is omitted, or +nil+, the original Enumerable#max
89
89
  # is called.
90
90
  def max(what = nil)
91
91
  what ? minmax(:max, what) : block_given? ?
@@ -95,7 +95,7 @@ module Enumerable
95
95
  # call-seq:
96
96
  # enum.min(what) => aValue
97
97
  #
98
- # Minimum #minmax. If +what+ is omitted, or nil, the original Enumerable#min
98
+ # Minimum #minmax. If +what+ is omitted, or +nil+, the original Enumerable#min
99
99
  # is called.
100
100
  def min(what = nil)
101
101
  what ? minmax(:min, what) : block_given? ?
@@ -30,10 +30,10 @@ module Nuggets
30
30
  module SetMixin
31
31
 
32
32
  # call-seq:
33
- # ENV.set(env = {}, clear = true) => aHash
34
- # ENV.set(env = {}, clear = true) { ... } => anObject
33
+ # ENV.set([env[, clear]]) => aHash
34
+ # ENV.set([env[, clear]]) { ... } => anObject
35
35
  #
36
- # Overrides ENV with +env+, clearing it beforehand if +clear+ is true. If a
36
+ # Overrides ENV with +env+, clearing it beforehand if +clear+ is +true+. If a
37
37
  # block is given, restores ENV to its original state afterwards and returns
38
38
  # the result of the block; otherwise returns the original ENV as a hash.
39
39
  def set(env = {}, clear = true)
@@ -56,7 +56,7 @@ module Nuggets
56
56
  alias_method :without, :set
57
57
 
58
58
  # call-seq:
59
- # ENV.with(env = {}, clear = false) { ... } => anObject
59
+ # ENV.with([env[, clear]]) { ... } => anObject
60
60
  #
61
61
  # Temporarily overrides ENV with +env+ for the block execution. See #set.
62
62
  def with(env = {}, clear = false)
@@ -30,7 +30,7 @@ module Nuggets
30
30
  module UserHomeMixin
31
31
 
32
32
  # call-seq:
33
- # ENV.user_home(default = '/') => aString
33
+ # ENV.user_home([default]) => aString
34
34
  #
35
35
  # Returns the user's home directory, or +default+ if it could not be found.
36
36
  def user_home(default = ::File::ALT_SEPARATOR ? 'C:/' : '/')
@@ -30,13 +30,13 @@ module Nuggets
30
30
  module ReplaceMixin
31
31
 
32
32
  # call-seq:
33
- # File.replace(name, create_if_missing = false) { ... } => aString
34
- # File.replace(name, create_if_missing = false) { |content| ... } => aString
33
+ # File.replace(name[, create_if_missing]) { ... } => aString
34
+ # File.replace(name[, create_if_missing]) { |content| ... } => aString
35
35
  #
36
36
  # Replaces the contents of file +name+ with the result of the block. Yields
37
37
  # the file's contents to the block if requested. Returns the new content.
38
38
  #
39
- # If +create_if_missing+ is true and the file does not exist, it will be
39
+ # If +create_if_missing+ is +true+ and the file does not exist, it will be
40
40
  # created.
41
41
  def replace(name, create_if_missing = false, &block)
42
42
  open(name, create_if_missing && !exist?(name) ? 'w+' : 'r+') { |f|
@@ -47,7 +47,7 @@ module Nuggets
47
47
  end
48
48
 
49
49
  # call-seq:
50
- # File.sub!(name, *args, &block) => aString or nil
50
+ # File.sub!(name, *args, &block) => aString or +nil+
51
51
  #
52
52
  # Calls String#sub! on file +name+'s contents with +args+ and (optional)
53
53
  # +block+ and replaces the file with the new content. Returns the result
@@ -75,7 +75,7 @@ module Nuggets
75
75
  end
76
76
 
77
77
  # call-seq:
78
- # File.gsub!(name, *args, &block) => aString or nil
78
+ # File.gsub!(name, *args, &block) => aString or +nil+
79
79
  #
80
80
  # Calls String#gsub! on file +name+'s contents with +args+ and (optional)
81
81
  # +block+ and replaces the file with the new content. Returns the result
@@ -34,7 +34,7 @@ module Nuggets
34
34
  DEFAULT_EXTENSIONS = [RbConfig::CONFIG['EXEEXT']]
35
35
 
36
36
  # call-seq:
37
- # File.which(executable, extensions = DEFAULT_EXTENSIONS) => aString or nil
37
+ # File.which(executable[, extensions]) => aString or +nil+
38
38
  #
39
39
  # Returns +executable+ if it's executable, or the full path to +executable+
40
40
  # found in PATH, or +nil+ otherwise. Checks +executable+ with each extension
@@ -44,27 +44,28 @@ module Nuggets
44
44
  def which(executable, extensions = DEFAULT_EXTENSIONS)
45
45
  extensions |= ['']
46
46
 
47
- extensions.each { |extension|
48
- executable += extension
49
- return executable if executable?(executable)
47
+ if env = ENV['PATH']
48
+ dirs = env.split(self::PATH_SEPARATOR)
49
+ dirs.map! { |dir| expand_path(dir) }
50
+ end
50
51
 
51
- if path = ENV['PATH']
52
- path.split(::File::PATH_SEPARATOR).each { |dir|
53
- candidate = join(expand_path(dir), executable)
54
- return candidate if executable?(candidate)
55
- }
56
- end
57
- }
52
+ extensions.find { |extension|
53
+ file = "#{executable}#{extension}"
54
+ return file if file?(file) && executable?(file)
58
55
 
59
- nil
56
+ dirs.find { |dir|
57
+ path = join(dir, file)
58
+ return path if file?(path) && executable?(path)
59
+ } if dirs
60
+ }
60
61
  end
61
62
 
62
63
  # call-seq:
63
- # File.which_command(commands) => aString or nil
64
+ # File.which_command(commands) => aString or +nil+
64
65
  #
65
66
  # Returns the first of +commands+ that is executable (according to #which).
66
67
  def which_command(commands, extensions = DEFAULT_EXTENSIONS)
67
- commands.find { |command| which(command[/\S+/], extensions) }
68
+ commands.find { |command| which(command.to_s[/\S+/], extensions) }
68
69
  end
69
70
 
70
71
  end