Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 88 additions & 140 deletions pytrnsys/utils/unitConverter.py
Original file line number Diff line number Diff line change
@@ -1,151 +1,99 @@
# pylint: skip-file
# type: ignore

#!/usr/bin/python

"""
File to do basic conversion units
Author : Daniel Carbonell
Date : 2014
ToDo :
"""
import typing as _typ


def getkPaToBar():
return 1.0 / 101.3


def getPaToBar():
return 1.0 / 101300


def getBarToPa():
return 101300.0


def getPaToMmca():
return 1.0 / 9.80665


def getPaToMca():
return 1.0 / 9806.65


def getBarToMmca():
return 101300.0 / 9.80665


def getPaTokgCm2():
return 1.0 / 98066.52


def getkgCm2ToPa():
return 98066.52


def getPsiToPa():
return 6894.757293178


def getPaToPsi():
return 0.000145038


# Energy


def getJTokWh():
return 1e-6 / 3.6


def getkWhToJ():
return 3.6 * 1e6


def getkWhToMJ():
return 3.6


def getJToMWh():
return 1e-9 / 3.6


def getkJToMWh():
return 1e-6 / 3.6


def getMJTokWh():
return 1.0 / 3.6


def getKJhToW():
return 1.0 / 3.6


def getWToKJh():
return 3.6
# BEGIN-NOSCAN
# this function is ignored when a function exists.
def __getattr__(name: str):
# END-NOSCAN
if name == "UnitConverter":
raise ValueError
return getattr(UnitConverter(), name)


class UnitConverter:
def __init__(self):

unit = ""

# PRESSURE

def getkPaToBar(self):
return 1.0 / 101.3

def getPaToBar(self):
return 1.0 / 101300

def getBarToPa(self):
return 101300.0

def getPaToMmca(self):
return 1.0 / 9.80665

def getPaToMca(self):
return 1.0 / 9806.65

def getBarToMmca(self):
return 101300.0 / 9.80665

def getPaTokgCm2(self):
return 1.0 / 98066.52

def getkgCm2ToPa(self):
return 98066.52

def getPsiToPa(self):
return 6894.757293178

def getPaToPsi(self):
return 0.000145038

# Energy

def getJTokWh(self):
return 1e-6 / 3.6

def getkWhToJ(self):
return 3.6 * 1e6

def getJToMWh(self):
return 1e-9 / 3.6

def getkJToMWh(self):
return 1e-6 / 3.6

def getMJTokWh(self):
return 1.0 / 3.6

def getKJhToW(self):
return 1.0 / 3.6

def getWToKJh(self):
return 3.6

self.unit: str = ""
self._conversionFactor: _typ.Optional[float] = None
self._method: _typ.Optional[str] = None
self._factors: dict = {
"kPaToBar": 1.0 / 101.3,
"PaToBar": 1.0 / 101300,
"BarToPa": 101300.0,
"PaToMca": 1.0 / 9806.65,
"PaToMmca": 1.0 / 9.80665,
"BarToMmca": 101300.0 / 9.80665,
"PaTokgCm2": 1.0 / 98066.52,
"kgCm2ToPa": 98066.52,
"PsiToPa": 6894.757293178,
"PaToPsi": 0.000145038,
"JTokWh": 1e-6 / 3.6,
"kWhToJ": 3.6 * 1e6,
"kWhToMJ": 3.6,
"JToMWh": 1e-9 / 3.6,
"kJToMWh": 1e-6 / 3.6,
"MJTokWh": 1.0 / 3.6,
"kJhToW": 1.0 / 3.6,
"WTokJh": 3.6,
}
self._conversionMethods: dict = {
"getkPaToBar": "kPaToBar",
"getPaToBar": "PaToBar",
"getBarToPa": "BarToPa",
"getPaToMca": "PaToMca",
"getPaToMmca": "PaToMmca",
"getBarToMmca": "BarToMmca",
"getPaTokgCm2": "PaTokgCm2",
"getkgCm2ToPa": "kgCm2ToPa",
"getPsiToPa": "PsiToPa",
"getPaToPsi": "PaToPsi",
"getJTokWh": "JTokWh",
"getkWhToJ": "kWhToJ",
"getkWhToMJ": "kWhToMJ",
"getJToMWh": "JToMWh",
"getkJToMWh": "kJToMWh",
"getMJTokWh": "MJTokWh",
"getkJhToW": "kJhToW",
"getWTokJh": "WTokJh",
"getKJhToW": "kJhToW",
"getWToKJh": "WTokJh",
}

def getAvailableConversions(self) -> list:
return list(self._factors.keys())

def setConversionFactor(self, name: str):
self._conversionFactor = self.getConversionFactor(name)

def convert(self, value: float, desiredConversionFactor=None) -> float:
if desiredConversionFactor:
factor = self.getConversionFactor(desiredConversionFactor)
elif self._conversionFactor:
factor = self._conversionFactor
else:
raise ValueError("Conversion factor not given. Either use UnitConverter.setConversionFactor, "
"or provide a desiredConversionFactor.")

return factor * value

def getConversionFactor(self, conversionType: _typ.Optional[str]) -> float:
if conversionType in self.getAvailableConversions():
return self._factors[conversionType]

raise ValueError(f"Unkown conversion type: {conversionType}")

def __getattr__(self, item: str):
self._method = self._conversionMethods[item]
return self._helperFunction

def _helperFunction(self) -> float:
return self.getConversionFactor(self._method)


def dummyFunction():
# Used to test the __getattr__ implementation
pass

# /* Power */
#
Expand Down
Empty file.
151 changes: 151 additions & 0 deletions tests/pytrnsys/utils/testUnitConverter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import pytest as _pt

import pytrnsys.utils.unitConverter as _uc

_TOLERANCE = 1e-9
_CONVERSION_METHODS = [
"getkPaToBar",
"getPaToBar",
"getBarToPa",
"getPaToMca",
"getPaToMmca",
"getBarToMmca",
"getPaTokgCm2",
"getkgCm2ToPa",
"getPsiToPa",
"getPaToPsi",
"getJTokWh",
"getkWhToJ",
"getkWhToMJ",
"getJToMWh",
"getkJToMWh",
"getMJTokWh",
"getkJhToW",
"getWTokJh",
"getKJhToW",
"getWToKJh",
]

_CONVERSION_FACTORS = [
0.009871668311944718,
9.87166831194472e-06,
101300.0,
0.00010197162129779283,
0.10197162129779283,
10329.725237466413,
1.0197160050137396e-05,
98066.52,
6894.757293178,
0.000145038,
2.7777777777777776e-07,
3600000.0,
3.6,
2.7777777777777777e-10,
2.7777777777777776e-07,
0.2777777777777778,
0.2777777777777778,
3.6,
0.2777777777777778,
3.6,
]
_CONVERSION_NAMES = [
"kPaToBar",
"PaToBar",
"BarToPa",
"PaToMca",
"PaToMmca",
"BarToMmca",
"PaTokgCm2",
"kgCm2ToPa",
"PsiToPa",
"PaToPsi",
"JTokWh",
"kWhToJ",
"kWhToMJ",
"JToMWh",
"kJToMWh",
"MJTokWh",
"kJhToW",
"WTokJh",
]

_METHOD_CASES = list(zip(_CONVERSION_METHODS, _CONVERSION_FACTORS))
_CONVERSION_NAME_CASES = list(zip(_CONVERSION_NAMES, _CONVERSION_FACTORS))


def _getRelativeError(value, value2):
maxValue = abs(max(value, value2))
if maxValue != 0.0:
return abs(value - value2) / maxValue
return 0.0


def testGetRelativeErrorZeros():
assert _getRelativeError(0, 0) == 0
assert _getRelativeError(0.0, 0) == 0
assert _getRelativeError(0.0, 0.0) == 0


class TestGetAttrFromModule:
@staticmethod
def testIgnoreEntirely():
assert hasattr(_uc.dummyFunction, '__call__')
assert not _uc.dummyFunction()

@staticmethod
def testGetAttrFromModuleRaises():
with _pt.raises(ValueError):
_uc.__getattr__("UnitConverter")

@staticmethod
def testGetAttrFromModuleDoesNotRaise():
try:
_uc.UnitConverter
except ValueError:
_pt.fail(f"Unexpected exception: {ValueError}")


class TestUnitConverter:
def setup(self):
self.converter = _uc.UnitConverter() # pylint: disable=attribute-defined-outside-init

def _testHelper(self, method, value):
conversionRate = getattr(_uc, method)()
conversionRate2 = getattr(self.converter, method)()
assert _getRelativeError(conversionRate, value) < _TOLERANCE
assert conversionRate == conversionRate2

@_pt.mark.parametrize("method, factor", _METHOD_CASES)
def testGetConversionUsingIndividualMethods(self, method, factor):
self._testHelper(method, factor)

@_pt.mark.parametrize("name, factor", _CONVERSION_NAME_CASES)
def testGetConversionFactor(self, name, factor):
result = self.converter.getConversionFactor(name)
assert result == factor

def testGetConversionFactorRaises(self):
with _pt.raises(ValueError):
self.converter.getConversionFactor("test")

def testGetAvailableConversions(self):
names = self.converter.getAvailableConversions()
assert names == _CONVERSION_NAMES

@_pt.mark.parametrize("name, factor", _CONVERSION_NAME_CASES)
def testConversionsUsingConstantConverter(self, name, factor):
self.converter.setConversionFactor(name)
assert self.converter.convert(1) == factor

@_pt.mark.parametrize("name, factor", _CONVERSION_NAME_CASES)
def testConversionsOverridingAssignedFactor(self, name, factor):
self.converter.setConversionFactor("kPaToBar")
assert self.converter.convert(1, desiredConversionFactor=name) == factor

@_pt.mark.parametrize("name, factor", _CONVERSION_NAME_CASES)
def testConversionsWithoutAssigningFactorBeforehand(self, name, factor):
assert self.converter.convert(1, desiredConversionFactor=name) == factor

def testConversionsWithoutFactorRaises(self):
with _pt.raises(ValueError):
self.converter.convert(1)