sycsvpro 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sycsvpro (0.1.8)
4
+ sycsvpro (0.1.9)
5
5
  gli (= 2.9.0)
6
6
  timeleap (~> 0.0.1)
7
7
 
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
  [![Gem Version](https://badge.fury.io/rb/sycsvpro.png)](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
@@ -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 =~ /^c\d+(?:[=~]{,2}).*$/
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 =~ /^c\d+=~/) ? last_eval : col
46
- header_patterns[i+1] = h if h =~ /^c\d+[=~+-]{1,2}/
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 =~ /^c\d+$/
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 !~ /^c\d+[=~+]{1,2}/ }
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
@@ -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").execute
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]) #options[:key].split(',')
76
- @cols = options[:cols].split(COL_SPLITTER)
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 =~ /^c\d+[=~+]/
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 =~ /^c\d+[=~+]/
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.each_with_index do |col, index|
244
+ header.clear_header_cols.each do |col|
244
245
  line << @sum_row[col] || ""
245
246
  end
246
247
  line.flatten.join(';')
@@ -1,5 +1,5 @@
1
1
  # Operating csv files
2
2
  module Sycsvpro
3
3
  # Version number of sycsvpro
4
- VERSION = '0.1.8'
4
+ VERSION = '0.1.9'
5
5
  end
@@ -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: "SP:+n2 if #{sp_order_type}.index(c1),"+
142
- "RP:+n2 if #{rp_order_type}.index(c1),"+
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: "c1=~/^([A-Z]{1,2})/:+n2,Total:+n2",
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: "c1=~/^([A-Z]{1,2})/:+n2,Total:+n2",
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.8
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-28 00:00:00.000000000 Z
12
+ date: 2014-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake