The class below sets the pressure coefficients coeffs
based on the chemical name. In a real application, these coefficients might be read from a chemical database; therefore, getting the coefficients could take time to retrieve. This is demonstrated by the time.sleep()
associated with the coefficients variable.
import time
class Chemical:
def __init__(self, name):
self.name = name
def calc_pressure(self, temp):
if self.name == 'CO2':
time.sleep(2)
coeffs = [2, 5, 8.7]
elif self.name == 'H2O':
time.sleep(2)
coeffs = [9, 1, 0.4]
else:
print('Chemical not available')
return 0
press = (coeffs[0] * temp) + (coeffs[1] * temp**2) + (coeffs[2] * temp**3)
return press
Calculating the pressure for a range of temperatures is demonstrated below; the output is also shown. Notice the elapsed time for each loop is about 2 seconds because the coefficients are set during each iteration.
chem = Chemical('CO2')
for t in [25, 35.2, 45]:
ti = time.perf_counter()
press = chem.calc_pressure(temp=t)
tf = time.perf_counter()
print(f'Temp {t:5} | Press {press:,.2f} | Elapsed {tf - ti:.4f} s')
Temp 25 | Press 139,112.50 | Elapsed 2.0032 s
Temp 35.2 | Press 385,709.21 | Elapsed 2.0051 s
Temp 45 | Press 803,002.50 | Elapsed 2.0051 s
Since the class instance represents a particlar chemical, the coefficients only need to be determined once. Using the cached_property
from functools
allows the coefficients variable coeffs
to be a cached property of the class. This prevents the coefficients from being retrieved multiple times.
import time
from functools import cached_property
class Chemical:
def __init__(self, name):
self.name = name
@cached_property
def coeffs(self):
if self.name == 'CO2':
time.sleep(2)
coeff = [2, 5, 8.7]
elif self.name == 'H2O':
time.sleep(2)
coeff = [9, 1, 0.4]
return coeff
def calc_pressure(self, temp):
coeffs = self.coeffs
press = (coeffs[0] * temp) + (coeffs[1] * temp**2) + (coeffs[2] * temp**3)
return press
Now, calculating the pressure for a range of temperatures is significantly faster after the first iteration. Notice the elapsed time for the first loop is about 2 seconds and the remaining loops are practically zero.
chem = Chemical('CO2')
for t in [25, 35.2, 45]:
ti = time.perf_counter()
press = chem.calc_pressure(temp=t)
tf = time.perf_counter()
print(f'Temp {t:5} | Press {press:,.2f} | Elapsed {tf - ti:.4f} s')
Temp 25 | Press 139,112.50 | Elapsed 2.0043 s
Temp 35.2 | Press 385,709.21 | Elapsed 0.0000 s
Temp 45 | Press 803,002.50 | Elapsed 0.0000 s
Pythonic Programming © 2023
Built by Gavin Wiggins