Source code for pydy.utils

#!/usr/bin/env python

import re
import textwrap

from pkg_resources import parse_version
from setuptools import __version__ as SETUPTOOLS_VERSION
import sympy as sm
from sympy.core.function import AppliedUndef
from sympy.utilities.iterables import iterable
from sympy.physics.mechanics import dynamicsymbols

SYMPY_VERSION = sm.__version__


[docs]def sympy_equal_to_or_newer_than(version, installed_version=None): """Returns true if the installed version of SymPy is equal to or newer than the provided version string.""" if installed_version is None: v = SYMPY_VERSION else: v = installed_version if v.endswith('-git') and \ parse_version(SETUPTOOLS_VERSION) >= parse_version('8.0'): msg = ('You are using an older development version of SymPy with a ' 'non-PEP440 compliant version number: {}. Please install ' 'setuptools < 8.0 or a newer development version of SymPy.') raise ValueError(msg.format(v)) return parse_version(v) >= parse_version(version)
[docs]def sympy_newer_than(version): """Returns true if the installed version of SymPy is newer than the provided version string.""" return parse_version(SYMPY_VERSION) > parse_version(version)
[docs]def wrap_and_indent(lines, indentation=4, width=79, continuation=None, comment=None): """Returns a single string in which the lines have been indented and wrapped into a block of text. Parameters ========== indentation : integer The number of characters to indent. width : integer The maximum line width. continuation : string The continuation characters. comment : string The character that designates a comment line. """ if continuation is None: cont_len = 0 else: cont_len = len(continuation) if comment is None: comment_len = 0 else: comment_len = len(comment) # TODO : This will indent any lines that only contain a new line. Which # may not be preferable. new_lines = [] # TODO : The Octave printer has ".*" and "./" as operators and this doesn't # deal with that. # add whitespace before and after [*/] binary operands between # subexpressions and input/output pattern = re.compile('(\w\])([*/])(\w)') for line in lines: if line != '\n': line = pattern.sub(lambda m: ' '.join(m.groups()), line) wrapped = textwrap.wrap(line, width=width-indentation-cont_len-comment_len, break_long_words=False) if continuation: last = wrapped[-1] wrapped = [l + continuation for l in wrapped[:-1]] wrapped.append(last) if comment: for i, l in enumerate(wrapped[1:]): wrapped[i + 1] = comment + ' ' + l else: wrapped = [line] new_lines += wrapped spacer = '\n' + ' ' * indentation return ' ' * indentation + spacer.join(new_lines)
# This is a copy of the function in SymPy. It doesn't exist in SymPy 0.7.4 # so we keep it here for now.
[docs]def find_dynamicsymbols(expression, exclude=None): """Find all dynamicsymbols in expression. >>> from sympy.physics.mechanics import dynamicsymbols, find_dynamicsymbols >>> x, y = dynamicsymbols('x, y') >>> expr = x + x.diff()*y >>> find_dynamicsymbols(expr) set([x(t), y(t), Derivative(x(t), t)]) If the optional ``exclude`` kwarg is used, only dynamicsymbols not in the iterable ``exclude`` are returned. >>> find_dynamicsymbols(expr, [x, y]) set([Derivative(x(t), t)]) """ t_set = set([dynamicsymbols._t]) if exclude: if iterable(exclude): exclude_set = set(exclude) else: raise TypeError("exclude kwarg must be iterable") else: exclude_set = set() return set([i for i in expression.atoms(AppliedUndef, sm.Derivative) if i.free_symbols == t_set]) - exclude_set
[docs]class PyDyDeprecationWarning(DeprecationWarning): pass
[docs]class PyDyImportWarning(ImportWarning): pass
[docs]class PyDyFutureWarning(FutureWarning): pass
[docs]class PyDyUserWarning(UserWarning): pass