eaternet 0.3.14 → 0.3.15

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: 909fb5a4626a18c37b4d3694bd0fdf1a8f8b69a7
4
- data.tar.gz: b6a05cf7dc6d76a5f10b4dc2e949c03d277da7da
3
+ metadata.gz: dd015ab0c5ca911589f85116ca59297a938ad9d8
4
+ data.tar.gz: 35bacfa01690959bc0f051b6208d6b460c9cba6d
5
5
  SHA512:
6
- metadata.gz: e45b4ee75bf988fb28461b3cc19267ada7963e43967b80bb87537055b6f96a119829eafab6029bff68ede7830f433f129065a43a8a26827f51a09a4c9b81204c
7
- data.tar.gz: 2cb9c2a9f6e221c52c8a8905e501aefd3b7f0a28cc4ff2e3d0a477726644eba9779c383aefefe94b988686265125b4ce70585b7f15136858835dbc9e397c4bec
6
+ metadata.gz: bdf91cc1304eb2c2ab998c06fb57c22e73bb0cf1e766c1abb5e148c43976db802d5da7981ad0843bfc456c6bd74969df60f5e7274012169d1c06fc7f940a0326
7
+ data.tar.gz: cdceb406ed81a5eabb6d5cf9c78be604392f8022cf9c786fae625f726c24ccee572ed947935b192ce5f4e3c84d898e3f86b3be1ec2edea9984f55e44cc309fed
@@ -4,7 +4,7 @@ require 'logger'
4
4
  require 'set'
5
5
  require 'tempfile'
6
6
 
7
- require 'ext/lazy'
7
+ require 'ext/enumerator'
8
8
 
9
9
  require 'eaternet/lives_1_0'
10
10
  require 'eaternet/loggable'
@@ -13,21 +13,21 @@ require 'eaternet/loggable'
13
13
  module Eaternet
14
14
  module Agencies
15
15
  # A data source for New York City food service health inspections. It
16
- # retrieves the latest CSV export from
17
- # [the official source](https://data.cityofnewyork.us/Health/DOHMH-New-York-City-Restaurant-Inspection-Results/xx67-kt59)
18
- # and makes it easy to work with. The downloaded CSV is cached for twelve
19
- # hours in a temporary file.
16
+ # retrieves the latest CSV export from [the official
17
+ # source](https://data.cityofnewyork.us/Health/DOHMH-New-York-City-Restaurant-Inspection-Results/xx67-kt59)
18
+ # and makes it easy to work with.
20
19
  #
21
- # This library conforms to the
22
- # [LIVES 1.0 standard](http://www.yelp.com/healthscores) developed by
23
- # Yelp and the cities of San Francisco and New York.
20
+ # Output is produced in the [LIVES 1.0](http://www.yelp.com/healthscores)
21
+ # format developed by Yelp and the cities of San Francisco and New York.
22
+ #
23
+ # The downloaded CSV is cached for twelve hours in a temporary file.
24
24
  #
25
25
  # @example Print the names of all the restaurants in New York City
26
26
  # require 'eaternet'
27
27
  # nyc = Eaternet::Nyc.new
28
28
  # puts nyc.businesses.map(&:name)
29
29
  #
30
- # @example Compute the average inspection score for NYC.
30
+ # @example Compute the average inspection score
31
31
  # # The library is optimized for memory use at the expense
32
32
  # # of speed. E.g., each call to #inspections will iterate
33
33
  # # through the raw CSV. So here, we first retrieve the
@@ -63,8 +63,8 @@ module Eaternet
63
63
  # @return [Enumerable<Business>]
64
64
  def businesses
65
65
  map_csv { |row| try_to_create_business(row) }
66
- .compact
67
66
  .unique
67
+ .compact
68
68
  end
69
69
 
70
70
  # @example Compute the average inspection score for NYC.
@@ -82,21 +82,15 @@ module Eaternet
82
82
  #
83
83
  # @return [Enumerable<Inspection>]
84
84
  def inspections
85
- cache = Set.new
86
- map_csv do |row|
87
- if inspection_should_be_skipped?(cache, row)
88
- nil
89
- else
90
- save_to_inspection_cache(cache, row)
91
- try_to_create_inspection(row)
92
- end
93
- end.compact
85
+ map_csv { |row| skip_inspection?(row) ? nil : try_to_create_inspection(row) }
86
+ .unique
87
+ .compact
94
88
  end
95
89
 
90
+ # @return [Enumerable<Violation>]
96
91
  def violations
97
- map_csv do |row|
98
- violation_should_be_skipped?(row) ? nil : violation(row)
99
- end.compact
92
+ map_csv { |row| skip_violation?(row) ? nil : violation(row) }
93
+ .compact
100
94
  end
101
95
 
102
96
  # @example Print the name & URL of NYC's health agency.
@@ -114,6 +108,7 @@ module Eaternet
114
108
  end
115
109
  end
116
110
 
111
+ # @return [Enumerable<Legend>]
117
112
  def legends
118
113
  LegendGroup.new do |lg|
119
114
  lg.legends = [
@@ -157,7 +152,7 @@ module Eaternet
157
152
  nil
158
153
  end
159
154
 
160
- public # To enable testing
155
+ public # To support testing
161
156
 
162
157
  # @private
163
158
  def business(row)
@@ -180,7 +175,7 @@ module Eaternet
180
175
  Violation.new do |v|
181
176
  v.business_id = business_id(row)
182
177
  v.date = Date.strptime(row['INSPECTION DATE'], '%m/%d/%Y')
183
- v.code = violation_kind_id(row)
178
+ v.code = violation_code(row)
184
179
  v.description = row['VIOLATION DESCRIPTION']
185
180
  end
186
181
  end
@@ -193,34 +188,22 @@ module Eaternet
193
188
  end
194
189
  end
195
190
 
196
- def violation_should_be_skipped?(row)
197
- transfat_inspection?(row) || violation_kind_id(row).nil?
191
+ def skip_violation?(row)
192
+ transfat_inspection?(row) || violation_code(row).nil?
198
193
  end
199
194
 
200
- def inspection_should_be_skipped?(cache, row)
201
- cache.include?(inspection_cache_key(row)) || transfat_inspection?(row)
195
+ def skip_inspection?(row)
196
+ transfat_inspection?(row)
202
197
  end
203
198
 
204
199
  def business_id(row)
205
200
  row['CAMIS']
206
201
  end
207
202
 
208
- def violation_kind_id(row)
203
+ def violation_code(row)
209
204
  row['VIOLATION CODE']
210
205
  end
211
206
 
212
- def save_to_inspection_cache(cache, row)
213
- cache.add(inspection_cache_key(row))
214
- end
215
-
216
- def inspection_cache_key(row)
217
- inspection_id(row)
218
- end
219
-
220
- def inspection_id(row)
221
- [row['CAMIS'], row['INSPECTION DATE']].join('-')
222
- end
223
-
224
207
  def transfat_inspection?(row)
225
208
  if row['INSPECTION TYPE']
226
209
  row['INSPECTION TYPE'].include?('Trans Fat')
@@ -229,10 +212,10 @@ module Eaternet
229
212
  end
230
213
  end
231
214
 
232
- def map_csv(&block)
215
+ def map_csv(&row_handler)
233
216
  CSV.new(File.open(table_file, encoding: 'utf-8'), headers: true)
234
217
  .lazy
235
- .map { |row| block.call(row) }
218
+ .map { |row| row_handler.call(row) }
236
219
  end
237
220
 
238
221
  def table_file
@@ -65,6 +65,18 @@ module Eaternet
65
65
  def to_s
66
66
  "Inspection #{business_id}/#{date}/#{score}"
67
67
  end
68
+
69
+ def ==(other)
70
+ business_id == other.business_id && date == other.date
71
+ end
72
+
73
+ def eql?(other)
74
+ self == other
75
+ end
76
+
77
+ def hash
78
+ "#{business_id} #{date}".hash
79
+ end
68
80
  end
69
81
  end
70
82
  end
@@ -11,8 +11,6 @@ module Eaternet
11
11
  # example, if 80-90 is a ‘B’ and 90-100 is an ‘A’, a score of 90 would be
12
12
  # an ‘A’. These are optional.
13
13
  #
14
- # @see LegendGroup Lives_1_0::LegendGroup, which enforces the 0–100 span and
15
- # checks for overlap.
16
14
  # @see http://www.yelp.com/healthscores#legend LIVES / Legend specification
17
15
  class Legend < ValidatedObject
18
16
  # Minimum score that can be classified with this description.
@@ -13,6 +13,7 @@ module Eaternet
13
13
  #
14
14
  # @see http://www.yelp.com/healthscores#legend LIVES / Score Legend
15
15
  # specification
16
+ # @private
16
17
  class LegendGroup < ValidatedObject
17
18
  attr_accessor :legends
18
19
 
@@ -6,7 +6,7 @@ module Eaternet
6
6
  #
7
7
  # Uses [ActiveModel::Validations](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates)
8
8
  # to create self-validating Plain Old Ruby objects. This is especially
9
- # useful for data validation when importing from CSV.
9
+ # useful when importing data from one system into another.
10
10
  #
11
11
  # @example Writing a self-validating object
12
12
  # class Dog < Eaternet::ValidatedObject
@@ -17,8 +17,8 @@ module Eaternet
17
17
  # end
18
18
  #
19
19
  # @example Instantiating and automatically validating
20
- # # The dog1 instance is validated at the end of instantiation.
21
- # # Here, it succeeds without exception.
20
+ # # The dog1 instance validates itself at the end of instantiation.
21
+ # # Here, it succeeds and so doesn't raise an exception.
22
22
  # dog1 = Dog.new do |d|
23
23
  # d.name = 'Spot'
24
24
  # end
@@ -1,3 +1,3 @@
1
1
  module Eaternet
2
- VERSION = '0.3.14'
2
+ VERSION = '0.3.15'
3
3
  end
@@ -0,0 +1,13 @@
1
+ class Enumerator
2
+ # Create a #compact similar to {Array.compact}.
3
+ #
4
+ # @return [Enumerator] with {nil}s removed
5
+ def compact
6
+ select { |i| !i.nil? }
7
+ end
8
+
9
+ # @return [Enumerator] only my unique elements
10
+ def unique
11
+ Set.new(self).each
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eaternet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.14
4
+ version: 0.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robb Shecter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-27 00:00:00.000000000 Z
11
+ date: 2015-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -199,7 +199,7 @@ files:
199
199
  - lib/eaternet/util.rb
200
200
  - lib/eaternet/validated_object.rb
201
201
  - lib/eaternet/version.rb
202
- - lib/ext/lazy.rb
202
+ - lib/ext/enumerator.rb
203
203
  - test/eaternet/agencies/nyc_test.rb
204
204
  - test/eaternet/agencies/snhd_test.rb
205
205
  - test/eaternet/eaternet_test.rb
data/lib/ext/lazy.rb DELETED
@@ -1,13 +0,0 @@
1
- class Enumerator
2
- class Lazy
3
- # Create a lazy compact similar to Array#compact.
4
- def compact
5
- select { |i| !i.nil? }
6
- end
7
-
8
- # Return only my unique elements
9
- def unique
10
- Set.new(self).each
11
- end
12
- end
13
- end