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 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