sixarm_ruby_ramp 2.1.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.
@@ -0,0 +1,397 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'csv'
4
+
5
+ # Array extensions
6
+
7
+ class Array
8
+
9
+
10
+ # Alias join because we're going to override it
11
+
12
+ alias :ruby_join :join
13
+
14
+
15
+ # Concatenate the items into a string by join.
16
+ #
17
+ # @return [String] concatenated string
18
+ #
19
+ # @example Typical Array#join with infix
20
+ # list=['a','b','c']
21
+ # list.join("*") => "a*b*c"
22
+ #
23
+ # @example Improved join with infix, prefix, suffix
24
+ # list=['a','b','c']
25
+ # list.join("*","[","]") => "[a]*[b]*[c]"
26
+ #
27
+ # @example Improved join with just prefix and suffix
28
+ # list=['a','b','c']
29
+ # list.join("[","]") => "[a][b][c]"
30
+
31
+ def join(*fixes)
32
+ if fixes.is_a?(String) then return self.ruby_join(fixes) end
33
+ case fixes.size
34
+ when 0
35
+ return self.ruby_join()
36
+ when 1
37
+ return self.ruby_join(fixes[0])
38
+ when 2
39
+ prefix=fixes[0].to_s
40
+ suffix=fixes[1].to_s
41
+ return self.map{|item| prefix + item.to_s + suffix}.ruby_join()
42
+ when 3
43
+ infix =fixes[0].to_s
44
+ prefix=fixes[1].to_s
45
+ suffix=fixes[2].to_s
46
+ return self.map{|item| prefix + item.to_s + suffix}.ruby_join(infix)
47
+ else
48
+ raise ArgumentError, "join() takes 0-3 arguments; you gave #{fixes.size}]"
49
+ end
50
+ end
51
+
52
+
53
+ # @return [Boolean] true if size > 0
54
+ #
55
+ # @example
56
+ # [1,2,3].size? => true
57
+ # [].size? => false
58
+
59
+ def size?
60
+ return size>0
61
+ end
62
+
63
+
64
+ # Move the first item to the last by using Array#shift and Array#push
65
+ #
66
+ # @example
67
+ # [1,2,3,4].rotate! => [2,3,4,1]
68
+ # ['a','b','c'].rotate! => ['b','c','a']
69
+ # [].rotate! => []
70
+ #
71
+ # @return [Array] self
72
+
73
+ def rotate!
74
+ if size>0
75
+ push item=shift
76
+ end
77
+ self
78
+ end
79
+
80
+
81
+ # @return [Object] a random item from the array
82
+ #
83
+ # @example
84
+ # [1,2,3,4].choice => 2
85
+ # [1,2,3,4].choice => 4
86
+ # [1,2,3,4].choice => 3
87
+ #
88
+ # Implemented in Ruby 1.9
89
+
90
+ def choice
91
+ self[Kernel.rand(size)]
92
+ end
93
+
94
+
95
+ # @return [Array] a new array filled with _count_ calls to choice
96
+ #
97
+ # @example
98
+ # [1,2,3,4].choices(2) => [3,1]
99
+ # [1,2,3,4].choices(3) => [4,2,3]
100
+
101
+ def choices(count)
102
+ arr = Array.new
103
+ count.times { arr << self.choice }
104
+ return arr
105
+ end
106
+
107
+
108
+ # @return [Hash] a hash of this array's items as keys,
109
+ # mapped onto another array's items as values.
110
+ #
111
+ # @example
112
+ # foo=[:a,:b,:c]
113
+ # goo=[:x,:y,:z]
114
+ # foo.onto(goo) => {:a=>:x, :b=>:y, :c=>:z}
115
+ #
116
+ # This is identical to calling foo.zip(values).to_h
117
+
118
+ def onto(values)
119
+ size==values.size or raise ArgumentError, "Array size #{size} must match values size #{size}"
120
+ zip(values).to_h
121
+ end
122
+
123
+
124
+ ##############################################################
125
+ #
126
+ # GROUPINGS
127
+ #
128
+ ##############################################################
129
+
130
+
131
+ # Slice the array.
132
+ #
133
+ # @return [Array<Array<Object>>] items in groups of _n_ items (aka slices)
134
+ #
135
+ # @example
136
+ # [1,2,3,4,5,6,7,8].slices(2) => [[1,2],[3,4],[5,6],[7,8]]
137
+ # [1,2,3,4,5,6,7,8].slices(4) => [[1,2,3,4],[5,6,7,8]]
138
+ #
139
+ # If the slices don't divide evenly, then the last is smaller.
140
+ #
141
+ # @example
142
+ # [1,2,3,4,5,6,7,8].slices(3) => [[1,2,3],[4,5,6],[7,8]]
143
+ # [1,2,3,4,5,6,7,8].slices(5) => [[1,2,3,4,5],[6,7,8]]
144
+
145
+ def slices(slice_length)
146
+ (slice_length.is_a? Integer) or (raise ArgumentError, "slice_length must be an integer")
147
+ (slice_length > 0) or (raise ArgumentError, "slice_length must be > 0")
148
+ arr=[]
149
+ index=0
150
+ while index<length
151
+ arr.push self[index...(index+slice_length)]
152
+ index+=slice_length
153
+ end
154
+ return arr
155
+ end
156
+
157
+
158
+ # Divvy the array, like a pie, into _n_ number of slices.
159
+ #
160
+ # @return [Array<Array<Object>>] items grouped into _n_ slices
161
+ #
162
+ # If the array divides evenly, then each slice has size/n items.
163
+ #
164
+ # Otherwise, divvy makes a best attempt by rounding up to give
165
+ # earlier slices one more item, which makes the last slice smaller:
166
+ #
167
+ # @example
168
+ # [1,2,3,4,5].divvy(2) => [[1,2,3],[4,5]]
169
+ # [1,2,3,4,5,6,7].divvy(3) => [[1,2,3],[4,5,6],[7]]
170
+ #
171
+ # If the array size so small compared to _n_ that there is
172
+ # no mathematical way to _n_ slices, then divvy will return
173
+ # as many slices as it can.
174
+ #
175
+ # @example
176
+ # [1,2,3,4,5,6].divvy(4) => [[1,2],[3,4],[5,6]]
177
+
178
+ def divvy(number_of_slices)
179
+ (number_of_slices.is_a? Integer) or (raise ArgumentError, "number_of_slices must be an integer")
180
+ (number_of_slices > 0) or (raise ArgumentError, "number_of_slices must be > 0")
181
+ return slices((length.to_f/number_of_slices.to_f).ceil)
182
+ end
183
+
184
+
185
+ ##############################################################
186
+ #
187
+ # COMBINATIONS
188
+ #
189
+ ##############################################################
190
+
191
+
192
+ # @return [Array] the union of the array's items.
193
+ #
194
+ # In typical use, each item is an array.
195
+ #
196
+ # @example using Ruby Array pipe
197
+ # arr=[[1,2,3,4],[3,4,5,6]]
198
+ # arr.union => [1,2,3,4,5,6]
199
+ #
200
+ # @example with proc
201
+ # arr.map(&:foo).union
202
+ # => foos that are in any of the array items
203
+ #
204
+ # @example with nil
205
+ # [].union => []
206
+
207
+ def union
208
+ inject{|inj,item| inj | item.to_a } || []
209
+ end
210
+
211
+
212
+ # @return [Array] the intersection of the array's items.
213
+ #
214
+ # In typical usage, each item is an array.
215
+ #
216
+ # @example
217
+ # arr=[[1,2,3,4],[3,4,5,6]]
218
+ # arr.intersect
219
+ # => [3,4]
220
+ #
221
+ # @example with proc
222
+ # arr.map(&:foo).intersect
223
+ # => foos that are in all of the array items
224
+ #
225
+ # @example with nil
226
+ # [].intersect => []
227
+
228
+ def intersect
229
+ inject{|inj,item| inj & item.to_a } || []
230
+ end
231
+
232
+
233
+
234
+ ##############################################################
235
+ #
236
+ # LIST PROCESSING
237
+ #
238
+ ##############################################################
239
+
240
+ # @return [Array] the rest of the items of self, after a shift.
241
+ #
242
+ # @example
243
+ # list=['a','b','c']
244
+ # list.shift => 'a'
245
+ # list.shifted => ['b','c']
246
+ #
247
+ # @example with length
248
+ # list.shifted(0) => ['a','b','c']
249
+ # list.shifted(1) => ['b','c']
250
+ # list.shifted(2) => ['c']
251
+ # list.shifted(3) => []
252
+ #
253
+ # Ruby programmers may prefer this alias wording:
254
+ # list.first => 'a'
255
+ # list.rest => ['b','c']
256
+ #
257
+ # LISP programmers may prefer this alias wording:
258
+ # list.car => 'a'
259
+ # list.cdr => ['b','c']
260
+ #
261
+
262
+ def shifted(number_of_items=1)
263
+ (number_of_items.is_a? Integer) or (raise ArgumentError, "number_of_items must be an integer")
264
+ (number_of_items >= 0) or (raise ArgumentError, "number_of_items must be >= 0")
265
+ slice(number_of_items,self.length-number_of_items)
266
+ end
267
+
268
+ alias :car :first
269
+ alias :cdr :shifted
270
+ alias :rest :shifted
271
+
272
+
273
+ # Delete the first _number_of_items_ items.
274
+ #
275
+ # @return [Array] the array, minus the deleted items.
276
+ #
277
+ # @example
278
+ # list=['a','b','c']
279
+ # list.shifted!
280
+ # list => ['b','c']
281
+ #
282
+ # @example with length:
283
+ # list=['a','b','c']
284
+ # list.shifted!(2)
285
+ # list => ['c']
286
+ #
287
+ # If _n_ is greater than the array size, then return []
288
+
289
+ def shifted!(number_of_items=1)
290
+ (number_of_items.is_a? Integer) or (raise ArgumentError, "number_of_items must be an integer")
291
+ (number_of_items >= 0) or (raise ArgumentError, "number_of_items must be >= 0")
292
+ slice!(0,number_of_items)
293
+ return self
294
+ end
295
+
296
+ alias :cdr! :shifted!
297
+ alias :rest! :shifted!
298
+
299
+
300
+ # Randomly arrange the array items.
301
+ #
302
+ # @return [Array] the array, with its items shuffled.
303
+ #
304
+ # This implementation is optimized for speed, not for memory use.
305
+ # See http://codeidol.com/other/rubyckbk/Arrays/Shuffling-an-Array/
306
+ #
307
+ # @example
308
+ # list=
309
+ # list=['a','b','c']
310
+ # list.shuffle!
311
+ # list => ['c','a','b']
312
+
313
+ def shuffle!
314
+ each_index do |i|
315
+ j = rand(length-i) + i
316
+ self[j], self[i] = self[i], self[j]
317
+ end
318
+ end
319
+
320
+
321
+ # @return [Array] a new array with the items shuffled.
322
+ #
323
+ # This implementation is optimized for speed, not for memory use.
324
+ # See http://codeidol.com/other/rubyckbk/Arrays/Shuffling-an-Array/
325
+ #
326
+ # @example
327
+ # list=
328
+ # list=['a','b','c']
329
+ # list.shuffle!
330
+ # list => ['c','a','b']
331
+
332
+ def shuffle
333
+ dup.shuffle!
334
+ end
335
+
336
+
337
+ ##############################################################
338
+ #
339
+ # CASTS
340
+ #
341
+ ##############################################################
342
+
343
+ # @return [String] a CSV (Comma Separated Value) string of this array.
344
+ #
345
+ # @example of a one-dimensional array
346
+ #
347
+ # [1,2,3].to_csv => "1,2,3\n"
348
+ #
349
+ # @example of a multi-dimensional array
350
+ #
351
+ # [[1,2,3],[4,5,6]] => "1,2,3\n4,5,6\n"
352
+ #
353
+ # @example of a blank array
354
+ #
355
+ # [].to_csv => ""
356
+ #
357
+ # N.b. this method uses the multi-dimensional if the
358
+ # array's first item is also an array.
359
+
360
+ def to_csv(ops={})
361
+
362
+ return "" if size==0
363
+
364
+ generator = RUBY_VERSION >= "1.9" ? CSV : CSV::Writer
365
+
366
+ str=''
367
+ if size>0 and self[0].is_a?Array
368
+ generator.generate(str) do |csv|
369
+ self.each do |row|
370
+ csv << row
371
+ end
372
+ end
373
+ else
374
+ generator.generate(str) do |csv|
375
+ csv << self.map{|item| item.to_s}
376
+ end
377
+ end
378
+ return str
379
+ end
380
+
381
+
382
+ # @return [String] a TSV (Tab Separated Value) string
383
+ # representation of a multi-dimensional array.
384
+ #
385
+ # Each subarray becomes one 'line' in the output.
386
+ #
387
+ # @example of a blank array
388
+ #
389
+ # [].to_csv => ""
390
+
391
+ def to_tsv(ops={})
392
+ self.map{|row| row.join("\t")+"\n"}.join
393
+ end
394
+
395
+ alias to_tdf to_tsv
396
+
397
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Class extensions
4
+
5
+
6
+ class Class
7
+
8
+ # Make all the methods public for a block.
9
+ #
10
+ # This is especially useful for unit testing
11
+ # a class's private and protected methods
12
+ #
13
+ # From http://blog.jayfields.com/2007/11/ruby-testing-private-methods.html
14
+ #
15
+ # @example
16
+ # MyClass.publicize_methods do
17
+ # ...call some method that was private or protected...
18
+ # end
19
+ #
20
+ # @return void
21
+
22
+ def publicize_methods
23
+ saved_private_instance_methods = self.private_instance_methods
24
+ saved_protected_instance_methods = self.protected_instance_methods
25
+ self.class_eval {
26
+ public *saved_private_instance_methods
27
+ public *saved_protected_instance_methods
28
+ }
29
+ yield
30
+ self.class_eval {
31
+ private *saved_private_instance_methods
32
+ protected *saved_protected_instance_methods
33
+ }
34
+ end
35
+
36
+ end
37
+
38
+
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Comma Separated Values extensions
4
+
5
+ class CSV
6
+
7
+ # @return [Hash<String,String>] HTTP headers for a typical CSV file download without caching.
8
+ #
9
+ # ==Options
10
+ # - filename: defaults to "data.csv"
11
+ # - request: the incoming http request, which is used to return MSIE-specific headers
12
+ #
13
+ # @example
14
+ # headers = CSV.http_headers("myfile.csv")
15
+ #
16
+ # @example for Rails
17
+ # response.headers.merge CSV.http_headers("myfile.csv")
18
+ #
19
+ # Ideas from http://stackoverflow.com/questions/94502/in-rails-how-to-return-records-as-a-csv-file/94520
20
+
21
+ def self.http_headers(options={})
22
+ filename = options[:filename] || 'data.csv'
23
+ options=self.http_headers_adjust_for_broken_msie(options)
24
+ content_type = options[:content_type] || 'text/csv'
25
+ return options[:cache] \
26
+ ? {
27
+ 'Content-Type' => content_type,
28
+ 'Content-Disposition' => "attachment; filename=\"#{filename}\"",
29
+ } \
30
+ : {
31
+ 'Content-Type' => content_type,
32
+ 'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
33
+ 'Expires' => "0",
34
+ 'Pragma' => 'no-cache',
35
+ 'Content-Disposition' => "attachment; filename=\"#{filename}\"",
36
+ }
37
+ end
38
+
39
+
40
+ # Helper to try to "do the right thing" for the common case of Rails & MS IE.
41
+ #
42
+ # Rails automatically defines a _request_ object,
43
+ # that has an env HTTP_USER_AGENT.
44
+ #
45
+ # @return [Hash<String,String>] HTTP headers
46
+
47
+ def self.http_headers_adjust_for_broken_msie(options={})
48
+ request = options[:request] || request
49
+ msie = (request and request.env['HTTP_USER_AGENT'] =~ /msie/i)
50
+ if msie
51
+ options[:content_type]||='text/plain'
52
+ options[:cache]||=false
53
+ end
54
+ return options
55
+ end
56
+
57
+ end
58
+
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'date'
4
+
5
+ # Date extensions
6
+
7
+ class Date
8
+
9
+ # @return [Boolean] true if the date is a weekday: Mon, Tue, Wed, Thu, Fri
10
+ #
11
+ # @example
12
+ # d = Date.parse('2008-01-01')
13
+ # d.wday => 2
14
+ # d.weekday? => true
15
+
16
+ def weekday?
17
+ wday>0 and wday<6
18
+ end
19
+
20
+
21
+ # @return [Boolean] true if the date is a weekend: Sat, Sun
22
+ #
23
+ # @example
24
+ # d = Date.parse('2008-01-05')
25
+ # d.wday => 6
26
+ # d.weekend? => true
27
+
28
+ def weekend?
29
+ wday==0 or wday==6
30
+ end
31
+
32
+
33
+ # @return [Date] a random date between min & max
34
+ #
35
+ # @example
36
+ # d1= Date.parse('2008-01-01')
37
+ # d2= Date.parse('2009-01-01')
38
+ # Date.between(d1,d3) => Date 2008-11-22
39
+
40
+ def self.between(min,max)
41
+ min+rand(max-min)
42
+ end
43
+
44
+
45
+ # @return [String] date in a sql format: YYYY-MM-DD
46
+ #
47
+ # @example
48
+ # d=Date.today
49
+ # d.to_sql => "2007-12-31"
50
+
51
+ def to_sql
52
+ return sprintf("%04d-%02d-%02d",year,month,mday)
53
+ end
54
+
55
+ end