HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Simple medication dosage calculator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
medicationsimpledosagecalculator

Problem

I am a nurse and I'm learning to code. I have coded this simple tool that helps me doing some common nursing formulas for medication. It works, however I think it is too bulky/redundant. Can you help me with some ideas for refactoring it?

class NursingFormulas
  def initialize
    puts "What do you want to do?"
    puts "1) How many tablets should I administer?"
    puts "2) How many ml should I administer?"
    puts "3) What's the ml per hour rate of my IV?"
    puts "4) What's the drop rate of my IV?"
    puts "5) Exit"
    choice = gets.chomp.to_i
    case choice
    when 1 then mass_for_mass
    when 2 then mass_for_liquid
    when 3 then iv_ml_rate
    when 4 then iv_drop_rate
    when 5 then exit(0)
    else
      exit(0)
    end
  end

  def mass_for_mass
    puts "What's the prescribed mass in mg?"
    prescribed = gets.chomp.to_f
    puts "What's the mass you've got in mg?"
    mass = gets.chomp.to_f
    result = prescribed / mass
    puts "Administer #{result} tablets"
  end

  def mass_for_liquid
    puts "What's the prescribed mass in mg?"
    prescribed = gets.chomp.to_f
    puts "What's the mass you've got in mg?"
    mass = gets.chomp.to_f
    puts "How many mL do you have?"
    ml = gets.chomp.to_f
    result = (prescribed / mass) * ml
    puts "Administer #{result} ml"
  end

  def iv_ml_rate
    puts "What's the volume in mL?"
    volume = gets.chomp.to_f
    puts "What's the time in hours?"
    time = gets.chomp.to_f
    result = (volume / time).round
    puts "The rate is #{result} ml per hour"
  end

  def iv_drop_rate
    puts "What's the volume in mL?"
    volume = gets.chomp.to_f
    puts "What's the time in hours?"
    time = gets.chomp.to_f
    time = time * 60
    puts "What's the drop factor?"
    factor = gets.chomp.to_f
    result = ((volume / time) * factor).round
    puts "The drop rate is #{result} drops per minute"
  end
end

Solution

Here is a solution using the Command Pattern.

Each action will live in its own class. I'm using some mixins so we don't have repeated code.

nursing_formulas.rb

require_relative "formulas/mass_for_mass"
require_relative "formulas/mass_for_liquid"
require_relative "formulas/iv_ml_rate"
require_relative "formulas/iv_drop_rate"

class NursingFormulas
  def initialize
    show_instructions

    @instructions = {
      1 => MassForMass.new,
      2 => MassForLiquid.new,
      3 => IvMlRate.new,
      4 => IvDropRate.new
    }

    choice = gets.chomp.to_i

    @instructions.key?(choice) ? @instructions[choice].do : exit(0)
  end

  def show_instructions
    puts "What do you want to do?"
    puts "1) How many tablets should I administer?"
    puts "2) How many ml should I administer?"
    puts "3) What's the ml per hour rate of my IV?"
    puts "4) What's the drop rate of my IV?"
    puts "5) Exit"
  end
end


mass_for_mass.rb

require_relative "mixins/mass_actions"

class MassForMass
  include MassActions

  def do
    result = ask_for_prescribed_mass / ask_for_mass
    puts "Administer #{result} tablets"
  end
end


mass_for_liquid.rb

require_relative "mixins/mass_actions"

class MassForLiquid
  include MassActions

  def do
    prescribed = ask_for_prescribed_mass
    mass = ask_for_mass
    ml = ask_for_ml

    result = (prescribed / mass) * ml
    puts "Administer #{result} ml"
  end

  def ask_for_ml
    puts "How many mL do you have?"
    gets.chomp.to_f
  end
end


iv_ml_rate.rb

require_relative "mixins/iv_actions"

class IvMlRate
  include IvActions

  def do
    volume = ask_for_volume
    time = ask_for_time

    result = (volume / time).round
    puts "The rate is #{result} ml per hour"
  end
end


iv_drop_rate.rb

require_relative "mixins/iv_actions"

class IvDropRate
  include IvActions

  def do
    volume = ask_for_volume
    time_in_min = ask_for_time * 60
    factor = ask_for_drop_factor

    result = ((volume / time_in_min) * factor).round
    puts "The drop rate is #{result} drops per minute"
  end

  def ask_for_drop_factor
    puts "What's the drop factor?"
    gets.chomp.to_f
  end
end


MIXINS

mass_actions.rb

module MassActions
  def ask_for_prescribed_mass
    puts "What's the prescribed mass in mg?"
    gets.chomp.to_f
  end

  def ask_for_mass
    puts "What's the mass you've got in mg?"
    gets.chomp.to_f
  end
end


iv_actions.rb

module IvActions
  def ask_for_volume
    puts "What's the volume in mL?"
    gets.chomp.to_f
  end

  def ask_for_time
    puts "What's the time in hours?"
    gets.chomp.to_f
  end
end

Code Snippets

require_relative "formulas/mass_for_mass"
require_relative "formulas/mass_for_liquid"
require_relative "formulas/iv_ml_rate"
require_relative "formulas/iv_drop_rate"

class NursingFormulas
  def initialize
    show_instructions

    @instructions = {
      1 => MassForMass.new,
      2 => MassForLiquid.new,
      3 => IvMlRate.new,
      4 => IvDropRate.new
    }

    choice = gets.chomp.to_i

    @instructions.key?(choice) ? @instructions[choice].do : exit(0)
  end

  def show_instructions
    puts "What do you want to do?"
    puts "1) How many tablets should I administer?"
    puts "2) How many ml should I administer?"
    puts "3) What's the ml per hour rate of my IV?"
    puts "4) What's the drop rate of my IV?"
    puts "5) Exit"
  end
end
require_relative "mixins/mass_actions"

class MassForMass
  include MassActions

  def do
    result = ask_for_prescribed_mass / ask_for_mass
    puts "Administer #{result} tablets"
  end
end
require_relative "mixins/mass_actions"

class MassForLiquid
  include MassActions

  def do
    prescribed = ask_for_prescribed_mass
    mass = ask_for_mass
    ml = ask_for_ml

    result = (prescribed / mass) * ml
    puts "Administer #{result} ml"
  end

  def ask_for_ml
    puts "How many mL do you have?"
    gets.chomp.to_f
  end
end
require_relative "mixins/iv_actions"

class IvMlRate
  include IvActions

  def do
    volume = ask_for_volume
    time = ask_for_time

    result = (volume / time).round
    puts "The rate is #{result} ml per hour"
  end
end
require_relative "mixins/iv_actions"

class IvDropRate
  include IvActions

  def do
    volume = ask_for_volume
    time_in_min = ask_for_time * 60
    factor = ask_for_drop_factor

    result = ((volume / time_in_min) * factor).round
    puts "The drop rate is #{result} drops per minute"
  end

  def ask_for_drop_factor
    puts "What's the drop factor?"
    gets.chomp.to_f
  end
end

Context

StackExchange Code Review Q#118211, answer score: 2

Revisions (0)

No revisions yet.