Search code examples
pythonclasstemperature

Python Temperature class converter (K,F,C)


Here's what's I'm trying to do : I want to code a working python class that convert everything by himself just by giving it a random value.

What I want exactly is the following :

>>> first=Temperature()
>>> first.celsius = 60
>>> first.kelvin
333.15
>>> first.fahrenheit
140

And whatever the first descriptor I set-up, I want the others to convert by themselves, even if I do the following :

>>> first.celsius = 60
>>> first.kelvin
333.15
>>> first.celsius += 1
>>> first.kelvin
334.15

Here's the code I've been working on :

class Celsius:
    def __get__(self, instance, owner):
        return 5 * (instance.fahrenheit - 32) / 9
    def __set__(self, instance, value):
        instance.fahrenheit = 32 + 9 * value / 5
    def __set__(self, instance, value):
        instance.kelvin = value + 273.15

class Temperature:
    celsius = Celsius()
    def __init__(self):
        self.fahrenheit = 0
    def __init__(self):
        self.kelvin = 0

Some things are working, but the convert back is not working well and it makes some errors but I really don't know how to make this work, would appreciate some help, even if you guys give me a 20 pages documentation.


Solution

  • What you need are properties. Use one common internal value and set it based on the property set:

    class Temperature:
        def __init__(self):
            self.__kelvin = 273.15
    
        @property
        def kelvin(self):
            return self.__kelvin
    
        @property
        def celsius(self):
            return self.__kelvin - 273.15
    
        @property
        def fahrenheit(self):
            return (self.__kelvin - 273.15) * 9 / 5 + 32
    
        @kelvin.setter
        def kelvin(self,value):
            self.__kelvin = value
    
        @celsius.setter
        def celsius(self,value):
            self.__kelvin = value + 273.15
    
        @fahrenheit.setter
        def fahrenheit(self,value):
            self.__kelvin = (value - 32) * 5 / 9 + 273.15
    
        def __repr__(self):
            return f'Temperature(__kelvin={self.__kelvin})'
    
        def __str__(self):
            return f'{self.kelvin:.2f}\N{DEGREE SIGN}K/{self.celsius:.2f}\N{DEGREE SIGN}C/{self.fahrenheit:.2f}\N{DEGREE SIGN}F'
    
    first = Temperature()
    print(first)
    first.kelvin = 0
    print(first)
    first.fahrenheit = 212
    print(first)
    first.celsius = 10
    print(first)
    

    Output:

    273.15°K/0.00°C/32.00°F
    0.00°K/-273.15°C/-459.67°F
    373.15°K/100.00°C/212.00°F
    283.15°K/10.00°C/50.00°F