Source code for piel.base.units

# Helper function to combine datum
[docs] def combine_datum(datum1, datum2, operation: str = "mul"): """ Combine two datum based on the operation. For multiplication, add the exponents. For division, subtract the exponents. """ if isinstance(datum1, str) or isinstance(datum2, str): # If datum is a string, handle accordingly if operation == "mul": return f"({datum1})·({datum2})" elif operation == "div": return f"({datum1})/({datum2})" else: raise ValueError("Unsupported operation for datum combination.") # Assuming datum1 and datum2 are dicts combined = datum1.copy() for unit, exponent in datum2.items(): if operation == "mul": combined[unit] = combined.get(unit, 0) + exponent elif operation == "div": combined[unit] = combined.get(unit, 0) - exponent else: raise ValueError("Unsupported operation for datum combination.") # Remove unit if exponent is zero if combined[unit] == 0: del combined[unit] return combined
# External operator functions
[docs] def unit_mul(self, other): from piel.types.units import Unit if isinstance(other, Unit): # Combine base numerical factors new_base = self.base * other.base # Combine datum (unit exponents) new_datum = combine_datum(self.datum, other.datum, operation="mul") # Create a new Unit instance new_unit = Unit( name=f"({self.name} * {other.name})", label=f"{self.label} * {other.label}", shorthand=f"{self.shorthand}·{other.shorthand}", symbol=f"{self.symbol}·{other.symbol}", datum=new_datum, base=new_base, ) return new_unit elif isinstance(other, (int, float)): # Multiply the base numerical factor return Unit( name=self.name, label=self.label, shorthand=self.shorthand, symbol=self.symbol, datum=self.datum, base=self.base * other, ) else: return NotImplemented
[docs] def unit_rmul(self, other): # Support commutative multiplication return unit_mul(self, other)
[docs] def unit_add(self, other): from piel.types.units import Unit if isinstance(other, Unit): if self.datum != other.datum: raise ValueError("Cannot add Units with different dimensions.") # Combine base numerical factors new_base = self.base + other.base # Create a new Unit instance new_unit = Unit( name=f"({self.name} + {other.name})", label=f"{self.label} + {other.label}", shorthand=f"{self.shorthand} + {other.shorthand}", symbol=f"{self.symbol} + {other.symbol}", datum=self.datum, base=new_base, ) return new_unit else: return NotImplemented
[docs] def unit_radd(self, other): # Support commutative addition return unit_add(self, other)
# Division
[docs] def unit_truediv(self, other): from piel.types.units import Unit if isinstance(other, Unit): # Combine base numerical factors new_base = self.base / other.base # Combine datum (unit exponents) with division new_datum = combine_datum(self.datum, other.datum, operation="div") # Create a new Unit instance new_unit = Unit( name=f"({self.name} / {other.name})", label=f"{self.label} / {other.label}", shorthand=f"{self.shorthand}/{other.shorthand}", symbol=f"{self.symbol}/{other.symbol}", datum=new_datum, base=new_base, ) return new_unit elif isinstance(other, (int, float)): # Divide the base numerical factor return Unit( name=self.name, label=self.label, shorthand=self.shorthand, symbol=self.symbol, datum=self.datum, base=self.base / other, ) else: return NotImplemented
[docs] def unit_rtruediv(self, other): from piel.types.units import Unit # Handle cases like 2 / meter if isinstance(other, (int, float)): new_base = other / self.base new_datum = combine_datum({}, self.datum, operation="div") # Invert exponents # If datum is a string, adjust accordingly if isinstance(self.datum, str): new_datum = f"{other}/({self.datum})" else: # Invert the exponents in the datum dictionary new_datum = {unit: -exponent for unit, exponent in self.datum.items()} return Unit( name=f"({other} / {self.name})", label=f"{other} / {self.label}", shorthand=f"{other}/{self.shorthand}", symbol=f"{other}/{self.symbol}", datum=new_datum, base=new_base, ) else: return NotImplemented