Ticket #5538: family.diff

File family.diff, 8.9 KB (added by hivert, 13 years ago)

Difference of family.py before and after the patch.

Line 
120,21c20,21
2< from sage.combinat.finite_class import FiniteCombinatorialClass_l
3< from sage.rings.all import ZZ
4---
5> from sage.combinat.finite_class import FiniteCombinatorialClass
6> from sage.rings.integer import Integer
737,39c37,39
8<     In its simplest form, a list l by itself is considered as the
9<     family `(l[i]_{i \in I})` where `I` is the range
10<     `0\dots,len(l)`. So Family(l) just returns it.
11---
12>     In its simplest form, a list l or a tuple by itself is considered as the
13>     family `(l[i]_{i \in I})` where `I` is the range `0\dots,len(l)`. So
14>     Family(l) returns the corresponding family.
1545c45,48
16<         [1, 2, 3]
17---
18>         Family (1, 2, 3)
19>         sage: f = Family((1,2,3))
20>         sage: f
21>         Family (1, 2, 3)
2287,91c90,99
23<     By default, if the index set is a list, all images are computed
24<     right away, and stored in an internal dictionary. Note that this
25<     requires all the elements of the list to be hashable. One can ask
26<     instead for the images `f(i)` to be computed lazily, when
27<     needed::
28---
29>     By default, if the index set is a list or a tuple, all images are
30>     computed right away, and stored in an internal dictionary::
31>
32>         sage: f = Family((3,4,7), lambda i: 2*i)
33>         sage: f
34>         Finite family {3: 6, 4: 8, 7: 14}
35>
36>     Note that this requires all the elements of the list to be
37>     hashable. One can ask instead for the images `f(i)` to be computed
38>     lazily, when needed::
39121c129
40<        sage: f = LazyFamily(Permutations(3), lambda i: (i.to_lehmer_code()))
41---
42>        sage: f = LazyFamily(Permutations(3), attrcall("to_lehmer_code"))
43130,131c138,153
44<     unpickle.
45<     
46---
47>     unpickle. The following two work::
48>
49>        sage: loads(dumps(LazyFamily(Permutations(3), lambda p: p.to_lehmer_code())))
50>        Lazy family (f(i))_{i in Standard permutations of 3}
51>
52>        sage: loads(dumps(LazyFamily(Permutations(3), attrcall("to_lehmer_code"))))
53>        Lazy family (f(i))_{i in Standard permutations of 3}
54>
55>     But this one dont::   
56>
57>        sage: def plus_n(n): return lambda x: x+n
58>        sage: loads(dumps(LazyFamily([1,2,3], plus_n(3))))
59>        Traceback (most recent call last):
60>        ...
61>        ValueError: Cannot pickle code objects from closures
62>       
63249a272,293
64>
65>     The factory ``Family`` is supposed to be idempotent. We test this feature here::
66>     
67>         sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
68>         sage: g = Family(f)
69>         sage: f == g
70>         True
71>     
72>         sage: f = Family([3,4,7], lambda i: 2r*i, hidden_keys=[2])
73>         sage: g = Family(f)
74>         sage: f == g
75>         True
76>
77>         sage: f = LazyFamily([3,4,7], lambda i: 2r*i)
78>         sage: g = Family(f)
79>         sage: f == g
80>         True
81>
82>         sage: f = TrivialFamily([3,4,7])
83>         sage: g = Family(f)
84>         sage: f == g
85>         True
86252,255c296,297
87<     if function == None and hidden_keys == []:
88<         if type(indices) == list or isinstance(indices, FiniteCombinatorialClass_l) or isinstance(indices, FiniteFamily) or isinstance(indices, LazyFamily):
89<             return indices
90<         if type(indices) == dict:
91---
92>     if function is None and hidden_keys == []:
93>         if isinstance(indices, dict):
94256a299,303
95>         if isinstance(indices, (list, tuple) ):
96>             return TrivialFamily(indices)
97>         if isinstance(indices, (FiniteCombinatorialClass,
98>                                 FiniteFamily, LazyFamily, TrivialFamily) ):
99>             return indices
100258c305
101<         if type(indices) == list or isinstance(indices, FiniteCombinatorialClass_l):
102---
103>         if isinstance(indices, (list, tuple, FiniteCombinatorialClass) ):
104270a318,322
105>     """
106>     The abstract class for family
107>
108>     Any family belongs to a class which inherits from ``AbstractFamily``.
109>     """
110360c412,420
111<         """
112---
113>
114>         Check for bug #5538::
115>
116>             sage: d = {1:"a", 3:"b", 4:"c"}
117>             sage: f = Family(d)
118>             sage: d[2] = 'DD'
119>             sage: f
120>             Finite family {1: 'a', 3: 'b', 4: 'c'}
121>             """
122362c422
123<         self.dictionary = dictionary
124---
125>         self.dictionary = dict(dictionary)
126409c469
127<         return ZZ(len(self.dictionary))
128---
129>         return Integer(len(self.dictionary))
130450c510
131<         EXAMPLES::
132---
133>         TESTS::
134524c584
135<         EXAMPLES::
136---
137>         TESTS::
138540c600
139<         EXAMPLES::
140---
141>         TESTS::
142549a610,617
143>             
144>             sage: f = LazyFamily(Permutations(3), lambda p: p.to_lehmer_code())
145>             sage: f == loads(dumps(f))
146>             True
147>
148>             sage: f = LazyFamily(Permutations(3), attrcall("to_lehmer_code"))
149>             sage: f == loads(dumps(f))
150>             True
151551,552c619,623
152<         from sage.misc.fpickle import unpickle_function
153<         hidden_function = unpickle_function(d['hidden_function'])
154---
155>         hidden_function = d['hidden_function']
156>         if isinstance(hidden_function, str):
157>         # Let's assume that hidden_function is an unpicled function.             
158>             from sage.misc.fpickle import unpickle_function
159>             hidden_function = unpickle_function(hidden_function)
160567c638
161<         EXAMPLES::
162---
163>         TESTS::
164572a644,652
165>
166>         Check for bug #5538::
167>         
168>             sage: l = [3,4,7]
169>             sage: f = LazyFamily(l, lambda i: 2r*i);
170>             sage: l[1] = 18
171>             sage: f
172>             Lazy family (f(i))_{i in [3, 4, 7]}
173>             
174574c654,655
175<         self.set = set
176---
177>         from copy import copy
178>         self.set = copy(set)
179610c691
180<             return ZZ(len(self.set))
181---
182>             return Integer(len(self.set))
183649,650c730,736
184<         from sage.misc.fpickle import pickle_function
185<         f = pickle_function(self.function)
186---
187>         f = self.function
188>         # This should be done once for all by registering
189>         # sage.misc.fpickle.pickle_function to copy_reg
190>         if type(f) is type(Family): # TODO: where is the python `function` type?
191>             from sage.misc.fpickle import pickle_function
192>             f = pickle_function(f)
193>         
194668,669c754,759
195<         from sage.misc.fpickle import unpickle_function
196<         function = unpickle_function(d['function'])
197---
198>         function = d['function']
199>         if isinstance(function, str):
200>         # Let's assume that function is an unpicled function.             
201>             from sage.misc.fpickle import unpickle_function
202>             function = unpickle_function(function)
203>             
204670a761,858
205>
206>
207> class TrivialFamily(AbstractFamily):
208>     r"""
209>     ``TrivialFamily(c)`` turn the container c into a family indexed by
210>     the set `{0,\dots, len(c)}`. The container `c` can be either a list or a
211>     tuple.
212>     
213>     Instances should be created via the Family factory, which see for
214>     examples and tests.
215>     """
216>     def __init__(self, set):
217>         """
218>         EXAMPLES::
219>         
220>             sage: f = TrivialFamily((3,4,7)); f
221>             Family (3, 4, 7)
222>             sage: f = TrivialFamily([3,4,7]); f
223>             Family (3, 4, 7)
224>             sage: f == loads(dumps(f))
225>             True
226>         """
227>         self.set = tuple(set)
228>
229>     def __repr__(self):
230>         """
231>         EXAMPLES::
232>         
233>             sage: f = TrivialFamily([3,4,7]); f
234>             Family (3, 4, 7)
235>         """
236>         return "Family %s"%((self.set),)
237>
238>     def keys(self):
239>         """
240>         Returns self's keys.
241>         
242>         EXAMPLES::
243>         
244>             sage: f = TrivialFamily([3,4,7])
245>             sage: f.keys()
246>             [0, 1, 2]
247>         """
248>         return range(len(self.set))
249>
250>     def cardinality(self):
251>         """
252>         Return the number of elements in self.
253>         
254>         EXAMPLES::
255>         
256>             sage: f = TrivialFamily([3,4,7])
257>             sage: f.cardinality()
258>             3
259>         """
260>         return Integer(len(self.set))
261>     
262>     def __iter__(self):
263>         """
264>         EXAMPLES::
265>         
266>             sage: f = TrivialFamily([3,4,7])
267>             sage: [i for i in f]
268>             [3, 4, 7]
269>         """
270>         for i in self.set:
271>             yield i
272>
273>     def __getitem__(self, i):
274>         """       
275>         EXAMPLES::
276>         
277>             sage: f = TrivialFamily([3,4,7])
278>             sage: f[1]
279>             4       
280>         """
281>         return self.set[i]
282>
283>     def __getstate__(self):
284>         """
285>         TESTS::
286>         
287>             sage: f = TrivialFamily([3,4,7])
288>             sage: f.__getstate__()
289>             {'set': (3, 4, 7)}
290>         """
291>         return {'set': self.set}
292>
293>     def __setstate__(self, state):
294>         """
295>         TESTS::
296>         
297>             sage: f = TrivialFamily([3,4,7])
298>             sage: f.__setstate__({'set': (2, 4, 8)})
299>             sage: f
300>             Family (2, 4, 8)
301>         """
302>         self.__init__(state['set'])