sycsvpro 0.2.1 → 0.2.2

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.2.1)
4
+ sycsvpro (0.2.2)
5
5
  gli (= 2.9.0)
6
6
  timeleap (~> 0.0.1)
7
7
 
data/README.md CHANGED
@@ -731,6 +731,15 @@ Version 0.2.1
731
731
  * Dsl module has got 3 new methods #is\_integer?, #is\_float? and #str2num to
732
732
  convert strings that represent numbers to numericals
733
733
 
734
+ Version 0.2.2
735
+ -------------
736
+ * Add the equalize switch to the spread sheet command line
737
+ * Optimize performance of SpreadSheet#write
738
+ * Introduce _r_ and _c_ arguments to SpreadSheet#write to indicate whether the
739
+ row and column labels should be written to the file. Row and column labels are
740
+ written per default for compatibility reasons
741
+ * Catch encoding errors when creating spread sheet from file
742
+
734
743
  Documentation
735
744
  =============
736
745
  The class documentation can be found at
data/bin/sycsvpro CHANGED
@@ -430,6 +430,10 @@ command :spreadsheet do |c|
430
430
  c.arg_name '.|,'
431
431
  c.flag [:ds], default: '.'
432
432
 
433
+ c.desc 'In order to build spread sheets rows have to be of equal size. The '+
434
+ 'e switch equalizes row sizes over all rows'
435
+ c.switch [:e, :equalize], :default_value => false
436
+
433
437
  c.desc 'The arithmetic operation with the table data'
434
438
  c.arg_name 'ARITHMETIC_OPERATION'
435
439
  c.flag [:o, :operation]
@@ -446,6 +450,7 @@ command :spreadsheet do |c|
446
450
  aliases: options[:a],
447
451
  operation: options[:o],
448
452
  ds: options[:ds],
453
+ equalize: options[:e],
449
454
  print: options[:p]).execute
450
455
  print 'done'
451
456
  end
data/lib/sycsvpro/dsl.rb CHANGED
@@ -108,7 +108,7 @@ module Dsl
108
108
 
109
109
  # Remove non-UTF chars from string
110
110
  def str2utf8(str)
111
- str.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
111
+ str.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: EMPTY)
112
112
  end
113
113
 
114
114
  # Retrieves the values scanned by a COMMA_SPLITTER_REGEX
@@ -10,12 +10,13 @@ module Sycsvpro
10
10
  # 1 + na -> na
11
11
  class NotAvailable
12
12
 
13
+ # The string representation of NotAvailable
14
+ NA = "NA"
15
+
13
16
  class << self
14
17
 
15
18
  # Catches all expressions where na is the first argument
16
19
  def method_missing(name, *args, &block)
17
- super if name == :to_ary
18
- super if name == :to_str
19
20
  self
20
21
  end
21
22
 
@@ -25,9 +26,17 @@ module Sycsvpro
25
26
  [self,value]
26
27
  end
27
28
 
29
+ # Checks whether SpreadSheet responds to 'name'. The methods :to_ary and
30
+ # :to_str are excluded
31
+ def respond_to?(name)
32
+ return false if name == :to_ary
33
+ return false if name == :to_str
34
+ super
35
+ end
36
+
28
37
  # Returns NA as the string representation
29
38
  def to_s
30
- "NA"
39
+ NA
31
40
  end
32
41
 
33
42
  end
@@ -82,6 +82,7 @@ module Sycsvpro
82
82
  # values:: flat array with values
83
83
  # rows:: indicates the row count in combination with values param
84
84
  # cols:: indicates the col count in combination with values param
85
+ # equalize:: If columns are of different size equalizes the column size
85
86
  # file:: file that contains values to create spread sheet with
86
87
  # ds:: decimal spearator '.' or ',' where '.' is default. The
87
88
  # decimal separator is used when spread sheet is created from
@@ -325,12 +326,31 @@ module Sycsvpro
325
326
  @col_labels = opts[:cols] if opts[:cols]
326
327
  end
327
328
 
328
- # Writes spread sheet to a file separated with ';'
329
- def write(file)
329
+ # Writes spread sheet to a file separated with ';'. Accepts two boolean
330
+ # arguments to indicate whether the row and column labels should be saved
331
+ # along with the spread sheet's labels
332
+ # r:: when true row labels will be saved, default is true
333
+ # c:: when true column labels will be saved, default is true
334
+ def write(file, opts = {})
335
+ opts = {r: true, c: true}.merge(opts)
336
+
337
+ if opts[:r]
338
+ construct_row = -> row,i { row.insert(0,row_labels[i]).join(SEMICOLON) }
339
+ else
340
+ construct_row = -> row,i { row.join(SEMICOLON) }
341
+ end
342
+
330
343
  File.open(file, 'w') do |out|
331
- out.puts ";#{col_labels.join(';')}"
344
+ if opts[:c]
345
+ if opts[:r]
346
+ out.puts "#{SEMICOLON}#{col_labels.join(SEMICOLON)}"
347
+ else
348
+ out.puts col_labels.join(SEMICOLON)
349
+ end
350
+ end
351
+
332
352
  rows.each_with_index do |row, i|
333
- out.puts "#{row_labels[i]};#{row.join(';')}"
353
+ out.puts construct_row.call row, i
334
354
  end
335
355
  end
336
356
  end
@@ -399,14 +419,13 @@ module Sycsvpro
399
419
  end
400
420
  values.each_slice(col_count) { |row| rows << row }
401
421
  elsif opts[:file]
402
- start_read = Time.now
403
- File.readlines(opts[:file]).each do |line|
422
+ File.foreach(opts[:file]) do |line|
404
423
  next if line.chomp.empty?
405
- rows << line.split(SEMICOLON).collect { |v|
424
+ values = line.split(SEMICOLON) rescue str2utf8(line).split(SEMICOLON)
425
+ rows << values.collect { |v|
406
426
  v.strip.empty? ? NotAvailable : str2num(v.chomp, opts[:ds])
407
427
  }
408
428
  end
409
- STDERR.puts "Reading file in #{Time.now - start_read} seconds"
410
429
  end
411
430
 
412
431
  rows
@@ -435,10 +454,10 @@ module Sycsvpro
435
454
  # * not nil
436
455
  # * at least one row
437
456
  def check_validity_of(rows)
438
- raise "rows need to be arrays" if !rows_are_arrays?(rows)
439
- raise "needs at least one row" if rows.empty?
440
- raise "rows must be of same column size. "+
441
- "Use equalize: true flag to fix." if !same_column_size?(rows)
457
+ raise "rows need to be arrays" if !rows_are_arrays?(rows)
458
+ raise "needs at least one row" if rows.empty?
459
+ raise "rows must be of same column size. Use "+
460
+ "'equalize: true' flag to fix this." if !same_column_size?(rows)
442
461
  end
443
462
 
444
463
  # Checks whether all rows have the same column size. Returns true if
@@ -522,7 +541,8 @@ module Sycsvpro
522
541
  # a spread sheet
523
542
  def process(operator, s)
524
543
  s = coerce(s) || s
525
- raise "operand needs to be a SpreadSheet, Numeric or Array" unless s.is_a?(SpreadSheet)
544
+ raise "operand needs to be a SpreadSheet, "+
545
+ "Numeric or Array" unless s.is_a?(SpreadSheet)
526
546
  result = []
527
547
  rlabel = []
528
548
  clabel = []
@@ -25,23 +25,25 @@ module Sycsvpro
25
25
  # aliases: "a,b",
26
26
  # operation: "(a*b).transpose",
27
27
  # ds: ",",
28
+ # equalize: "true",
28
29
  # print: "true").execute
29
30
  #
30
- # outfile: file where the result of the operation is written to
31
- # files: files that hold the spread sheet data
32
- # r: indication whether the corresponding file has row labels
33
- # c: indication whether the corresponding file has column labels
34
- # aliases: symbols that correspond to the spread sheet created from the
35
- # files. The symbols are used in the operation. The symbols have
36
- # to be choosen carefully not to conflict with existing methods
37
- # and variables
38
- # ds: decimal spearator '.' or ',' where '.' is default
39
- # operation: arithmetic operation on spread sheets using the aliases as
40
- # place holders for the spread sheets. The last evaluated
41
- # operation is returned as result and saved to outfile in case
42
- # the result is a spread sheet. In all other cases the result can
43
- # be printed with the print flag.
44
- # print: print the result
31
+ # outfile:: file where the result of the operation is written to
32
+ # files:: files that hold the spread sheet data
33
+ # r:: indication whether the corresponding file has row labels
34
+ # c:: indication whether the corresponding file has column labels
35
+ # aliases:: symbols that correspond to the spread sheet created from the
36
+ # files. The symbols are used in the operation. The symbols have
37
+ # to be choosen carefully not to conflict with existing methods
38
+ # and variables
39
+ # ds:: decimal spearator '.' or ',' where '.' is default
40
+ # equalize:: indicates whether different column sizes should be equalized
41
+ # operation:: arithmetic operation on spread sheets using the aliases as
42
+ # place holders for the spread sheets. The last evaluated
43
+ # operation is returned as result and saved to outfile in case
44
+ # the result is a spread sheet. In all other cases the result
45
+ # can be printed with the print flag.
46
+ # print:: print the result
45
47
  def initialize(opts = {})
46
48
  @print = opts[:print]
47
49
  @operands = create_operands(opts)
@@ -96,6 +98,7 @@ module Sycsvpro
96
98
  operands = {}
97
99
  opts[:aliases].split(',').each_with_index do |a,i|
98
100
  operands[a] = SpreadSheet.new(file: files[i], ds: opts[:ds],
101
+ equalize: opts[:equalize],
99
102
  r: rlabels[i], c: clabels[i])
100
103
  end
101
104
 
@@ -1,5 +1,5 @@
1
1
  # Operating csv files
2
2
  module Sycsvpro
3
3
  # Version number of sycsvpro
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
@@ -7,8 +7,8 @@ module Sycsvpro
7
7
  # Creation of spread sheets
8
8
  it "should ensure all rows have the same column size" do
9
9
  expect { SpreadSheet.new([1,2], [3,4,5]) }.to raise_error(RuntimeError,
10
- "rows must be of same column size. Use equalize: true "+
11
- "flag to fix.")
10
+ "rows must be of same column size. Use 'equalize: true' "+
11
+ "flag to fix this.")
12
12
  end
13
13
 
14
14
  it "should not accept non arrays as rows" do
@@ -115,6 +115,48 @@ module Sycsvpro
115
115
  Dir.glob(file).size.should eq 1
116
116
  end
117
117
 
118
+ it "should write to file without row labels" do
119
+ file = File.join(File.dirname(__FILE__), "files/spread_sheet_out.csv")
120
+
121
+ s1 = SpreadSheet.new(['A', 'B', 'C'],['I',1,2,3],['II',4,5,6],
122
+ r: true, c: true)
123
+ s1.write(file, r: false)
124
+
125
+ lines = File.readlines(file)
126
+
127
+ content = ["A;B;C\n", "1;2;3\n", "4;5;6\n"]
128
+
129
+ lines.should eq content
130
+ end
131
+
132
+ it "should write to file without column labels" do
133
+ file = File.join(File.dirname(__FILE__), "files/spread_sheet_out.csv")
134
+
135
+ s1 = SpreadSheet.new(['A', 'B', 'C'],['I',1,2,3],['II',4,5,6],
136
+ r: true, c: true)
137
+ s1.write(file, c: false)
138
+
139
+ lines = File.readlines(file)
140
+
141
+ content = ["I;1;2;3\n", "II;4;5;6\n"]
142
+
143
+ lines.should eq content
144
+ end
145
+
146
+ it "should only write data to file" do
147
+ file = File.join(File.dirname(__FILE__), "files/spread_sheet_out.csv")
148
+
149
+ s1 = SpreadSheet.new(['A', 'B', 'C'],['I',1,2,3],['II',4,5,6],
150
+ r: true, c: true)
151
+ s1.write(file, r: false, c: false)
152
+
153
+ lines = File.readlines(file)
154
+
155
+ content = ["1;2;3\n", "4;5;6\n"]
156
+
157
+ lines.should eq content
158
+ end
159
+
118
160
  # Manipulating spread sheets
119
161
 
120
162
  it "should transpose rows and columns" do
data/sycsvpro.rdoc CHANGED
@@ -5,7 +5,7 @@ SYNOPSIS
5
5
  sycsvpro [global options] command [command options] [arguments...]
6
6
 
7
7
  VERSION
8
- 0.2.0
8
+ 0.2.2
9
9
 
10
10
  GLOBAL OPTIONS
11
11
  -f, --file=FILE - CSV file to operate on (default: none)
@@ -20,22 +20,27 @@ COMMANDS
20
20
  analyze - Analyze the CSV file regarding columns, rows and content
21
21
  calc - Process operations on columns. Optionally add a sum row for columns withnumber values
22
22
  collect - Collect values of specified rows and columns from the file and group them in categories
23
- count - Counts the occurences of column values. Uses column values as headings with count as values. Columns with a condition will be added as new columns
24
- and the condition will be set as column name. Optionally adds a sum row
23
+ count - Counts the occurences of column values. Uses column values as headings with count as values.
24
+ Columns with a condition will be added as new columns and the condition will be set as
25
+ column name. Optionally adds a sum row
25
26
  edit - Creates a script/insert file or opens a script/insert file for editing if it exists
26
27
  execute - Executes the code provided in a file
27
28
  extract - Extract specified rows and columns from the file
28
29
  help - Shows a list of commands or help for one command
29
- insert - Inserts rows from a file to a csv-file. You can for instance add sum operations in Excel or LibreOffice style if you want to process the resulting
30
- file in Excel or LibreOffice
30
+ insert - Inserts rows from a file to a csv-file. You can for instance add sum operations in Excel or
31
+ LibreOffice style if you want to process the resulting file in Excel or LibreOffice
31
32
  join - Join two files based on a joint column value
32
- list - Lists script or insert files in the scripts directory with optionally listing methods of script files
33
+ list - Lists script or insert files in the scripts directory with optionally listing methods of
34
+ script files
33
35
  map - Map values in columns to new values
34
- merge - Merge multiple files based on a common column value with a key value at the first column of a row
36
+ merge - Merge multiple files based on a common column value with a key value at the first column of
37
+ a row
35
38
  sort - Sort rows based on column values. It is possible to sort on multiple columns
36
- spreadsheet - Do arithmetic operation with table like data. The table has to have rows with same size. Arithmetic operations are *, /, + and - where the results
37
- can be concatenated. Complete functions can be looked up at https://rubygems.org/gem/sycsvpro
38
- table - Associates columns to a key value. A key value can be a combination of multiple column values. Values associated can be generated from an arithmetic
39
- or string operation. Header columns can be generated dynamically based on column values
39
+ spreadsheet - Do arithmetic operation with table like data. The table has to have rows with same size.
40
+ Arithmetic operations are *, /, + and - where the results can be concatenated. Complete
41
+ functions can be looked up at https://rubygems.org/gem/sycsvpro
42
+ table - Associates columns to a key value. A key value can be a combination of multiple column
43
+ values. Values associated can be generated from an arithmetic or string operation. Header
44
+ columns can be generated dynamically based on column values
40
45
  transpose - Transposes rows and columns
41
46
  unique - Remove duplicate rows from a file. Duplicates are identified by key columns
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.2.1
4
+ version: 0.2.2
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-10-11 00:00:00.000000000 Z
12
+ date: 2014-10-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake