sixarm_ruby_ramp 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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