require "date" class Tariff attr_reader :kilowatt_hour_rate # Arbeitspreis attr_reader :basic_rate # Grundpreis attr_reader :month def initialize(kilowatt_hour_rate:, basic_rate:, month:) @kilowatt_hour_rate = kilowatt_hour_rate @basic_rate = basic_rate @month = month end end class Reading attr_reader :date attr_reader :kilowatts def initialize(date:, kilowatts:) @date = date @kilowatts = kilowatts end end class MonthlyConsumption def self.calculate_for(month:, tariffs:, readings:) start_reading = readings.find { |reading| reading.date == Date.new(month.year, month.month, 1) } end_reading = readings.find { |reading| reading.date == Date.new(month.next_month.year, month.next_month.month, 1) } kilowatts = end_reading.kilowatts - start_reading.kilowatts tariff = tariffs.take_while { |tariff| tariff.month < month }.last price = tariff.basic_rate + kilowatts * tariff.kilowatt_hour_rate "In #{month.strftime('%B %Y')} you consumed #{kilowatts} kilowatts for #{price / 100} Euro" end end tariffs = [ Tariff.new( kilowatt_hour_rate: 35, basic_rate: 1200, month: Date.new(2022, 1, 1) ), Tariff.new( kilowatt_hour_rate: 37, basic_rate: 1200, month: Date.new(2022, 5, 1) ), Tariff.new( kilowatt_hour_rate: 30, basic_rate: 1200, month: Date.new(2022, 7, 1) ) ] current_reading = 3220 readings = (Date.new(2022, 1, 1)...Date.new(2022, 12, 31)).map do |date| current_reading += [3, 4, 6].sample Reading.new( date: date, kilowatts: current_reading ) end puts MonthlyConsumption.calculate_for(month: Date.new(2022, 6), tariffs: tariffs, readings: readings)