Exemplo n.º 1
0
def testArrayOperations(unit_database_len_time):
    unit_database = unit_database_len_time

    m = Quantity.CreateDerived(odict([("Table size", ["m", 1])]))
    km_city = Quantity.CreateDerived(odict([("City size", ["km", 1])]))

    s1 = Array.CreateWithQuantity(m, [1])
    s2 = Array.CreateWithQuantity(km_city, [0.01])
    initial1 = s1.GetQuantity().GetComposingUnits()
    initial2 = s2.GetQuantity().GetComposingUnits()
    # Check that they doesn't raise ComposedUnitError
    s1.GetValues()
    s2.GetValues()

    quantity, value = unit_database.Multiply(m, km_city, 1, 0.01)
    assert initial1 == s1.GetQuantity().GetComposingUnits()
    assert initial2 == s2.GetQuantity().GetComposingUnits()
    calculated1 = Array.CreateWithQuantity(quantity, [value])

    array = s1 * s2
    six.text_type(array)  # just to see if it works...
    assert calculated1 == s1 * s2

    quantity, value = unit_database.Sum(m, km_city, 1, 0.01)
    assert Array.CreateWithQuantity(quantity, [value]) == s1 + s2

    quantity, value = unit_database.Subtract(m, km_city, 1, 0.01)
    assert Array.CreateWithQuantity(quantity, [value]) == s1 - s2
Exemplo n.º 2
0
def testDivision(unit_database_len_time):
    unit_database = unit_database_len_time
    m = Quantity.CreateDerived(odict([("Table size", ["m", 1])]))
    km_city = Quantity.CreateDerived(odict([("City size", ["km", 1])]))
    quantity, value = unit_database.Divide(m, km_city, 1, 0.01)
    calculated1 = Array.CreateWithQuantity(quantity, [value])
    s1 = Array.CreateWithQuantity(m, [1])
    s2 = Array.CreateWithQuantity(km_city, [0.01])
    assert calculated1 == s1 / s2
Exemplo n.º 3
0
def testCreationWithDerivedQuantity(unit_database_len_time):
    unit_database = unit_database_len_time

    m = Quantity.CreateDerived(odict([("Table size", ["m", 1])]))
    km_city = Quantity.CreateDerived(odict([("City size", ["km", 1])]))

    quantity, value = unit_database.Multiply(m, km_city, 1, 0.01)
    calculated1 = Scalar.CreateWithQuantity(quantity, value)
    assert six.text_type(calculated1)

    s1 = Scalar.CreateWithQuantity(m, 1)
    s2 = Scalar.CreateWithQuantity(km_city, 0.01)
    assert calculated1 == s1 * s2
Exemplo n.º 4
0
def _ObtainReduced(state):
    """
    :param list state:
        The value returned from _Quantity.__reduce__ (used in pickle protocol).
    """
    unknown_unit_caption = state.pop(-1)
    return ObtainQuantity(odict(state), None, unknown_unit_caption)
Exemplo n.º 5
0
def testDeepcopy(unit_database_len_time):
    import copy

    # Note: the part below is flaky for a test because it relies on getting a refcount to None
    # which could change if there are other threads running. The code is kept just as a
    # reference in case we have to debug such a situation again (there was a bug in odict where
    # it decreased references to None when it shouldn't and it crashed the program later on).

    # m = odict([('Table size', ['m', 1])])
    # import gc
    # import sys
    # my_none = None
    # for i in range(100):
    #     gc.collect()
    #
    # Note:
    # for i in range(200):
    #     gc.collect()
    #     if i < 100:
    #         prev = sys.getrefcount(my_none)
    #     else:
    #         curr = sys.getrefcount(my_none)
    #         self.assert_(curr >= prev,
    #             'The ref count cannot get lower for None (previous:%s current:%s).' % (prev, curr))
    #
    #     # Notice that print sys.getrefcount(None) is always decrementing (this is the error)
    #     m = copy.deepcopy(m)

    m = Quantity.CreateDerived(odict([("Table size", ["m", 1])]))
    m0 = copy.deepcopy(m)
    assert m is m0  # Check if our cache is working.
Exemplo n.º 6
0
def testDelWithSlices():
    d = odict()
    d[1] = 1
    d[2] = 2
    d[3] = 3

    del d[1:]

    assert len(d) == 1
    assert d[1] == 1
Exemplo n.º 7
0
def testCreateWithQuantity(unit_database_start_units):
    units.FixedArray.CreateWithQuantity(Quantity.CreateDerived(odict()),
                                        [100, 150, 200],
                                        dimension=3)

    quantity = ObtainQuantity("m", "length")
    a1 = units.FixedArray(3, quantity, values=[1, 2, 3])
    a2 = units.FixedArray(3, quantity, values=[1, 2, 3])

    assert a1.GetValues("km") == [0.001, 0.002, 0.003]
    assert a2.GetValues() == [1, 2, 3]
Exemplo n.º 8
0
    def CreateEmpty(cls):
        """
        Create a quantity without any internal unit.

        :rtype: Quantity
        :returns:
            Returns an empty quantity.
        """
        empty = cls._EMPTY_QUANTITY
        if empty is None:
            empty = cls._EMPTY_QUANTITY = ObtainQuantity(odict())
        return empty
Exemplo n.º 9
0
 def GetComposingUnitsJoiningExponents(self):
     try:
         return self._composing_units_joining_exponents
     except AttributeError:
         ret = odict()
         for _category, (unit, exp) in six.iteritems(
             self._category_to_unit_and_exps
         ):
             existing = ret.get(unit, 0)
             ret[unit] = existing + exp
         self._composing_units_joining_exponents = tuple(ret.items())
     return self._composing_units_joining_exponents
Exemplo n.º 10
0
def testDerivedQuantities(unit_database_len_time):
    # define a simple quantity
    ObtainQuantity(unit="s", category="Time")  # see if it works
    ObtainQuantity(unit="m", category="Table size")  # see if it works
    q3 = Quantity.CreateDerived(
        odict([("Table size", ["m", 2]), ("Time", ["s", -1])]))
    q4 = Quantity.CreateDerived(
        odict([("Table size", ["m", 2]), ("Time", ["s", -2])]))
    q5 = Quantity.CreateDerived(
        odict([("Table size", ["m", 1]), ("City size", ["m", 1]),
               ("Time", ["s", -2])]))
    q6 = Quantity.CreateDerived(odict([("Time", ["s", -2])]))
    q7 = Quantity.CreateDerived(
        odict([("Table size", ["m", 1]), ("Time", ["s", 2])]))

    with pytest.raises(InvalidUnitError):
        Quantity.CreateDerived(
            odict([
                ("Table size", ["invalid", 1]),
                ("City size", ["m", 1]),
                ("Time", ["s", -2]),
            ]))

    assert "(Table size) ** 2 / Time" == q3.GetCategory()
    assert "m2/s" == q3.GetUnit()

    assert "(Table size) ** 2 / (Time) ** 2" == q4.GetCategory()
    assert "m2/s2" == q4.GetUnit()
    assert "1/s2" == q6.GetUnit()
    assert "m.s2" == q7.GetUnit()

    assert (("m", 2), ("s", -2)) == q4.GetComposingUnits()
    assert (("m", 1), ("m", 1), ("s", -2)) == q5.GetComposingUnits()
Exemplo n.º 11
0
    def GetCategoryToUnitAndExpsCopy(self, unit_and_exps=None):
        """
        Same as Quantity.GetCategoryToUnitAndExps but returns a copy instead of the internal
        instance.

        .. see:: Quantity.GetCategoryToUnitAndExps
        """
        if unit_and_exps is None:
            unit_and_exps = self._category_to_unit_and_exps

        return odict(
            (category, unit_and_exp[:])
            for (category, unit_and_exp) in six.iteritems(unit_and_exps)
        )
Exemplo n.º 12
0
def testNumberInteractions(unit_database_len_time):
    scalar = Scalar("Table size", 1, "m")
    scalar2 = Scalar.CreateWithQuantity(Quantity.CreateDerived(odict()), 0)

    assert scalar == scalar + scalar2

    assert scalar == scalar + 0
    assert scalar == 0 + scalar

    assert 9 == (10 - scalar).value
    assert -9 == (scalar - 10).value

    assert 10 == (10 * scalar).value
    assert 10 == (scalar * 10).value

    assert 10 == (10.0 / scalar).value
    assert 1 / 10.0 == (scalar / 10.0).value
Exemplo n.º 13
0
def testQuantityCaption(unit_database_posc_len):
    unit_database = unit_database_posc_len
    unit_database.AddUnitBase(UNKNOWN_QUANTITY_TYPE, UNKNOWN_QUANTITY_TYPE,
                              UNKNOWN_UNIT)
    unit_database.AddCategory(UNKNOWN_QUANTITY_TYPE, UNKNOWN_QUANTITY_TYPE)

    q0 = ObtainQuantity(unit=UNKNOWN_UNIT, category=UNKNOWN_QUANTITY_TYPE)
    assert "" == q0.GetUnknownCaption()

    q = ObtainQuantity(unit=UNKNOWN_UNIT,
                       unknown_unit_caption="Feeeet",
                       category=UNKNOWN_QUANTITY_TYPE)
    assert "Feeeet" == q.GetUnknownCaption()
    assert "Feeeet <unknown>" == q.GetUnitCaption()

    q = Quantity.CreateDerived(odict([("length", ("m", 1))]),
                               unknown_unit_caption="Feeeet")
    assert "m" == q.GetUnitCaption()
Exemplo n.º 14
0
def testConvertionWithDerivedUnits(unit_database_len_time):
    empty = Quantity.CreateDerived(odict())
    m = Quantity.CreateDerived(odict([("Table size", ["m", 1])]))
    m_city = Quantity.CreateDerived(odict([("City size", ["m", 1])]))
    cm = Quantity.CreateDerived(odict([("Table size", ["cm", 1])]))
    km_city = Quantity.CreateDerived(odict([("City size", ["km", 1])]))
    m2 = Quantity.CreateDerived(odict([("Table size", ["m", 2])]))
    s = Quantity.CreateDerived(odict([("Time", ["s", -1])]))
    m2s = Quantity.CreateDerived(
        odict([("Table size", ["m", 2]), ("Time", ["s", -1])]))
    cat_mix_m2 = Quantity.CreateDerived(
        odict([("Table size", ["m", 1]), ("City size", ["m", 1])]))

    unit_database = unit_database_len_time
    # multiplication
    assert (m2, 2) == unit_database.Multiply(m, m, 1, 2)
    assert (m2s, 2) == unit_database.Multiply(m2, s, 1, 2)
    assert (m2s, 2) == unit_database.Multiply(m2, s, 1, 2)
    assert (m2, 1) == unit_database.Multiply(m, cm, 1, 100)
    assert (cat_mix_m2, 1) == unit_database.Multiply(m, m_city, 1, 1)
    assert (cat_mix_m2, 1) == unit_database.Multiply(m, km_city, 1, 0.001)

    # division
    assert (m, 0.001) == unit_database.Divide(cat_mix_m2, km_city, 1, 1)
    # check division with cancelling units (and different categories)
    assert (empty, 1) == unit_database.Divide(m, m_city, 1, 1)

    # sum
    assert (m, 1 + 0.01) == unit_database.Sum(m, cm, 1, 1)
    assert (m, 2) == unit_database.Sum(m, m_city, 1, 1)

    # subtraction
    # check with operation so that we have an exact match (without need for almost equals,
    # as that should be the same exact operation done later)
    assert (m, 1 - 0.01) == unit_database.Subtract(m, cm, 1, 1)
    with pytest.raises(InvalidOperationError):
        unit_database.Subtract(m, s, 1, 1)
Exemplo n.º 15
0
def testNumberInteractions(unit_database_len_time):
    import numpy

    m = Quantity.CreateDerived(odict([("Table size", ["m", 1])]))
    s1 = Array.CreateWithQuantity(m, list(range(10)))
    s2 = Array.CreateWithQuantity(m, [x + x for x in range(10)])
    assert s1 == 0 + s1
    assert s1 == s1 + 0
    assert s2 == s1 + s1

    num_arr = Array.CreateWithQuantity(m, numpy.array([x for x in range(10)]))
    sum_array = num_arr + s1
    assert isinstance(sum_array.values, numpy.ndarray)

    sum_array2 = num_arr + numpy.array([x for x in range(10)])
    assert isinstance(sum_array2.values, numpy.ndarray)

    tup_arr = Array.CreateWithQuantity(m, tuple([x for x in range(10)]))
    tup_arr = tup_arr + 1
    assert isinstance(tup_arr.values, tuple)
Exemplo n.º 16
0
    def GetUnitName(self):
        """
        :rtype: unicode
        :returns:
            A description of the unit showing all the containing parts in the category,
            units and the exponent for each. This differs from the default unit because the
            default GetUnit will only return the final name of the unit, composing all the
            available parts into a single exponent (e.g. if it's composed of more than one
            'm', each with exponent 1, it would appear 2 times in this method and would appear
            'm2' in the GetUnit).
        """
        repr_and_exp = odict()
        unit_database = self._unit_database

        for category, (unit, exp) in six.iteritems(self._category_to_unit_and_exps):
            quantity_type = unit_database.GetCategoryQuantityType(category)
            unit_name = unit_database.GetUnitName(quantity_type, unit)
            existing = repr_and_exp.get(unit_name, 0)
            repr_and_exp[unit_name] = existing + exp

        return self._MakeStr(list(repr_and_exp.items()))
Exemplo n.º 17
0
def testDerivedUnits(unit_database_empty):
    unit_database = unit_database_empty

    unit_database.AddUnitBase("length", "meters", "m")
    unit_database.AddUnit("length", "milimeters", "mm", "x * 1000.0", "x / 1000.0")
    unit_database.AddUnit("length", "centimeters", "cm", "x * 100.0", "x / 100.0")
    unit_database.AddCategory("well-diameter", "length")
    unit_database.AddUnitBase("time", "seconds", "s")
    unit_database.AddCategory(category="Time", quantity_type="time")

    s1 = Scalar("well-diameter", 10, "m")
    s2 = Scalar("well-diameter", 10, "cm")
    s3 = Scalar("Time", 10, "s")

    assert Scalar("well-diameter", 10.10, "m") == s1 + s2
    assert Scalar("well-diameter", 9.90, "m") == s1 - s2

    quantity = Quantity.CreateDerived(odict())
    assert Scalar.CreateWithQuantity(quantity, 100) == s1 / s2
    assert Scalar("well-diameter", 9.90, "m") == s1 - s2
    with pytest.raises(InvalidOperationError):
        s1.__sub__(s3)
Exemplo n.º 18
0
def testInsert():
    d = odict()
    d[1] = "alpha"
    d[3] = "charlie"

    assert list(d.items()) == [(1, "alpha"), (3, "charlie")]

    d.insert(0, 0, "ZERO")
    assert list(d.items()) == [(0, "ZERO"), (1, "alpha"), (3, "charlie")]

    d.insert(2, 2, "bravo")
    assert list(d.items()) == [(0, "ZERO"), (1, "alpha"), (2, "bravo"),
                               (3, "charlie")]

    d.insert(99, 4, "echo")
    assert list(d.items()) == [
        (0, "ZERO"),
        (1, "alpha"),
        (2, "bravo"),
        (3, "charlie"),
        (4, "echo"),
    ]
Exemplo n.º 19
0
def testReadOnlyOperation(unit_database_len_time):
    unit_database = unit_database_len_time
    m_ro = ObtainQuantity("m", "Table size")
    m_rw = ObtainQuantity("m", "Table size")

    m2 = Quantity.CreateDerived(odict([("Table size", ["m", 2])]))

    # multiplication
    assert (m2, 2) == unit_database.Multiply(m_rw, m_rw, 1, 2)
    assert (m2, 2) == unit_database.Multiply(m_ro, m_rw, 1, 2)
    assert (m2, 2) == unit_database.Multiply(m_ro, m_ro, 1, 2)
    assert (m2, 2) == unit_database.Multiply(m_rw, m_ro, 1, 2)

    quantity, _ = unit_database.Multiply(m_ro, m_ro, 1, 2)
    assert isinstance(quantity, Quantity)

    quantity, _ = unit_database.Multiply(m_rw, m_rw, 1, 2)
    assert isinstance(quantity, Quantity)
    quantity, _ = unit_database.Multiply(m_rw, m_ro, 1, 2)
    assert isinstance(quantity, Quantity)
    quantity, _ = unit_database.Multiply(m_ro, m_rw, 1, 2)
    assert isinstance(quantity, Quantity)
Exemplo n.º 20
0
    def __init__(self, category, unit, unknown_unit_caption=None):
        """
        :type category: unicode or odict
        :param category:
            The category to which the new quantity should be bound or an odict with information on
            the derived category/unit (in which case the unit parameter is ignored).

        :param unicode unit:
            The unit which the new quantity should have.
        """
        try:
            # Bail out if unit is already configured: this may happen when the Quantity constructor
            # is called directly: if Quantity() is called, the protocol will call __new__ and even
            # if a configured instance is returned, it'll call __init__ again, so, this is a check
            # for this situation so that we return if the quantity is already configured.
            self._unknown_unit_caption
            return
        except AttributeError:
            pass

        # Keep self._unit_database for faster access.
        unit_database = self._unit_database = UnitDatabase.GetSingleton()

        if unknown_unit_caption is not None:
            assert (
                unknown_unit_caption.__class__ == six.text_type
            ), "Unit caption must be a string. Note: the unit database and unit system parameters were removed."
            self._unknown_unit_caption = unknown_unit_caption
        else:
            self._unknown_unit_caption = ""

        if category.__class__ == odict:
            assert unit is None
            self._category_to_unit_and_exps = category
            self._is_derived = True

            rep_and_exp = odict()
            for category, (_unit, exp) in six.iteritems(
                self._category_to_unit_and_exps
            ):
                quantity_type = unit_database.GetCategoryQuantityType(category)
                existing = rep_and_exp.get(quantity_type, 0)
                rep_and_exp[quantity_type] = existing + exp

            self._category = self._MakeStr(
                [
                    (category, exp)
                    for category, (_unit, exp) in six.iteritems(
                        self._category_to_unit_and_exps
                    )
                ]
            )
            self._quantity_type = self._MakeStr(list(rep_and_exp.items()))
            self._unit = self._CreateUnitsWithJoinedExponentsString()
            self._composing_units = tuple(
                (unit, exp)
                for _category, (unit, exp) in six.iteritems(
                    self._category_to_unit_and_exps
                )
            )
            self._composing_categories = tuple(
                six.iterkeys(self._category_to_unit_and_exps)
            )
            self._category_info = None
            return

        self._is_derived = False

        # changes to accommodate making operations with derived units (internally the
        # information must be a dict)
        if category.__class__ != six.text_type:
            raise TypeError("Only unicode is accepted. %s is not." % category.__class__)

        # Getting the category should be enough to check that it's valid.
        category_info = unit_database.GetCategoryInfo(category)
        self._category_info = category_info

        # if no unit was given, assume base unit for this quantity_type
        if unit is None:
            unit = category_info.default_unit
        else:
            if unit.__class__ != six.text_type:
                raise TypeError("Only unicode is accepted. %s is not." % unit.__class__)
            unit_database.CheckCategoryUnit(category, unit)

        # store it as odict so that we can have a decent order when creating a string from
        # an operation.
        category_to_unit_and_exps = odict()
        category_to_unit_and_exps[category] = [unit, 1]
        self._category_to_unit_and_exps = category_to_unit_and_exps

        self._category = category
        self._quantity_type = unit_database.GetCategoryQuantityType(category)
        self._unit = unit
        self._tobase = self._unit_database.GetInfo(
            self._quantity_type, self._unit, fix_unknown=True
        ).tobase
        self._composing_units = unit
        self._composing_categories = category
Exemplo n.º 21
0
def ObtainQuantity(unit, category=None, unknown_unit_caption=None):
    """
    :type unit: unicode or odict(unicode -> list(unicode, int))
    :param unit:
        Either the string representing the unit or an ordered dict with the composing unit
        information (if composing all the info, including the category will be received in this
        parameter).

    :param unicode category:
        The category for the quantity. If not given it's gotten based on the unit passed.

    :param unicode unknown_unit_caption:
        The caption for the unit (used if unknown).

    :rtype Quantity:
    """
    unit_database = UnitDatabase.GetSingleton()
    quantities_cache = unit_database.quantities_cache

    if unit.__class__ in (list, tuple):
        # It may be a derived unit with list(tuple(unicode, int)) -- in which case the category
        # must also be a list (of the same size)
        if len(unit) == 1 and unit[0][1] == 1:
            # Although passed as composing, it's a simple case
            unit = unit[0][0]
            if category.__class__ in (list, tuple):
                category = category[0]
        else:
            assert category.__class__ in (list, tuple)
            unit = odict(
                (cat, unit_and_exp) for (cat, unit_and_exp) in zip(category, unit)
            )
            category = None

    if hasattr(unit, "items"):
        assert category is None
        if len(unit) == 1 and next(six.itervalues(unit))[1] == 1:
            # Although passed as composing, it's a simple case
            category, (unit, _exp) = next(six.iteritems(unit))
        else:
            key = tuple(
                (category, tuple(unit_and_exp))
                for (category, unit_and_exp) in six.iteritems(unit)
            )
            if unknown_unit_caption:
                key += (unknown_unit_caption,)
            try:
                return quantities_cache[key]
            except KeyError:
                quantity = quantities_cache[key] = _Quantity(
                    unit, None, unknown_unit_caption
                )
                return quantity

    key = (category, unit, unknown_unit_caption)
    try:
        return quantities_cache[key]
    except KeyError:
        pass  # Just go on with the regular flow.

    assert unit.__class__ != bytes, "unit must be given as unicode string always"
    if unit.__class__ != six.text_type:
        if category is None:
            raise AssertionError("Currently only supporting unit as a string.")
        else:
            # Unit is given by the category
            unit = unit_database.GetDefaultUnit(category)
        quantity = quantities_cache[key] = _Quantity(
            category, unit, unknown_unit_caption
        )
        return quantity

    elif category is None:
        category = unit_database.GetDefaultCategory(unit)
        if not category:
            raise UnitsError("Unable to get default category for: %s" % (unit,))

        key_with_resolved_category = (category, unit, unknown_unit_caption)
        try:
            return quantities_cache[key_with_resolved_category]
        except KeyError:
            quantity = quantities_cache[key_with_resolved_category] = _Quantity(
                category, unit, unknown_unit_caption
            )
            # Cache it with None category too.
            quantities_cache[key] = quantity
            return quantity

    else:
        quantities_cache[key] = quantity = _Quantity(
            category, unit, unknown_unit_caption
        )
        return quantity
Exemplo n.º 22
0
    def _CreateDerived(
        cls,
        category_to_unit_and_exps,
        resulting_class=None,
        validate_category_and_units=True,
        unknown_unit_caption=None,
    ):
        """
        Create a category that represents a derived quantity (usually resulting from operations
        among quantities).

        :type category_to_unit_and_exps: odict(unicode->(list(unicode, int)))
        :param category_to_unit_and_exps:
            This odict defines the category as well as the unit in a way that we can specify exponents.

        :param type resulting_class:
            Deprecated (no longer used).

        :param bool validate_category_and_units:
            If True, the category and units will be validated (otherwise, it'll just create it
            without trying to validate any value (note that it's meant to be used internally
            to make creating the quantity faster without having to actually validate it)

        :rtype: cls
        :returns:
            An instance that represents a quantity with the given categories, units and exponents.
        """
        unit_database = UnitDatabase.GetSingleton()

        if validate_category_and_units:
            assert hasattr(
                category_to_unit_and_exps, "items"
            ), "validate_category_and_units needs to be a dict"
            for category, (unit, _exp) in six.iteritems(category_to_unit_and_exps):
                # will do the checkings needed for validation (category/unit)
                # so that we can later just store the internal information without
                # any other check.

                # changes to accomodate making operations with derived units (internally the
                # information must be a dict)
                if category.__class__ != six.text_type:
                    raise TypeError(
                        "Only unicode is accepted. %s is not." % category.__class__
                    )

                # Getting the category should be enough to know that it's valid.
                category_info = unit_database.GetCategoryInfo(category)

                # if no unit was given, assume base unit for this quantity_type
                if unit is None:
                    unit = category_info.default_unit
                else:
                    if unit.__class__ != six.text_type:
                        raise TypeError(
                            "Only unicode is accepted. %s is not." % unit.__class__
                        )
                    unit_database.CheckQuantityTypeUnit(
                        category_info.quantity_type, unit
                    )

        return ObtainQuantity(
            odict(
                (category, unit_and_exp[:])
                for (category, unit_and_exp) in six.iteritems(category_to_unit_and_exps)
            ),
            unknown_unit_caption=unknown_unit_caption,
        )