forked from sympy/sympy
/
containers.py
101 lines (78 loc) · 2.81 KB
/
containers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""Module for Sympy containers
(Sympy objects that store other Sympy objects)
The containers implemented in this module are subclassed to Basic.
They are supposed to work seamlessly within the Sympy framework.
"""
from basic import Basic
class Tuple(Basic):
"""
Wrapper around the builtin tuple object
The Tuple is a subclass of Basic, so that it works well in the
Sympy framework. The wrapped tuple is available as self.args, but
you can also access elements or slices with [:] syntax.
>>> from sympy import symbols
>>> from sympy.core.containers import Tuple
>>> a, b, c, d = symbols('a b c d')
>>> Tuple(a, b, c)[1:]
Tuple(b, c)
>>> Tuple(a, b, c).subs(a, d)
Tuple(d, b, c)
"""
def __getitem__(self,i):
if isinstance(i,slice):
indices = i.indices(len(self))
return Tuple(*[self.args[i] for i in range(*indices)])
return self.args[i]
def __len__(self):
return len(self.args)
def __contains__(self, item):
return item in self.args
def __iter__(self):
return iter(self.args)
def __add__(self, other):
if isinstance(other, Tuple):
return Tuple(*(self.args + other.args))
elif isinstance(other, tuple):
return Tuple(*(self.args + other))
else:
return NotImplemented
def __radd__(self, other):
if isinstance(other, Tuple):
return Tuple(*(other.args + self.args))
elif isinstance(other, tuple):
return Tuple(*(other + self.args))
else:
return NotImplemented
def __eq__(self, other):
if isinstance(other, Basic):
return super(Tuple, self).__eq__(other)
return self.args == other
def __ne__(self, other):
if isinstance(other, Basic):
return super(Tuple, self).__ne__(other)
return self.args != other
def __hash__(self):
return hash(self.args)
def tuple_wrapper(method):
"""
Decorator that converts any tuple in the function arguments into a Tuple.
The motivation for this is to provide simple user interfaces. The user can
call a function with regular tuples in the argument, and the wrapper will
convert them to Tuples before handing them to the function.
>>> from sympy.core.containers import tuple_wrapper, Tuple
>>> def f(*args):
... return args
>>> g = tuple_wrapper(f)
The decorated function g sees only the Tuple argument:
>>> g(0, (1, 2), 3)
(0, Tuple(1, 2), 3)
"""
def wrap_tuples(*args, **kw_args):
newargs=[]
for arg in args:
if type(arg) is tuple:
newargs.append(Tuple(*arg))
else:
newargs.append(arg)
return method(*newargs, **kw_args)
return wrap_tuples