zipcoder 0.5.0 → 0.6.0

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