ibge 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80232f32e1ca3fe301c1abfe7a5a87981df49c71
4
- data.tar.gz: bc5e203e2309aa62d263418a9b5d4fec2807b60e
3
+ metadata.gz: 6ed56fa3c4b240472a91542f75c8a216f78ce28c
4
+ data.tar.gz: 9e49eb09876bbd6c12d1ae6778303b227c7ca68d
5
5
  SHA512:
6
- metadata.gz: d51d20081b0f09a6096f3f881d77bb6468528fbf604a85c9ff042390abc875ca3d4921ea046e26ac4e0d6d5d73986ef6b9a93e87377211c1b7744ce9898231f8
7
- data.tar.gz: 9c5c550044bd2d2cff27b079b97ec40d1ef4056ef48419b8e707e62f9cc2057ec857e4d9cdd3df1531d048f8e8049fe24b2312a62a56b8dcc1734157e46787a2
6
+ metadata.gz: 95c9383f0d6f2cdc4c8a79a7847159408ab6f1acad4e92027f8bcf41837d5a23efc6cb878c619c7a1ed6ec3160372a81d24f326e3372bde43b290293e4a0119c
7
+ data.tar.gz: 23cb3405ae6b2be14e7cd5c0afad076947b445fe62341b6c778322ae9bd05ba77cd23a5007fc361c59162c833ae9fd5e27359be1299addf37296162e7523767a
data/lib/ibge.rb CHANGED
@@ -6,13 +6,14 @@ module Ibge
6
6
  DATA_PATH = File.expand_path(File.join(__dir__, '..', 'data'))
7
7
 
8
8
  module Reader
9
- autoload :Base, 'ibge/reader/base'
10
- autoload :State, 'ibge/reader/state'
11
- autoload :MesoRegion, 'ibge/reader/meso_region'
12
- autoload :MicroRegion, 'ibge/reader/micro_region'
13
- autoload :Municipality, 'ibge/reader/municipality'
14
- autoload :District, 'ibge/reader/district'
15
- autoload :SubDistrict, 'ibge/reader/sub_district'
16
- autoload :Neighborhood, 'ibge/reader/neighborhood'
9
+ autoload :Helpers, "ibge/reader/helpers"
10
+ autoload :Base, "ibge/reader/base"
11
+ autoload :State, "ibge/reader/state"
12
+ autoload :MesoRegion, "ibge/reader/meso_region"
13
+ autoload :MicroRegion, "ibge/reader/micro_region"
14
+ autoload :Municipality, "ibge/reader/municipality"
15
+ autoload :District, "ibge/reader/district"
16
+ autoload :SubDistrict, "ibge/reader/sub_district"
17
+ autoload :Neighborhood, "ibge/reader/neighborhood"
17
18
  end
18
19
  end
@@ -3,30 +3,7 @@ require 'spreadsheet'
3
3
  module Ibge
4
4
  module Reader
5
5
  class Base
6
- class << self
7
- SOURCES = {
8
- dtb: 'DTB_2014_subdistrito.xls',
9
- sidra: 'sidra.xls'
10
- }
11
-
12
- attr_reader :defined_columns, :selected_source
13
-
14
- def columns(columns = {})
15
- @defined_columns = columns
16
- end
17
-
18
- def source(selected_source = :dtb)
19
- unless SOURCES.keys.include?(selected_source)
20
- raise ArgumentError, "Source must be one of those '#{SOURCES.keys.flatten.join(', ')}'"
21
- end
22
-
23
- @selected_source = selected_source
24
- end
25
-
26
- def sources
27
- SOURCES
28
- end
29
- end
6
+ extend Ibge::Reader::Helpers
30
7
 
31
8
  attr_reader :filename
32
9
 
@@ -35,37 +12,102 @@ module Ibge
35
12
  end
36
13
 
37
14
  def initialize(options = {})
38
- @filename = options.fetch(:filename, default_filename)
15
+ @spreadsheet = {}
16
+ @rows = {}
17
+ @selected_sheet = {}
18
+
19
+ self.selected_source = self.class.selected_source
20
+
21
+ unless options.fetch(:filename, nil).nil?
22
+ filename = options.fetch(:filename)
23
+
24
+ if filename.is_a?(Hash)
25
+ sources_filename = options.fetch(:filename).keys
26
+
27
+ sources_filename.each do |source_filename|
28
+ self.class.valid_informed_source(source_filename)
29
+ end
30
+ else
31
+ raise ArgumentError,
32
+ "Filename must be a hash with the source as key"
33
+ end
34
+ end
35
+
36
+ default_filename = default_filename_to(selected_source)
37
+
38
+ @filename = options.fetch(:filename, "#{DATA_PATH}/#{default_filename}")
39
39
  end
40
40
 
41
41
  def read
42
- transformed_rows = rows[1..-1].map do |row|
43
- transform(row.compact.values_at(*column_range), column_range)
42
+ transformed_rows = []
43
+ previous_column_range = nil
44
+
45
+ if multiple_sources?
46
+ loaded_sources = defined_columns.keys.sort
47
+
48
+ loaded_sources.each do |loaded_source|
49
+ self.selected_source = loaded_source
50
+ @filename = default_filename_to(loaded_source)
51
+
52
+ if transformed_rows == []
53
+ transformed_rows = rows[1..-1].map do |row|
54
+ transform(row.compact.values_at(*column_range), column_range)
55
+ end
56
+
57
+ transformed_rows = transformed_rows.uniq
58
+
59
+ previous_column_range = column_range
60
+ else
61
+ transformed_rows.each do |transformed_row|
62
+ selected_rows = rows[1..-1].select do |r|
63
+ r[previous_column_range.first] == transformed_row.values.first
64
+ end
65
+
66
+ new_row = selected_rows.compact.uniq { |r| r[0] }.map do |row|
67
+ transform(row.compact.values_at(*column_range), column_range)
68
+ end
69
+
70
+ if new_row.empty?
71
+ columns = self.class.defined_columns[selected_source]
72
+
73
+ columns.each do |column|
74
+ new_row << { column[1] => "" }
75
+ end
76
+ end
77
+
78
+ transformed_row.merge!(*new_row)
79
+ end
80
+ end
81
+ end
82
+ else
83
+ transformed_rows = rows[1..-1].map do |row|
84
+ transform(row.compact.values_at(*column_range), column_range)
85
+ end
44
86
  end
45
87
 
46
- transformed_rows.uniq.sort_by { |hash| data_sort(hash) }
88
+ transformed_rows.uniq.sort_by { |h| data_sort(h) }
47
89
  end
48
90
 
49
91
  protected
50
92
 
51
- def default_filename
52
- File.join DATA_PATH, sources[selected_source]
93
+ attr_accessor :selected_source
94
+
95
+ def default_filename_to(source)
96
+ sources[source.to_sym]
53
97
  end
54
98
 
55
99
  def spreadsheet
56
- @spreadsheet ||= Spreadsheet.open filename
100
+ filename = File.join(DATA_PATH, default_filename_to(selected_source))
101
+
102
+ @spreadsheet[selected_source] ||= Spreadsheet.open filename
57
103
  end
58
104
 
59
105
  def sheet
60
- @selected_sheet ||= spreadsheet.worksheets.first
106
+ @selected_sheet[selected_source] ||= spreadsheet.worksheets.first
61
107
  end
62
108
 
63
109
  def rows
64
- @rows ||= sheet.rows
65
- end
66
-
67
- def selected_source
68
- self.class.selected_source || :dtb
110
+ @rows[selected_source] ||= sheet.rows
69
111
  end
70
112
 
71
113
  def sources
@@ -77,7 +119,7 @@ module Ibge
77
119
  end
78
120
 
79
121
  def column_keys
80
- defined_columns.keys.map(&:to_s).map(&:to_i)
122
+ defined_columns[selected_source].keys.map(&:to_s).map(&:to_i)
81
123
  end
82
124
 
83
125
  def column_range
@@ -86,9 +128,13 @@ module Ibge
86
128
 
87
129
  def transform(row, column_range)
88
130
  row.each_with_index.inject({}) do |item, (raw_data, index)|
89
- column_index = column_range[index]
131
+ column_index = column_range[index].to_s.to_sym
132
+
133
+ hash = {
134
+ defined_columns[selected_source][column_index] => raw_data
135
+ }
90
136
 
91
- item.merge!(self.class.defined_columns[column_index.to_s.to_sym] => raw_data)
137
+ item.merge!(hash)
92
138
  end
93
139
  end
94
140
 
@@ -102,6 +148,10 @@ module Ibge
102
148
 
103
149
  order_values
104
150
  end
151
+
152
+ def multiple_sources?
153
+ defined_columns.keys.size > 1
154
+ end
105
155
  end
106
156
  end
107
157
  end
@@ -0,0 +1,78 @@
1
+ module Ibge
2
+ module Reader
3
+ module Helpers
4
+ SOURCES = {
5
+ dtb: "DTB_2014_subdistrito.xls",
6
+ sidra: "sidra.xls"
7
+ }
8
+
9
+ attr_reader :defined_columns, :selected_source
10
+
11
+ def columns(columns)
12
+ if columns.empty?
13
+ raise ArgumentError,
14
+ "Columns must be provided as hash which contains " /
15
+ "the index and field name"
16
+ end
17
+
18
+ @defined_columns ||= {}
19
+ @selected_source ||= :dtb
20
+
21
+ distinct_sources = []
22
+
23
+ columns.each do |_, v|
24
+ if v.is_a?(Hash)
25
+ hash_column_definition = v.values.first
26
+
27
+ unless hash_column_definition.key?(:from_source)
28
+ raise ArgumentError, "#{v.key} must have the key from_source"
29
+ end
30
+
31
+ valid_informed_source(hash_column_definition[:from_source])
32
+
33
+ distinct_sources << hash_column_definition[:from_source]
34
+ end
35
+ end
36
+
37
+ distinct_sources = distinct_sources.compact.uniq.sort
38
+
39
+ distinct_sources.each do |source|
40
+ extracted_columns = columns.select do |_, v|
41
+ v.is_a?(Hash) && v.values.first[:from_source] == source
42
+ end
43
+
44
+ @defined_columns[source] = extracted_columns.inject({}) do |h, (k, v)|
45
+ h.merge!(k.to_s.to_sym => v.is_a?(Hash) ? v.keys.first : v)
46
+
47
+ h
48
+ end
49
+ end
50
+
51
+ if @selected_source
52
+ @defined_columns[@selected_source] = columns.select do |_, v|
53
+ v.is_a?(Symbol)
54
+ end
55
+ end
56
+ end
57
+
58
+ def source(selected_source = :dtb)
59
+ valid_informed_source(selected_source)
60
+
61
+ @selected_source = selected_source
62
+ end
63
+
64
+ def sources
65
+ SOURCES
66
+ end
67
+
68
+ def valid_informed_source(informed_source)
69
+ source_keys = sources.keys
70
+
71
+ unless source_keys.include?(informed_source)
72
+ raise ArgumentError,
73
+ "Source must be one of those '#{source_keys.join(', ')}'"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,11 +1,9 @@
1
1
  module Ibge
2
2
  module Reader
3
3
  class State < Base
4
- source :sidra
5
-
6
4
  columns "0": :code,
7
5
  "1": :state_name,
8
- "2": :state_federative_unit
6
+ "2": { state_federative_unit: { from_source: :sidra } }
9
7
  end
10
8
  end
11
9
  end
data/lib/ibge/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ibge
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,47 +1,97 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Ibge::Reader::Base do
4
- class Reader < Ibge::Reader::Base
5
- source :sidra
4
+ context "source on top of the reader" do
5
+ class ReaderWithSource < Ibge::Reader::Base
6
+ source :sidra
6
7
 
7
- columns "0": :code
8
- end
8
+ columns "0": :code
9
+ end
9
10
 
10
- subject { Reader }
11
+ subject { ReaderWithSource }
11
12
 
12
- describe '.columns' do
13
- it { should respond_to :columns }
13
+ describe ".columns" do
14
+ it { should respond_to :columns }
14
15
 
15
- it 'maps the column index to a recognized column name' do
16
- expect(subject.defined_columns).to eq "0": :code
16
+ it "maps the column index to a recognized column name" do
17
+ expect(subject.defined_columns).to eq sidra: { "0": :code }
18
+ end
17
19
  end
18
- end
19
20
 
20
- describe '.read' do
21
- context 'without pass a :filename as option' do
22
- it 'reads the file inside data folder' do
23
- expect(subject.read).to include code: "11"
21
+ describe ".read" do
22
+ context "without pass a :filename as option" do
23
+ it "reads the file inside data folder" do
24
+ expect(subject.read).to include code: "11"
25
+ end
26
+ end
27
+
28
+ context "passing a :filename" do
29
+ it "reads the file provided" do
30
+ filename = "spec/fixtures/DTB_example_subdistrito.xls"
31
+
32
+ content = subject.read(filename: { dtb: filename })
33
+
34
+ expect(content).to include code: "11"
35
+ end
24
36
  end
25
37
  end
26
38
 
27
- context 'passing a :filename' do
28
- it 'reads the file provided' do
29
- filename = "spec/fixtures/DTB_example_subdistrito.xls"
39
+ describe ".selected_source" do
40
+ it "show the default file source to read" do
41
+ expect(subject.selected_source).to eq :sidra
42
+ end
43
+ end
30
44
 
31
- expect(subject.read(filename: filename)).to include code: "11"
45
+ describe "#filename" do
46
+ it "sets the default to file inside data folder" do
47
+ expect(subject.new.filename).to include "data/sidra.xls"
32
48
  end
33
49
  end
34
50
  end
35
51
 
36
- describe '.selected_source' do
37
- it 'show the default file source to read' do
38
- expect(subject.selected_source).to eq :sidra
52
+ context "without source defined" do
53
+ class ReaderWithoutSource < Ibge::Reader::Base
54
+ columns "0": :code
39
55
  end
40
- end
41
56
 
42
- describe '#filename' do
43
- it 'sets the default to file inside data folder' do
44
- expect(subject.new.filename).to include 'data/sidra.xls'
57
+ subject { ReaderWithoutSource }
58
+
59
+ describe ".columns" do
60
+ it { should respond_to :columns }
61
+
62
+ it "maps the column index to a recognized column name" do
63
+ expect(subject.defined_columns).to eq dtb: { "0": :code }
64
+ end
65
+ end
66
+
67
+ describe ".read" do
68
+ context "without pass a :filename as option" do
69
+ it "reads the file inside data folder" do
70
+ expect(subject.read).to include code: "11"
71
+ end
72
+ end
73
+
74
+ context "passing a :filename" do
75
+ it "reads the file provided" do
76
+ filename = "spec/fixtures/DTB_example_subdistrito.xls"
77
+
78
+ content = subject.read(filename: { dtb: filename })
79
+
80
+ expect(content).to include code: "11"
81
+ end
82
+ end
83
+ end
84
+
85
+ describe ".selected_source" do
86
+ it "show the default file source to read" do
87
+ expect(subject.selected_source).to eq :dtb
88
+ end
89
+ end
90
+
91
+ describe "#filename" do
92
+ it "sets the default to file inside data folder" do
93
+ expect(subject.new.filename).to include "data/DTB_2014_subdistrito.xls"
94
+ end
45
95
  end
46
96
  end
47
97
  end
@@ -3,13 +3,21 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::District do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :micro_region_code,
12
+ "6": :municipality_code,
13
+ "9": :code,
14
+ "10": :full_code,
15
+ "11": :name
16
+ }
17
+ }
18
+ end
19
+
6
20
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :micro_region_code,
10
- "6": :municipality_code,
11
- "9": :code,
12
- "10": :full_code,
13
- "11": :name
21
+ expect(subject.defined_columns).to eq columns
14
22
  end
15
23
  end
@@ -3,9 +3,17 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::MesoRegion do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :code,
11
+ "3": :name
12
+ }
13
+ }
14
+ end
15
+
6
16
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :code,
9
- "3": :name
17
+ expect(subject.defined_columns).to eq columns
10
18
  end
11
19
  end
@@ -3,10 +3,18 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::MicroRegion do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :code,
12
+ "5": :name
13
+ }
14
+ }
15
+ end
16
+
6
17
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :code,
10
- "5": :name
18
+ expect(subject.defined_columns).to eq columns
11
19
  end
12
20
  end
@@ -3,12 +3,20 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::Municipality do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :micro_region_code,
12
+ "6": :code,
13
+ "7": :full_code,
14
+ "8": :name
15
+ }
16
+ }
17
+ end
18
+
6
19
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :micro_region_code,
10
- "6": :code,
11
- "7": :full_code,
12
- "8": :name
20
+ expect(subject.defined_columns).to eq columns
13
21
  end
14
22
  end
@@ -3,7 +3,17 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::Neighborhood do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ sidra: {
9
+ "0": :state_code,
10
+ "3": :municipality_full_code,
11
+ "5": :name
12
+ }
13
+ }
14
+ end
15
+
6
16
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code, "3": :municipality_full_code, "5": :name
17
+ expect(subject.defined_columns).to eq columns
8
18
  end
9
19
  end
@@ -1,9 +1,28 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Ibge::Reader::State do
4
4
  subject { described_class }
5
5
 
6
- it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :code, "1": :state_name
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :code,
10
+ "1": :state_name
11
+ },
12
+
13
+ sidra: {
14
+ "2": :state_federative_unit
15
+ }
16
+ }
17
+ end
18
+
19
+ it "should have defined columns" do
20
+ expect(subject.defined_columns).to eq columns
21
+ end
22
+
23
+ it "should read from multiple sources" do
24
+ expect(subject.read).to include code: "11",
25
+ state_name: "Rondônia",
26
+ state_federative_unit: "RO"
8
27
  end
9
28
  end
@@ -3,14 +3,22 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::SubDistrict do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :micro_region_code,
12
+ "6": :municipality_code,
13
+ "9": :district_code,
14
+ "12": :code,
15
+ "13": :full_code,
16
+ "14": :name
17
+ }
18
+ }
19
+ end
20
+
6
21
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :micro_region_code,
10
- "6": :municipality_code,
11
- "9": :district_code,
12
- "12": :code,
13
- "13": :full_code,
14
- "14": :name
22
+ expect(subject.defined_columns).to include columns
15
23
  end
16
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Arueira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2015-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spreadsheet
@@ -73,6 +73,7 @@ files:
73
73
  - lib/ibge.rb
74
74
  - lib/ibge/reader/base.rb
75
75
  - lib/ibge/reader/district.rb
76
+ - lib/ibge/reader/helpers.rb
76
77
  - lib/ibge/reader/meso_region.rb
77
78
  - lib/ibge/reader/micro_region.rb
78
79
  - lib/ibge/reader/municipality.rb