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
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --colour
2
+ --debug
data/README CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to ruby-nuggets version 0.6.9
5
+ This documentation refers to ruby-nuggets version 0.7.0
6
6
 
7
7
 
8
8
  == DESCRIPTION
data/Rakefile CHANGED
@@ -10,10 +10,10 @@ begin
10
10
  },
11
11
 
12
12
  :gem => {
13
- :version => Nuggets::VERSION,
14
- :summary => 'Some extensions to the Ruby programming language.',
15
- :files => FileList['lib/**/*.rb'].to_a,
16
- :extra_files => FileList['[A-Z]*', '.rspec', 'spec/**/*.rb'].to_a
13
+ :version => Nuggets::VERSION,
14
+ :summary => %q{Some extensions to the Ruby programming language.},
15
+ :author => %q{Jens Wille},
16
+ :email => %q{jens.wille@uni-koeln.de}
17
17
  }
18
18
  }}
19
19
  rescue LoadError => err
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/correlation_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::CorrelationMixin
5
+ end
@@ -0,0 +1,62 @@
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/variance_mixin'
29
+
30
+ module Nuggets
31
+ class Array
32
+ module CorrelationMixin
33
+
34
+ def self.included(base)
35
+ base.send :include, Nuggets::Array::VarianceMixin
36
+ end
37
+
38
+ # call-seq:
39
+ # array.correlation_coefficient => anArray
40
+ #
41
+ # Calculates the {Pearson product-moment correlation
42
+ # coefficient}[http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient]
43
+ # for the <tt>{x,y}</tt> pairs in _array_.
44
+ def correlation_coefficient
45
+ sx, sy = 0.0, 0.0
46
+
47
+ return sx if empty?
48
+
49
+ each { |x, y|
50
+ sx += x
51
+ sy += y
52
+ }
53
+
54
+ (sx * cov) / (sy * var { |x, _| x })
55
+ end
56
+
57
+ alias_method :corr, :correlation_coefficient
58
+ alias_method :pmcc, :correlation_coefficient
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/histogram_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::HistogramMixin
5
+ end
@@ -0,0 +1,155 @@
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
+ module Nuggets
29
+ class Array
30
+ module HistogramMixin
31
+
32
+ # Provides some default formats for #formatted_histogram.
33
+ #
34
+ # Example:
35
+ #
36
+ # (default) ab [==] 2
37
+ # (percent) xyz [===] 3 (37.50%)
38
+ # (numeric) 42 [==] 2
39
+ # (numeric_percent) 123 [=] 1 (12.50%)
40
+ #
41
+ # The "numeric" variants format the item as a (decimal) number.
42
+ FORMATS = {
43
+ :default => '%-*s [%s]%*s %*d',
44
+ :percent => '%-*s [%s]%*s %*d (%.2f%%)',
45
+ :numeric => '%*d [%s]%*s %*d',
46
+ :numeric_percent => '%*d [%s]%*s %*d (%.2f%%)'
47
+ }
48
+
49
+ # Encapsulates a #histogram item and provides the following attributes (see
50
+ # also #annotated_histogram):
51
+ #
52
+ # item:: The original item
53
+ # freq:: The item's frequency in the collection
54
+ # percentage:: The percentage of the item's frequency in the collection
55
+ # max_freq:: The maximum frequency in the collection
56
+ # max_freq_length:: The maximum frequency's "width"
57
+ # max_item_length:: The maximum item length in the collection
58
+ HistogramItem = ::Struct.new(
59
+ :item, :freq, :max_freq, :max_freq_length, :max_item_length, :percentage
60
+ )
61
+
62
+ # call-seq:
63
+ # array.histogram => aHash
64
+ # array.histogram { |x| ... } => aHash
65
+ #
66
+ # Calculates the {frequency histogram}[http://en.wikipedia.org/wiki/Histogram]
67
+ # of the values in _array_. Returns a Hash that maps any value, or the result
68
+ # of the value yielded to the block, to its frequency.
69
+ def histogram
70
+ hist = ::Hash.new(0)
71
+ each { |x| hist[block_given? ? yield(x) : x] += 1 }
72
+ hist
73
+ end
74
+
75
+ # call-seq:
76
+ # array.annotated_histogram => anArray
77
+ # array.annotated_histogram { |hist_item| ... } => aHash
78
+ #
79
+ # Calculates the #histogram for _array_ and yields each histogram item
80
+ # (see HistogramItem) to the block or returns an Array of the histogram
81
+ # items.
82
+ def annotated_histogram
83
+ hist, items = histogram, []
84
+
85
+ percentage = size / 100.0
86
+
87
+ max_freq = hist.values.max
88
+ max_freq_length = max_freq.to_s.length
89
+
90
+ max_item_length = hist.keys.map { |item| item.to_s.length }.max
91
+
92
+ # try to sort the histogram hash
93
+ begin
94
+ hist = hist.sort
95
+ rescue ::ArgumentError
96
+ end
97
+
98
+ hist.each { |item, freq|
99
+ hist_item = HistogramItem.new(
100
+ item, freq, max_freq, max_freq_length, max_item_length, freq / percentage
101
+ )
102
+
103
+ block_given? ? yield(hist_item) : items << hist_item
104
+ }
105
+
106
+ block_given? ? hist : items
107
+ end
108
+
109
+ # call-seq:
110
+ # array.formatted_histogram([format[, indicator]]) => aString
111
+ #
112
+ # Returns the #histogram of _array_ as a formatted String according to
113
+ # +format+, using +indicator+ to draw the frequency bar.
114
+ #
115
+ # +format+ may be a Symbol indicating one of the provided default formats
116
+ # (see FORMATS) or a format String (see Kernel#sprintf) that will receive
117
+ # the following arguments (in order):
118
+ #
119
+ # 1. +max_item_length+ (Integer)
120
+ # 1. +item+ (String)
121
+ # 1. "frequency_bar" (String)
122
+ # 1. "padding" (String)
123
+ # 1. +max_freq_length+ (Integer)
124
+ # 1. +freq+ (Integer)
125
+ # 1. +percentage+ (Float, optional)
126
+ #
127
+ # See HistogramItem for further details on the individual arguments.
128
+ def formatted_histogram(format = :default, indicator = '=')
129
+ format = FORMATS[format] if FORMATS.has_key?(format)
130
+ raise ::TypeError, "String expected, got #{format.class}" unless format.is_a?(::String)
131
+
132
+ include_percentage = format.include?('%%')
133
+ indicator_length = indicator.length
134
+
135
+ lines = []
136
+
137
+ annotated_histogram { |hist|
138
+ arguments = [
139
+ hist.max_item_length, hist.item, # item (padded)
140
+ indicator * hist.freq, # indicator bar
141
+ (hist.max_freq - hist.freq) * indicator_length, '', # indicator padding
142
+ hist.max_freq_length, hist.freq # frequency (padded)
143
+ ]
144
+
145
+ arguments << hist.percentage if include_percentage # percentage (optional)
146
+
147
+ lines << format % arguments
148
+ }
149
+
150
+ lines.join("\n")
151
+ end
152
+
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/mean_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::MeanMixin
5
+ end
@@ -0,0 +1,139 @@
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
+ module Nuggets
29
+ class Array
30
+ module MeanMixin
31
+
32
+ # call-seq:
33
+ # array.generalized_mean(exponent) => aFloat
34
+ # array.generalized_mean(exponent) { |x| ... } => aFloat
35
+ #
36
+ # Calculates the {generalized mean}[http://en.wikipedia.org/wiki/Generalized_mean]
37
+ # of the values in _array_ for +exponent+. Returns the #geometric_mean if
38
+ # +exponent+ is zero.
39
+ #
40
+ # An optional block may be passed to provide a weight for each value.
41
+ # Defaults to 1. Returns +nil+ if the sum of all weights is zero (this
42
+ # includes _array_ being empty).
43
+ def generalized_mean(exponent, &block)
44
+ return geometric_mean(&block) if exponent.zero?
45
+
46
+ total, weights = 0, 0
47
+
48
+ each { |x|
49
+ weight = block ? block[x] : 1
50
+
51
+ total += weight * x ** exponent
52
+ weights += weight
53
+ }
54
+
55
+ (total / weights.to_f) ** (1 / exponent) unless weights.zero?
56
+ end
57
+
58
+ alias_method :power_mean, :generalized_mean
59
+ alias_method :minkowski_mean, :generalized_mean
60
+
61
+ # call-seq:
62
+ # array.arithmetic_mean => aFloat
63
+ # array.arithmetic_mean { |x| ... } => aFloat
64
+ #
65
+ # Calculates the {arithmetic mean}[http://en.wikipedia.org/wiki/Arithmetic_mean]
66
+ # of the values in _array_.
67
+ #
68
+ # An optional block may be passed to provide a weight for each value.
69
+ # Defaults to 1. Returns +nil+ if the sum of all weights is zero (this
70
+ # includes _array_ being empty).
71
+ def arithmetic_mean(&block)
72
+ generalized_mean(1, &block)
73
+ end
74
+
75
+ alias_method :mean, :arithmetic_mean
76
+ alias_method :average, :arithmetic_mean
77
+ alias_method :avg, :arithmetic_mean
78
+
79
+ # call-seq:
80
+ # array.root_mean_square => aFloat
81
+ # array.root_mean_square { |x| ... } => aFloat
82
+ #
83
+ # Calculates the {root mean square}[http://en.wikipedia.org/wiki/Root_mean_square]
84
+ # (quadratic mean) of the values in _array_.
85
+ #
86
+ # An optional block may be passed to provide a weight for each value.
87
+ # Defaults to 1. Returns +nil+ if the sum of all weights is zero (this
88
+ # includes _array_ being empty).
89
+ def root_mean_square(&block)
90
+ generalized_mean(2, &block)
91
+ end
92
+
93
+ alias_method :rms, :root_mean_square
94
+ alias_method :quadratic_mean, :root_mean_square
95
+
96
+ # call-seq:
97
+ # array.harmonic_mean => aFloat
98
+ # array.harmonic_mean { |x| ... } => aFloat
99
+ #
100
+ # Calculates the {harmonic mean}[http://en.wikipedia.org/wiki/Harmonic_mean]
101
+ # of the values in _array_.
102
+ #
103
+ # An optional block may be passed to provide a weight for each value.
104
+ # Defaults to 1. Returns +nil+ if the sum of all weights is zero (this
105
+ # includes _array_ being empty).
106
+ def harmonic_mean(&block)
107
+ generalized_mean(-1, &block)
108
+ end
109
+
110
+ alias_method :harmean, :harmonic_mean
111
+
112
+ # call-seq:
113
+ # array.geometric_mean => aFloat
114
+ # array.geometric_mean { |x| ... } => aFloat
115
+ #
116
+ # Calculates the {geometric mean}[http://en.wikipedia.org/wiki/Geometric_median]
117
+ # of the values in _array_.
118
+ #
119
+ # An optional block may be passed to provide a weight for each value.
120
+ # Defaults to 1. Returns +nil+ if the sum of all weights is zero (this
121
+ # includes _array_ being empty).
122
+ def geometric_mean
123
+ total, weights = 1, 0
124
+
125
+ each { |x|
126
+ weight = block_given? ? yield(x) : 1
127
+
128
+ total *= x ** weight
129
+ weights += weight
130
+ }
131
+
132
+ total ** (1 / weights.to_f) unless weights.zero?
133
+ end
134
+
135
+ alias_method :geomean, :geometric_mean
136
+
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/median_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::MedianMixin
5
+ end
@@ -0,0 +1,74 @@
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
+ module Nuggets
29
+ class Array
30
+ module MedianMixin
31
+
32
+ # call-seq:
33
+ # array.median([prefer]) => anObject
34
+ # array.median { |left, right| ... } => anObject
35
+ #
36
+ # Determines the median[http://en.wikipedia.org/wiki/Median] of the values
37
+ # in _array_. _array_ must be sortable.
38
+ #
39
+ # If _array_ contains an even number of values, a block may be passed to
40
+ # decide what the "middle" (average) should be. For Numeric values, the
41
+ # block is optional and the arithmetic mean will be used when no block
42
+ # is passed; for other values, the block is mandatory.
43
+ #
44
+ # Alternatively, +prefer+ may either be set to +true+, 1, or <tt>:left</tt>
45
+ # to use the left "middle", or to +false+, 2, or <tt>:right</tt> to use the
46
+ # right "middle". The block will then be ignored.
47
+ def median(prefer = nil)
48
+ return if empty?
49
+
50
+ sorted, index = sort, (size / 2.0).ceil - 1
51
+
52
+ case prefer
53
+ when true, 1, :left then prefer_left = true
54
+ when false, 2, :right then prefer_right = true
55
+ end
56
+
57
+ middle1 = sorted[index]
58
+ return middle1 if prefer_left || size.odd?
59
+
60
+ middle2 = sorted[index + 1]
61
+ return middle2 if prefer_right
62
+
63
+ unless block_given?
64
+ # simple arithmetic mean
65
+ (middle1 + middle2) / 2.0
66
+ else
67
+ # make your own average
68
+ yield middle1, middle2
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end