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 +4 -4
- data/lib/eaternet/agencies/nyc.rb +26 -43
- data/lib/eaternet/lives_1_0/inspection.rb +12 -0
- data/lib/eaternet/lives_1_0/legend.rb +0 -2
- data/lib/eaternet/lives_1_0/legend_group.rb +1 -0
- data/lib/eaternet/validated_object.rb +3 -3
- data/lib/eaternet/version.rb +1 -1
- data/lib/ext/enumerator.rb +13 -0
- metadata +3 -3
- data/lib/ext/lazy.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd015ab0c5ca911589f85116ca59297a938ad9d8
|
4
|
+
data.tar.gz: 35bacfa01690959bc0f051b6208d6b460c9cba6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/
|
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
|
-
#
|
18
|
-
# and makes it easy to work with.
|
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
|
-
#
|
22
|
-
#
|
23
|
-
#
|
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
|
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
|
-
|
86
|
-
|
87
|
-
|
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
|
98
|
-
|
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
|
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 =
|
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
|
197
|
-
transfat_inspection?(row) ||
|
191
|
+
def skip_violation?(row)
|
192
|
+
transfat_inspection?(row) || violation_code(row).nil?
|
198
193
|
end
|
199
194
|
|
200
|
-
def
|
201
|
-
|
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
|
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(&
|
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|
|
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.
|
@@ -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
|
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
|
21
|
-
# # Here, it succeeds
|
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
|
data/lib/eaternet/version.rb
CHANGED
@@ -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.
|
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-
|
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/
|
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
|