Skip to content

Instantly share code, notes, and snippets.

@reggieb
Created June 4, 2019 13:20
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 reggieb/0acdb118dfcd8c60af4c9947e8d5eebb to your computer and use it in GitHub Desktop.
Save reggieb/0acdb118dfcd8c60af4c9947e8d5eebb to your computer and use it in GitHub Desktop.
Salaray Pattern Generator: Tool for creating sets of data for salaries paid in different patterns (weekly, two weekly, four weekly and monthly)
require 'active_support'
require 'active_support/core_ext/integer/time'
class SalaryPatternGenerator
def self.generate(*args)
new(*args).generate
end
attr_reader :period, :salary, :day_offset, :salary_offset, :start_at
def initialize(period:, salary:, day_offset:nil, salary_offset:nil, start_at:Time.now.utc)
@period = period
@salary = salary
@salary_offset = salary_offset
@day_offset = day_offset
@start_at = start_at
end
def generate
case period
when :monthly
generate_monthly
when :weekly
generate_weekly
when :two_weekly
generate_weekly(2)
when :four_weekly
generate_weekly(4)
end
end
def generate_monthly
dates_for 0..2, :month
end
def generate_weekly(step=1)
weeks = ((start_at_normalized - 3.months.ago) / 1.week).to_i
dates_for (0..weeks).step(step), :week
end
def dates_for(points, method)
points.to_a
points.each_with_object({}) do |n,h|
time = sample_day(n.__send__(method).ago + start_offset)
h[time] = sample_salary
end
end
def sample_day(day)
return day unless day_offset
offset = sample_around 0, day_offset
day + offset.days
end
def sample_salary
return salary unless salary_offset
sample_around salary, salary_offset
end
def sample_around(middle, offset)
first = middle - offset
last = middle + offset
(first..last).to_a.sample
end
def start_offset
@start_offset ||= start_at_normalized - Time.now.utc.beginning_of_day
end
def start_at_normalized
@start_at_normalized ||= (start_at.utc.beginning_of_day + 1.day)
end
end
start_at = Time.parse('2019-06-30 00:00:00').utc
puts 'Raw data of monthly salary with day offset'
m = SalaryPatternGenerator.generate(period: :monthly, salary: 1000, day_offset: 2, start_at: start_at)
p m
puts 'Weekly salary values showing effect of salary offset'
w = SalaryPatternGenerator.generate(period: :weekly, salary: 200, salary_offset: 10, start_at: start_at)
p w.values
puts 'Weekly days showing pattern back from start_at'
p w.keys.map(&:day)
puts 'Two weekly days showing pattern back from start_at'
ww = SalaryPatternGenerator.generate(period: :two_weekly, salary: 200, start_at: start_at)
p ww.keys.map(&:day)
puts 'Four weekly days showing pattern back from start_at'
wwww = SalaryPatternGenerator.generate(period: :four_weekly, salary: 200, start_at: start_at)
p wwww.keys.map(&:day)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment