sycsvpro 0.1.8 → 0.1.9
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.
- data/Gemfile.lock +1 -1
- data/README.md +5 -0
- data/bin/sycsvpro +7 -1
- data/lib/sycsvpro/header.rb +14 -6
- data/lib/sycsvpro/table.rb +12 -11
- data/lib/sycsvpro/version.rb +1 -1
- data/spec/sycsvpro/table_spec.rb +94 -4
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -434,6 +434,11 @@ Version 0.1.8
|
|
434
434
|
-------------
|
435
435
|
* Join now can join multiple key values in 1 streak
|
436
436
|
|
437
|
+
Version 0.1.9
|
438
|
+
-------------
|
439
|
+
* When creating columns dynamically they are in arbitrary sequence. You can now
|
440
|
+
provide a switch `sort: "2"` which will sort the header from column 2 on.
|
441
|
+
|
437
442
|
Installation
|
438
443
|
============
|
439
444
|
[](http://badge.fury.io/rb/sycsvpro)
|
data/bin/sycsvpro
CHANGED
@@ -341,6 +341,11 @@ command :table do |c|
|
|
341
341
|
c.arg_name "TOP|EOF:c0=~/\\.(\\d{4})/,Value"
|
342
342
|
c.flag [:s, :sum]
|
343
343
|
|
344
|
+
c.desc 'Indicate whether to sort the headline columns. If so you can specify'+
|
345
|
+
'an index from where on the columns will be sorted.'
|
346
|
+
c.arg_name 'COL_INDEX'
|
347
|
+
c.flag [:sort]
|
348
|
+
|
344
349
|
c.desc 'Format of date values'
|
345
350
|
c.arg_name '%d.%m.%Y|%m/%d/%Y|...'
|
346
351
|
c.flag [:df]
|
@@ -360,7 +365,8 @@ command :table do |c|
|
|
360
365
|
header: options[:h],
|
361
366
|
key: options[:k],
|
362
367
|
cols: options[:c],
|
363
|
-
sum: options[:s]
|
368
|
+
sum: options[:s],
|
369
|
+
sort: options[:sort])
|
364
370
|
table.execute
|
365
371
|
puts "done"
|
366
372
|
end
|
data/lib/sycsvpro/header.rb
CHANGED
@@ -15,12 +15,15 @@ module Sycsvpro
|
|
15
15
|
attr_reader :insert_cols
|
16
16
|
# Positions where to insert the insert_cols
|
17
17
|
attr_reader :positions
|
18
|
+
# Columns position from that on the header will be sorted
|
19
|
+
attr_reader :sort
|
18
20
|
|
19
21
|
# Create a new header
|
20
22
|
def initialize(header, options = {})
|
21
23
|
@header_cols = split_by_comma_regex(header || "")
|
22
24
|
@insert_cols = (options[:insert] || "").split(/,|;/)
|
23
25
|
@positions = options[:pos] || []
|
26
|
+
@sort = options[:sort]
|
24
27
|
end
|
25
28
|
|
26
29
|
def method_missing(id, *args, &block)
|
@@ -37,15 +40,15 @@ module Sycsvpro
|
|
37
40
|
@header_cols[0] = @row_cols
|
38
41
|
else
|
39
42
|
@header_cols.each_with_index do |h,i|
|
40
|
-
if h =~
|
43
|
+
if h =~ /^\(?c\d+(?:[=~]{,2}).*$/
|
41
44
|
if col = eval(h)
|
42
45
|
last_eval = $1
|
43
46
|
unless @header_cols.index(last_eval) || @header_cols.index(col)
|
44
47
|
if values
|
45
|
-
@header_cols[i] = (h =~
|
46
|
-
header_patterns[i+1] = h if h =~
|
48
|
+
@header_cols[i] = (h =~ /^\(?c\d+=~/) ? last_eval : col
|
49
|
+
header_patterns[i+1] = h if h =~ /^\(?c\d+[=~+-.]{1,2}/
|
47
50
|
else
|
48
|
-
@header_cols[i] = col if h =~
|
51
|
+
@header_cols[i] = col if h =~ /^\(?c\d+$/
|
49
52
|
end
|
50
53
|
end
|
51
54
|
end
|
@@ -59,9 +62,14 @@ module Sycsvpro
|
|
59
62
|
to_s
|
60
63
|
end
|
61
64
|
|
62
|
-
# Returns @header_cols without pattern
|
65
|
+
# Returns @header_cols without pattern. Will be sorted if sorted is not nil
|
63
66
|
def clear_header_cols
|
64
|
-
@header_cols.select { |col| col !~
|
67
|
+
clear_header = @header_cols.select { |col| col !~ /^\(?c\d+[=~+]{,2}/ }
|
68
|
+
if @sort
|
69
|
+
clear_header.slice!(0, @sort.to_i) + clear_header.sort
|
70
|
+
else
|
71
|
+
clear_header
|
72
|
+
end
|
65
73
|
end
|
66
74
|
|
67
75
|
# Returns the index of the column
|
data/lib/sycsvpro/table.rb
CHANGED
@@ -23,8 +23,6 @@ module Sycsvpro
|
|
23
23
|
|
24
24
|
include Dsl
|
25
25
|
|
26
|
-
# Regex to split parameters
|
27
|
-
COL_SPLITTER = /,(?=['\w +-]*:)/
|
28
26
|
# infile contains the data that is operated on
|
29
27
|
attr_reader :infile
|
30
28
|
# outfile is the file where the result is written to
|
@@ -52,7 +50,8 @@ module Sycsvpro
|
|
52
50
|
# cols: "Value:+n1,c2+c3:+n1",
|
53
51
|
# nf: "DE",
|
54
52
|
# pr: "2",
|
55
|
-
# sum: "TOP:Value,c2+c3"
|
53
|
+
# sum: "TOP:Value,c2+c3",
|
54
|
+
# sort: "2").execute
|
56
55
|
#
|
57
56
|
# infile:: csv file to operate on
|
58
57
|
# outfile:: csv file with the result
|
@@ -66,17 +65,19 @@ module Sycsvpro
|
|
66
65
|
# key:: Values located at value 0 and subsequent columns
|
67
66
|
# cols:: Values added to columns base on a operation or assignment
|
68
67
|
# sum:: sum row at specified position top or eof
|
68
|
+
# sort:: indicates that the columns have to sorted from index on
|
69
69
|
def initialize(options = {})
|
70
70
|
@infile = options[:infile]
|
71
71
|
@outfile = options[:outfile]
|
72
72
|
@date_format = options[:df] || "%Y-%m-%d"
|
73
73
|
@row_filter = RowFilter.new(options[:rows], df: options[:df])
|
74
|
-
@header = Header.new(options[:header])
|
75
|
-
@keys = split_by_comma_regex(options[:key])
|
76
|
-
@cols = options[:cols]
|
74
|
+
@header = Header.new(options[:header], sort: options[:sort])
|
75
|
+
@keys = split_by_comma_regex(options[:key])
|
76
|
+
@cols = split_by_comma_regex(options[:cols])
|
77
77
|
@number_format = options[:nf] || 'EN'
|
78
78
|
@precision = options[:pr].to_i if options[:pr]
|
79
79
|
prepare_sum_row options[:sum]
|
80
|
+
@sort = options[:sort]
|
80
81
|
@rows = {}
|
81
82
|
end
|
82
83
|
|
@@ -159,7 +160,7 @@ module Sycsvpro
|
|
159
160
|
row = rows[key] || rows[key] = { key: key, cols: Hash.new(0) }
|
160
161
|
@cols.each do |col|
|
161
162
|
column, formula = col.split(':')
|
162
|
-
column = evaluate(column) if column =~
|
163
|
+
column = evaluate(column) if column =~ /^\(?c\d+[=~+.]/
|
163
164
|
previous_value = row[:cols][column]
|
164
165
|
if value = eval("#{row[:cols][column]}#{formula}")
|
165
166
|
row[:cols][column] = @precision ? value.round(@precision) : value
|
@@ -204,7 +205,7 @@ module Sycsvpro
|
|
204
205
|
def evaluate(formula, fail_result = 0)
|
205
206
|
if value = eval(formula)
|
206
207
|
last_match = $1
|
207
|
-
(formula =~ /^c\d+=~/) ? last_match : value
|
208
|
+
(formula =~ /^c\(?\d+=~/) ? last_match : value
|
208
209
|
else
|
209
210
|
fail_result
|
210
211
|
end
|
@@ -214,7 +215,7 @@ module Sycsvpro
|
|
214
215
|
# provided sum option
|
215
216
|
def prepare_sum_row(pattern)
|
216
217
|
return if pattern.nil? || pattern.empty?
|
217
|
-
@sum_row_pos, sum_row_pattern = pattern.split(
|
218
|
+
@sum_row_pos, sum_row_pattern = pattern.split(/(?<=^top|^eof):/i)
|
218
219
|
@sum_row_pos.upcase!
|
219
220
|
@sum_row = Hash.new
|
220
221
|
@sum_row_patterns = split_by_comma_regex(sum_row_pattern)
|
@@ -224,7 +225,7 @@ module Sycsvpro
|
|
224
225
|
def add_to_sum_row(value, column)
|
225
226
|
return unless @sum_row_patterns
|
226
227
|
@sum_row_patterns.each do |pattern|
|
227
|
-
if pattern =~
|
228
|
+
if pattern =~ /^\(?c\d+[=~+.]/
|
228
229
|
header_column = evaluate(pattern, "")
|
229
230
|
else
|
230
231
|
header_column = pattern
|
@@ -240,7 +241,7 @@ module Sycsvpro
|
|
240
241
|
# Creates the sum_row when the file has been completely processed
|
241
242
|
def create_sum_row
|
242
243
|
line = []
|
243
|
-
header.clear_header_cols.
|
244
|
+
header.clear_header_cols.each do |col|
|
244
245
|
line << @sum_row[col] || ""
|
245
246
|
end
|
246
247
|
line.flatten.join(';')
|
data/lib/sycsvpro/version.rb
CHANGED
data/spec/sycsvpro/table_spec.rb
CHANGED
@@ -7,6 +7,8 @@ module Sycsvpro
|
|
7
7
|
@in_file = File.join(File.dirname(__FILE__), "files/table.csv")
|
8
8
|
@in_file_revenues = File.join(File.dirname(__FILE__),
|
9
9
|
"files/table_revenues.csv")
|
10
|
+
@in_file_orders = File.join(File.dirname(__FILE__),
|
11
|
+
"files/customer_orders.csv")
|
10
12
|
@out_file = File.join(File.dirname(__FILE__), "files/out.csv")
|
11
13
|
end
|
12
14
|
|
@@ -138,8 +140,8 @@ module Sycsvpro
|
|
138
140
|
outfile: @out_file,
|
139
141
|
header: "Year,SP,RP,Total",
|
140
142
|
key: "c0=~/\\.(\\d{4})/",
|
141
|
-
cols: "
|
142
|
-
"
|
143
|
+
cols: "BEGINSP:+n2 if #{sp_order_type}.index(c1)END,"+
|
144
|
+
"BEGINRP:+n2 if #{rp_order_type}.index(c1)END,"+
|
143
145
|
"Total:+n2",
|
144
146
|
nf: "DE",
|
145
147
|
pr: "2",
|
@@ -166,7 +168,7 @@ module Sycsvpro
|
|
166
168
|
outfile: @out_file,
|
167
169
|
header: "Year,BEGINc1=~/^([A-Z]{1,2})/END,Total",
|
168
170
|
key: "c0=~/\\.(\\d{4})/",
|
169
|
-
cols: "
|
171
|
+
cols: "BEGINc1=~/^([A-Z]{1,2})/:+n2END,Total:+n2",
|
170
172
|
nf: "DE",
|
171
173
|
pr: 2,
|
172
174
|
sum: "top:BEGINc1=~/^([A-Z]{1,2})/END,Total").execute
|
@@ -193,7 +195,7 @@ module Sycsvpro
|
|
193
195
|
outfile: @out_file,
|
194
196
|
header: "Year,BEGINc1=~/^([A-Z]{1,2})/END,Total",
|
195
197
|
key: "BEGINc0=~/\\d+\\.\\d+\\.(\\d{2,3})/END",
|
196
|
-
cols: "
|
198
|
+
cols: "BEGINc1=~/^([A-Z]{1,2})/:+n2END,Total:+n2",
|
197
199
|
nf: "DE",
|
198
200
|
sum: "top:BEGINc1=~/^([A-Z]{1,2})/END,Total").execute
|
199
201
|
|
@@ -236,6 +238,94 @@ module Sycsvpro
|
|
236
238
|
rows.should eq result.size
|
237
239
|
end
|
238
240
|
|
241
|
+
it "should create columns from regex scan and string interpolation" do
|
242
|
+
rp_order_type = %w{ ZRN ZRK }
|
243
|
+
sp_order_type = %w{ ZE ZEI ZO ZOI ZG ZGNT ZRE ZGUP }
|
244
|
+
order_type = sp_order_type + rp_order_type
|
245
|
+
|
246
|
+
header = "c3,c4,"+
|
247
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
248
|
+
"'-SP-R'END,"+
|
249
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
250
|
+
"'-RP-R'END,"+
|
251
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
252
|
+
"'-R'END,"+
|
253
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
254
|
+
"'-SP-O'END,"+
|
255
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
256
|
+
"'-RP-O'END,"+
|
257
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
258
|
+
"'-O'END"
|
259
|
+
|
260
|
+
cols = "BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
261
|
+
"'-SP-R':+n2 if #{sp_order_type}.index(c1)END,"+
|
262
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
263
|
+
"'-RP-R':+n2 if #{rp_order_type}.index(c1)END,"+
|
264
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
265
|
+
"'-R':+n2 if #{order_type}.index(c1)END,"+
|
266
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
267
|
+
"'-SP-O':+1 if #{sp_order_type}.index(c1)END,"+
|
268
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
269
|
+
"'-RP-O':+1 if #{rp_order_type}.index(c1)END,"+
|
270
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
271
|
+
"'-O':+1 if #{order_type}.index(c1)END"
|
272
|
+
|
273
|
+
sum = "BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
274
|
+
"'-SP-R'END,"+
|
275
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
276
|
+
"'-RP-R'END,"+
|
277
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
278
|
+
"'-R'END,"+
|
279
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
280
|
+
"'-SP-O'END,"+
|
281
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
282
|
+
"'-RP-O'END,"+
|
283
|
+
"BEGIN(c0.scan(/\\d+\\.\\d+\\.(\\d{4})/).flatten[0]||'')+"+
|
284
|
+
"'-O'END"
|
285
|
+
|
286
|
+
Sycsvpro::Table.new(infile: @in_file_orders,
|
287
|
+
outfile: @out_file,
|
288
|
+
header: header,
|
289
|
+
key: "c3,c4",
|
290
|
+
cols: cols,
|
291
|
+
nf: "DE",
|
292
|
+
sum: "top:#{sum}",
|
293
|
+
sort: "2").execute
|
294
|
+
|
295
|
+
result = [ "Customer;Customer-ID;2010-O;2010-R;"+
|
296
|
+
"2010-RP-O;2010-RP-R;"+
|
297
|
+
"2010-SP-O;2010-SP-R;"+
|
298
|
+
"2011-O;2011-R;"+
|
299
|
+
"2011-RP-O;2011-RP-R;"+
|
300
|
+
"2011-SP-O;2011-SP-R;"+
|
301
|
+
"2012-O;2012-R;"+
|
302
|
+
"2012-RP-O;2012-RP-R;"+
|
303
|
+
"2012-SP-O;2012-SP-R;"+
|
304
|
+
"2013-O;2013-R;"+
|
305
|
+
"2013-RP-O;2013-RP-R;"+
|
306
|
+
"2013-SP-O;2013-SP-R;"+
|
307
|
+
"2014-O;2014-R;"+
|
308
|
+
"2014-RP-O;2014-RP-R;"+
|
309
|
+
"2014-SP-O;2014-SP-R",
|
310
|
+
";;1;50.0;;;1;50.0;2;300.5;;;2;300.5;1;300.0;1;300.0;;;1;"+
|
311
|
+
"400.0;1;400.0;;;1;150.0;;;1;150.0",
|
312
|
+
"Hank;123;0;0;0;0;0;0;1;100.0;0;0;1;100.0;1;300.0;1;300.0;"+
|
313
|
+
"0;0;0;0;0;0;0;0;0;0;0;0;0;0",
|
314
|
+
"Mia;234;0;0;0;0;0;0;1;200.5;0;0;1;200.5;0;0;0;0;0;0;1;400.0;"+
|
315
|
+
"1;400.0;0;0;1;150.0;0;0;1;150.0",
|
316
|
+
"Ria;333;1;50.0;0;0;1;50.0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;"+
|
317
|
+
"0;0;0;0;0;0;0;0" ]
|
318
|
+
|
319
|
+
rows = 0
|
320
|
+
|
321
|
+
File.open(@out_file).each_with_index do |line, index|
|
322
|
+
line.chomp.should eq result[index]
|
323
|
+
rows += 1
|
324
|
+
end
|
325
|
+
|
326
|
+
rows.should eq result.size
|
327
|
+
end
|
328
|
+
|
239
329
|
end
|
240
330
|
|
241
331
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sycsvpro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-06-
|
12
|
+
date: 2014-06-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|