Skip to content

Instantly share code, notes, and snippets.

@mkaschenko
Last active August 22, 2022 06:39
Show Gist options
  • Save mkaschenko/6a329cb9ec2c1a9345a24dc340ffd7a4 to your computer and use it in GitHub Desktop.
Save mkaschenko/6a329cb9ec2c1a9345a24dc340ffd7a4 to your computer and use it in GitHub Desktop.
# NOTE: There are Application pages we need to calculate progress for.
# Every page has specific rules/conditions how to estimate progress.
# Rules have scores/weights and they are used to calculate progress.
# pages = {
# home_page: { home_page_rule => score },
# info_page: { info_page_rule_1 => score_1, info_page_rule_2 => score_2 }
# }
module ApplicationProgress
module Rules
def self.present?(attr, data)
!data[attr].nil?
end
def self.present_or(*attrs)
lambda do |data|
attrs.reduce(false) { |acc, attr| acc || present?(attr, data) }
end
end
def self.present_and(*attrs)
lambda do |data|
attrs.reduce(true) { |acc, attr| acc && present?(attr, data) }
end
end
end
module FirstPage
def self.rules
{ Rules.present_and(:age) => 1,
Rules.present_or(:sex, :gender) => 3 }
end
end
module SecondPage
def self.rules
{ Rules.present_and(:first_name, :last_name) => 2 }
end
end
def self.calculate(pages, application)
score = lambda do |rules, data|
rules
.select { |rule, _| rule.call(data) }
.values
.reduce(:+)
end
pages.reduce({}) do |acc, (page_name, rules)|
acc.merge(page_name => score.call(rules, application))
end
end
end
# main
pages = { first_page: ApplicationProgress::FirstPage.rules,
second_page: ApplicationProgress::SecondPage.rules }
application = { age: 28, first_name: 'Maxim', last_name: 'K', sex: 'M' }
ApplicationProgress.calculate(pages, application) # => { first_page: 4, second_page: 2 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment