7
7
You can add cyclers::
8
8
9
9
from cycler import cycler
10
- cc = (cycler(' color', list('rgb')) +
11
- cycler(' linestyle', ['-', '--', '-.']))
10
+ cc = (cycler(color= list('rgb')) +
11
+ cycler(linestyle= ['-', '--', '-.']))
12
12
for d in cc:
13
13
print(d)
14
14
22
22
You can multiply cyclers::
23
23
24
24
from cycler import cycler
25
- cc = (cycler(' color', list('rgb')) *
26
- cycler(' linestyle', ['-', '--', '-.']))
25
+ cc = (cycler(color= list('rgb')) *
26
+ cycler(linestyle= ['-', '--', '-.']))
27
27
for d in cc:
28
28
print(d)
29
29
@@ -113,8 +113,8 @@ def __init__(self, left, right=None, op=None):
113
113
Do not use this directly, use `cycler` function instead.
114
114
"""
115
115
self ._keys = _process_keys (left , right )
116
- self ._left = copy .copy (left )
117
- self ._right = copy .copy (right )
116
+ self ._left = copy .deepcopy (left )
117
+ self ._right = copy .deepcopy (right )
118
118
self ._op = op
119
119
120
120
@property
@@ -164,7 +164,7 @@ def __getitem__(self, key):
164
164
# TODO : maybe add numpy style fancy slicing
165
165
if isinstance (key , slice ):
166
166
trans = self ._transpose ()
167
- return reduce (add , (cycler (k , v [key ])
167
+ return reduce (add , (_cycler (k , v [key ])
168
168
for k , v in six .iteritems (trans )))
169
169
else :
170
170
raise ValueError ("Can only use slices with Cycler.__getitem__" )
@@ -203,7 +203,7 @@ def __mul__(self, other):
203
203
return Cycler (self , other , product )
204
204
elif isinstance (other , int ):
205
205
trans = self ._transpose ()
206
- return reduce (add , (cycler (k , v * other )
206
+ return reduce (add , (_cycler (k , v * other )
207
207
for k , v in six .iteritems (trans )))
208
208
else :
209
209
return NotImplemented
@@ -228,11 +228,11 @@ def __iadd__(self, other):
228
228
other : Cycler
229
229
The second Cycler
230
230
"""
231
- old_self = copy .copy (self )
231
+ old_self = copy .deepcopy (self )
232
232
self ._keys = _process_keys (old_self , other )
233
233
self ._left = old_self
234
234
self ._op = zip
235
- self ._right = copy .copy (other )
235
+ self ._right = copy .deepcopy (other )
236
236
return self
237
237
238
238
def __imul__ (self , other ):
@@ -245,11 +245,11 @@ def __imul__(self, other):
245
245
The second Cycler
246
246
"""
247
247
248
- old_self = copy .copy (self )
248
+ old_self = copy .deepcopy (self )
249
249
self ._keys = _process_keys (old_self , other )
250
250
self ._left = old_self
251
251
self ._op = product
252
- self ._right = copy .copy (other )
252
+ self ._right = copy .deepcopy (other )
253
253
return self
254
254
255
255
def __eq__ (self , other ):
@@ -329,17 +329,76 @@ def simplify(self):
329
329
# I would believe that there is some performance implications
330
330
331
331
trans = self ._transpose ()
332
- return reduce (add , (cycler (k , v ) for k , v in six .iteritems (trans )))
332
+ return reduce (add , (_cycler (k , v ) for k , v in six .iteritems (trans )))
333
333
334
334
335
- def cycler (label , itr ):
335
+ def cycler (* args , ** kwargs ):
336
+ """
337
+ Create a new `Cycler` object from a single positional argument,
338
+ a pair of positional arguments, or the combination of keyword arguments.
339
+
340
+ cycler(arg)
341
+ cycler(label1=itr1[, label2=iter2[, ...]])
342
+ cycler(label, itr)
343
+
344
+ Form 1 simply copies a given `Cycler` object.
345
+
346
+ Form 2 composes a `Cycler` as an inner product of the
347
+ pairs of keyword arguments. In other words, all of the
348
+ iterables are cycled simultaneously, as if through zip().
349
+
350
+ Form 3 creates a `Cycler` from a label and an iterable.
351
+ This is useful for when the label cannot be a keyword argument
352
+ (e.g., an integer or a name that has a space in it).
353
+
354
+ Parameters
355
+ ----------
356
+ arg : Cycler
357
+ Copy constructor for Cycler.
358
+
359
+ label : name
360
+ The property key. In the 2-arg form of the function,
361
+ the label can be any hashable object. In the keyword argument
362
+ form of the function, it must be a valid python identifier.
363
+
364
+ itr : iterable
365
+ Finite length iterable of the property values.
366
+
367
+ Returns
368
+ -------
369
+ cycler : Cycler
370
+ New `Cycler` for the given property
371
+
372
+ """
373
+ if args and kwargs :
374
+ raise TypeError ("cyl() can only accept positional OR keyword "
375
+ "arguments -- not both." )
376
+
377
+ if len (args ) == 1 :
378
+ if not isinstance (args [0 ], Cycler ):
379
+ raise TypeError ("If only one positional argument given, it must "
380
+ " be a Cycler instance." )
381
+ return copy .deepcopy (args [0 ])
382
+ elif len (args ) == 2 :
383
+ return _cycler (* args )
384
+ elif len (args ) > 2 :
385
+ raise TypeError ("Only a single Cycler can be accepted as the lone "
386
+ "positional argument. Use keyword arguments instead." )
387
+
388
+ if kwargs :
389
+ return reduce (add , (_cycler (k , v ) for k , v in six .iteritems (kwargs )))
390
+
391
+ raise TypeError ("Must have at least a positional OR keyword arguments" )
392
+
393
+
394
+ def _cycler (label , itr ):
336
395
"""
337
396
Create a new `Cycler` object from a property name and
338
397
iterable of values.
339
398
340
399
Parameters
341
400
----------
342
- label : str
401
+ label : hashable
343
402
The property key.
344
403
345
404
itr : iterable
@@ -357,7 +416,7 @@ def cycler(label, itr):
357
416
raise ValueError (msg )
358
417
359
418
if label in keys :
360
- return copy .copy (itr )
419
+ return copy .deepcopy (itr )
361
420
else :
362
421
lab = keys .pop ()
363
422
itr = list (v [lab ] for v in itr )
0 commit comments