nuggets 0.9.9 → 1.0.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 (222) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +663 -0
  3. data/ChangeLog +7 -0
  4. data/README +74 -0
  5. data/Rakefile +50 -0
  6. data/lib/nuggets.rb +73 -0
  7. data/lib/nuggets/all.rb +35 -0
  8. data/lib/nuggets/all_mixins.rb +33 -0
  9. data/lib/nuggets/ansicolor2css.rb +124 -0
  10. data/lib/nuggets/argv/option.rb +3 -0
  11. data/lib/nuggets/argv/option_mixin.rb +84 -0
  12. data/lib/nuggets/array/boost.rb +5 -0
  13. data/lib/nuggets/array/boost_mixin.rb +77 -0
  14. data/lib/nuggets/array/combination.rb +62 -0
  15. data/lib/nuggets/array/correlation.rb +5 -0
  16. data/lib/nuggets/array/correlation_mixin.rb +63 -0
  17. data/lib/nuggets/array/flatten_once.rb +56 -0
  18. data/lib/nuggets/array/flush.rb +5 -0
  19. data/lib/nuggets/array/flush_mixin.rb +46 -0
  20. data/lib/nuggets/array/format.rb +65 -0
  21. data/lib/nuggets/array/hashify.rb +5 -0
  22. data/lib/nuggets/array/hashify_mixin.rb +47 -0
  23. data/lib/nuggets/array/histogram.rb +5 -0
  24. data/lib/nuggets/array/histogram_mixin.rb +169 -0
  25. data/lib/nuggets/array/in_order.rb +50 -0
  26. data/lib/nuggets/array/limit.rb +5 -0
  27. data/lib/nuggets/array/limit_mixin.rb +56 -0
  28. data/lib/nuggets/array/mean.rb +5 -0
  29. data/lib/nuggets/array/mean_mixin.rb +202 -0
  30. data/lib/nuggets/array/median.rb +5 -0
  31. data/lib/nuggets/array/median_mixin.rb +73 -0
  32. data/lib/nuggets/array/mode.rb +5 -0
  33. data/lib/nuggets/array/mode_mixin.rb +69 -0
  34. data/lib/nuggets/array/monotone.rb +83 -0
  35. data/lib/nuggets/array/only.rb +41 -0
  36. data/lib/nuggets/array/rand.rb +44 -0
  37. data/lib/nuggets/array/regression.rb +5 -0
  38. data/lib/nuggets/array/regression_mixin.rb +149 -0
  39. data/lib/nuggets/array/runiq.rb +5 -0
  40. data/lib/nuggets/array/runiq_mixin.rb +52 -0
  41. data/lib/nuggets/array/shuffle.rb +132 -0
  42. data/lib/nuggets/array/standard_deviation.rb +5 -0
  43. data/lib/nuggets/array/standard_deviation_mixin.rb +50 -0
  44. data/lib/nuggets/array/to_hash.rb +64 -0
  45. data/lib/nuggets/array/variance.rb +5 -0
  46. data/lib/nuggets/array/variance_mixin.rb +81 -0
  47. data/lib/nuggets/content_type.rb +97 -0
  48. data/lib/nuggets/dotted_decimal.rb +59 -0
  49. data/lib/nuggets/enumerable/agrep.rb +79 -0
  50. data/lib/nuggets/enumerable/all_any_extended.rb +66 -0
  51. data/lib/nuggets/enumerable/minmax.rb +102 -0
  52. data/lib/nuggets/env/set.rb +3 -0
  53. data/lib/nuggets/env/set_mixin.rb +67 -0
  54. data/lib/nuggets/env/user_encoding.rb +3 -0
  55. data/lib/nuggets/env/user_encoding_mixin.rb +54 -0
  56. data/lib/nuggets/env/user_home.rb +3 -0
  57. data/lib/nuggets/env/user_home_mixin.rb +56 -0
  58. data/lib/nuggets/file/ext.rb +5 -0
  59. data/lib/nuggets/file/ext_mixin.rb +87 -0
  60. data/lib/nuggets/file/replace.rb +5 -0
  61. data/lib/nuggets/file/replace_mixin.rb +55 -0
  62. data/lib/nuggets/file/sub.rb +5 -0
  63. data/lib/nuggets/file/sub_mixin.rb +95 -0
  64. data/lib/nuggets/file/which.rb +5 -0
  65. data/lib/nuggets/file/which_mixin.rb +72 -0
  66. data/lib/nuggets/hash/at.rb +68 -0
  67. data/lib/nuggets/hash/deep_fetch.rb +5 -0
  68. data/lib/nuggets/hash/deep_fetch_mixin.rb +74 -0
  69. data/lib/nuggets/hash/deep_merge.rb +5 -0
  70. data/lib/nuggets/hash/deep_merge_mixin.rb +53 -0
  71. data/lib/nuggets/hash/idmap.rb +5 -0
  72. data/lib/nuggets/hash/idmap_mixin.rb +41 -0
  73. data/lib/nuggets/hash/in_order.rb +43 -0
  74. data/lib/nuggets/hash/insert.rb +53 -0
  75. data/lib/nuggets/hash/nest.rb +5 -0
  76. data/lib/nuggets/hash/nest_mixin.rb +78 -0
  77. data/lib/nuggets/hash/only.rb +52 -0
  78. data/lib/nuggets/hash/seen.rb +5 -0
  79. data/lib/nuggets/hash/seen_mixin.rb +58 -0
  80. data/lib/nuggets/hash/unroll.rb +5 -0
  81. data/lib/nuggets/hash/unroll_mixin.rb +88 -0
  82. data/lib/nuggets/hash/zip.rb +5 -0
  83. data/lib/nuggets/hash/zip_mixin.rb +159 -0
  84. data/lib/nuggets/i18n.rb +155 -0
  85. data/lib/nuggets/integer/factorial.rb +56 -0
  86. data/lib/nuggets/integer/length.rb +5 -0
  87. data/lib/nuggets/integer/length_mixin.rb +49 -0
  88. data/lib/nuggets/integer/map.rb +5 -0
  89. data/lib/nuggets/integer/map_mixin.rb +42 -0
  90. data/lib/nuggets/integer/to_binary_s.rb +38 -0
  91. data/lib/nuggets/io/agrep.rb +43 -0
  92. data/lib/nuggets/io/interact.rb +5 -0
  93. data/lib/nuggets/io/interact_mixin.rb +159 -0
  94. data/lib/nuggets/io/modes.rb +121 -0
  95. data/lib/nuggets/io/null.rb +5 -0
  96. data/lib/nuggets/io/null_mixin.rb +40 -0
  97. data/lib/nuggets/io/redirect.rb +5 -0
  98. data/lib/nuggets/io/redirect_mixin.rb +50 -0
  99. data/lib/nuggets/lazy_attr.rb +44 -0
  100. data/lib/nuggets/log_parser.rb +70 -0
  101. data/lib/nuggets/log_parser/apache.rb +101 -0
  102. data/lib/nuggets/log_parser/rails.rb +219 -0
  103. data/lib/nuggets/net/success.rb +59 -0
  104. data/lib/nuggets/numeric/between.rb +2 -0
  105. data/lib/nuggets/numeric/duration.rb +100 -0
  106. data/lib/nuggets/numeric/limit.rb +62 -0
  107. data/lib/nuggets/numeric/signum.rb +52 -0
  108. data/lib/nuggets/numeric/to_multiple.rb +61 -0
  109. data/lib/nuggets/object/blank.rb +20 -0
  110. data/lib/nuggets/object/blank_mixin.rb +99 -0
  111. data/lib/nuggets/object/boolean.rb +5 -0
  112. data/lib/nuggets/object/boolean_mixin.rb +61 -0
  113. data/lib/nuggets/object/eigenclass.rb +2 -0
  114. data/lib/nuggets/object/ghost_class.rb +2 -0
  115. data/lib/nuggets/object/metaclass.rb +2 -0
  116. data/lib/nuggets/object/msend.rb +5 -0
  117. data/lib/nuggets/object/msend_mixin.rb +43 -0
  118. data/lib/nuggets/object/silence.rb +5 -0
  119. data/lib/nuggets/object/silence_mixin.rb +44 -0
  120. data/lib/nuggets/object/singleton_class.rb +5 -0
  121. data/lib/nuggets/object/singleton_class_mixin.rb +95 -0
  122. data/lib/nuggets/object/uniclass.rb +2 -0
  123. data/lib/nuggets/object/virtual_class.rb +2 -0
  124. data/lib/nuggets/pluggable.rb +91 -0
  125. data/lib/nuggets/proc/bind.rb +5 -0
  126. data/lib/nuggets/proc/bind_mixin.rb +51 -0
  127. data/lib/nuggets/range/quantile.rb +5 -0
  128. data/lib/nuggets/range/quantile_mixin.rb +42 -0
  129. data/lib/nuggets/ruby.rb +235 -0
  130. data/lib/nuggets/statistics.rb +12 -0
  131. data/lib/nuggets/statistics_mixins.rb +12 -0
  132. data/lib/nuggets/string/camelscore.rb +5 -0
  133. data/lib/nuggets/string/camelscore_mixin.rb +116 -0
  134. data/lib/nuggets/string/capitalize_first.rb +46 -0
  135. data/lib/nuggets/string/case.rb +81 -0
  136. data/lib/nuggets/string/evaluate.rb +5 -0
  137. data/lib/nuggets/string/evaluate_mixin.rb +47 -0
  138. data/lib/nuggets/string/msub.rb +84 -0
  139. data/lib/nuggets/string/nsub.rb +65 -0
  140. data/lib/nuggets/string/sub_with_md.rb +111 -0
  141. data/lib/nuggets/string/wc.rb +5 -0
  142. data/lib/nuggets/string/wc_mixin.rb +95 -0
  143. data/lib/nuggets/string/word_wrap.rb +76 -0
  144. data/lib/nuggets/string/xor.rb +5 -0
  145. data/lib/nuggets/string/xor_mixin.rb +59 -0
  146. data/lib/nuggets/tempfile/open.rb +57 -0
  147. data/lib/nuggets/uri/content_type.rb +5 -0
  148. data/lib/nuggets/uri/content_type_mixin.rb +47 -0
  149. data/lib/nuggets/uri/exist.rb +5 -0
  150. data/lib/nuggets/uri/exist_mixin.rb +56 -0
  151. data/lib/nuggets/uri/redirect.rb +5 -0
  152. data/lib/nuggets/uri/redirect_mixin.rb +101 -0
  153. data/lib/nuggets/version.rb +27 -0
  154. data/spec/nuggets/array/boost_spec.rb +50 -0
  155. data/spec/nuggets/array/combination_spec.rb +25 -0
  156. data/spec/nuggets/array/correlation_spec.rb +81 -0
  157. data/spec/nuggets/array/flatten_once_spec.rb +16 -0
  158. data/spec/nuggets/array/flush_spec.rb +43 -0
  159. data/spec/nuggets/array/format_spec.rb +52 -0
  160. data/spec/nuggets/array/hashify_spec.rb +41 -0
  161. data/spec/nuggets/array/histogram_spec.rb +87 -0
  162. data/spec/nuggets/array/in_order_spec.rb +13 -0
  163. data/spec/nuggets/array/limit_spec.rb +62 -0
  164. data/spec/nuggets/array/mean_spec.rb +203 -0
  165. data/spec/nuggets/array/median_spec.rb +77 -0
  166. data/spec/nuggets/array/mode_spec.rb +57 -0
  167. data/spec/nuggets/array/monotone_spec.rb +30 -0
  168. data/spec/nuggets/array/only_spec.rb +26 -0
  169. data/spec/nuggets/array/regression_spec.rb +54 -0
  170. data/spec/nuggets/array/runiq_spec.rb +25 -0
  171. data/spec/nuggets/array/standard_deviation_spec.rb +33 -0
  172. data/spec/nuggets/array/to_hash_spec.rb +28 -0
  173. data/spec/nuggets/array/variance_spec.rb +106 -0
  174. data/spec/nuggets/dotted_decimal_spec.rb +27 -0
  175. data/spec/nuggets/enumerable/all_any_extended_spec.rb +31 -0
  176. data/spec/nuggets/enumerable/minmax_spec.rb +21 -0
  177. data/spec/nuggets/env/set_spec.rb +29 -0
  178. data/spec/nuggets/env/user_encoding_spec.rb +38 -0
  179. data/spec/nuggets/env/user_home_spec.rb +42 -0
  180. data/spec/nuggets/file/ext_spec.rb +38 -0
  181. data/spec/nuggets/file/replace_spec.rb +95 -0
  182. data/spec/nuggets/file/sub_spec.rb +149 -0
  183. data/spec/nuggets/file/which_spec.rb +22 -0
  184. data/spec/nuggets/hash/at_spec.rb +19 -0
  185. data/spec/nuggets/hash/deep_fetch_spec.rb +159 -0
  186. data/spec/nuggets/hash/deep_merge_spec.rb +78 -0
  187. data/spec/nuggets/hash/in_order_spec.rb +12 -0
  188. data/spec/nuggets/hash/insert_spec.rb +13 -0
  189. data/spec/nuggets/hash/nest_spec.rb +102 -0
  190. data/spec/nuggets/hash/only_spec.rb +29 -0
  191. data/spec/nuggets/hash/seen_spec.rb +36 -0
  192. data/spec/nuggets/hash/unroll_spec.rb +68 -0
  193. data/spec/nuggets/i18n_spec.rb +13 -0
  194. data/spec/nuggets/integer/factorial_spec.rb +10 -0
  195. data/spec/nuggets/integer/length_spec.rb +18 -0
  196. data/spec/nuggets/integer/map_spec.rb +19 -0
  197. data/spec/nuggets/integer/to_binary_s_spec.rb +19 -0
  198. data/spec/nuggets/numeric/duration_spec.rb +25 -0
  199. data/spec/nuggets/numeric/limit_spec.rb +16 -0
  200. data/spec/nuggets/numeric/signum_spec.rb +16 -0
  201. data/spec/nuggets/numeric/to_multiple_spec.rb +16 -0
  202. data/spec/nuggets/object/blank_spec.rb +34 -0
  203. data/spec/nuggets/object/boolean_spec.rb +23 -0
  204. data/spec/nuggets/object/msend_spec.rb +25 -0
  205. data/spec/nuggets/object/silence_spec.rb +36 -0
  206. data/spec/nuggets/object/singleton_class_spec.rb +51 -0
  207. data/spec/nuggets/proc/bind_spec.rb +28 -0
  208. data/spec/nuggets/range/quantile_spec.rb +33 -0
  209. data/spec/nuggets/string/camelscore_spec.rb +114 -0
  210. data/spec/nuggets/string/capitalize_first_spec.rb +13 -0
  211. data/spec/nuggets/string/case_spec.rb +31 -0
  212. data/spec/nuggets/string/evaluate_spec.rb +24 -0
  213. data/spec/nuggets/string/msub_spec.rb +20 -0
  214. data/spec/nuggets/string/nsub_spec.rb +13 -0
  215. data/spec/nuggets/string/sub_with_md_spec.rb +25 -0
  216. data/spec/nuggets/string/wc_spec.rb +73 -0
  217. data/spec/nuggets/string/word_wrap_spec.rb +81 -0
  218. data/spec/nuggets/string/xor_spec.rb +57 -0
  219. data/spec/nuggets/uri/content_type_spec.rb +42 -0
  220. data/spec/nuggets/uri/exist_spec.rb +49 -0
  221. data/spec/spec_helper.rb +36 -0
  222. metadata +309 -17
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/median_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::MedianMixin
5
+ end
@@ -0,0 +1,73 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # nuggets -- Extending Ruby #
5
+ # #
6
+ # Copyright (C) 2007-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # nuggets is free software; you can redistribute it and/or modify it under #
12
+ # the terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation; either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with nuggets. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ module Nuggets
28
+ class Array
29
+ module MedianMixin
30
+
31
+ # call-seq:
32
+ # array.median([prefer]) => anObject
33
+ # array.median { |left, right| ... } => anObject
34
+ #
35
+ # Determines the median[http://en.wikipedia.org/wiki/Median] of the values
36
+ # in _array_. _array_ must be sortable.
37
+ #
38
+ # If _array_ contains an even number of values, a block may be passed to
39
+ # decide what the "middle" (average) should be. For Numeric values, the
40
+ # block is optional and the arithmetic mean will be used when no block
41
+ # is passed; for other values, the block is mandatory.
42
+ #
43
+ # Alternatively, +prefer+ may either be set to +true+, 1, or <tt>:left</tt>
44
+ # to use the left "middle", or to +false+, 2, or <tt>:right</tt> to use the
45
+ # right "middle". The block will then be ignored.
46
+ def median(prefer = nil)
47
+ return if empty?
48
+
49
+ sorted, index = sort, (size / 2.0).ceil - 1
50
+
51
+ case prefer
52
+ when true, 1, :left then prefer_left = true
53
+ when false, 2, :right then prefer_right = true
54
+ end
55
+
56
+ middle1 = sorted[index]
57
+ return middle1 if prefer_left || size.odd?
58
+
59
+ middle2 = sorted[index + 1]
60
+ return middle2 if prefer_right
61
+
62
+ unless block_given?
63
+ # simple arithmetic mean
64
+ (middle1 + middle2) / 2.0
65
+ else
66
+ # make your own average
67
+ yield middle1, middle2
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/mode_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::ModeMixin
5
+ end
@@ -0,0 +1,69 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # nuggets -- Extending Ruby #
5
+ # #
6
+ # Copyright (C) 2007-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # nuggets is free software; you can redistribute it and/or modify it under #
12
+ # the terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation; either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with nuggets. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ require 'nuggets/array/histogram_mixin'
28
+
29
+ module Nuggets
30
+ class Array
31
+ module ModeMixin
32
+
33
+ def self.included(base)
34
+ base.send :include, Nuggets::Array::HistogramMixin
35
+ end
36
+
37
+ # call-seq:
38
+ # array.mode => anObject
39
+ # array.mode(+true+) => anArray
40
+ #
41
+ # Returns the mode[http://en.wikipedia.org/wiki/Mode_%28statistics%29] of
42
+ # the values in _array_ (via #histogram).
43
+ #
44
+ # If parameter +true+ is passed, an Array of all modes is returned.
45
+ def mode(all = false, &block)
46
+ hist, modes = histogram(&block), []
47
+ freq = hist.values.max
48
+
49
+ hist.each { |key, value|
50
+ if value == freq
51
+ modes << key
52
+ break unless all
53
+ end
54
+ }
55
+
56
+ all ? modes : modes.first
57
+ end
58
+
59
+ # call-seq:
60
+ # array.modes => anArray
61
+ #
62
+ # Returns an Array of all modes of the values in _array_ (see #mode).
63
+ def modes(&block)
64
+ mode(true, &block)
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,83 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # nuggets -- Extending Ruby #
5
+ # #
6
+ # Copyright (C) 2007-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # nuggets is free software; you can redistribute it and/or modify it under #
12
+ # the terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation; either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with nuggets. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ class Array
28
+
29
+ # call-seq:
30
+ # array.monotone?(operator) => +true+ or +false+
31
+ #
32
+ # Check whether _array_ is monotone according to +operator+.
33
+ def monotone?(operator = nil)
34
+ if [nil, true, false].include?(operator)
35
+ ascending?(operator) || descending?(operator)
36
+ else
37
+ inject { |a, b|
38
+ return false unless a.send(operator, b)
39
+ b
40
+ }
41
+
42
+ true
43
+ end
44
+ end
45
+ alias_method :monotonic?, :monotone?
46
+
47
+ # call-seq:
48
+ # array.ascending? => +true+ or +false+
49
+ #
50
+ # Check whether _array_ is (strictly) ascending.
51
+ def ascending?(strict = false)
52
+ monotone?(strict ? :< : :<=)
53
+ end
54
+ alias_method :increasing?, :ascending?
55
+
56
+ # call-seq:
57
+ # array.strictly_ascending? => +true+ or +false+
58
+ #
59
+ # Check whether _array_ is strictly ascending.
60
+ def strictly_ascending?
61
+ ascending?(true)
62
+ end
63
+ alias_method :strictly_increasing?, :strictly_ascending?
64
+
65
+ # call-seq:
66
+ # array.descending? => +true+ or +false+
67
+ #
68
+ # Check whether _array_ is (strictly) descending.
69
+ def descending?(strict = false)
70
+ monotone?(strict ? :> : :>=)
71
+ end
72
+ alias_method :decreasing?, :descending?
73
+
74
+ # call-seq:
75
+ # array.strictly_descending? => +true+ or +false+
76
+ #
77
+ # Check whether _array_ is strictly descending.
78
+ def strictly_descending?
79
+ descending?(true)
80
+ end
81
+ alias_method :strictly_decreasing?, :strictly_descending?
82
+
83
+ end
@@ -0,0 +1,41 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # nuggets -- Extending Ruby #
5
+ # #
6
+ # Copyright (C) 2007-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # nuggets is free software; you can redistribute it and/or modify it under #
12
+ # the terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation; either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with nuggets. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ class Array
28
+
29
+ # call-seq:
30
+ # array.only => anObject
31
+ # array.only(+true+) => anObject
32
+ #
33
+ # Returns the only element of _array_. Raises an IndexError if _array_'s
34
+ # size is not 1, unless parameter +true+ is passed.
35
+ #
36
+ # Idea stolen from Gavin Sinclair's Ruby Extensions Project.
37
+ def only(relax = size == 1)
38
+ relax ? first : raise(::IndexError, 'not a single-element array')
39
+ end
40
+
41
+ end
@@ -0,0 +1,44 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # nuggets -- Extending Ruby #
5
+ # #
6
+ # Copyright (C) 2007-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # nuggets is free software; you can redistribute it and/or modify it under #
12
+ # the terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation; either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with nuggets. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ class Array
28
+
29
+ # call-seq:
30
+ # array.rand => anItem
31
+ #
32
+ # Randomly pick an item from _array_.
33
+ def rand
34
+ at(::Kernel.rand(size))
35
+ end
36
+
37
+ end
38
+
39
+ if $0 == __FILE__
40
+ a = %w[a b c d]
41
+ p a
42
+ p a.rand
43
+ p a.rand
44
+ end
@@ -0,0 +1,5 @@
1
+ require 'nuggets/array/regression_mixin'
2
+
3
+ class Array
4
+ include Nuggets::Array::RegressionMixin
5
+ end
@@ -0,0 +1,149 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # nuggets -- Extending Ruby #
5
+ # #
6
+ # Copyright (C) 2007-2012 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # nuggets is free software; you can redistribute it and/or modify it under #
12
+ # the terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation; either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # nuggets is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with nuggets. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ module Nuggets
28
+ class Array
29
+ module RegressionMixin
30
+
31
+ # call-seq:
32
+ # array.linear_least_squares => anArray
33
+ #
34
+ # Calculates the {linear least squares regression}[http://en.wikipedia.org/wiki/Simple_linear_regression]
35
+ # for the <tt>{x,y}</tt> pairs in _array_. If _array_ only contains
36
+ # values instead of pairs, +y+ will be the value and +x+ will be each
37
+ # value's position (rank) in _array_.
38
+ def linear_least_squares
39
+ return [] if empty?
40
+
41
+ sx, sy, sq, sp, xys = 0.0, 0.0, 0.0, 0.0, first.respond_to?(:to_ary) ?
42
+ self : self.class.new(size) { |i| [i + 1, at(i)] }
43
+
44
+ xys.each { |x, y| sx += x; sy += y; sq += x ** 2; sp += x * y }
45
+
46
+ b = (v = sq * size - sx ** 2) == 0 ? 0 : (sp * size - sx * sy) / v
47
+ a = (sy - b * sx) / size
48
+
49
+ xys.map { |x, _| [x, a + b * x] }
50
+ end
51
+
52
+ alias_method :llsq, :linear_least_squares
53
+
54
+ # call-seq:
55
+ # array.linear_least_squares_incremental => anIncrementalLinearRegression
56
+ #
57
+ # Returns an instance of IncrementalLinearRegression for _array_; _array_
58
+ # being a list of values (in contrast to #linear_least_squares, which also
59
+ # accepts <tt>{x,y}</tt> pairs). Use IncrementalLinearRegression directly,
60
+ # or apply this method to an empty _array_, for more control over its input
61
+ # data.
62
+ def linear_least_squares_incremental
63
+ IncrementalLinearRegression.new(*self)
64
+ end
65
+
66
+ alias_method :llsqi, :linear_least_squares_incremental
67
+
68
+ # Inspired by {Incremental Simple Linear Regression in Ruby}[http://blog.codewren.ch/post/31378435699].
69
+ #
70
+ # Use #push to add a single <tt>{x,y}</tt> pair, #add to add a list of +y+
71
+ # values, and #<< to add a single +y+ value. Whenever a single +y+ value is
72
+ # added, it's associated with an +x+ value of its position (rank) in the
73
+ # data series.
74
+ #
75
+ # Call #to_a (or any Enumerable method) to work with the regression points.
76
+ class IncrementalLinearRegression
77
+
78
+ include ::Enumerable
79
+
80
+ def initialize(*ys)
81
+ clear
82
+ add(*ys)
83
+ end
84
+
85
+ def clear
86
+ @x = @y = @xx = @xy = 0.0
87
+ @cnt, @slope = 0, nil
88
+ self
89
+ end
90
+
91
+ def push(x, y)
92
+ cnt, @slope = @cnt += 1, nil
93
+
94
+ @x += (x - @x) / cnt
95
+ @y += (y - @y) / cnt
96
+ @xx += (x * x - @xx) / cnt
97
+ @xy += (x * y - @xy) / cnt
98
+
99
+ self
100
+ end
101
+
102
+ def add(*ys)
103
+ ys.each { |y| self << y }
104
+ self
105
+ end
106
+
107
+ def <<(y)
108
+ push(@cnt + 1, y)
109
+ end
110
+
111
+ def slope
112
+ @slope ||= @cnt < 2 ? 0 : (@xy - @x * @y) / (@xx - @x * @x)
113
+ end
114
+
115
+ def intercept
116
+ at(0)
117
+ end
118
+
119
+ def at(x)
120
+ @y + slope * (x - @x)
121
+ end
122
+
123
+ alias_method :[], :at
124
+
125
+ def each
126
+ @cnt.times { |i| yield [x = i + 1, at(x)] }
127
+ self
128
+ end
129
+
130
+ def to_a(range = nil)
131
+ range ? range.map { |x| [x, at(x)] } : super()
132
+ end
133
+
134
+ def to_s
135
+ s, i = slope, intercept
136
+
137
+ y = s == 0 ? i : begin
138
+ x = s.abs == 1 ? "#{'-' if s < 0}x" : "#{s} * x"
139
+ i == 0 ? x : "#{x} #{i < 0 ? '-' : '+'} #{i.abs}"
140
+ end
141
+
142
+ "y := #{y}".gsub(/\.0\b/, '')
143
+ end
144
+
145
+ end
146
+
147
+ end
148
+ end
149
+ end