Skip to content

Instantly share code, notes, and snippets.

@serradura
Last active January 15, 2023 21:24
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 serradura/2d9cab9a1f0975ba1e0a0bbd53ea8fa9 to your computer and use it in GitHub Desktop.
Save serradura/2d9cab9a1f0975ba1e0a0bbd53ea8fa9 to your computer and use it in GitHub Desktop.
class AssemblyLine
CARS_PRODUCED_PER_HOUR = 221.0
def self.calculate_cars_per_hour(speed)
speed * CARS_PRODUCED_PER_HOUR
end
def self.calculate_success_rate(speed)
case speed
when 1..4 then 1
when 5..8 then 0.9
when 9 then 0.8
when 10 then 0.77
end
end
def self.calculate_production_rate_per_hour(speed)
calculate_cars_per_hour(speed) * calculate_success_rate(speed)
end
def initialize(speed)
@speed = speed
end
def production_rate_per_hour
self.class.calculate_production_rate_per_hour(@speed)
end
ONE_HOUR_IN_MINUTES = 60
def working_items_per_minute
(production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
end
end
class AssemblyLine
module Calculate
def self.cars_per_hour(speed)
speed * 221.0
end
def self.success_rate(speed)
case speed
when 1..4 then 1
when 5..8 then 0.9
when 9 then 0.8
when 10 then 0.77
end
end
def self.production_rate_per_hour(speed)
cars_per_hour(speed) * success_rate(speed)
end
end
attr_reader :production_rate_per_hour
def initialize(speed)
@production_rate_per_hour = Calculate.production_rate_per_hour(speed)
end
ONE_HOUR_IN_MINUTES = 60
def working_items_per_minute
@working_items_per_minute ||= (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
end
end
class AssemblyLine
SuccessRate = Struct.new(:speed, :percentage, keyword_init: true) do
@options = [
{ speed: 1..4, percentage: 1.00 },
{ speed: 5..8, percentage: 0.90 },
{ speed: 9, percentage: 0.80 },
{ speed: 10, percentage: 0.77 }
].map! { |config| new(**config).freeze }.freeze
def self.detect_for(speed)
@options.find { |rate| rate.speed === speed }
end
end
attr_reader :speed, :success_rate
def initialize(speed)
@speed = speed
@success_rate = SuccessRate.detect_for(speed)
end
CARS_PRODUCED_PER_HOUR = 221.0
def production_rate_per_hour
@production_rate_per_hour ||= (CARS_PRODUCED_PER_HOUR * speed) * success_rate.percentage
end
ONE_HOUR_IN_MINUTES = 60
def working_items_per_minute
@working_items_per_minute ||= (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
end
end
class AssemblyLine
SuccessRate = Struct.new(:speed, :percentage, keyword_init: true) do
@options = [
new(speed: 1..4, percentage: 1.00),
new(speed: 5..8, percentage: 0.90),
new(speed: 9, percentage: 0.80),
new(speed: 10, percentage: 0.77)
].map!(&:freeze).freeze
def self.detect_for(speed)
@options.detect { |rate| rate.speed === speed }
end
end
attr_reader :speed, :success_rate
def initialize(speed)
@speed = speed
@success_rate = SuccessRate.detect_for(speed)
end
CARS_PRODUCED_PER_HOUR = 221.0
def production_rate_per_hour
@production_rate_per_hour ||= (CARS_PRODUCED_PER_HOUR * speed) * success_rate.percentage
end
ONE_HOUR_IN_MINUTES = 60
def working_items_per_minute
@working_items_per_minute ||= (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
end
end
class AssemblyLine
SuccessRate = Struct.new(:speed, :percentage, keyword_init: true) do
private_class_method :new
@options = [
new(speed: 1..4, percentage: 1.00),
new(speed: 5..8, percentage: 0.90),
new(speed: 9, percentage: 0.80),
new(speed: 10, percentage: 0.77)
].map!(&:freeze).freeze
def self.detect_for(speed)
@options.detect { |rate| rate.speed === speed }
end
end
attr_reader :speed, :success_rate
def initialize(speed)
@speed = speed
@success_rate = SuccessRate.detect_for(speed)
end
CARS_PRODUCED_PER_HOUR = 221.0
def production_rate_per_hour
@production_rate_per_hour ||= (CARS_PRODUCED_PER_HOUR * speed) * success_rate.percentage
end
ONE_HOUR_IN_MINUTES = 60
def working_items_per_minute
@working_items_per_minute ||= (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
end
end
@serradura
Copy link
Author

serradura commented Jan 14, 2023

I am adding an alternative (more procedural) implementation that "combines" all the iterations.

class AssemblyLine
  module SuccessRate
    def self.percentage(speed)
      case speed
      when 1..4 then 1.00
      when 5..8 then 0.90
      when 9    then 0.80
      when 10   then 0.77
      end
    end
  end

  attr_reader :speed

  def initialize(speed)
    @speed = speed
  end

  CARS_PRODUCED_PER_HOUR = 221.0

  def production_rate_per_hour
    @production_rate_per_hour ||= (CARS_PRODUCED_PER_HOUR * speed) * SuccessRate.percentage(speed)
  end

  ONE_HOUR_IN_MINUTES = 60

  def working_items_per_minute
    @working_items_per_minute ||= (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
  end
end

@serradura
Copy link
Author

This implementation is based on this suggestion: https://t.me/rubybrasil/241887

class AssemblyLine
  SuccessRate = Struct.new(:percentage) do
    def self.where_speed(speed)
      percentage = 
        case speed
        when 1..4 then 1.00
        when 5..8 then 0.90
        when 9    then 0.80
        when 10   then 0.77
        end

      new(percentage)
    end
  end

  attr_reader :speed

  def initialize(speed)
    @speed = speed
  end

  CARS_PRODUCED_PER_HOUR = 221.0

  def production_rate_per_hour
    @production_rate_per_hour ||= (CARS_PRODUCED_PER_HOUR * speed) * SuccessRate.where_speed(speed).percentage
  end

  ONE_HOUR_IN_MINUTES = 60

  def working_items_per_minute
    @working_items_per_minute ||= (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
  end
end

@serradura
Copy link
Author

The simplest version.

class AssemblyLine      
  def initialize(speed)
    @speed = speed
  end

  def production_rate_per_hour
    succes_rate = 
      case @speed
      when 1..4 then 1.00
      when 5..8 then 0.90
      when 9    then 0.80
      when 10   then 0.77
      end
      
    (221.0 * @speed) * succes_rate
  end

  def working_items_per_minute
    (production_rate_per_hour / 60).to_i
  end
end

And an iteration that adds constants to reduce the magic numbers code smell.

class AssemblyLine
  def initialize(speed)
    @speed = speed
  end

  CARS_PRODUCED_PER_HOUR = 221.0

  def production_rate_per_hour
    succes_rate =
      case @speed
      when 1..4 then 1.00
      when 5..8 then 0.90
      when 9    then 0.80
      when 10   then 0.77
      end

    (CARS_PRODUCED_PER_HOUR * @speed) * succes_rate
  end

  ONE_HOUR_IN_MINUTES = 60

  def working_items_per_minute
    (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
  end
end

@serradura
Copy link
Author

class AssemblyLine
  SuccessRate = Struct.new(:speed) do
    def percentage
      case speed
      when 1..4 then 1.00
      when 5..8 then 0.90
      when 9    then 0.80
      when 10   then 0.77
      end
    end

    def coerce(other)
      [other, percentage]
    end
  end

  attr_reader :speed

  def initialize(speed)
    @speed = speed
  end

  CARS_PRODUCED_PER_HOUR = 221.0

  def production_rate_per_hour
    (CARS_PRODUCED_PER_HOUR * speed) * SuccessRate[speed]
  end

  ONE_HOUR_IN_MINUTES = 60

  def working_items_per_minute
    (production_rate_per_hour / ONE_HOUR_IN_MINUTES).to_i
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment