~dinko-metalac/calculus-app2/trunk

« back to all changes in this revision

Viewing changes to lib/py/sympy/core/sympify.py

  • Committer: dinko.metalac at gmail
  • Date: 2015-04-14 13:28:14 UTC
  • Revision ID: dinko.metalac@gmail.com-20150414132814-j25k3qd7sq3warup
new sympy

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""sympify -- convert objects SymPy internal format"""
2
2
 
 
3
from __future__ import print_function, division
 
4
 
3
5
from inspect import getmro
4
6
 
5
7
from .core import all_classes as sympy_classes
6
 
from sympy.core.compatibility import iterable
 
8
from .compatibility import iterable, string_types
 
9
from .evaluate import global_evaluate
7
10
 
8
11
 
9
12
class SympifyError(ValueError):
47
50
    """
48
51
    pass
49
52
 
50
 
def sympify(a, locals=None, convert_xor=True, strict=False, rational=False):
51
 
    """
52
 
    Converts an arbitrary expression to a type that can be used inside SymPy.
 
53
def sympify(a, locals=None, convert_xor=True, strict=False, rational=False,
 
54
        evaluate=None):
 
55
    """Converts an arbitrary expression to a type that can be used inside SymPy.
53
56
 
54
57
    For example, it will convert Python ints into instance of sympy.Rational,
55
58
    floats into instances of sympy.Float, etc. It is also able to coerce symbolic
60
63
       - any object defined in sympy
61
64
       - standard numeric python types: int, long, float, Decimal
62
65
       - strings (like "0.09" or "2e-19")
63
 
       - booleans, including ``None`` (will leave them unchanged)
 
66
       - booleans, including ``None`` (will leave ``None`` unchanged)
64
67
       - lists, sets or tuples containing any of the above
65
68
 
66
69
    If the argument is already a type that SymPy understands, it will do
94
97
    The sympification happens with access to everything that is loaded
95
98
    by ``from sympy import *``; anything used in a string that is not
96
99
    defined by that import will be converted to a symbol. In the following,
97
 
    the ``bitcout`` function is treated as a symbol and the ``O`` is
 
100
    the ``bitcount`` function is treated as a symbol and the ``O`` is
98
101
    interpreted as the Order object (used with series) and it raises
99
102
    an error when used improperly:
100
103
 
111
114
    In order to have ``bitcount`` be recognized it can be imported into a
112
115
    namespace dictionary and passed as locals:
113
116
 
 
117
    >>> from sympy.core.compatibility import exec_
114
118
    >>> ns = {}
115
 
    >>> exec('from sympy.core.evalf import bitcount', ns)
 
119
    >>> exec_('from sympy.core.evalf import bitcount', ns)
116
120
    >>> sympify(s, locals=ns)
117
121
    6
118
122
 
122
126
 
123
127
    >>> from sympy import Symbol
124
128
    >>> ns["O"] = Symbol("O")  # method 1
125
 
    >>> exec('from sympy.abc import O', ns)  # method 2
 
129
    >>> exec_('from sympy.abc import O', ns)  # method 2
126
130
    >>> ns.update(dict(O=Symbol("O")))  # method 3
127
131
    >>> sympify("O + 1", locals=ns)
128
132
    O + 1
146
150
    explicit conversion has been defined are converted. In the other
147
151
    cases, a SympifyError is raised.
148
152
 
149
 
    >>> sympify(True)
150
 
    True
151
 
    >>> sympify(True, strict=True)
 
153
    >>> print(sympify(None))
 
154
    None
 
155
    >>> sympify(None, strict=True)
152
156
    Traceback (most recent call last):
153
157
    ...
154
 
    SympifyError: SympifyError: True
 
158
    SympifyError: SympifyError: None
 
159
 
 
160
    Evaluation
 
161
    ----------
 
162
 
 
163
    If the option ``evaluate`` is set to ``False``, then arithmetic and
 
164
    operators will be converted into their SymPy equivalents and the
 
165
    ``evaluate=False`` option will be added. Nested ``Add`` or ``Mul`` will
 
166
    be denested first. This is done via an AST transformation that replaces
 
167
    operators with their SymPy equivalents, so if an operand redefines any
 
168
    of those operations, the redefined operators will not be used.
 
169
 
 
170
    >>> sympify('2**2 / 3 + 5')
 
171
    19/3
 
172
    >>> sympify('2**2 / 3 + 5', evaluate=False)
 
173
    2**2/3 + 5
155
174
 
156
175
    Extending
157
176
    ---------
211
230
    -2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1
212
231
 
213
232
    """
 
233
    if evaluate is None:
 
234
        evaluate = global_evaluate[0]
214
235
    try:
215
236
        cls = a.__class__
216
237
    except AttributeError:  # a is probably an old-style class object
217
238
        cls = type(a)
218
239
    if cls in sympy_classes:
219
240
        return a
220
 
    if cls in (bool, type(None)):
 
241
    if cls is type(None):
221
242
        if strict:
222
243
            raise SympifyError(a)
223
244
        else:
240
261
    except AttributeError:
241
262
        pass
242
263
 
243
 
    if not isinstance(a, str):
 
264
    if not isinstance(a, string_types):
244
265
        for coerce in (float, int):
245
266
            try:
246
267
                return sympify(coerce(a))
274
295
    # and try to parse it. If it fails, then we have no luck and
275
296
    # return an exception
276
297
    try:
277
 
        a = str(a)
 
298
        from .compatibility import unicode
 
299
        a = unicode(a)
278
300
    except Exception as exc:
279
301
        raise SympifyError(a, exc)
280
302
 
292
314
 
293
315
    try:
294
316
        a = a.replace('\n', '')
295
 
        expr = parse_expr(a, local_dict=locals, transformations=transformations)
 
317
        expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
296
318
    except (TokenError, SyntaxError) as exc:
297
319
        raise SympifyError('could not parse %r' % a, exc)
298
320
 
350
372
    If use of the hack fails, the un-hacked string will be passed to sympify...
351
373
    and you get what you get.
352
374
 
353
 
    XXX This hack should not be necessary once issue 1497 has been resolved.
 
375
    XXX This hack should not be necessary once issue 4596 has been resolved.
354
376
    """
355
377
    import re
356
378
    from sympy.core.symbol import Symbol