diff --git a/sasdata/quantities/_build_tables.py b/sasdata/quantities/_build_tables.py index c07497471..ba07aee80 100644 --- a/sasdata/quantities/_build_tables.py +++ b/sasdata/quantities/_build_tables.py @@ -68,6 +68,7 @@ UnitData("y", None, None, "year", "years", 3600*24*365.2425, 0, 1, 0, 0, 0, 0, 0, []), UnitData("deg", None, None, "degree", "degrees", 180/np.pi, 0, 0, 0, 0, 0, 0, 1, []), UnitData("rad", None, None, "radian", "radians", 1, 0, 0, 0, 0, 0, 0, 1, []), + UnitData("rot", None, None, "rotation", "rotations", 2*np.pi, 0, 0, 0, 0, 0, 0, 1, []), UnitData("sr", None, None, "stradian", "stradians", 1, 0, 0, 0, 0, 0, 0, 2, []), UnitData("l", None, None, "litre", "litres", 1e-3, 3, 0, 0, 0, 0, 0, 0, []), UnitData("eV", None, None, "electronvolt", "electronvolts", 1.602176634e-19, 2, -2, 1, 0, 0, 0, 0, all_magnitudes), diff --git a/sasdata/quantities/_units_base.py b/sasdata/quantities/_units_base.py index 17897f895..9e6401b53 100644 --- a/sasdata/quantities/_units_base.py +++ b/sasdata/quantities/_units_base.py @@ -214,17 +214,20 @@ def _components(self, tokens: Sequence["UnitToken"]): pass def __mul__(self: Self, other: "Unit"): - if not isinstance(other, Unit): - return NotImplemented - - return Unit(self.scale * other.scale, self.dimensions * other.dimensions) + if isinstance(other, Unit): + return Unit(self.scale * other.scale, self.dimensions * other.dimensions) + elif isinstance(other, (int, float)): + return Unit(other * self.scale, self.dimensions) + return NotImplemented def __truediv__(self: Self, other: "Unit"): - if not isinstance(other, Unit): + if isinstance(other, Unit): + return Unit(self.scale / other.scale, self.dimensions / other.dimensions) + elif isinstance(other, (int, float)): + return Unit(self.scale / other, self.dimensions) + else: return NotImplemented - return Unit(self.scale / other.scale, self.dimensions / other.dimensions) - def __rtruediv__(self: Self, other: "Unit"): if isinstance(other, Unit): return Unit(other.scale / self.scale, other.dimensions / self.dimensions) diff --git a/sasdata/quantities/units.py b/sasdata/quantities/units.py index 8af224043..7d03abda0 100644 --- a/sasdata/quantities/units.py +++ b/sasdata/quantities/units.py @@ -299,17 +299,20 @@ def _components(self, tokens: Sequence["UnitToken"]): pass def __mul__(self: Self, other: "Unit"): - if not isinstance(other, Unit): - return NotImplemented - - return Unit(self.scale * other.scale, self.dimensions * other.dimensions) + if isinstance(other, Unit): + return Unit(self.scale * other.scale, self.dimensions * other.dimensions) + elif isinstance(other, (int, float)): + return Unit(other * self.scale, self.dimensions) + return NotImplemented def __truediv__(self: Self, other: "Unit"): - if not isinstance(other, Unit): + if isinstance(other, Unit): + return Unit(self.scale / other.scale, self.dimensions / other.dimensions) + elif isinstance(other, (int, float)): + return Unit(self.scale / other, self.dimensions) + else: return NotImplemented - return Unit(self.scale / other.scale, self.dimensions / other.dimensions) - def __rtruediv__(self: Self, other: "Unit"): if isinstance(other, Unit): return Unit(other.scale / self.scale, other.dimensions / self.dimensions) @@ -692,6 +695,7 @@ def __init__(self, name: str, units: list[NamedUnit]): years = NamedUnit(31556952.0, Dimensions(0, 1, 0, 0, 0, 0, 0),name='years',ascii_symbol='y',symbol='y') degrees = NamedUnit(57.29577951308232, Dimensions(0, 0, 0, 0, 0, 0, 1),name='degrees',ascii_symbol='deg',symbol='deg') radians = NamedUnit(1, Dimensions(0, 0, 0, 0, 0, 0, 1),name='radians',ascii_symbol='rad',symbol='rad') +rotations = NamedUnit(6.283185307179586, Dimensions(0, 0, 0, 0, 0, 0, 1),name='rotations',ascii_symbol='rot',symbol='rot') stradians = NamedUnit(1, Dimensions(0, 0, 0, 0, 0, 0, 2),name='stradians',ascii_symbol='sr',symbol='sr') litres = NamedUnit(0.001, Dimensions(3, 0, 0, 0, 0, 0, 0),name='litres',ascii_symbol='l',symbol='l') electronvolts = NamedUnit(1.602176634e-19, Dimensions(2, -2, 1, 0, 0, 0, 0),name='electronvolts',ascii_symbol='eV',symbol='eV') @@ -2052,6 +2056,7 @@ def __init__(self, name: str, units: list[NamedUnit]): "y": years, "deg": degrees, "rad": radians, + "rot": rotations, "sr": stradians, "l": litres, "eV": electronvolts, @@ -3385,6 +3390,7 @@ def __init__(self, name: str, units: list[NamedUnit]): units = [ degrees, radians, + rotations, ]) solid_angle = UnitGroup( diff --git a/test/quantities/utest_units.py b/test/quantities/utest_units.py index 258143e2a..3bc775313 100644 --- a/test/quantities/utest_units.py +++ b/test/quantities/utest_units.py @@ -1,3 +1,5 @@ +import math + import sasdata.quantities.units as units from sasdata.quantities.units import Unit @@ -9,7 +11,7 @@ def __init__(self, test_name: str, *units): def run_test(self): for i, unit_1 in enumerate(self.units): - for unit_2 in self.units[i+1:]: + for unit_2 in self.units[i + 1 :]: assert unit_1.equivalent(unit_2), "Units should be equivalent" assert unit_1 == unit_2, "Units should be equal" @@ -21,11 +23,22 @@ def __init__(self, test_name: str, *units): def run_test(self): for i, unit_1 in enumerate(self.units): - for unit_2 in self.units[i+1:]: + for unit_2 in self.units[i + 1 :]: assert unit_1.equivalent(unit_2), "Units should be equivalent" assert unit_1 != unit_2, "Units should not be equal" +class DissimilarUnits: + def __init__(self, test_name: str, *units): + self.test_name = "Dissimilar: " + test_name + self.units: list[Unit] = list(units) + + def run_test(self): + for i, unit_1 in enumerate(self.units): + for unit_2 in self.units[i + 1 :]: + assert not unit_1.equivalent(unit_2), "Units should not be equivalent" + + tests = [ EqualUnits("Pressure", @@ -36,7 +49,19 @@ def run_test(self): EqualUnits("Resistance", units.ohms, units.volts / units.amperes, - 1e-3/units.millisiemens) + 1e-3/units.millisiemens), + + EquivalentButUnequalUnits("Angular frequency", + units.rotations / units.minutes, + units.degrees * units.hertz), + + EqualUnits("Angular frequency", + (units.rotations/units.minutes ), + (units.radians*units.hertz) * 2 * math.pi/60.0), + + DissimilarUnits("Frequency and Angular frequency", + (units.rotations/units.minutes), + (units.hertz)), ]