Пример #1
0
    def to(self, unit_name=""):
        """
        Returns None and alters the instance into one of the elligible
        alternative units for its dimension, if it exists in the alternative_units dict;
        """
        dims = self.dimensions
        env_dims = environment.units_by_dimension
        derived = env_dims["derived"]
        defined = env_dims["defined"]
        power, dims_orig = phf._powers_of_derived(dims, env_dims)
        if not unit_name:
            print("Available units: ")
            for key in derived.get(dims_orig, {}):
                print(key)
            for key in defined.get(dims_orig, {}):
                print(key)

        if unit_name:
            defined_match = defined.get(dims_orig, {}).get(unit_name, {})
            derived_match = derived.get(dims_orig, {}).get(unit_name, {})
            unit_match = defined_match or derived_match
            if not unit_match:
                warnings.warn(f"No unit defined for '{unit_name}''.")
            new_factor = unit_match.get("Factor", 1)**power
            return Physical(self.value, self.dimensions, new_factor,
                            self.precision)
Пример #2
0
 def __float__(self):
     value = self.value
     dims = self.dimensions
     factor = self.factor
     prefixed = self.prefixed
     env_dims = environment.units_by_dimension or dict()
     power, _ = phf._powers_of_derived(dims, env_dims)
     if factor != 1:
         float_value = value * factor
     else:
         float_value = phf._auto_prefix_value(value, power, prefixed)
     return float(float_value)
Пример #3
0
 def __float__(self):
     value = self.value
     factor = self.factor
     if factor != 1:
         return value * factor
     kg_bool = False
     dims = self.dimensions
     env_dims = environment.units_by_dimension or dict()
     power, _ = phf._powers_of_derived(dims, env_dims)
     dim_components = phf._get_unit_components_from_dims(dims)
     if len(dim_components) == 1 and dim_components[0][0] == "kg":
         kg_bool = True
     if self.prefixed:
         prefix = self.prefixed
     else:
         prefix = phf._auto_prefix(value, power, kg_bool)
     float_value = phf._auto_prefix_value(value, power, prefix, kg_bool)
     return float_value
Пример #4
0
    def __mul__(self, other):
        if phf.is_nan(other):
            return other
        elif isinstance(other, NUMBER):
            return Physical(
                self.value * other,
                self.dimensions,
                self.factor,
                self.precision,
                self.prefixed,
            )

        elif isinstance(other, Physical):
            new_dims = vec.add(self.dimensions, other.dimensions)
            new_power, new_dims_orig = phf._powers_of_derived(
                new_dims, environment.units_by_dimension)
            new_factor = self.factor * other.factor
            test_factor = phf._get_units_by_factor(new_factor, new_dims_orig,
                                                   environment.units_by_factor,
                                                   new_power)
            if not test_factor:
                new_factor = 1
            try:
                new_value = self.value * other.value
            except:
                raise ValueError(
                    f"Cannot multiply between {self} and {other}: " +
                    ".value attributes are incompatible.")
            if new_dims == Dimensions(0, 0, 0, 0, 0, 0, 0):
                return new_value
            else:
                return Physical(new_value, new_dims, new_factor,
                                self.precision)
        else:
            try:
                return Physical(self.value * other, self.dimensions,
                                self.factor, self.precision)
            except:
                raise ValueError(
                    f"Cannot multiply between {self} and {other}: " +
                    ".value attributes are incompatible.")
Пример #5
0
 def __truediv__(self, other):
     if isinstance(other, NUMBER):
         return Physical(
             self.value / other,
             self.dimensions,
             self.factor,
             self.precision,
             self.prefixed,
         )
     elif isinstance(other, Physical):
         new_dims = vec.subtract(self.dimensions, other.dimensions)
         new_power, new_dims_orig = phf._powers_of_derived(
             new_dims, environment.units_by_dimension)
         new_factor = self.factor / other.factor
         if not phf._get_units_by_factor(new_factor, new_dims_orig,
                                         environment.units_by_factor,
                                         new_power):
             new_factor = 1
         try:
             new_value = self.value / other.value
         except:
             raise ValueError(
                 f"Cannot divide between {self} and {other}: " +
                 ".value attributes are incompatible.")
         if new_dims == Dimensions(0, 0, 0, 0, 0, 0, 0):
             return new_value
         else:
             return Physical(new_value, new_dims, new_factor,
                             self.precision)
     else:
         try:
             return Physical(self.value / other, self.dimensions,
                             self.factor, self.precision)
         except:
             raise ValueError(
                 f"Cannot divide between {self} and {other}: " +
                 ".value attributes are incompatible.")
Пример #6
0
    def _repr_template_(self, template: str = "") -> str:
        """
        Returns a string that appropriately represents the Physical
        instance. The parameter,'template', allows two optional values:
        'html' and 'latex'. which will only be utilized if the Physical
        exists in the Jupyter/iPython environment.
        """
        # Access req'd attributes
        precision = self.precision
        dims = self.dimensions
        factor = self.factor
        val = self.value
        prefix = ""
        prefixed = self.prefixed
        eps = self._eps

        # Access external environment
        env_fact = environment.units_by_factor or dict()
        env_dims = environment.units_by_dimension or dict()

        # Do the expensive vector math method (call once, only)
        power, dims_orig = phf._powers_of_derived(dims, env_dims)

        # Determine if there is a symbol for these dimensions in the environment
        # and if the quantity is elligible to be prefixed
        symbol, prefix_bool = phf._evaluate_dims_and_factor(
            dims_orig, factor, power, env_fact, env_dims)
        # Get the appropriate prefix
        if prefix_bool and prefixed:
            prefix = prefixed
        elif prefix_bool and dims_orig == Dimensions(1, 0, 0, 0, 0, 0, 0):
            prefix = phf._auto_prefix(val, power, kg=True)
        elif prefix_bool:
            prefix = phf._auto_prefix(val, power, kg=False)

        # Format the exponent (may not be used, though)
        exponent = phf._format_exponent(power, repr_format=template, eps=eps)

        # Format the units
        if not symbol and phf._dims_basis_multiple(dims):
            components = phf._get_unit_components_from_dims(dims)
            units_symbol = phf._get_unit_string(components,
                                                repr_format=template)
            units = units_symbol
            units = phf._format_symbol(prefix,
                                       units_symbol,
                                       repr_format=template)
            exponent = ""
        elif not symbol:
            components = phf._get_unit_components_from_dims(dims)
            units_symbol = phf._get_unit_string(components,
                                                repr_format=template)
            units = units_symbol
            exponent = ""
        else:
            units = phf._format_symbol(prefix, symbol, repr_format=template)

        # Determine the appropriate display value
        value = val * factor

        if prefix_bool:
            # If the quantity has a "pre-fixed" prefix, it will override
            # the value generated in _auto_prefix_value
            if dims_orig == Dimensions(1, 0, 0, 0, 0, 0, 0):
                value = phf._auto_prefix_value(val, power, prefixed, kg=True)
            else:
                value = phf._auto_prefix_value(val, power, prefixed)

        pre_super = ""
        post_super = ""
        space = " "
        if template == "latex":
            space = r"\ "
            pre_super = "^{"
            post_super = "}"
        elif template == "html":
            space = " "
            pre_super = "<sup>"
            post_super = "</sup>"

        if not exponent:
            pre_super = ""
            post_super = ""

        return f"{value:.{precision}f}{space}{units}{pre_super}{exponent}{post_super}"
### TODO: add Ohms to definitions for testing
# add energy modelling units to definitions for testing

### Testing parameters ###
env_dims = si.environment.units_by_dimension
env_fact = si.environment.units_by_factor
units = {
    "A": 0.05 * kg,
    "B": 3.2e-3 * m,
    "C": 1000 * ft,
    "D": 1e6 * N,
    "E": 0.2 * kip,
    "F": 5 * N * 1e3 * kip,
    "Matt": 0.22 * kip,  ## 20200417Matt added for dummy merge test
}
parameters = [(value, phf._powers_of_derived(value.dimensions, env_dims))
              for value in units.values()]

### Tests of the Physical class ###


## Testing "._repr_" methods in order of appearance in ._repr_template_() ##
def test__evaluate_dims_and_factor():
    func = phf._evaluate_dims_and_factor
    assert func(
        si.Dimensions(1, 1, -2, 0, 0, 0, 0),
        1 / 0.45359237 / 9.80665,
        1,
        env_fact,
        env_dims,
    ) == ("lb", False)