1 | Index: geos/geometries.py
|
---|
2 | ===================================================================
|
---|
3 | --- geos/geometries.py (revision 2)
|
---|
4 | +++ geos/geometries.py (revision 7)
|
---|
5 | @@ -156,10 +156,12 @@
|
---|
6 |
|
---|
7 | # Getting the correct initialization function
|
---|
8 | if kwargs.get('ring', False):
|
---|
9 | - func = create_linearring
|
---|
10 | + self._init_func = create_linearring
|
---|
11 | else:
|
---|
12 | - func = create_linestring
|
---|
13 | + self._init_func = create_linestring
|
---|
14 |
|
---|
15 | + func = self._init_func
|
---|
16 | +
|
---|
17 | # If SRID was passed in with the keyword arguments
|
---|
18 | srid = kwargs.get('srid', None)
|
---|
19 |
|
---|
20 | @@ -168,13 +170,152 @@
|
---|
21 | super(LineString, self).__init__(func(cs.ptr), srid=srid)
|
---|
22 |
|
---|
23 | def __getitem__(self, index):
|
---|
24 | - "Gets the point at the specified index."
|
---|
25 | - return self._cs[index]
|
---|
26 | + "Gets the coordinates of the point(s) at the specified index/slice."
|
---|
27 | + if isinstance(index, slice):
|
---|
28 | + return [self._cs[i] for i in xrange(*index.indices(len(self._cs)))]
|
---|
29 | + else:
|
---|
30 | + if index < 0:
|
---|
31 | + index += len(self._cs)
|
---|
32 | + return self._cs[index]
|
---|
33 |
|
---|
34 | + def __delitem__(self, index):
|
---|
35 | + "Delete the point(s) at the specified index/slice."
|
---|
36 | + if not isinstance(index, (int, long, slice)):
|
---|
37 | + raise TypeError("%s is not a legal index" % index)
|
---|
38 | +
|
---|
39 | + # calculate new length and dimensions
|
---|
40 | + currLen = len(self._cs)
|
---|
41 | + if isinstance(index, (int, long)):
|
---|
42 | + if index < 0: index += currLen
|
---|
43 | + if index < 0 or currLen <= index:
|
---|
44 | + raise GEOSIndexError('invalid GEOS Geometry index: %d' % index)
|
---|
45 | + indexRange = [index]
|
---|
46 | + else:
|
---|
47 | + indexRange = range(*index.indices(currLen))
|
---|
48 | +
|
---|
49 | + newLen = currLen - len(indexRange)
|
---|
50 | + ndim = self._cs.dims
|
---|
51 | + hasz = self._cs.hasz # I don't understand why these are different
|
---|
52 | +
|
---|
53 | + # create a new coordinate sequence and populate accordingly
|
---|
54 | + cs = GEOSCoordSeq(create_cs(newLen, ndim), z=hasz)
|
---|
55 | + new_i = 0
|
---|
56 | + for old_i in xrange(currLen):
|
---|
57 | + if old_i in indexRange: continue
|
---|
58 | + cs[new_i] = self._cs[old_i]
|
---|
59 | + new_i += 1
|
---|
60 | +
|
---|
61 | + ptr = self._init_func(cs.ptr)
|
---|
62 | + if ptr:
|
---|
63 | + destroy_geom(self.ptr)
|
---|
64 | + self._ptr = ptr
|
---|
65 | + self._post_init(self.srid)
|
---|
66 | + else:
|
---|
67 | + # can this happen?
|
---|
68 | + raise GEOSException('Geometry resulting from slice deletion was invalid.')
|
---|
69 | +
|
---|
70 | def __setitem__(self, index, value):
|
---|
71 | - "Sets the point at the specified index, e.g., line_str[0] = (1, 2)."
|
---|
72 | - self._cs[index] = value
|
---|
73 | + """Sets the point(s) at the specified index/slice,
|
---|
74 | + e.g., line_str[0] = (1, 2)."""
|
---|
75 | + if isinstance(index, slice):
|
---|
76 | + try:
|
---|
77 | + valueIter = iter(value)
|
---|
78 | + except TypeError:
|
---|
79 | + raise TypeError('can only assign an iterable')
|
---|
80 |
|
---|
81 | + # calculate length and dimensions
|
---|
82 | + currLen = len(self._cs)
|
---|
83 | + valueList = list(value)
|
---|
84 | + start, stop, step = index.indices(currLen)
|
---|
85 | + stop = max(0, stop) # stop will be -1 if out-of-bounds
|
---|
86 | + # negative index is given
|
---|
87 | +
|
---|
88 | + # CAREFUL: index.step and step are not the same!
|
---|
89 | + # step will never be None
|
---|
90 | + #
|
---|
91 | + if index.step is None:
|
---|
92 | + # this is a simple slice, can assign slice of any length
|
---|
93 | + # calculate new length
|
---|
94 | + newLen = currLen - stop + start + len(valueList)
|
---|
95 | + ndim = self._cs.dims
|
---|
96 | + hasz = self._cs.hasz # not sure why these are different
|
---|
97 | +
|
---|
98 | + # create a new coordinate sequence and populate accordingly
|
---|
99 | + cs = GEOSCoordSeq(create_cs(newLen, ndim), z=hasz)
|
---|
100 | + new_i = 0
|
---|
101 | + for old_i in xrange(currLen + 1):
|
---|
102 | + if old_i == start:
|
---|
103 | + for val in valueList:
|
---|
104 | + cs[new_i] = val
|
---|
105 | + new_i += 1
|
---|
106 | +
|
---|
107 | + if old_i < currLen:
|
---|
108 | + if old_i < start or old_i >= stop:
|
---|
109 | + cs[new_i] = self._cs[old_i]
|
---|
110 | + new_i += 1
|
---|
111 | +
|
---|
112 | + ptr = self._init_func(cs.ptr)
|
---|
113 | + # Polygon.__setitem__ doesn't check this, but it seems
|
---|
114 | + # that it can't hurt.
|
---|
115 | + if ptr:
|
---|
116 | + destroy_geom(self.ptr)
|
---|
117 | + self._ptr = ptr
|
---|
118 | + self._post_init(self.srid)
|
---|
119 | + else:
|
---|
120 | + raise GEOSException('Geometry resulting from slice deletion was invalid.')
|
---|
121 | +
|
---|
122 | + else:
|
---|
123 | + indexList = range(start, stop, step)
|
---|
124 | + # extended slice, only allow assigning slice of same size
|
---|
125 | + if len(valueList) != len(indexList):
|
---|
126 | + raise ValueError('attempt to assign sequence of size %d '
|
---|
127 | + 'to extended slice of size %d'
|
---|
128 | + % (len(valueList), len(indexList)))
|
---|
129 | +
|
---|
130 | + # we're not changing the length of the sequence
|
---|
131 | + # we can just iterate the indices and value and set them
|
---|
132 | + for i, val in zip(indexList , valueList):
|
---|
133 | + self._cs[i] = val
|
---|
134 | +
|
---|
135 | + else:
|
---|
136 | + length = len(self._cs)
|
---|
137 | + if index < 0: index += length
|
---|
138 | + self._cs[index] = value
|
---|
139 | +
|
---|
140 | + def append(self, val):
|
---|
141 | + "Standard list append method"
|
---|
142 | + self[len(self):] = [val]
|
---|
143 | +
|
---|
144 | + def extend(self, vals):
|
---|
145 | + "Standard list extend method"
|
---|
146 | + self[len(self):] = vals
|
---|
147 | +
|
---|
148 | + def insert(self, index, val):
|
---|
149 | + "Standard list insert method"
|
---|
150 | + if not isinstance(index, (int, long)):
|
---|
151 | + raise TypeError("%s is not a legal index" % index)
|
---|
152 | + self[index:index] = [val]
|
---|
153 | +
|
---|
154 | + def pop(self, index=-1):
|
---|
155 | + "Standard list pop method"
|
---|
156 | + result = self[index]
|
---|
157 | + del self[index]
|
---|
158 | + return result
|
---|
159 | +
|
---|
160 | + def index(self, val):
|
---|
161 | + "Standard list index method"
|
---|
162 | + for i in xrange(0, len(self)):
|
---|
163 | + if self[i] == val: return i
|
---|
164 | + raise ValueError('%s not in geometry' % str(val))
|
---|
165 | +
|
---|
166 | + def remove(self, val):
|
---|
167 | + "Standard list remove method"
|
---|
168 | + del self[self.index(val)]
|
---|
169 | +
|
---|
170 | + def count(self):
|
---|
171 | + "Standard list count method"
|
---|
172 | + return len(self)
|
---|
173 | +
|
---|
174 | def __iter__(self):
|
---|
175 | "Allows iteration over this LineString."
|
---|
176 | for i in xrange(len(self)):
|
---|
177 | Index: tests/__init__.py
|
---|
178 | ===================================================================
|
---|
179 | --- tests/__init__.py (revision 2)
|
---|
180 | +++ tests/__init__.py (revision 7)
|
---|
181 | @@ -18,6 +18,7 @@
|
---|
182 | # Tests that do not require setting up and tearing down a spatial database.
|
---|
183 | test_suite_names = [
|
---|
184 | 'test_geos',
|
---|
185 | + 'test_geos_pymutable',
|
---|
186 | 'test_measure',
|
---|
187 | ]
|
---|
188 | if HAS_GDAL:
|
---|
189 | Index: tests/test_geos_pymutable.py
|
---|
190 | ===================================================================
|
---|
191 | --- tests/test_geos_pymutable.py (revision 0)
|
---|
192 | +++ tests/test_geos_pymutable.py (revision 7)
|
---|
193 | @@ -0,0 +1,174 @@
|
---|
194 | +import unittest
|
---|
195 | +from pymutable_geometries import *
|
---|
196 | +from django.contrib.gis.geos.error import GEOSIndexError
|
---|
197 | +
|
---|
198 | +class GEOSPyMutableTest(unittest.TestCase):
|
---|
199 | + '''
|
---|
200 | + Tests Pythonic Mutability of Python GEOS geometry wrappers
|
---|
201 | + get/set/delitem on a slice, normal list methods
|
---|
202 | + '''
|
---|
203 | +
|
---|
204 | + def test01_getslice(self):
|
---|
205 | + 'Test getting a slice from a geometry'
|
---|
206 | + for f in getslice_functions():
|
---|
207 | + for g in slice_geometries():
|
---|
208 | + self.assertEqual(f(g.coords), f(g.geom), f.__name__)
|
---|
209 | +
|
---|
210 | + def test02_getitem(self):
|
---|
211 | + 'Test getting a single item from a geometry'
|
---|
212 | + for g in slice_geometries():
|
---|
213 | + for i in seqrange():
|
---|
214 | + self.assertEqual(g.coords[i], g.geom[i])
|
---|
215 | +
|
---|
216 | + def test03_getitem_indexException(self):
|
---|
217 | + 'Test get single item with out-of-bounds index'
|
---|
218 | + for g in slice_geometries():
|
---|
219 | + for i in SEQ_OUT_OF_BOUNDS:
|
---|
220 | + self.assertRaises(GEOSIndexError, lambda: g.geom[i])
|
---|
221 | +
|
---|
222 | + def test04_delitem_single(self):
|
---|
223 | + 'Test delete single item from a geometry'
|
---|
224 | + for i in seqrange():
|
---|
225 | + for g in slice_geometries():
|
---|
226 | + if g.geom.ring and i in SEQ_BOUNDS: continue
|
---|
227 | + del g.coords[i]
|
---|
228 | + del g.geom[i]
|
---|
229 | + self.assertEqual(g.coords , g.geom[:])
|
---|
230 | +
|
---|
231 | + def test05_delitem_slice(self):
|
---|
232 | + 'Test delete slice from a geometry'
|
---|
233 | + for f in delslice_functions():
|
---|
234 | + for g in slice_geometries():
|
---|
235 | + if g.geom.ring and not f.ring: continue
|
---|
236 | + f(g.coords)
|
---|
237 | + f(g.geom)
|
---|
238 | + self.assertEqual(g.coords , g.geom[:], f.__name__)
|
---|
239 | +
|
---|
240 | + def test06_delitem_single_indexException(self):
|
---|
241 | + 'Test delete single item with out-of-bounds index'
|
---|
242 | + def func(x, i): del x[i]
|
---|
243 | + for g in slice_geometries():
|
---|
244 | + for i in SEQ_OUT_OF_BOUNDS:
|
---|
245 | + self.assertRaises(GEOSIndexError, func, g.geom, i)
|
---|
246 | +
|
---|
247 | + def test07_setitem_single(self):
|
---|
248 | + "Test set single item (make sure we didn't break this)"
|
---|
249 | + for i in seqrange():
|
---|
250 | + for g in slice_geometries():
|
---|
251 | + if g.geom.ring and i in SEQ_BOUNDS: continue
|
---|
252 | + g.coords[i] = (3.14159, 3.14159)
|
---|
253 | + g.geom[i] = (3.14159, 3.14159)
|
---|
254 | + self.assertEqual(g.coords , g.geom[:])
|
---|
255 | +
|
---|
256 | + def test08_setslice_simple(self):
|
---|
257 | + 'Test setting a simple slice of a geometry'
|
---|
258 | + for f in setslice_simple_functions():
|
---|
259 | + for g in slice_geometries():
|
---|
260 | + if g.geom.ring and not f.ring: continue
|
---|
261 | + f(g.coords)
|
---|
262 | + f(g.geom)
|
---|
263 | + self.assertEqual(g.coords , g.geom[:], f.__name__)
|
---|
264 | +
|
---|
265 | + def test09_setslice_extended(self):
|
---|
266 | + 'Test setting an extended slice of a geometry'
|
---|
267 | + for f in setslice_extended_functions():
|
---|
268 | + for g in slice_geometries():
|
---|
269 | + if g.geom.ring and not f.ring: continue
|
---|
270 | + f(g.coords)
|
---|
271 | + f(g.geom)
|
---|
272 | + self.assertEqual(g.coords , g.geom[:], f.__name__)
|
---|
273 | +
|
---|
274 | + def test10_setslice_extended_mismatched(self):
|
---|
275 | + 'Test setting extended slice with array of mismatched length'
|
---|
276 | + def func(x): x[2:8:2] = [(3.1415, 3.1415)]
|
---|
277 | + for g in slice_geometries():
|
---|
278 | + self.assertRaises(ValueError, func, g.geom)
|
---|
279 | +
|
---|
280 | + def test11_setitem_single_indexException(self):
|
---|
281 | + 'Test set single item with out-of-bounds index'
|
---|
282 | + def func(x, i): x[i] = (3.1415, 3.1415)
|
---|
283 | + for g in slice_geometries():
|
---|
284 | + for i in SEQ_OUT_OF_BOUNDS:
|
---|
285 | + self.assertRaises(GEOSIndexError, func, g.geom, i)
|
---|
286 | +
|
---|
287 | + def test12_append(self):
|
---|
288 | + 'Test list method append'
|
---|
289 | + for g in slice_geometries():
|
---|
290 | + if g.geom.ring: continue
|
---|
291 | + g.geom.append((200.0,200.0))
|
---|
292 | + g.coords.append((200.0,200.0))
|
---|
293 | + self.assertEqual(g.coords , g.geom[:])
|
---|
294 | +
|
---|
295 | + def test13_extend(self):
|
---|
296 | + 'Test list method extend'
|
---|
297 | + for g in slice_geometries():
|
---|
298 | + points = random_coords(5)
|
---|
299 | + if g.geom.ring: points[-1] = g.coords[0]
|
---|
300 | + g.geom.extend(points)
|
---|
301 | + g.coords.extend(points)
|
---|
302 | + self.assertEqual(g.coords , g.geom[:])
|
---|
303 | +
|
---|
304 | + def test14_insert(self):
|
---|
305 | + 'Test list method insert'
|
---|
306 | + for i in xrange(*SEQ_OUT_OF_BOUNDS):
|
---|
307 | + for g in slice_geometries():
|
---|
308 | + if g.geom.ring and i in SEQ_BOUNDS + SEQ_OUT_OF_BOUNDS:
|
---|
309 | + continue
|
---|
310 | + g.geom.insert(i, (3141.5, 3141.5))
|
---|
311 | + g.coords.insert(i, (3141.5, 3141.5))
|
---|
312 | + self.assertEqual(g.coords , g.geom[:])
|
---|
313 | +
|
---|
314 | + def test15_insert_typeError(self):
|
---|
315 | + 'Test list method insert raises error on invalid index'
|
---|
316 | + for g in slice_geometries():
|
---|
317 | + self.assertRaises(TypeError, g.geom.insert,
|
---|
318 | + 'hi', (3141.5, 3141.5))
|
---|
319 | +
|
---|
320 | + def test16_pop(self):
|
---|
321 | + 'Test list method pop'
|
---|
322 | + for i in seqrange():
|
---|
323 | + for g in slice_geometries():
|
---|
324 | + if g.geom.ring and i in SEQ_BOUNDS + SEQ_OUT_OF_BOUNDS:
|
---|
325 | + continue
|
---|
326 | + self.assertEqual(g.coords.pop(i), g.geom.pop(i))
|
---|
327 | +
|
---|
328 | + def test16_index(self):
|
---|
329 | + 'Test list method index'
|
---|
330 | + for i in xrange(0, SEQ_LENGTH):
|
---|
331 | + for g in slice_geometries():
|
---|
332 | + if g.geom.ring and i in SEQ_BOUNDS: continue
|
---|
333 | + p = (200.0, 200.0)
|
---|
334 | + g.geom[i] = p
|
---|
335 | + self.assertEqual(i, g.geom.index(p))
|
---|
336 | +
|
---|
337 | + def test17_index_ValueError(self):
|
---|
338 | + 'Test list method raises ValueError if value not found'
|
---|
339 | + for g in slice_geometries():
|
---|
340 | + self.assertRaises(ValueError, g.geom.index, (200.0,200.0))
|
---|
341 | +
|
---|
342 | + def test18_remove(self):
|
---|
343 | + 'Test list method remove'
|
---|
344 | + for i in xrange(0, SEQ_LENGTH):
|
---|
345 | + for g in slice_geometries():
|
---|
346 | + if g.geom.ring and i in SEQ_BOUNDS: continue
|
---|
347 | + p = (200.0, 200.0)
|
---|
348 | + g.geom[i] = p
|
---|
349 | + g.coords[i] = p
|
---|
350 | + g.geom.remove(p)
|
---|
351 | + g.coords.remove(p)
|
---|
352 | + self.assertEqual(g.coords, g.geom[:])
|
---|
353 | +
|
---|
354 | + def test19_count(self):
|
---|
355 | + 'Test list method count'
|
---|
356 | + for g in slice_geometries():
|
---|
357 | + self.assertEqual(SEQ_LENGTH, g.geom.count())
|
---|
358 | +def suite():
|
---|
359 | + s = unittest.TestSuite()
|
---|
360 | + s.addTest(unittest.makeSuite(GEOSPyMutableTest))
|
---|
361 | + return s
|
---|
362 | +
|
---|
363 | +def run(verbosity=2):
|
---|
364 | + unittest.TextTestRunner(verbosity=verbosity).run(suite())
|
---|
365 | +
|
---|
366 | +if __name__ == '__main__':
|
---|
367 | + run()
|
---|
368 |
|
---|
369 | Property changes on: tests/test_geos_pymutable.py
|
---|
370 | ___________________________________________________________________
|
---|
371 | Name: svn:executable
|
---|
372 | + *
|
---|
373 |
|
---|
374 | Index: tests/pymutable_geometries.py
|
---|
375 | ===================================================================
|
---|
376 | --- tests/pymutable_geometries.py (revision 0)
|
---|
377 | +++ tests/pymutable_geometries.py (revision 7)
|
---|
378 | @@ -0,0 +1,125 @@
|
---|
379 | +from django.contrib.gis.geos import *
|
---|
380 | +from random import random
|
---|
381 | +
|
---|
382 | +SEQ_LENGTH = 10
|
---|
383 | +SEQ_RANGE = (-1 * SEQ_LENGTH, SEQ_LENGTH)
|
---|
384 | +SEQ_BOUNDS = (-1 * SEQ_LENGTH, -1, 0, SEQ_LENGTH - 1)
|
---|
385 | +SEQ_OUT_OF_BOUNDS = (-1 * SEQ_LENGTH -1 , SEQ_LENGTH)
|
---|
386 | +
|
---|
387 | +def seqrange(): return xrange(*SEQ_RANGE)
|
---|
388 | +
|
---|
389 | +class PyMutTestGeom:
|
---|
390 | + "The Test Geometry class container."
|
---|
391 | + def __init__(self, geom_type, coords, **kwargs):
|
---|
392 | + self.coords = coords
|
---|
393 | + self.geom = geom_type(coords)
|
---|
394 | +
|
---|
395 | + for key, value in kwargs.items():
|
---|
396 | + setattr(self, key, value)
|
---|
397 | +
|
---|
398 | +def random_coords(length=SEQ_LENGTH, dim=2, rng=(-50,50), type=float,
|
---|
399 | + ring=False, round_coords=True):
|
---|
400 | + if round_coords:
|
---|
401 | + num = lambda: type(round(random() * (rng[1]-rng[0]) + rng[0]))
|
---|
402 | + else:
|
---|
403 | + num = lambda: type(random() * (rng[1]-rng[0]) + rng[0])
|
---|
404 | +
|
---|
405 | + result = [ tuple( num() for axis in xrange(dim) )
|
---|
406 | + for index in xrange(length) ]
|
---|
407 | + if ring:
|
---|
408 | + result[-1] = result[0]
|
---|
409 | +
|
---|
410 | + return result
|
---|
411 | +
|
---|
412 | +
|
---|
413 | +def slice_geometries():
|
---|
414 | + return (
|
---|
415 | + PyMutTestGeom(LineString, random_coords()),
|
---|
416 | + PyMutTestGeom(LinearRing, random_coords(ring=True)),
|
---|
417 | + )
|
---|
418 | +
|
---|
419 | +def getslice_functions():
|
---|
420 | + return (
|
---|
421 | + lambda x: x[0:4],
|
---|
422 | + lambda x: x[5:-1],
|
---|
423 | + lambda x: x[6:2:-1],
|
---|
424 | + lambda x: x[:],
|
---|
425 | + lambda x: x[:3],
|
---|
426 | + lambda x: x[::2],
|
---|
427 | + lambda x: x[::-4],
|
---|
428 | + lambda x: x[7:7],
|
---|
429 | + lambda x: x[20:],
|
---|
430 | + )
|
---|
431 | +
|
---|
432 | +def delslice_functions():
|
---|
433 | + def ds_01(x): del x[0:4]
|
---|
434 | + def ds_02(x): del x[5:-1]
|
---|
435 | + def ds_03(x): del x[6:2:-1]
|
---|
436 | + def ds_04(x): del x[:] # should this be allowed?
|
---|
437 | + def ds_05(x): del x[:3]
|
---|
438 | + def ds_06(x): del x[1:9:2]
|
---|
439 | + def ds_07(x): del x[::-4]
|
---|
440 | + def ds_08(x): del x[7:7]
|
---|
441 | + def ds_09(x): del x[-7:-2]
|
---|
442 | +
|
---|
443 | + return mark_ring(vars(), 'ds_')
|
---|
444 | +
|
---|
445 | +def setslice_extended_functions():
|
---|
446 | + a = [(1.0,2.0),(1.0,2.0),(1.0,2.0)]
|
---|
447 | + def sse_00(x): x[:3:1] = a
|
---|
448 | + def sse_01(x): x[0:3:1] = a
|
---|
449 | + def sse_02(x): x[2:5:1] = a
|
---|
450 | + def sse_03(x): x[-3::1] = a
|
---|
451 | + def sse_04(x): x[-4:-1:1] = a
|
---|
452 | + def sse_05(x): x[8:5:-1] = a
|
---|
453 | + def sse_06(x): x[-6:-9:-1] = a
|
---|
454 | + def sse_07(x): x[:8:3] = a
|
---|
455 | + def sse_08(x): x[1::3] = a
|
---|
456 | + def sse_09(x): x[-2::-3] = a
|
---|
457 | + def sse_10(x): x[7:1:-2] = a
|
---|
458 | + def sse_11(x): x[2:8:2] = a
|
---|
459 | +
|
---|
460 | + return mark_ring(vars(), 'sse_')
|
---|
461 | +
|
---|
462 | +def setslice_simple_functions():
|
---|
463 | + a = [(1.0,2.0),(2.0,1.0),(2.0,2.0)]
|
---|
464 | + def ss_00(x): x[:0] = a
|
---|
465 | + def ss_01(x): x[:1] = a
|
---|
466 | + def ss_02(x): x[:2] = a
|
---|
467 | + def ss_03(x): x[:3] = a
|
---|
468 | + def ss_04(x): x[-4:] = a
|
---|
469 | + def ss_05(x): x[-3:] = a
|
---|
470 | + def ss_06(x): x[-2:] = a
|
---|
471 | + def ss_07(x): x[-1:] = a
|
---|
472 | + def ss_08(x): x[5:] = a
|
---|
473 | + def ss_09(x): x[:] = a
|
---|
474 | + def ss_10(x): x[4:4] = a
|
---|
475 | + def ss_11(x): x[4:5] = a
|
---|
476 | + def ss_12(x): x[4:7] = a
|
---|
477 | + def ss_13(x): x[4:8] = a
|
---|
478 | + def ss_14(x): x[20:30] = a
|
---|
479 | + def ss_15(x): x[-13:-8] = a
|
---|
480 | + def ss_16(x): x[-13:-9] = a
|
---|
481 | + def ss_17(x): x[-13:-10] = a
|
---|
482 | + def ss_18(x): x[-13:-11] = a
|
---|
483 | + def ss_19(x): x[10:] = a
|
---|
484 | +
|
---|
485 | + return mark_ring(vars(), 'ss_')
|
---|
486 | +
|
---|
487 | +def mark_ring(locals, name_pat, length=SEQ_LENGTH):
|
---|
488 | + '''
|
---|
489 | + Accepts an array of functions which perform slice modifications
|
---|
490 | + and labels each function as to whether or not it preserves ring-ness
|
---|
491 | + '''
|
---|
492 | + func_array = [ val for name, val in locals.items()
|
---|
493 | + if hasattr(val, '__call__')
|
---|
494 | + and name.startswith(name_pat) ]
|
---|
495 | +
|
---|
496 | + for i in xrange(len(func_array)):
|
---|
497 | + a = range(length)
|
---|
498 | + a[-1] = a[0]
|
---|
499 | + func_array[i](a)
|
---|
500 | + ring = len(a) == 0 or (len(a) > 3 and a[-1] == a[0])
|
---|
501 | + func_array[i].ring = ring
|
---|
502 | +
|
---|
503 | + return func_array
|
---|
504 |
|
---|
505 | Property changes on: tests/pymutable_geometries.py
|
---|
506 | ___________________________________________________________________
|
---|
507 | Name: svn:executable
|
---|
508 | + *
|
---|
509 |
|
---|