Exemple #1
0
def unitsAreConsistent(expr, targetUnits=None):
    """Check if an expression's units are compatible.
    If `targetUnits` provided, also checks for compatibility for
    converting to `targetUnits`.

    Raises UnitMisMatchError when applicable.

    Notes:
    If `targetUnits` is a units.Dimension, requires `expr` to
        evaluate to units with same units.Dimension (eg. must include units in `expr`)
    If `expr` has dimension of `1` (unit-less), returns `True`
        barring other errors or targetUnits being units.Dimension.

    :param expr: sympy.Expr
    :param targetUnits: str\\units.Quantity\\units.Dimension
    :return: True or raises UnitMisMatchError
    """
    logger.log(logging.DEBUG - 1, f'unitsAreConsistent({expr}, {targetUnits})')

    try:
        # rough check within expression
        check_dimensions(expr)
        logger.log(logging.DEBUG - 1,
                   f"check_dimensions -> {bool(check_dimensions(expr))}")
    except ValueError as e:
        raise UnitMisMatchError(repr(e))
    except TypeError as e:
        raise UnitMisMatchError(repr(e))

    expr_dim = getDimension(expr)
    logger.log(logging.DEBUG - 1, f"expr_dim = {expr_dim}")
    if expr_dim is None:
        raise UnitMisMatchError("Dimension could not be determined")

    if targetUnits is None:
        return True

    # get dimensions of target units
    if isinstance(targetUnits, str):
        try:
            targetUnits = unitSubs[targetUnits]
        except KeyError:
            targetUnits = parseUnits(targetUnits)

    target_dim = getDimension(targetUnits)
    logger.log(logging.DEBUG - 1, f"target_dim = {target_dim}")

    if isinstance(targetUnits, units.Dimension):
        if targetUnits.name == expr_dim.name:
            return True
        else:
            raise UnitMisMatchError(
                f"{expr_dim} is not specified {target_dim}")

    # compare dimensions
    if expr_dim.name == 1 or expr_dim.name == target_dim.name:
        return True
    else:
        raise UnitMisMatchError(f"{expr_dim} incompatible with {target_dim}")
Exemple #2
0
def test_check_dimensions():
    x = symbols('x')
    assert check_dimensions(inch + x) == inch + x
    assert check_dimensions(length + x) == length + x
    # after subs we get 2*length; check will clear the constant
    assert check_dimensions((length + x).subs(x, length)) == length
    assert check_dimensions(newton * meter + joule) == joule + meter * newton
    raises(ValueError, lambda: check_dimensions(inch + 1))
    raises(ValueError, lambda: check_dimensions(length + 1))
    raises(ValueError, lambda: check_dimensions(length + time))
    raises(ValueError, lambda: check_dimensions(meter + second))
    raises(ValueError, lambda: check_dimensions(2 * meter + second))
    raises(ValueError, lambda: check_dimensions(2 * meter + 3 * second))
    raises(ValueError, lambda: check_dimensions(1 / second + 1 / meter))
    raises(ValueError, lambda: check_dimensions(2 * meter *
                                                (mile + centimeter) + km))
Exemple #3
0
def test_check_dimensions():
    x = symbols('x')
    assert check_dimensions(inch + x) == inch + x
    assert check_dimensions(length + x) == length + x
    # after subs we get 2*length; check will clear the constant
    assert check_dimensions((length + x).subs(x, length)) == length
    raises(ValueError, lambda: check_dimensions(inch + 1))
    raises(ValueError, lambda: check_dimensions(length + 1))
    raises(ValueError, lambda: check_dimensions(length + time))
    raises(ValueError, lambda: check_dimensions(meter + second))
    raises(ValueError, lambda: check_dimensions(2 * meter + second))
    raises(ValueError, lambda: check_dimensions(2 * meter + 3 * second))
    raises(ValueError, lambda: check_dimensions(1 / second + 1 / meter))
    raises(ValueError, lambda: check_dimensions(2 * meter*(mile + centimeter) + km))