So I'm trying to understand the concept of descriptors and gathered some code together and made an exampel out of different sources. Like the offical documentation and StackOverflow answers. I'd hope someone can me tell some tricks about this concept or how to make this code better in general. Thanks in advanced.
PS: If someon could tell me why celsius needs to be 9_007_199_254_740_991 + 1 higher instead of just * += 1 * would be nice to know.
from abc import ABC
class Validator(ABC):
def __set_name__(self,owner,name):
self.private_name = '_' + name
def __get__(self,obj,objtype=None):
return getattr(obj,self.private_name)
def __set__(self,obj,value):
self.validate(obj,value)
rval = round(value,3)
setattr(obj,self.private_name,rval)
return obj._notify(self.private_name.replace('_',''))
def validate(self,obj,value):
if not isinstance(value, (int, float)):
raise TypeError(f'Expected {value!r} to be an int or float')
if self.minvalue is not None and value < self.minvalue:
raise ValueError(
f'Expected {value!r} to be at least {self.minvalue!r}'
)
if self.maxvalue is not None and value > self.maxvalue:
raise ValueError(
f'Expected {value!r} to be no more than {self.maxvalue!r}'
)
class Celsius(Validator):
minvalue = -273.150 #Absolute zero
maxvalue = 1.42*pow(10,32) #Planck temperature
class Farenheit(Validator):
minvalue = -459.670 #Absolute zero
maxvalue = 2.55*pow(10,32) #Planck temperature
class Kelvin(Validator):
minvalue = 0 #Absolute zero
maxvalue = 1.417*pow(10,32) #Planck temperature
class Temperature( object ):
celsius= Celsius()
farenheit= Farenheit()
kelvin = Kelvin()
def __init__(self,typ='celsius',val=0.0):
setattr(self,typ,val)
def _notify(self,changed_by):
lst = ['celsius','farenheit','kelvin']
lst.remove(changed_by)
val = getattr(self,changed_by)
for i in lst:
con = getattr(Temperature,f'convert_{changed_by}_to_{i}')(val)
rcon= round(con,3)
setattr(self,'_'+i,rcon)
@staticmethod
def convert_kelvin_to_celsius(kelvin) -> celsius:
return kelvin-273.15
@staticmethod
def convert_celsius_to_kelvin(celsius) -> kelvin:
return celsius+273.15
@staticmethod
def convert_celsius_to_farenheit(celsius) -> farenheit:
return celsius*1.8+32
@staticmethod
def convert_kelvin_to_farenheit(kelvin) -> farenheit:
return kelvin*1.8-459.67
@staticmethod
def convert_farenheit_to_kelvin(farenheit) -> kelvin:
return (farenheit+459.67)*1.8
@staticmethod
def convert_farenheit_to_celsius(farenheit) -> celsius:
return (farenheit-32)*1.8
if __name__ == '__main__':
t = Temperature(typ='celsius',val=0.0)
print(t.kelvin,t.farenheit)
t.celsius = -273.15
print(t.kelvin,t.farenheit)
t.celsius = 1.42*pow(10,32)
print(t.kelvin,t.farenheit)
t.celsius += 9_007_199_254_740_991 #+ 1
Output
273.15 32.0
0.0 -459.67
1.42e+32 2.556e+32