Class: Sycsvpro::Aggregator

Inherits:
Object
  • Object
show all
Includes:
Dsl
Defined in:
lib/sycsvpro/aggregator.rb

Overview

An Aggregator counts specified row values and adds a sum to the end of the row

in.csv

| Customer | 2013 | 2014 | | A | A1 | | | B | B1 | B16 | | A | A3 | A7 |

out.csv

| Customer | 2013 | 2014 | Sum | | A | 2 | 1 | 3 | | B | 1 | 1 | 2 |

Constant Summary

Constants included from Dsl

Dsl::COMMA_SPLITTER_REGEX

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Dsl

#clean_up, #params, #rows, #split_by_comma_regex, #str2utf8, #unstring, #write_to

Constructor Details

#initialize(options = {}) ⇒ Aggregator

Creates a new aggregator. Takes as attributes infile, outfile, key, rows, cols, date-format and indicator whether to add a sum row :call-seq:

Sycsvpro::Aggregator.new(infile:     "in.csv",
                         outfile:    "out.csv",
                         headerless: false,
                         rows:       "1,2-4,/\S/"
                         cols:       "0,5",
                         df:         "%d.%m.%Y",
                         sum:        "Total:1,Items").execute


62
63
64
65
66
67
68
69
70
71
72
# File 'lib/sycsvpro/aggregator.rb', line 62

def initialize(options={})
  @infile     = options[:infile]
  @outfile    = options[:outfile]
  @headerless = options[:headerless] || false
  @row_filter = RowFilter.new(options[:rows], df: options[:df])
  @col_filter = ColumnFilter.new(options[:cols], df: options[:df])
  @key_values = Hash.new(0)
  @heading    = []
  @sums       = Hash.new(0)
  init_sum_scheme(options[:sum])
end

Instance Attribute Details

#col_filterObject (readonly)

filter that is used for columns



36
37
38
# File 'lib/sycsvpro/aggregator.rb', line 36

def col_filter
  @col_filter
end

#headerlessObject (readonly)

file doesn’t contain a header



32
33
34
# File 'lib/sycsvpro/aggregator.rb', line 32

def headerless
  @headerless
end

#headingObject (readonly)

header of the out file



40
41
42
# File 'lib/sycsvpro/aggregator.rb', line 40

def heading
  @heading
end

#infileObject (readonly)

infile contains the data that is operated on



28
29
30
# File 'lib/sycsvpro/aggregator.rb', line 28

def infile
  @infile
end

#key_valuesObject (readonly)

values that are aggregated



38
39
40
# File 'lib/sycsvpro/aggregator.rb', line 38

def key_values
  @key_values
end

#outfileObject (readonly)

outfile is the file where the result is written to



30
31
32
# File 'lib/sycsvpro/aggregator.rb', line 30

def outfile
  @outfile
end

#row_filterObject (readonly)

filter that is used for rows



34
35
36
# File 'lib/sycsvpro/aggregator.rb', line 34

def row_filter
  @row_filter
end

#sum_colObject (readonly)

column where to add the sum of the row sum



48
49
50
# File 'lib/sycsvpro/aggregator.rb', line 48

def sum_col
  @sum_col
end

#sum_col_titleObject (readonly)

Title of the sum column



46
47
48
# File 'lib/sycsvpro/aggregator.rb', line 46

def sum_col_title
  @sum_col_title
end

#sum_rowObject (readonly)

row where to add the sums of the columns



44
45
46
# File 'lib/sycsvpro/aggregator.rb', line 44

def sum_row
  @sum_row
end

#sum_row_titleObject (readonly)

Title of the sum row



42
43
44
# File 'lib/sycsvpro/aggregator.rb', line 42

def sum_row_title
  @sum_row_title
end

#sumsObject (readonly)

sums of the column values



50
51
52
# File 'lib/sycsvpro/aggregator.rb', line 50

def sums
  @sums
end

Instance Method Details

#executeObject

Executes the aggregator



75
76
77
78
# File 'lib/sycsvpro/aggregator.rb', line 75

def execute
  process_aggregation
  write_result
end

#process_aggregationObject

Process the aggregation of the key values. The result will be written to outfile



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/sycsvpro/aggregator.rb', line 82

def process_aggregation
  File.new(infile).each_with_index do |line, index|
    result = col_filter.process(row_filter.process(line.chomp, row: index))
    unless result.nil? or result.empty?
      if heading.empty? and not headerless
        heading << result.split(';')
        next
      else
        @sum_col = [result.split(';').size, sum_col].max 
      end
      key_values[result]  += 1
      sums[sum_col_title] += 1
    end
  end
  heading.flatten!
  heading[sum_col] = sum_col_title
end

#write_resultObject

Writes the aggration results



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/sycsvpro/aggregator.rb', line 101

def write_result
  sum_line = [sum_row_title]
  (heading.size - 2).times { sum_line << "" }
  sum_line << sums[sum_col_title]
  row = 0;
  File.open(outfile, 'w') do |out|
    out.puts sum_line.join(';') if row == sum_row ; row += 1
    out.puts heading.join(';')
    key_values.each do |k, v|
      out.puts sum_line.join(';') if row == sum_row ; row += 1
      out.puts [k, v].join(';')
    end
  end
end