Skip to content

Instantly share code, notes, and snippets.

@davetron5000
Created October 7, 2016 13:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davetron5000/accdc9d4033210985d2bab1fb74a0d68 to your computer and use it in GitHub Desktop.
Save davetron5000/accdc9d4033210985d2bab1fb74a0d68 to your computer and use it in GitHub Desktop.
class MarketResearch
# Assume we parsed some file or fetched an HTTP endpoint and
# got this JSON
DATA = [
{age: 19, smoker: false, income: 10_000, education: :high_school},
{age: 49, smoker: true, income: 120_000, education: :bachelors},
{age: 55, smoker: false, income: 400_000, education: :masters},
{age: 23, smoker: true, income: 10_000, education: :bachelors},
{age: 70, smoker: false, income: 70_000, education: :phd },
{age: 34, smoker: false, income: 90_000, education: :masters},
{age: 90, smoker: true, income: 0, education: :high_school},
]
# Since we're looking at people, we need a type to know what we are
# operating on
class Person
def self.to_proc(hash)
Person.new(
hash.fetch(:income),
hash.fetch(:smoker))
end
attr_reader :income
# Just care about income and is a smoker, but could add more here if needed
def initialize(income,smoker)
# Coerce types here using protocols
@income = income.to_i
@smoker = !!smoker
end
def smoker?
@smoker
end
end
def average_income_by_smoking(data)
# name the operations, but no need to pollute anything other
# than local namespace with this stuff for now
income_under_10_000 = ->(person) { person.income < 10_000 }
averge_hash_values = ->(_,values) { values.map(&:income).reduce(&:+).to_f / values.size }
data.map(&Person). # Turn our data into a typed object
reject(&income_under_10_000)). # no need to parameterize this - YAGNI
group_by(&:smoker?). # group by an attribute of our person. Use of "?" method
# should make it clear we get a Map<Boolean,Array<Person>>
map(&averge_hash_values). # name the operation, doesn't need to be a global feature of ActiveSupport :)
to_h # Type conversion using a protocol
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment