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.
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