class FortuneTeller::Simulator
Simulates personal finances.
Attributes
partner[RW]
primary[RW]
spending_strategy[RW]
Public Class Methods
new()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 6 def initialize @objects = {} @available_keys = ('AA'..'ZZ').to_a end
Public Instance Methods
calculate_take_home_pay(_date)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 20 def calculate_take_home_pay(_date) # TODO: make this date dependant @objects[:job].each_value.map(&:calculate_take_home_pay).sum end
inflating_int(int, start_date = nil)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 35 def inflating_int(int, start_date = nil) FortuneTeller::InflatingInt.new( int: int, start_date: (start_date.nil? ? Date.today : start_date) ) end
simulate()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 25 def simulate validate_plan! end_date = first_day_of_year((youngest_birthday.year + 101)) states = [initial_state] while states.last.date != end_date states << simulate_next_state(states.last) end puts states.as_json end
Private Instance Methods
add_object(type:, object:)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 101 def add_object(type:, object:) key = @available_keys.shift @objects[type] ||= {} @objects[type][key] = object key end
evolve_state(state, transforms, to)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 60 def evolve_state(state, transforms, to) state = state.init_next transforms.each { |t| t.apply_to(state) } state.pass_time(to: to) state end
first_day_of_year(year)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 56 def first_day_of_year(year) Date.new(year, 1, 1) end
initial_state()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 91 def initial_state s = FortuneTeller::State.new(start_date: Date.today) @objects[:account].each { |k, a| s.add_account(key: k, account: a) } s end
no_partner?()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 83 def no_partner? @partner.nil? end
no_primary?()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 87 def no_primary? @primary.nil? end
retrieve_objects(type:)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 108 def retrieve_objects(type:) @objects[type] rescue NoMethodError {} end
simulate_next_state(last)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 44 def simulate_next_state(last) end_date = first_day_of_year((last.date.year + 1)) transforms = static_transforms(from: last.date, to: end_date) state = evolve_state(last, transforms, end_date) extra = spending_strategy.resolution_transforms(state: state) unless extra.empty? transforms.concat(extra).sort! state = evolve_state(last, transforms, end_date) end state end
static_transforms(from:, to:)
click to toggle source
# File lib/fortuneteller/simulator.rb, line 67 def static_transforms(from:, to:) transforms = [] %i[job social_security].each do |object_type| @objects[object_type].each_value { |o| transforms.push(o) } end transforms = transforms.map do |x| x.bounded_gen_transforms(from: from, to: to, plan: self) end transforms.reduce([], :concat).sort end
validate_plan!()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 97 def validate_plan! throw 'Please assign primary' if no_primary? end
youngest_birthday()
click to toggle source
# File lib/fortuneteller/simulator.rb, line 78 def youngest_birthday return @primary.birthday if no_partner? [@primary.birthday, @partner.birthday].min end