zipcoder 0.5.0 → 0.6.0

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: 6acfa10df7bcb97c1d077f57b44eb8f07db3ff49
4
- data.tar.gz: 466550b2bbf85a28a1b67381fb6408c71d3b8fcd
3
+ metadata.gz: cb1e8913fb697af3a6480f88c203a2185bc04314
4
+ data.tar.gz: ad5b873b490e4e31f9d1dc692baa4d457bdd9b43
5
5
  SHA512:
6
- metadata.gz: 268af7c1b49cd0528cc2caae8d040ee64127063d5cb292f4a26ed62b76e3f910785f74c77425b05466fd0c0ee9e591d7e66d7e26293288d43ac15e4ce2fd4ca7
7
- data.tar.gz: f2ba366f03a0ec93c31d62b17fb8ab09ddd274c0e53be3bf1ee3deba1ceecfbf581818faea8f6bba17c608a11baa8e13211a67efdbfbfc5eba399e8d0da284d8
6
+ metadata.gz: b3431d07be11bb3338bf0c73a3cacc0a3b9ca1b54fecea557a8a070acb6e1213f8d15e8efd3fffa6097ad06447b62710362b58a0ba94205d2ddd74f641febeed
7
+ data.tar.gz: 8b466c4f9d1e334bae0d2726574d5ba1ca73bec5eeb6a7adcb446b54e0410823875a3b7fe4dba30efa6db4abb779682f835ec69a369a8e3d30477784b6d10aec
data/README.md CHANGED
@@ -7,6 +7,8 @@ Gem for performing zip code lookup operations
7
7
 
8
8
  ## Revision History
9
9
 
10
+ - v0.6.0:
11
+ - added "grouped" option to "zip_cities"
10
12
  - v0.5.0:
11
13
  - added Redis backend support
12
14
  - v0.4.2:
@@ -74,7 +76,7 @@ following
74
76
  **install the 'redis' Gem (or add to your Gemfile if using Rails):**
75
77
 
76
78
  ```ruby
77
- gme 'redis'
79
+ gem 'redis'
78
80
  ```
79
81
 
80
82
  *Note that this Gem supports Ruby >= 2.0 so I could NOT use the latest Redis
@@ -90,8 +92,8 @@ cacher = Zipcoder::Cacher::Redis.new(**args)
90
92
  Zipcoder.load_cache(cacher)
91
93
  ```
92
94
 
93
- Please check the [here](https://github.com/redis/redis-rb) for the different
94
- options to use when instantiating the "Redis" client.
95
+ Please check [here](https://github.com/redis/redis-rb) for the different options
96
+ to use when instantiating the "Redis" client.
95
97
 
96
98
  ### Methods
97
99
 
@@ -104,10 +106,12 @@ Returns the info for the "zip"
104
106
 
105
107
  **variations:**
106
108
 
107
- - ```Zipcoder.zip_info(78748, **args)```
108
- - ```Zipcoder.zip_info("78748", **args)```
109
- - ```"78748".zip_info(**args)```
110
- - ```78748.zip_info(**args)```
109
+ ``` ruby
110
+ Zipcoder.zip_info(78748, **args)
111
+ Zipcoder.zip_info("78748", **args)
112
+ "78748".zip_info(**args)
113
+ 78748.zip_info(**args)
114
+ ```
111
115
 
112
116
  **parameters:**
113
117
 
@@ -143,8 +147,10 @@ Returns the cities that are covered by the "zip_string"
143
147
 
144
148
  **variations:**
145
149
 
146
- - ```Zipcoder.zip_cities("78701-78799,78613", **args)```
147
- - ```"78701-78799,78613".zip_cities(**args)```
150
+ ``` ruby
151
+ Zipcoder.zip_cities("78701-78799,78613", **args)
152
+ "78701-78799,78613".zip_cities(**args)
153
+ ```
148
154
 
149
155
  **parameters:**
150
156
 
@@ -156,7 +162,8 @@ Returns the cities that are covered by the "zip_string"
156
162
  **arguments:**
157
163
 
158
164
  - keys [Array] - array of keys to include (filters out the others)
159
- - names_only [Bool] - set to "true" if you only want the city names returned
165
+ - names_only [Bool] - set to "true" if you only want the city/state names returned
166
+ - grouped [Bool] - set to "true" if you want the zip codes returned grouped by city/state
160
167
  - max [Integer] - maximum number of cities to return
161
168
 
162
169
  **notes:**
@@ -174,7 +181,15 @@ puts "78701-78750,78613".zip_cities
174
181
 
175
182
  # Returns just the name of the cities
176
183
  puts "78701-78750,78613".zip_cities names_only: true
177
- # > ["Austin", "Cedar Park"]
184
+ # > ["Austin, TX", "Cedar Park, TX"]
185
+
186
+ # Returns the cities grouped by city/state
187
+ puts "78701-78750,78613".zip_cities grouped: true
188
+ # > {"78701-78750" => {:zip=>"78748", :city=>"Austin", :state=>"TX", ...
189
+
190
+ # Returns the cities grouped by city/state with names only
191
+ puts "78701-78750,78613".zip_cities grouped: true, names_only: true
192
+ # > {"78701-78750" => "Austin, TX", "78613" => "Cedar Park"}
178
193
  ```
179
194
 
180
195
  #### Method: Zipcoder.city_info(city_state, **args)
@@ -183,8 +198,10 @@ Returns the zip object for a city
183
198
 
184
199
  **variations:**
185
200
 
186
- - ```Zipcoder.city_info("Atlanta, GA", **args)```
187
- - ```"zip_string".zip_cities(**args)```
201
+ ``` ruby
202
+ Zipcoder.city_info("Atlanta, GA", **args)
203
+ "Atlanta, GA".city_info(**args)
204
+ ```
188
205
 
189
206
  **parameters:**
190
207
 
@@ -218,8 +235,10 @@ This will return the cities in a state
218
235
 
219
236
  **variations:**
220
237
 
221
- - ```Zipcoder.state_cities("GA", **args)```
222
- - ```"GA".state_cities(**args)```
238
+ ``` ruby
239
+ Zipcoder.state_cities("GA", **args)
240
+ "GA".state_cities(**args)
241
+ ```
223
242
 
224
243
  **parameters:**
225
244
 
@@ -252,7 +271,9 @@ This will return the states in the US
252
271
 
253
272
  **variations:**
254
273
 
255
- - ```Zipcoder.states```
274
+ ``` ruby
275
+ Zipcoder.states
276
+ ```
256
277
 
257
278
  **parameters:**
258
279
 
@@ -1,3 +1,5 @@
1
+ require_relative '../ext/array'
2
+
1
3
  module Zipcoder
2
4
  module Cacher
3
5
  # The cacher base class places all of the objects in memory. The
@@ -146,8 +148,7 @@ module Zipcoder
146
148
  # Normalizes the values
147
149
  def _normalize_city(infos)
148
150
  # Values
149
- zip_min = 100000
150
- zip_max = 0
151
+ zips =[]
151
152
  lat_min = 200
152
153
  lat_max = -200
153
154
  long_min = 200
@@ -155,9 +156,7 @@ module Zipcoder
155
156
 
156
157
  # Iterate through the info and get min/max of zip/lat/long
157
158
  infos.each do |info|
158
- zip = info[:zip].to_i
159
- zip_min = zip if zip < zip_min
160
- zip_max = zip if zip > zip_max
159
+ zips << info[:zip]
161
160
  lat_min = info[:lat] if info[:lat] < lat_min
162
161
  lat_max = info[:lat] if info[:lat] > lat_max
163
162
  long_min = info[:long] if info[:long] < long_min
@@ -179,7 +178,7 @@ module Zipcoder
179
178
  normalized = {
180
179
  city: infos[0][:city],
181
180
  state: infos[0][:state],
182
- zip: "#{zip_min.to_zip}-#{zip_max.to_zip}",
181
+ zip: zips.combine_zips,
183
182
  lat: ((lat_min+lat_max)/2).round(4),
184
183
  long: ((long_min+long_max)/2).round(4)
185
184
  }
@@ -0,0 +1,39 @@
1
+ require_relative 'string'
2
+
3
+ class Array
4
+ def combine_zips
5
+ zips = []
6
+ start = nil
7
+ last = nil
8
+
9
+ self.sort.each do |zip|
10
+ zip_int = zip.to_i
11
+
12
+ if start == nil
13
+ start = zip_int
14
+ last = zip_int
15
+ else
16
+ if zip_int == last+1
17
+ last = zip_int
18
+ else
19
+ if last == start
20
+ zips << start.to_zip
21
+ else
22
+ zips << "#{start.to_zip}-#{last.to_zip}"
23
+ end
24
+ start = zip_int
25
+ last = zip_int
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ if last == start
32
+ zips << start.to_zip
33
+ else
34
+ zips << "#{start.to_zip}-#{last.to_zip}"
35
+ end
36
+
37
+ zips.join ","
38
+ end
39
+ end
@@ -20,4 +20,8 @@ class String
20
20
  self
21
21
  end
22
22
 
23
+ def is_zip?
24
+ self.length == 5
25
+ end
26
+
23
27
  end
@@ -1,3 +1,3 @@
1
1
  module Zipcoder
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/zipcoder.rb CHANGED
@@ -2,6 +2,7 @@ require "zipcoder/version"
2
2
  require "zipcoder/cacher/memory"
3
3
  require "zipcoder/ext/string"
4
4
  require "zipcoder/ext/integer"
5
+ require "zipcoder/ext/array"
5
6
  require "yaml"
6
7
 
7
8
  module Zipcoder
@@ -56,27 +57,49 @@ module Zipcoder
56
57
  max = kwargs[:max]
57
58
 
58
59
  cities = {}
60
+ last_key = nil
59
61
  self._parse_zip_string(zip_string).each do |zip|
60
62
  info = zip.zip_info
61
63
  if info == nil
64
+ key = last_key
65
+ else
66
+ key = "#{info[:city]}, #{info[:state]}"
67
+ end
68
+ last_key = key
69
+
70
+ if key == nil
62
71
  next
63
72
  end
64
73
 
65
- cities["#{info[:city]}, #{info[:state]}"] = true
74
+ zip_codes = cities[key] || []
75
+ zip_codes << zip
76
+ cities[key] = zip_codes
66
77
 
67
78
  if max != nil and cities.keys.count >= max
68
79
  break
69
80
  end
70
81
  end
71
82
 
72
- cities = cities.keys.uniq.sort
73
83
 
74
- if kwargs[:names_only]
75
- zips = cities.map{ |x| x.split(",")[0].strip }
84
+ if kwargs[:grouped]
85
+ zips = {}
86
+ cities.each do |city, zip_codes|
87
+ key = zip_codes.combine_zips
88
+ if kwargs[:names_only]
89
+ zips[key] = city
90
+ else
91
+ zips[key] = city.city_info(keys: kwargs[:keys])
92
+ end
93
+ end
76
94
  else
77
- zips = []
78
- cities.each do |key|
79
- zips << key.city_info(keys: kwargs[:keys])
95
+ cities = cities.keys.uniq.sort
96
+ if kwargs[:names_only]
97
+ zips = cities
98
+ else
99
+ zips = []
100
+ cities.each do |key|
101
+ zips << key.city_info(keys: kwargs[:keys])
102
+ end
80
103
  end
81
104
  end
82
105
  zips
@@ -164,11 +187,10 @@ module Zipcoder
164
187
 
165
188
  # Check the zip codes
166
189
  def self._check_zip(zip)
167
- if zip.length != 5
190
+ unless zip.is_zip?
168
191
  raise ZipcoderError, "zip code #{zip} is not 5 characters"
169
192
  end
170
193
  zip
171
194
  end
172
195
 
173
-
174
196
  end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+ require "zipcoder/ext/array"
3
+
4
+
5
+ describe Array do
6
+ it 'combines the zip codes' do
7
+ [
8
+ [["12345","12346","12347"], "12345-12347"],
9
+ [["12347","12346","12345"], "12345-12347"],
10
+ [["12346","12347","12345"], "12345-12347"],
11
+ [["12346","12347","12345","78746"], "12345-12347,78746"],
12
+ [["78748","78746","12346","12347","12345"], "12345-12347,78746,78748"],
13
+ ].each do |test|
14
+ expect(test[0].combine_zips).to eq(test[1])
15
+ end
16
+ end
17
+ end
@@ -88,7 +88,7 @@ describe Zipcoder do
88
88
  city_info = described_class.city_info "Austin, TX"
89
89
  expect(city_info[:city]).to eq("Austin")
90
90
  expect(city_info[:state]).to eq("TX")
91
- expect(city_info[:zip]).to eq("78701-78799")
91
+ expect(city_info[:zip].start_with?("78701")).to eq(true)
92
92
  expect(city_info[:lat]).to eq(30.315)
93
93
  expect(city_info[:long]).to eq(-97.71)
94
94
  end
@@ -97,7 +97,7 @@ describe Zipcoder do
97
97
  city_info = described_class.city_info " San Antonio , TX"
98
98
  expect(city_info[:city]).to eq("San Antonio")
99
99
  expect(city_info[:state]).to eq("TX")
100
- expect(city_info[:zip]).to eq("78201-78285")
100
+ expect(city_info[:zip].start_with?("78201")).to eq(true)
101
101
  expect(city_info[:lat]).to eq(29.435)
102
102
  expect(city_info[:long]).to eq(-98.495)
103
103
  end
@@ -106,7 +106,7 @@ describe Zipcoder do
106
106
  city_info = described_class.city_info "Austin, TX", keys: [:zip, :lat, :long]
107
107
  expect(city_info[:city]).to be_nil
108
108
  expect(city_info[:state]).to be_nil
109
- expect(city_info[:zip]).to eq("78701-78799")
109
+ expect(city_info[:zip].start_with?("78701")).to eq(true)
110
110
  expect(city_info[:lat]).to eq(30.315)
111
111
  expect(city_info[:long]).to eq(-97.71)
112
112
  end
@@ -157,7 +157,7 @@ describe Zipcoder do
157
157
  zip_info = zip_cities[0]
158
158
  expect(zip_info[:city]).to eq("Austin")
159
159
  expect(zip_info[:state]).to eq("TX")
160
- expect(zip_info[:zip]).to eq("78701-78799")
160
+ expect(zip_info[:zip].start_with?("78701")).to eq(true)
161
161
  expect(zip_info[:lat]).to eq(30.315)
162
162
  expect(zip_info[:long]).to eq(-97.71)
163
163
  end
@@ -169,7 +169,7 @@ describe Zipcoder do
169
169
  zip_info = zip_cities[0]
170
170
  expect(zip_info[:city]).to eq("Austin")
171
171
  expect(zip_info[:state]).to eq("TX")
172
- expect(zip_info[:zip]).to eq("78701-78799")
172
+ expect(zip_info[:zip].start_with?("78701")).to eq(true)
173
173
  expect(zip_info[:lat]).to eq(30.315)
174
174
  expect(zip_info[:long]).to eq(-97.71)
175
175
 
@@ -188,7 +188,41 @@ describe Zipcoder do
188
188
 
189
189
  it "returns just names of cities sorted" do
190
190
  zip_cities = "13601,78613,78702-78750".zip_cities names_only: true
191
- expect(zip_cities).to eq(["Austin", "Cedar Park", "Watertown"])
191
+ expect(zip_cities).to eq(["Austin, TX", "Cedar Park, TX", "Watertown, NY"])
192
+ end
193
+
194
+ context "#grouped" do
195
+ it "returns the cities grouped" do
196
+ zip_cities = "78751,13601,78613,78702-78750".zip_cities grouped: true
197
+ expect(zip_cities.keys.sort).to eq(["13601", "78613", "78702-78751"])
198
+
199
+ zip_info = zip_cities["78702-78751"]
200
+ expect(zip_info[:city]).to eq("Austin")
201
+ expect(zip_info[:state]).to eq("TX")
202
+ expect(zip_info[:zip].start_with?("78701")).to eq(true)
203
+ expect(zip_info[:lat]).to eq(30.315)
204
+ expect(zip_info[:long]).to eq(-97.71)
205
+
206
+ zip_info = zip_cities["78613"]
207
+ expect(zip_info[:city]).to eq("Cedar Park")
208
+ expect(zip_info[:state]).to eq("TX")
209
+ expect(zip_info[:zip]).to eq("78613")
210
+ expect(zip_info[:lat]).to eq(30.51)
211
+ expect(zip_info[:long]).to eq(-97.83)
212
+
213
+ zip_info = zip_cities["13601"]
214
+ expect(zip_info[:city]).to eq("Watertown")
215
+ expect(zip_info[:state]).to eq("NY")
216
+ expect(zip_info[:zip]).to eq("13601,13603")
217
+ expect(zip_info[:lat]).to eq(43.97)
218
+ expect(zip_info[:long]).to eq(-75.91)
219
+ end
220
+
221
+ it "returns just names of cities grouped" do
222
+ zip_cities = "78751,13601,78613,78702-78750".zip_cities grouped: true, names_only: true
223
+ expect(zip_cities.keys.sort).to eq(["13601", "78613", "78702-78751"])
224
+ expect(zip_cities).to eq({"78702-78751" => "Austin, TX", "78613" => "Cedar Park, TX", "13601" => "Watertown, NY"})
225
+ end
192
226
  end
193
227
  end
194
228
 
@@ -236,7 +270,7 @@ describe Zipcoder do
236
270
  city_info = "Austin, TX".city_info
237
271
  expect(city_info[:city]).to eq("Austin")
238
272
  expect(city_info[:state]).to eq("TX")
239
- expect(city_info[:zip]).to eq("78701-78799")
273
+ expect(city_info[:zip].start_with?("78701")).to eq(true)
240
274
  expect(city_info[:lat]).to eq(30.315)
241
275
  expect(city_info[:long]).to eq(-97.71)
242
276
  end
@@ -244,7 +278,7 @@ describe Zipcoder do
244
278
  city_info = "Austin, TX".city_info keys: [:zip, :city]
245
279
  expect(city_info[:city]).to eq("Austin")
246
280
  expect(city_info[:state]).to be_nil
247
- expect(city_info[:zip]).to eq("78701-78799")
281
+ expect(city_info[:zip].start_with?("78701")).to eq(true)
248
282
  expect(city_info[:lat]).to be_nil
249
283
  expect(city_info[:long]).to be_nil
250
284
  end
metadata CHANGED
@@ -1,97 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipcoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Chapman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-13 00:00:00.000000000 Z
11
+ date: 2018-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.7'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 3.5.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.5.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: simplecov
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: codecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: redis
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: 3.3.5
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.3.5
97
97
  description:
@@ -103,9 +103,9 @@ executables:
103
103
  extensions: []
104
104
  extra_rdoc_files: []
105
105
  files:
106
- - .gitignore
107
- - .rspec
108
- - .ruby-version
106
+ - ".gitignore"
107
+ - ".rspec"
108
+ - ".ruby-version"
109
109
  - Gemfile
110
110
  - LICENSE.txt
111
111
  - README.md
@@ -119,9 +119,11 @@ files:
119
119
  - lib/zipcoder/cacher/base.rb
120
120
  - lib/zipcoder/cacher/memory.rb
121
121
  - lib/zipcoder/cacher/redis.rb
122
+ - lib/zipcoder/ext/array.rb
122
123
  - lib/zipcoder/ext/integer.rb
123
124
  - lib/zipcoder/ext/string.rb
124
125
  - lib/zipcoder/version.rb
126
+ - spec/array_spec.rb
125
127
  - spec/cacher_redis_spec.rb
126
128
  - spec/spec_helper.rb
127
129
  - spec/zipcoder_spec.rb
@@ -136,21 +138,22 @@ require_paths:
136
138
  - lib
137
139
  required_ruby_version: !ruby/object:Gem::Requirement
138
140
  requirements:
139
- - - '>='
141
+ - - ">="
140
142
  - !ruby/object:Gem::Version
141
143
  version: '2.0'
142
144
  required_rubygems_version: !ruby/object:Gem::Requirement
143
145
  requirements:
144
- - - '>='
146
+ - - ">="
145
147
  - !ruby/object:Gem::Version
146
148
  version: '0'
147
149
  requirements: []
148
150
  rubyforge_project:
149
- rubygems_version: 2.4.8
151
+ rubygems_version: 2.5.1
150
152
  signing_key:
151
153
  specification_version: 4
152
154
  summary: Converts zip codes to cities, lat/long, and vice-versa
153
155
  test_files:
156
+ - spec/array_spec.rb
154
157
  - spec/cacher_redis_spec.rb
155
158
  - spec/spec_helper.rb
156
159
  - spec/zipcoder_spec.rb