Skip to content

Instantly share code, notes, and snippets.

@jeffdeville
Created May 29, 2015 17:34
Show Gist options
  • Save jeffdeville/57b9eef87d9eaab2282b to your computer and use it in GitHub Desktop.
Save jeffdeville/57b9eef87d9eaab2282b to your computer and use it in GitHub Desktop.
Splitting the mapping and the normalizing process for testability
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
@algodave
Copy link

algodave commented Jun 1, 2015

@jeffdeville After looking at lines L30-L37, should I assume the . in Zillow's bathrooms field as a separator between Full and Partial bathrooms, or was it just an example?

@algodave
Copy link

algodave commented Jun 1, 2015

@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

@jeffdeville
Copy link
Author

@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