Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added .free_symbols to Variable. #28

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ env:
before_install:
- travis_retry pip install twine wheel coveralls
- travis_retry pip install check-manifest pydocstyle
- travis_retry pip install https://github.com/sympy/sympy/archive/1.1.zip
- travis_retry pip install https://github.com/sympy/sympy/zipball/master

install:
- pip install -e .[all]
Expand Down
16 changes: 13 additions & 3 deletions essm/variables/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
# MA 02111-1307, USA.
"""Define unit symbols."""

import functools
import operator

import sympy.physics.units as u
from sympy.physics.units import Quantity
from sympy.physics.units import Dimension, Quantity, find_unit

from .SI import SI

Expand All @@ -33,6 +36,8 @@
second = u.second
watt = u.watt

SI_DIMENSIONS = {str(d._dimension.name): d for d in SI._base_units}


def markdown(unit):
"""Return markdown representation of a unit."""
Expand All @@ -55,8 +60,13 @@ def derive_quantity(expr, name=None):


def derive_unit(expr, name=None):
"""Derive a unit from an expression."""
return SI.print_unit_base(derive_quantity(expr, name=name))
"""Derive SI-unit from an expression, omitting scale factors."""
dim = Dimension(Quantity.get_dimensional_expr(expr))
return functools.reduce(
operator.mul, (
SI_DIMENSIONS[d] ** p
for d, p in Dimension.get_dimensional_dependencies(dim).items()),
1)


__all__ = (
Expand Down
11 changes: 11 additions & 0 deletions essm/variables/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"""Utility function for variables."""

from .units import markdown
from ._core import BaseVariable
from sympy import preorder_traversal


def generate_metadata_table(variables=None, include_header=True):
Expand All @@ -40,3 +42,12 @@ def generate_metadata_table(variables=None, include_header=True):
val = str(Variable.__defaults__.get(variable, '-'))

yield (symbol, name, doc, val, markdown(variable.short_unit))


def get_variables(expr):
"""Traverses through expression and returns set of variables as list."""
variables = []
for arg in preorder_traversal(expr):
if isinstance(arg, BaseVariable):
variables.append(arg)
return list(set(variables))
21 changes: 21 additions & 0 deletions tests/test_equations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from essm.equations import Equation
from essm.variables import Variable
from essm.variables.units import joule, kelvin, meter, mole, second
from essm.variables.utils import get_variables


class demo_g(Variable):
Expand All @@ -17,6 +18,14 @@ class demo_g(Variable):
unit = meter / second ** 2


class demo_v(Variable):
unit = meter/second


class demo_t(Variable):
unit = second


class demo_fall(Equation):
"""Test equation."""

Expand All @@ -29,6 +38,12 @@ class t(Variable):
expr = Eq(d, 1 / 2 * demo_g * t ** 2)


class demo_velocity(Equation):
"""Test equation."""

expr = Eq(demo_v, demo_g * demo_t)


def test_equation():
"""Test variable definition."""
assert demo_fall.__doc__ == demo_fall.definition.__doc__
Expand Down Expand Up @@ -56,6 +71,12 @@ def test_args():
demo_fall.definition.t.definition, }


def test_get_variables():
"""Test free variables."""
assert set(get_variables(demo_velocity)) == {
demo_v, demo_t, demo_g}


def test_unit_check():
"""Check unit test involving temperature."""

Expand Down
21 changes: 20 additions & 1 deletion tests/test_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from essm.variables import Variable
from essm.variables.units import meter, second
from essm.variables.units import derive_unit, joule, kilogram, meter, second


class demo_variable(Variable):
Expand Down Expand Up @@ -59,6 +59,25 @@ class invalid_unit(Variable):
unit = second


def test_derive_unit():
"""Test derive_unit from expression."""

class lambda_E(Variable):
unit = joule / kilogram

class E_l(Variable):
unit = joule / (meter ** 2 * second)

assert derive_unit(2 * lambda_E * E_l) \
== kilogram * meter ** 2 / second ** 5
assert derive_unit(E_l/E_l) == 1

class dimensionless(Variable):
expr = demo_variable / demo_expression_variable

assert dimensionless.definition.unit == 1


def test_remove_variable_from_registry():
"""Check is the variable is removed from registry."""

Expand Down