Skip to content

Instantly share code, notes, and snippets.

@jameskerr
Last active November 13, 2015 23:32
Show Gist options
  • Save jameskerr/cf645644b5624dd36ee6 to your computer and use it in GitHub Desktop.
Save jameskerr/cf645644b5624dd36ee6 to your computer and use it in GitHub Desktop.
# See if an object is "complete" and give it a score. Example useage
# would look like this.
CompletenessAnalyzer.new(object: Event.find(1), criteria: [
Criterion.new({
name: 'Audience',
message: 'Whom is your event is intended for?',
condition: ->(event) { event.audiences.empty? }
}),
Criterion.new({
name: 'Contact Info',
message: 'Who is the event contact person?',
condition: ->(event) { [event.contact_name, event.contact_email, event.contact_phone].reject(&:blank?).length == 0 }
}),
])
# A simple class that has a name, a message, and a
# callable object that returns either truthy or falsey.
class Criterion
attr_accessor :name, :message, :condition
def initialize(args)
@name, @message, @condition = args[:name], args[:message], args[:condition]
end
end
# Analyze the completeness of an object.
class CompletenessAnalyzer
attr_accessor :object, :criteria, :incomplete_criteria
def initialize(args)
@object = args[:object]
@criteria = args[:criteria] || []
@incomplete_criteria = []
analyze
end
def complete?
score.to_i == 1
end
def score
if criteria.empty?
0.0
else
(criteria.length - incomplete_criteria.length) / criteria.length.to_f
end
end
def score_message
case score
when 0.0...0.2
'Not too good'
when 0.2...0.4
'Could use some improvment'
when 0.4...0.6
'About half way there'
when 0.6...0.8
'Pretty good'
when 0.8...0.99
'Great job'
when 0.99..1.0
'Perfect score'
end
end
def each_criterion
criteria.each do |criterion|
result = criterion.condition.call(object)
yield(criterion, result)
end
end
private
def analyze
incomplete_criteria.clear
criteria.each do |criterion|
incomplete_criteria << criterion if criterion.condition.call(object)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment