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
data/.rspec
CHANGED
data/README
CHANGED
data/Rakefile
CHANGED
@@ -10,10 +10,10 @@ begin
|
|
10
10
|
},
|
11
11
|
|
12
12
|
:gem => {
|
13
|
-
:version
|
14
|
-
:summary
|
15
|
-
:
|
16
|
-
:
|
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,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,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,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,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
|