Assembly Line

The skeleton of the class is provided to us with the methods named by whoever created this challenge. The tests themselves check on those specific methods. Yet, production_rate_per_hour doesn’t sound like the best name as it actually calculates the success production rate per hour.

Solution 1

Using if/elsif/else like explained on the exercise page.

class AssemblyLine
  CARS_PER_HOUR = 221

  def initialize(speed)
    @speed = speed
  end

  def production_rate_per_hour
    if @speed <= 4
      @speed * AssemblyLine::CARS_PER_HOUR * 1.0
    elsif 5 <= @speed && @speed <= 8
      @speed * AssemblyLine::CARS_PER_HOUR * 0.9
    elsif @speed == 9
      @speed * AssemblyLine::CARS_PER_HOUR * 0.8
    else
      @speed * AssemblyLine::CARS_PER_HOUR * 0.77
    end
  end

  def working_items_per_minute
    (production_rate_per_hour / 60).to_i
  end
end

Solution 2

This approach uses some procs provided through a module which are then tested against on the when clases. Maybe a bit overkill but just to try another approach.

module RANGES
  FOR_ONE_HUNDRED_PERCENT = proc { |speed| speed <= 4 }
  FOR_NINETY_PERCENT = proc { |speed| 5 <= speed && speed <= 8 }
  FOR_EIGHTY_PERCENT = proc { |speed| speed == 9 }
  FOR_SEVENTY_SEVEN_PERCENT = proc { |speed| speed > 9 }
end

class AssemblyLine
  include RANGES

  CARS_PER_HOUR = 221

  def initialize(speed)
    @speed = speed
  end

  def production_rate_per_hour
    case @speed
    when FOR_ONE_HUNDRED_PERCENT
      @speed * AssemblyLine::CARS_PER_HOUR * 1.0
    when FOR_NINETY_PERCENT
      @speed * AssemblyLine::CARS_PER_HOUR * 0.9
    when FOR_EIGHTY_PERCENT
      @speed * AssemblyLine::CARS_PER_HOUR * 0.8
    when FOR_SEVENTY_SEVEN_PERCENT
      @speed * AssemblyLine::CARS_PER_HOUR * 0.77
    end
  end

  def working_items_per_minute
    (production_rate_per_hour / 60).to_i
  end
end

Solution 3

Using ranges instead of procs.

class AssemblyLine
  CARS_PER_HOUR = 221

  def initialize(speed)
    @speed = speed
  end

  def production_rate_per_hour
    case @speed
    when 1..4
      @speed * CARS_PER_HOUR * 1.0
    when 5..8
      @speed * CARS_PER_HOUR * 0.9
    when 9
      @speed * CARS_PER_HOUR * 0.8
    when 10
      @speed * CARS_PER_HOUR * 0.77
    else
      raise "Speed ‘#{@speed}’ is out of the range 1..10."
    end
  end

  def working_items_per_minute
    (production_rate_per_hour / 60).to_i
  end
end

Solution 4

Using ranges. As in Ruby almost everything is an expression that returns a value, we case use the case/when to return the percentage in decimal and avoid repeating the similar calculation four times.

class AssemblyLine
  CARS_PER_HOUR = 221

  def initialize(speed)
    @speed = speed
  end

  def production_rate_per_hour
    @speed * CARS_PER_HOUR *
      case @speed
      when 1..4
        1.0
      when 5..8
        0.9
      when 9
        0.8
      when 10
        0.77
      end
  end

  def working_items_per_minute
    (production_rate_per_hour / 60).to_i
  end
end

Solution 5

I like it that I can read in one line how the production_rate_per_hour is computed and which part of this formula changes depending on the speed. The other solution requires me to check four different formulas and figure out how they differ.

— Lapizistik