From 963ff79ce3278911001315d87d2703f69cfa8f3f Mon Sep 17 00:00:00 2001 From: David Huang Date: Fri, 17 Apr 2026 11:05:15 +0100 Subject: [PATCH 1/2] feat: added value_in method to SIObject Allows for better readability compare to single division back to dimensionless quantity. Example: - obj / METER <- unclear if it is per meter or dimless - obj.value_in(METER) <- clear dimless numeric --- si-units/src/lib.rs | 7 +++++++ si-units/src/si_units/_core.pyi | 31 +++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/si-units/src/lib.rs b/si-units/src/lib.rs index f74b39d..dc36a43 100644 --- a/si-units/src/lib.rs +++ b/si-units/src/lib.rs @@ -135,6 +135,13 @@ impl PySIObject { self.unit.eq(&other.unit) } + pub fn value_in<'py>(&self, py: Python<'py>, unit: &Self) -> PyResult> { + self.check_units(unit)?; + self.value + .bind(py) + .call_method1("__truediv__", (&unit.value,)) + } + #[classattr] fn __array_priority__() -> u64 { 1000 diff --git a/si-units/src/si_units/_core.pyi b/si-units/src/si_units/_core.pyi index 1f8d394..28895e8 100644 --- a/si-units/src/si_units/_core.pyi +++ b/si-units/src/si_units/_core.pyi @@ -1,4 +1,4 @@ -from typing import Self, Any +from typing import Any, Self class SIObject: """Combination of value and unit. @@ -14,7 +14,7 @@ class SIObject: def __init__(self, value: float | Any, unit: list[int]) -> None: """Constructs a new quantity. - Warning: Don't use the default constructor + Warning: Don't use the default constructor This constructor should not be used to construct a quantity. Instead, multiply the value (float or array of floats) by the appropriate unit. See example below. @@ -64,7 +64,7 @@ class SIObject: Raises: RuntimeError: When exponents of units are not multiples of three. AttributeError: When the inner data type has no 'cbrt' method. - + Examples: >>> from si_units import METER >>> volume = METER**3 @@ -83,6 +83,29 @@ class SIObject: """ ... + def value_in(self, unit: Self) -> float | Any: + """Return the numeric value expressed in specified unit. + + The underlying value (float, numpy.ndarray, torch.tensor, ...) + is divided by unit and returned without the unit wrapper. + + Args: + unit: A quantity describing target unit (e.g. KILO * WATT * HOUR). + + Returns: + The numeric value of self expressed in unit. + + Raises: + RuntimeError: When self and unit have incompatible units. + + Examples: + >>> from si_units import JOULE, KILO, WATT, HOUR + >>> energy = 5.4e6 * JOULE + >>> energy.value_in(KILO * WATT * HOUR) + 1.5 + """ + ... + def array(value: SIObject | list[SIObject]) -> SIObject: """Build SIObject from scalar or list. @@ -92,7 +115,7 @@ def array(value: SIObject | list[SIObject]) -> SIObject: value: Values to store. Must all have the same unit. Returns: - The quantity with values stored within array, + The quantity with values stored within array, even if value is given as a scalar. Raises: From 7e7931c0b26de362f9abaace90541a9f5f4a83f8 Mon Sep 17 00:00:00 2001 From: David Huang Date: Sat, 18 Apr 2026 15:10:58 +0100 Subject: [PATCH 2/2] docs: added value_in method under SIObject in api docs --- si-units/docs/api.md | 1 + 1 file changed, 1 insertion(+) diff --git a/si-units/docs/api.md b/si-units/docs/api.md index 7a64d7a..622e5a1 100644 --- a/si-units/docs/api.md +++ b/si-units/docs/api.md @@ -6,6 +6,7 @@ - cbrt - sqrt - has_unit + - value_in summary: attributes: false functions: true