2
\$\begingroup\$
  1. Design a temperature class for nurses to store patient temperature and the method of taking the temperature.
  2. How would you handle different units of temperature? Write a function to determine if a patient has a fever.

My approach

class Temperature
    attr_accessor :temp, :method

    def initialize(temp,method)
        @temp = temp
        @method =method
    end

end

class Celsius < Temperature

    TEMP = 37

    def has_fever
        if temp > TEMP
            true
        else
            false
        end
    end

end

class Fahrenheit < Temperature

    TEMP =98.6

        def has_fever
            if temp > TEMP
                true
            else
                false
            end
        end
end

I know there is a code duplication in Celsius and Fahrenheit class. I tried declaring has_fever method in Temperature class but it didn't work. It says "uninitialized constant Temperature::TEMP".

Is there something to improve this design?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Make the base class meaningful

Right now you've declared Temperature as a base class, but all it really does is set up your two variables. One way to utilize it more would be to assign a unit of some sort to the class (I've chosen Kelvin, but it could have been anything).

In my version, Temperature stores everything as Kelvin. Any class that inherits from it only has to know how to convert back and forth to Kelvin (So Celsius<->Kelvin and Fahrenheit<->Kelvin). Later, if I wanted to add operators to add/subtract/compare temperatures, since the base units are all kelvin, everything is easy.

You'll also notice that I've moved has_temp? to the base class and the threshold temperature is in Kelvin. This gives all sub-classes the functionality without having to know anything about where the theshold is, and likewise the base class will always work without needing to know the details of a particular unit of measure.

Finally, while I've used Kelvin as the unit for Temperature, the base class could have just as easily been called Kelvin.

class Temperature
  attr_accessor :temp, :method

  FEVER_THRESHOLD = 310.15  # 98.6F to K

  def initialize(temp, method)
    @temp = temp
    @method =method
  end

  def to_s
    "#{@temp} K"
  end

  def has_fever?
    @temp > FEVER_THRESHOLD
  end
end


class Celsius < Temperature
  def self.to_k(value)
    value + 273.15
  end

  def self.from_k(value)
    value - 273.15
  end

  def initialize(temp, method)
    super(Celsius.to_k(temp), method)
  end

  def to_s
    "%0.2f C" % [Celsius.from_k(@temp)]
  end  
end


class Fahrenheit < Temperature
  def self.to_k(value)
    (value + 459.67) * (5.0/9.0)
  end

  def self.from_k(value)
    (value * 9.0/5.0) - 459.67
  end

  def initialize(temp, method)
    super(Fahrenheit.to_k(temp), method)
  end

  def to_s
    "%0.2f F" % [Fahrenheit.from_k(@temp)]
  end  
end

#test Celsius
temp = Celsius.new(39, nil)
puts temp.to_s         # 39.0 C
puts temp.has_fever?   # true

#test Fahrenheit
temp = Fahrenheit.new(97.9, nil)
puts temp.to_s         # 97.90 F
puts temp.has_fever?   # false

On a personal note, I wouldn't necessarily use inheritance as my go-to solution for this problem without a lot more knowledge and thought about the use-cases; I only followed your initial design. Temperatures themselves are fairly trivial, but perhaps for a more complicated scenario this implementation would have advantages.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.