Skip to content

Commit 62a29f2

Browse files
committed
[API] Change the cycler() form to be kwargs only.
* Update documentation * Update tests
1 parent 7a811d8 commit 62a29f2

File tree

3 files changed

+71
-89
lines changed

3 files changed

+71
-89
lines changed

cycler.py

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
You can add cyclers::
88
99
from cycler import cycler
10-
cc = (cycler('color', list('rgb')) +
11-
cycler('linestyle', ['-', '--', '-.']))
10+
cc = (cycler(color=list('rgb')) +
11+
cycler(linestyle=['-', '--', '-.']))
1212
for d in cc:
1313
print(d)
1414
@@ -22,8 +22,8 @@
2222
You can multiply cyclers::
2323
2424
from cycler import cycler
25-
cc = (cycler('color', list('rgb')) *
26-
cycler('linestyle', ['-', '--', '-.']))
25+
cc = (cycler(color=list('rgb')) *
26+
cycler(linestyle=['-', '--', '-.']))
2727
for d in cc:
2828
print(d)
2929
@@ -164,8 +164,8 @@ def __getitem__(self, key):
164164
# TODO : maybe add numpy style fancy slicing
165165
if isinstance(key, slice):
166166
trans = self._transpose()
167-
return reduce(add, (cycler(k, v[key])
168-
for k, v in six.iteritems(trans)))
167+
return cycler(**dict((k, v[key])
168+
for k, v in six.iteritems(trans)))
169169
else:
170170
raise ValueError("Can only use slices with Cycler.__getitem__")
171171

@@ -203,8 +203,8 @@ def __mul__(self, other):
203203
return Cycler(self, other, product)
204204
elif isinstance(other, int):
205205
trans = self._transpose()
206-
return reduce(add, (cycler(k, v*other)
207-
for k, v in six.iteritems(trans)))
206+
return cycler(**dict((k, v*other)
207+
for k, v in six.iteritems(trans)))
208208
else:
209209
return NotImplemented
210210

@@ -268,7 +268,7 @@ def __repr__(self):
268268
if self._right is None:
269269
lab = self.keys.pop()
270270
itr = list(v[lab] for v in self)
271-
return "cycler({lab!r}, {itr!r})".format(lab=lab, itr=itr)
271+
return "cycler({lab}={itr!r})".format(lab=lab, itr=itr)
272272
else:
273273
op = op_map.get(self._op, '?')
274274
msg = "({left!r} {op} {right!r})"
@@ -329,7 +329,7 @@ def simplify(self):
329329
# I would believe that there is some performance implications
330330

331331
trans = self._transpose()
332-
return reduce(add, (cycler(k, v) for k, v in six.iteritems(trans)))
332+
return cycler(**dict((k, v) for k, v in six.iteritems(trans)))
333333

334334

335335
def cycler(*args, **kwargs):
@@ -338,13 +338,10 @@ def cycler(*args, **kwargs):
338338
positional arguments or keyword arguments.
339339
340340
cycler(arg)
341-
cycler(label1, itr1[, label2, iter2[, ...]])
342341
cycler(label1=itr1[, label2=iter2[, ...]])
343342
344343
Form 1 simply copies a given `Cycler` object.
345-
Form 2 composes a `Cycler` as an outer product of the
346-
pairs of label/iter.
347-
Form 3 composes a `Cycler` as an inner product of the
344+
Form 2 composes a `Cycler` as an inner product of the
348345
pairs of keyword arguments.
349346
350347
Parameters
@@ -359,31 +356,25 @@ def cycler(*args, **kwargs):
359356
-------
360357
cycler : Cycler
361358
New `Cycler` for the given property
362-
"""
363359
360+
"""
364361
if args and kwargs:
365362
raise TypeError("cyl() can only accept positional OR keyword "
366363
"arguments -- not both.")
367-
elif not args and not kwargs:
368-
raise TypeError("cyl() must have positional OR keyword arguments")
369364

370365
if len(args) == 1:
371366
if not isinstance(args[0], Cycler):
372367
raise TypeError("If only one positional argument given, it must "
373368
" be a Cycler instance.")
374369
return copy.copy(args[0])
375370
elif len(args) > 1:
376-
if (len(args) % 2) == 1:
377-
raise TypeError("Positional arguments must be in pairs. Odd "
378-
" number of arguments found: %d" % len(args))
379-
pairs = [(args[i], args[i+1]) for i in range(0, len(args), 2)]
380-
op = mul
371+
raise TypeError("Only a single Cycler can be accepted as the lone "
372+
"positional argument. Use keyword arguments instead.")
381373

382374
if kwargs:
383-
pairs = six.iteritems(kwargs)
384-
op = add
375+
return reduce(add, (_cycler(k, v) for k, v in six.iteritems(kwargs)))
385376

386-
return reduce(op, (_cycler(k, v) for k, v in pairs))
377+
raise TypeError("Must have at least a positional OR keyword arguments")
387378

388379

389380
def _cycler(label, itr):

doc/source/index.rst

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ hashable (as it will eventually be used as the key in a :obj:`dict`).
4242
from cycler import cycler
4343
4444
45-
color_cycle = cycler('color', ['r', 'g', 'b'])
45+
color_cycle = cycler(color=['r', 'g', 'b'])
4646
color_cycle
4747
4848
The `Cycler` knows it's length and keys:
@@ -61,12 +61,12 @@ the label
6161
for v in color_cycle:
6262
print(v)
6363
64-
`Cycler` objects can be passed as the second argument to :func:`cycler`
64+
`Cycler` objects can be passed as the argument to :func:`cycler`
6565
which returns a new `Cycler` with a new label, but the same values.
6666

6767
.. ipython:: python
6868
69-
cycler('ec', color_cycle)
69+
cycler(ec=color_cycle)
7070
7171
7272
Iterating over a `Cycler` results in the finite list of entries, to
@@ -94,12 +94,12 @@ Equal length `Cycler` s with different keys can be added to get the
9494

9595
.. ipython:: python
9696
97-
lw_cycle = cycler('lw', range(1, 4))
97+
lw_cycle = cycler(lw=range(1, 4))
9898
9999
wc = lw_cycle + color_cycle
100100
101101
The result has the same length and has keys which are the union of the
102-
two input `Cycler` s.
102+
two input `Cycler`'s.
103103

104104
.. ipython:: python
105105
@@ -123,6 +123,17 @@ As with arithmetic, addition is commutative
123123
for j, (a, b) in enumerate(zip(lw_c, c_lw)):
124124
print('({j}) A: {A!r} B: {B!r}'.format(j=j, A=a, B=b))
125125
126+
For convenience, the :func:`cycler` function can have multiple
127+
key-value pairs and will automatically compose them into a single
128+
`Cycler` via addition
129+
130+
.. ipython:: python
131+
132+
wc = cycler(c=['r', 'g', 'b'], lw=range(3))
133+
134+
for s in wc:
135+
print(s)
136+
126137
127138
Multiplication
128139
~~~~~~~~~~~~~~
@@ -131,7 +142,7 @@ Any pair of `Cycler` can be multiplied
131142

132143
.. ipython:: python
133144
134-
m_cycle = cycler('marker', ['s', 'o'])
145+
m_cycle = cycler(marker=['s', 'o'])
135146
136147
m_c = m_cycle * color_cycle
137148
@@ -199,7 +210,7 @@ We can use `Cycler` instances to cycle over one or more ``kwarg`` to
199210
figsize=(8, 4))
200211
x = np.arange(10)
201212

202-
color_cycle = cycler('c', ['r', 'g', 'b'])
213+
color_cycle = cycler(c=['r', 'g', 'b'])
203214

204215
for i, sty in enumerate(color_cycle):
205216
ax1.plot(x, x*(i+1), **sty)
@@ -219,7 +230,7 @@ We can use `Cycler` instances to cycle over one or more ``kwarg`` to
219230
figsize=(8, 4))
220231
x = np.arange(10)
221232

222-
color_cycle = cycler('c', ['r', 'g', 'b'])
233+
color_cycle = cycler(c=['r', 'g', 'b'])
223234
ls_cycle = cycler('ls', ['-', '--'])
224235
lw_cycle = cycler('lw', range(1, 4))
225236

@@ -243,14 +254,14 @@ A :obj:`ValueError` is raised if unequal length `Cycler` s are added together
243254
.. ipython:: python
244255
:okexcept:
245256
246-
cycler('c', ['r', 'g', 'b']) + cycler('ls', ['-', '--'])
257+
cycler(c=['r', 'g', 'b']) + cycler(ls=['-', '--'])
247258
248259
or if two cycles which have overlapping keys are composed
249260

250261
.. ipython:: python
251262
:okexcept:
252263
253-
color_cycle = cycler('c', ['r', 'g', 'b'])
264+
color_cycle = cycler(c=['r', 'g', 'b'])
254265
255266
color_cycle + color_cycle
256267

0 commit comments

Comments
 (0)