Created
May 29, 2015 17:34
-
-
Save jeffdeville/57b9eef87d9eaab2282b to your computer and use it in GitHub Desktop.
Splitting the mapping and the normalizing process for testability
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SherlockHomes | |
module PropertyCoercer | |
def self.coerce(input) | |
case | |
when property.respond_to?(:zillow_thing) | |
ZillowCoercer.coerce(input) | |
when property.respond_to?(:redfin_thing) | |
RedfinCoercer.coerce(input) | |
when property.respond_to?(:trulia_thing) | |
TruliaCoercer.coerce(input) | |
else | |
fail ArgumentError "Can't figure out how to coerce #{input}" | |
end | |
end | |
end | |
module ZillowCoercer | |
def self.coerce(property) | |
attrs = { | |
property_type: property.doodah.property_type_code, | |
bedrooms: property.bedrooms, | |
full_bathrooms: full_bathrooms(property), | |
partial_bathrooms: partial_bathrooms(property), | |
total_rooms: property.total_rooms, | |
interior_features: interior_features(property) | |
} | |
Property.new(attrs) | |
end | |
def full_bathrooms(property) | |
property.bathrooms.split(".").first.to_i | |
end | |
def half_bathrooms(property) | |
property.bathrooms.split(".").last.to_i | |
end | |
end | |
# (etc etc) | |
class Normalizer | |
attr_reader :redfin, :zillow, :trulia, :property | |
def initialize(redfin=Property.new, trulia=Property.new, zillow=Property.new) | |
@redfin = redfin | |
@zillow = zillow | |
@trulia = trulia | |
@property = Property.new | |
end | |
def normalize | |
attrs = { | |
property_type: property_type, | |
bedrooms: bedrooms, | |
full_bathrooms: full_bathrooms, | |
partial_bathrooms: partial_bathrooms, | |
total_rooms: total_rooms, | |
interior_features: interior_features | |
} | |
Property.new(attrs) | |
end | |
def property_type | |
if zillow | |
zillow.property_type | |
else | |
redfin.property_type | |
end | |
end | |
def bedrooms | |
bedrooms = all_sources.collect(&:bedrooms) | |
if bedrooms.uniq.len == 1 | |
return bedrooms | |
else | |
store_differences(:bedrooms) | |
end | |
end | |
private | |
def all_sources | |
[redfin, zillow, trulia] | |
end | |
def store_differences(field) | |
property.differences[field] = { | |
redfin: redfin.send(field), | |
trulia: trulia.send(field), | |
zillow: zillow.send(field) | |
} | |
end | |
end | |
end |
@jeffdeville Another question: even though discrepancies are found, shouldn't we store the preferred source's value? Example: store bedrooms from redfin even though Zillow and Trulia report a different number. That was my understanding after our conversation based on the spreadsheet, but I'm asking 'cause I'm seeing no value is returned in your example in lines L71-L78
@algodave -
Comment 1: It was just an example, though 2.5 bathrooms does mean 2 full, and 1 partial.
Comment 2: For now, go ahead and return the redfin number if the sources disagree
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jeffdeville After looking at lines L30-L37, should I assume the
.
in Zillow'sbathrooms
field as a separator between Full and Partial bathrooms, or was it just an example?