ruby-nuggets 0.6.9 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/README +1 -1
- data/Rakefile +4 -4
- data/lib/nuggets/array/correlation.rb +5 -0
- data/lib/nuggets/array/correlation_mixin.rb +62 -0
- data/lib/nuggets/array/histogram.rb +5 -0
- data/lib/nuggets/array/histogram_mixin.rb +155 -0
- data/lib/nuggets/array/mean.rb +5 -0
- data/lib/nuggets/array/mean_mixin.rb +139 -0
- data/lib/nuggets/array/median.rb +5 -0
- data/lib/nuggets/array/median_mixin.rb +74 -0
- data/lib/nuggets/array/mode.rb +5 -0
- data/lib/nuggets/array/mode_mixin.rb +70 -0
- data/lib/nuggets/array/monotone.rb +5 -5
- data/lib/nuggets/array/only.rb +3 -2
- data/lib/nuggets/array/regression.rb +5 -0
- data/lib/nuggets/array/regression_mixin.rb +63 -0
- data/lib/nuggets/array/runiq_mixin.rb +1 -1
- data/lib/nuggets/array/standard_deviation_mixin.rb +5 -8
- data/lib/nuggets/array/variance_mixin.rb +30 -11
- data/lib/nuggets/enumerable/all_any_extended.rb +6 -6
- data/lib/nuggets/enumerable/minmax.rb +2 -2
- data/lib/nuggets/env/set_mixin.rb +4 -4
- data/lib/nuggets/env/user_home_mixin.rb +1 -1
- data/lib/nuggets/file/replace_mixin.rb +3 -3
- data/lib/nuggets/file/sub_mixin.rb +2 -2
- data/lib/nuggets/file/which_mixin.rb +15 -14
- data/lib/nuggets/hash/nest_mixin.rb +3 -3
- data/lib/nuggets/hash/only.rb +6 -4
- data/lib/nuggets/hash/unroll_mixin.rb +1 -1
- data/lib/nuggets/io/modes.rb +12 -12
- data/lib/nuggets/numeric/duration.rb +3 -3
- data/lib/nuggets/object/blank_mixin.rb +6 -6
- data/lib/nuggets/object/boolean_mixin.rb +3 -3
- data/lib/nuggets/object/singleton_class_mixin.rb +3 -3
- data/lib/nuggets/range/quantile_mixin.rb +1 -1
- data/lib/nuggets/statistics.rb +11 -0
- data/lib/nuggets/statistics_mixins.rb +11 -0
- data/lib/nuggets/string/case.rb +4 -4
- data/lib/nuggets/string/msub.rb +1 -1
- data/lib/nuggets/string/nsub.rb +2 -2
- data/lib/nuggets/string/sub_with_md.rb +2 -2
- data/lib/nuggets/tempfile/open.rb +1 -1
- data/lib/nuggets/uri/content_type_mixin.rb +1 -1
- data/lib/nuggets/uri/exist_mixin.rb +2 -2
- data/lib/nuggets/util/content_type.rb +1 -1
- data/lib/nuggets/util/i18n.rb +63 -63
- data/lib/nuggets/util/ruby.rb +7 -7
- data/lib/nuggets/version.rb +2 -2
- data/spec/nuggets/array/mean_spec.rb +127 -0
- data/spec/nuggets/array/median_spec.rb +79 -0
- data/spec/nuggets/array/mode_spec.rb +59 -0
- data/spec/nuggets/string/evaluate_spec.rb +2 -2
- metadata +29 -15
@@ -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?
|
data/lib/nuggets/array/only.rb
CHANGED
@@ -28,10 +28,11 @@
|
|
28
28
|
class Array
|
29
29
|
|
30
30
|
# call-seq:
|
31
|
-
# array.only
|
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 +
|
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,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
|
@@ -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-
|
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
|
42
|
-
|
43
|
-
|
44
|
-
|
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-
|
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
|
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
|
-
|
38
|
+
sx, sq = 0.0, 0.0
|
40
39
|
|
41
|
-
return
|
40
|
+
return sx if empty?
|
42
41
|
|
43
|
-
|
42
|
+
each { |x|
|
44
43
|
x = yield x if block_given?
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
s += delta * (x - mean)
|
45
|
+
sx += x
|
46
|
+
sq += x ** 2
|
49
47
|
}
|
50
48
|
|
51
|
-
|
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
|
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
|
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
|
34
|
-
# ENV.set(env
|
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
|
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
|
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
|
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
|
34
|
-
# File.replace(name, create_if_missing
|
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
|
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
|
-
|
48
|
-
|
49
|
-
|
47
|
+
if env = ENV['PATH']
|
48
|
+
dirs = env.split(self::PATH_SEPARATOR)
|
49
|
+
dirs.map! { |dir| expand_path(dir) }
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
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
|