webget_ruby_ramp 1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/lib/webget_ruby_ramp.rb +250 -0
- data/lib/webget_ruby_ramp/active_record.rb +119 -0
- data/lib/webget_ruby_ramp/active_record/connection_adapters/abstract/schema_statements.rb +24 -0
- data/lib/webget_ruby_ramp/active_record/save_extensions.rb +35 -0
- data/lib/webget_ruby_ramp/array.rb +370 -0
- data/lib/webget_ruby_ramp/csv.rb +53 -0
- data/lib/webget_ruby_ramp/date.rb +90 -0
- data/lib/webget_ruby_ramp/enumerable.rb +385 -0
- data/lib/webget_ruby_ramp/file.rb +15 -0
- data/lib/webget_ruby_ramp/hash.rb +223 -0
- data/lib/webget_ruby_ramp/integer.rb +22 -0
- data/lib/webget_ruby_ramp/io.rb +65 -0
- data/lib/webget_ruby_ramp/kernel.rb +36 -0
- data/lib/webget_ruby_ramp/math.rb +20 -0
- data/lib/webget_ruby_ramp/nil.rb +17 -0
- data/lib/webget_ruby_ramp/numeric.rb +98 -0
- data/lib/webget_ruby_ramp/object.rb +20 -0
- data/lib/webget_ruby_ramp/process.rb +153 -0
- data/lib/webget_ruby_ramp/string.rb +221 -0
- data/lib/webget_ruby_ramp/symbol.rb +11 -0
- data/lib/webget_ruby_ramp/time.rb +11 -0
- data/lib/webget_ruby_ramp/xml.rb +193 -0
- data/lib/webget_ruby_ramp/yaml.rb +34 -0
- data/test/webget_ruby_ramp/active_record/connection_adapters/abstract/schema_statements_test.rb +9 -0
- data/test/webget_ruby_ramp/active_record/save_extensions_test.rb +7 -0
- data/test/webget_ruby_ramp/active_record_test.rb +64 -0
- data/test/webget_ruby_ramp/array_test.rb +171 -0
- data/test/webget_ruby_ramp/csv_test.rb +18 -0
- data/test/webget_ruby_ramp/date_test.rb +60 -0
- data/test/webget_ruby_ramp/enumerable_test.rb +275 -0
- data/test/webget_ruby_ramp/file_test.rb +15 -0
- data/test/webget_ruby_ramp/hash_test.rb +105 -0
- data/test/webget_ruby_ramp/integer_test.rb +19 -0
- data/test/webget_ruby_ramp/io_test.rb +31 -0
- data/test/webget_ruby_ramp/io_test.txt +1 -0
- data/test/webget_ruby_ramp/kernel_test.rb +15 -0
- data/test/webget_ruby_ramp/math_test.rb +17 -0
- data/test/webget_ruby_ramp/nil_test.rb +15 -0
- data/test/webget_ruby_ramp/numeric_test.rb +28 -0
- data/test/webget_ruby_ramp/object_test.rb +12 -0
- data/test/webget_ruby_ramp/process_test.rb +24 -0
- data/test/webget_ruby_ramp/string_test.rb +125 -0
- data/test/webget_ruby_ramp/symbol_test.rb +26 -0
- data/test/webget_ruby_ramp/time_test.rb +12 -0
- data/test/webget_ruby_ramp/xml_test.rb +93 -0
- data/test/webget_ruby_ramp/xml_test_1.xml +5 -0
- data/test/webget_ruby_ramp/xml_test_2.xml +5 -0
- data/test/webget_ruby_ramp/xml_test_msword_clean.html +1 -0
- data/test/webget_ruby_ramp/xml_test_msword_dirty.html +148 -0
- data/test/webget_ruby_ramp/yaml_test.rb +32 -0
- data/test/webget_ruby_ramp/yaml_test_1.yml +38 -0
- data/test/webget_ruby_ramp/yaml_test_2.yml +38 -0
- metadata +128 -0
- metadata.gz.sig +1 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# File extensions
|
2
|
+
|
3
|
+
class File
|
4
|
+
|
5
|
+
# Return File.join(File.dirname(dirname),strings)
|
6
|
+
#
|
7
|
+
# ==Example
|
8
|
+
# File.joindir(__FILE__,'foo.txt')
|
9
|
+
# => '/home/john/foo.txt'
|
10
|
+
|
11
|
+
def File.joindir(dirname,*strings)
|
12
|
+
File.join(File.dirname(dirname),strings)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# Hash extensions
|
4
|
+
|
5
|
+
class Hash
|
6
|
+
|
7
|
+
|
8
|
+
# Return true if size > 0
|
9
|
+
def size?
|
10
|
+
size>0
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# Calls block once for each key in hsh, passing the key and value to the block as a two-element array.
|
15
|
+
#
|
16
|
+
# The keys are sorted.
|
17
|
+
|
18
|
+
def each_sort
|
19
|
+
keys.sort.each{|key| yield key,self[key] }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# Calls block once for each key in hsh,
|
24
|
+
# passing the key as a parameter,
|
25
|
+
# and updating it in place.
|
26
|
+
#
|
27
|
+
# ==Example
|
28
|
+
# h = { "a" => "b", "c" => "d" }
|
29
|
+
# h.each_key! {|key| key.upcase }
|
30
|
+
# h => { "A" => "b", "C" => "d" }
|
31
|
+
#
|
32
|
+
# Return self.
|
33
|
+
|
34
|
+
def each_key!
|
35
|
+
each_pair{|key,value|
|
36
|
+
key2=yield(key)
|
37
|
+
if key===key2
|
38
|
+
#nop
|
39
|
+
else
|
40
|
+
self.delete(key)
|
41
|
+
self[key2]=value
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Calls block once for each key in hsh,
|
48
|
+
# passing the key and value as parameters,
|
49
|
+
# and updated them in place.
|
50
|
+
#
|
51
|
+
# ==Example
|
52
|
+
# h = { "a" => "b", "c" => "d" }
|
53
|
+
# h.each_pair! {|key,value| key.upcase, value.upcase }
|
54
|
+
# h => { "A" => "B", "C" => "D" }
|
55
|
+
#
|
56
|
+
# Return self.
|
57
|
+
|
58
|
+
def each_pair!
|
59
|
+
each_pair{|key,value|
|
60
|
+
key2,value2=yield(key,value)
|
61
|
+
if key===key2
|
62
|
+
if value===value2
|
63
|
+
#nop
|
64
|
+
else
|
65
|
+
self[key]=value2
|
66
|
+
end
|
67
|
+
else
|
68
|
+
self.delete(key)
|
69
|
+
self[key2]=value2
|
70
|
+
end
|
71
|
+
}
|
72
|
+
return self
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Calls block once for each key in hsh,
|
77
|
+
# passing the value as a parameter,
|
78
|
+
# and updating it in place.
|
79
|
+
#
|
80
|
+
# ==Example
|
81
|
+
# h = { "a" => "b", "c" => "d" }
|
82
|
+
# h.each_value! {|value| value.upcase }
|
83
|
+
# h => { "a" => "B", "c" => "d" }
|
84
|
+
#
|
85
|
+
# Return self.
|
86
|
+
|
87
|
+
def each_value!
|
88
|
+
each_pair{|key,value|
|
89
|
+
value2=yield(value)
|
90
|
+
if value===value2
|
91
|
+
#nop
|
92
|
+
else
|
93
|
+
self[key]=yield(value)
|
94
|
+
end
|
95
|
+
}
|
96
|
+
return self
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Calls block once for each key-value pair in hsh,
|
101
|
+
# passing the key and value as paramters to the block.
|
102
|
+
#
|
103
|
+
# ==Example
|
104
|
+
# h = {"a"=>"b", "c"=>"d", "e"=>"f" }
|
105
|
+
# h.map_pair{|key,value| key+value }
|
106
|
+
# => ["ab","cd","ef"]
|
107
|
+
|
108
|
+
def map_pair
|
109
|
+
keys.map{|key| yield key, self[key] }
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# Hash#to_yaml with sort
|
114
|
+
#
|
115
|
+
# From http://snippets.dzone.com/tag/yaml
|
116
|
+
|
117
|
+
def to_yaml_sort( opts = {} )
|
118
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
119
|
+
out.map( taguri, to_yaml_style ) do |map|
|
120
|
+
sort.each do |key, val| # <-- here's my addition (the 'sort')
|
121
|
+
map.add(key, val)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
# Hash#pivot aggregates values for a hash of hashes,
|
129
|
+
# for example to calculate subtotals and groups.
|
130
|
+
#
|
131
|
+
# Suppose you have data arranged by companies, roles, and headcounts.
|
132
|
+
#
|
133
|
+
# data = {
|
134
|
+
# "Apple" => {"Accountants" => 11, "Designers" => 22, "Developers" => 33},
|
135
|
+
# "Goggle" => {"Accountants" => 44, "Designers" => 55, "Developers" => 66},
|
136
|
+
# "Microsoft" => {"Accountants" => 77, "Designers" => 88, "Developers" => 99},
|
137
|
+
# }
|
138
|
+
#
|
139
|
+
# To calculate each company's total headcount, you pivot up, then sum:
|
140
|
+
#
|
141
|
+
# data.pivot(:up,&:sum)
|
142
|
+
# => {
|
143
|
+
# "Apple"=>66,
|
144
|
+
# "Goggle"=>165,
|
145
|
+
# "Microsoft"=>264
|
146
|
+
# }
|
147
|
+
#
|
148
|
+
# To calculate each role's total headcount, you pivot down, then sum:
|
149
|
+
#
|
150
|
+
# data.pivot(:down,&:sum)
|
151
|
+
# => {
|
152
|
+
# "Accountants"=>132,
|
153
|
+
# "Designers"=>165,
|
154
|
+
# "Developers"=>198
|
155
|
+
# }
|
156
|
+
#
|
157
|
+
# Generic xxample:
|
158
|
+
# h={
|
159
|
+
# "a"=>{"x"=>1,"y"=>2,"z"=>3},
|
160
|
+
# "b"=>{"x"=>4,"y"=>5,"z"=>6},
|
161
|
+
# "c"=>{"x"=>7,"y"=>8,"z"=>9},
|
162
|
+
# }
|
163
|
+
# h.pivot(:keys) => {"a"=>[1,2,3],"b"=>[4,5,6],"c"=>[7,8,9]}
|
164
|
+
# h.pivot(:vals) => {"x"=>[1,4,7],"y"=>[2,5,8],"z"=>[3,6,9]}
|
165
|
+
#
|
166
|
+
# = Calculating subtotals
|
167
|
+
#
|
168
|
+
# The pivot method is especially useful for calculating subtotals.
|
169
|
+
#
|
170
|
+
# ==Example
|
171
|
+
# r = h.pivot(:keys)
|
172
|
+
# r['a'].sum => 6
|
173
|
+
# r['b'].sum => 15
|
174
|
+
# r['c'].sum => 24
|
175
|
+
#
|
176
|
+
# ==Example
|
177
|
+
# r=h.pivot(:vals)
|
178
|
+
# r['x'].sum => 12
|
179
|
+
# r['y'].sum => 15
|
180
|
+
# r['z'].sum => 18
|
181
|
+
#
|
182
|
+
# = Block customization
|
183
|
+
#
|
184
|
+
# You can provide a block that will be called for the pivot items.
|
185
|
+
#
|
186
|
+
# ==Examples
|
187
|
+
# h.pivot(:keys){|items| items.max } => {"a"=>3,"b"=>6,"c"=>9}
|
188
|
+
# h.pivot(:keys){|items| items.join("/") } => {"a"=>"1/2/3","b"=>"4/5/6","c"=>"7/8/9"}
|
189
|
+
# h.pivot(:keys){|items| items.inject{|sum,x| sum+=x } } => {"a"=>6,"b"=>15,"c"=>24}
|
190
|
+
#
|
191
|
+
# ==Examples
|
192
|
+
# h.pivot(:vals){|items| items.max } => {"a"=>7,"b"=>8,"c"=>9}
|
193
|
+
# h.pivot(:vals){|items| items.join("-") } => {"a"=>"1-4-7","b"=>"2-5-8","c"=>"3-6-9"}
|
194
|
+
# h.pivot(:vals){|items| items.inject{|sum,x| sum+=x } } => {"a"=>12,"b"=>15,"c"=>18}
|
195
|
+
|
196
|
+
def pivot(direction='keys',&b)
|
197
|
+
a=self.class.new
|
198
|
+
direction=direction.to_s
|
199
|
+
up=pivot_direction_up?(direction)
|
200
|
+
each_pair{|k1,v1|
|
201
|
+
v1.each_pair{|k2,v2|
|
202
|
+
k = up ? k1 : k2
|
203
|
+
a[k]=[] if (a[k]==nil or a[k]=={})
|
204
|
+
a[k]<<(v2)
|
205
|
+
}
|
206
|
+
}
|
207
|
+
if block_given?
|
208
|
+
a.each_pair{|k,v| a[k]=(yield v)}
|
209
|
+
end
|
210
|
+
a
|
211
|
+
end
|
212
|
+
|
213
|
+
protected
|
214
|
+
|
215
|
+
def pivot_direction_up?(direction_name)
|
216
|
+
case direction_name
|
217
|
+
when 'key','keys','up','left','out' then return true
|
218
|
+
when 'val','vals','down','right','in' then return false
|
219
|
+
else raise 'Pivot direction must be either: up/left/out or down/right/in'
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Integer extensions
|
2
|
+
|
3
|
+
class Integer
|
4
|
+
|
5
|
+
# Syntactic sugar to yield n times to a block.
|
6
|
+
#
|
7
|
+
# Return an array of any results.
|
8
|
+
#
|
9
|
+
# ==Example
|
10
|
+
# 3.maps{rand} => [0.0248131784304143, 0.814666170190905, 0.15812816258206]
|
11
|
+
#
|
12
|
+
# ==Parallel to Integer#times
|
13
|
+
#
|
14
|
+
# Integer#maps is similar to Integer#times except that the output from each
|
15
|
+
# call to the block is captured in an array element and that array is
|
16
|
+
# returned to the calling code.
|
17
|
+
|
18
|
+
def maps
|
19
|
+
(0...self).map{|item| yield item}
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# IO extensions
|
2
|
+
|
3
|
+
class IO
|
4
|
+
|
5
|
+
|
6
|
+
# Reads the entire file specified by name as individual lines as with IO#readlines,
|
7
|
+
# and returns those lines in an array of rows, where each row is an array of fields.
|
8
|
+
#
|
9
|
+
# ==Example
|
10
|
+
# IO.readrows("my.tsv")
|
11
|
+
# => [["A1","B1","C1"],["A2","B2","C2"],["A3","B3","C3"]]
|
12
|
+
#
|
13
|
+
# ==Options
|
14
|
+
# - Rows are separated by _row_ option, which defaults to Ruby's record separator $/ or "\n"
|
15
|
+
# - Cols are separated by _col_ option, which defaults to Ruby's string split separator $; or "\t"
|
16
|
+
#
|
17
|
+
# ==Example with options suitable for a file using TSV (Tab Separated Values)
|
18
|
+
# IO.readrows("my.tsv", :row=>"\n", :col=>"\t")
|
19
|
+
#
|
20
|
+
# Note: the col option is sent along to String#split, so can be a string or a regexp.
|
21
|
+
#
|
22
|
+
# See:
|
23
|
+
# - File#readline
|
24
|
+
# - File#readlines
|
25
|
+
# - File#readrow
|
26
|
+
|
27
|
+
def IO.readrows(name, options={})
|
28
|
+
row_sep||=options[:row]||$/||"\n"
|
29
|
+
col_sep||=options[:col]||$;||"\t"
|
30
|
+
return IO.readlines(name, row_sep).map{|line| line.chomp(row_sep).split(col_sep)}
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Read a line as with IO#readline and return the line as a row of fields.
|
35
|
+
#
|
36
|
+
# ==Example
|
37
|
+
# file = File.new("my.tsv")
|
38
|
+
# file.readrow() => ["A1","B1","C1"]
|
39
|
+
# file.readrow() => ["A2","B2","C2"]
|
40
|
+
# file.readrow() => ["A3","B3","C3"]]
|
41
|
+
#
|
42
|
+
# ==Options
|
43
|
+
# - Rows are separated by _row_ option, which defaults to Ruby's record separator $/ or "\n"
|
44
|
+
# - Cols are separated by _col_ option, which defaults to Ruby's string split separator $; or "\t"
|
45
|
+
#
|
46
|
+
# ==Example with options suitable for a file using TSV (Tab Separated Values)
|
47
|
+
# file = File.new("my.tsv")
|
48
|
+
# file.readrow(:row=>"\n", :col=>"\t") => ["A1","B1","C1"]
|
49
|
+
# file.readrow(:row=>"\n", :col=>"\t") => ["A2","B2","C2"]
|
50
|
+
# file.readrow(:row=>"\n", :col=>"\t") => ["A3","B3","C3"]
|
51
|
+
#
|
52
|
+
# Note: the col option is sent along to String#split, so can be a string or a regexp.
|
53
|
+
#
|
54
|
+
# See:
|
55
|
+
# - File#readline
|
56
|
+
# - File#readlines
|
57
|
+
# - File#readrows
|
58
|
+
|
59
|
+
def readrow(options={})
|
60
|
+
row_sep||=options[:row]||$/||"\n"
|
61
|
+
col_sep||=options[:col]||$;||"\t"
|
62
|
+
return readline(row_sep).chomp(row_sep).split(col_sep)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
# Kernel extensions
|
5
|
+
|
6
|
+
module Kernel
|
7
|
+
|
8
|
+
# See:
|
9
|
+
# - http://www.ruby-forum.com/topic/75258
|
10
|
+
# - In 1.9 (Ruby CVS HEAD) there is #__method__ and #__callee__
|
11
|
+
# - http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l90
|
12
|
+
|
13
|
+
def method_name(caller_index=0)
|
14
|
+
# Make this fast because its often doing logging & reporting.
|
15
|
+
# Inline this and use $1 because it's empirically faster than /1
|
16
|
+
caller[caller_index] =~ /`([^']*)'/ and $1
|
17
|
+
end
|
18
|
+
|
19
|
+
# Pretty print to a string.
|
20
|
+
#
|
21
|
+
# Created by Graeme Mathieson.
|
22
|
+
#
|
23
|
+
# See http://rha7dotcom.blogspot.com/2008/07/ruby-and-rails-how-to-get-pp-pretty.html
|
24
|
+
|
25
|
+
def pp_s(*objs)
|
26
|
+
str = StringIO.new
|
27
|
+
objs.each {|obj|
|
28
|
+
PP.pp(obj, str)
|
29
|
+
}
|
30
|
+
str.rewind
|
31
|
+
str.read
|
32
|
+
end
|
33
|
+
module_function :pp_s
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Math extensions
|
2
|
+
|
3
|
+
module Math
|
4
|
+
|
5
|
+
|
6
|
+
# Return the natural log of _num_
|
7
|
+
|
8
|
+
def Math.ln(num)
|
9
|
+
Math.log(num)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
# Return the log of _num_ in base _base_
|
14
|
+
|
15
|
+
def Math.logn(num,base)
|
16
|
+
Math.ln(num)/Math.ln(base)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# Numeric extensions
|
2
|
+
|
3
|
+
class Numeric
|
4
|
+
|
5
|
+
|
6
|
+
# Return 0 if the given flag is any of: nil, false, 0, [], {}
|
7
|
+
#
|
8
|
+
# ==Example
|
9
|
+
# 3.if(true) => 3
|
10
|
+
# 3.if(false) => 0
|
11
|
+
#
|
12
|
+
|
13
|
+
def if(flag)
|
14
|
+
# inline for speed
|
15
|
+
return (flag==nil or flag==false or flag==0 or flag==[] or flag=={}) ? 0 : self
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Return self if flag is nil, false, 0, [], {}; otherwise return 0.
|
20
|
+
#
|
21
|
+
# ==Example
|
22
|
+
# 3.unless(true) => 0
|
23
|
+
# 3.unless(false) => 3
|
24
|
+
|
25
|
+
def unless(flag)
|
26
|
+
# inline for speed
|
27
|
+
return (flag==nil or flag==false or flag==0 or flag==[] or flag=={}) ? self : 0
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
###
|
32
|
+
#
|
33
|
+
# Metric conversions
|
34
|
+
#
|
35
|
+
###
|
36
|
+
|
37
|
+
# Return self / 10^15
|
38
|
+
def peta
|
39
|
+
self/1000000000000000
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return self / 10^12
|
43
|
+
def tera
|
44
|
+
self/1000000000000
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return self / 10^9
|
48
|
+
def giga
|
49
|
+
self/1000000000
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return self / 10^6
|
53
|
+
def mega
|
54
|
+
self/100000
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return self / 10^3
|
58
|
+
def kilo
|
59
|
+
self/1000
|
60
|
+
end
|
61
|
+
|
62
|
+
# Return self / 10^2
|
63
|
+
def hecto
|
64
|
+
self/100
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return self / 10
|
68
|
+
def deka
|
69
|
+
self/10
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return self * 10
|
73
|
+
def deci
|
74
|
+
self*10
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return self * 10^2
|
78
|
+
def centi
|
79
|
+
self*100
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return self * 10^3
|
83
|
+
def milli
|
84
|
+
self*1000
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return self * 10^6
|
88
|
+
def micro
|
89
|
+
self*1000000
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return self * 10^9
|
93
|
+
def nano
|
94
|
+
self*1000000000
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
end
|