Skip to content

Commit a1d60c7

Browse files
committed
Merge pull request #20 from tacaswell/enh_concat
ENH: add concat
2 parents 1f3e5c4 + 495d0f4 commit a1d60c7

File tree

4 files changed

+104
-4
lines changed

4 files changed

+104
-4
lines changed

.travis.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ language: python
22

33
matrix:
44
include:
5-
- python: 2.6
65
- python: 2.7
7-
- python: 3.3
86
- python: 3.4
7+
- python: 3.5
98
- python: "nightly"
109
env: PRE=--pre
1110
allow_failures:

cycler.py

+68
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,74 @@ def simplify(self):
389389
trans = self._transpose()
390390
return reduce(add, (_cycler(k, v) for k, v in six.iteritems(trans)))
391391

392+
def concat(self, other):
393+
"""Concatenate this cycler and an other.
394+
395+
The keys must match exactly.
396+
397+
This returns a single Cycler which is equivalent to
398+
`itertools.chain(self, other)`
399+
400+
Examples
401+
--------
402+
403+
>>> num = cycler('a', range(3))
404+
>>> let = cycler('a', 'abc')
405+
>>> num.concat(let)
406+
cycler('a', [0, 1, 2, 'a', 'b', 'c'])
407+
408+
Parameters
409+
----------
410+
other : `Cycler`
411+
The `Cycler` to concatenate to this one.
412+
413+
Returns
414+
-------
415+
ret : `Cycler`
416+
The concatenated `Cycler`
417+
"""
418+
return concat(self, other)
419+
420+
421+
def concat(left, right):
422+
"""Concatenate two cyclers.
423+
424+
The keys must match exactly.
425+
426+
This returns a single Cycler which is equivalent to
427+
`itertools.chain(left, right)`
428+
429+
Examples
430+
--------
431+
432+
>>> num = cycler('a', range(3))
433+
>>> let = cycler('a', 'abc')
434+
>>> num.concat(let)
435+
cycler('a', [0, 1, 2, 'a', 'b', 'c'])
436+
437+
Parameters
438+
----------
439+
left, right : `Cycler`
440+
The two `Cycler` instances to concatenate
441+
442+
Returns
443+
-------
444+
ret : `Cycler`
445+
The concatenated `Cycler`
446+
"""
447+
if left.keys != right.keys:
448+
msg = '\n\t'.join(["Keys do not match:",
449+
"Intersection: {both!r}",
450+
"Disjoint: {just_one!r}"
451+
]).format(
452+
both=left.keys&right.keys,
453+
just_one=left.keys^right.keys)
454+
455+
raise ValueError(msg)
456+
457+
_l = left._transpose()
458+
_r = right._transpose()
459+
return reduce(add, (_cycler(k, _l[k] + _r[k]) for k in left.keys))
392460

393461
def cycler(*args, **kwargs):
394462
"""

doc/source/index.rst

+16
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,22 @@ Integer Multiplication
180180
2 * color_cycle
181181
182182
183+
Concatenation
184+
~~~~~~~~~~~~~
185+
186+
`Cycler` objects can be concatenated either via the :py:meth:`Cycler.concat` method
187+
188+
.. ipython:: python
189+
190+
color_cycle.concat(color_cycle)
191+
192+
or the top-level :py:func:`concat` function
193+
194+
.. ipython:: python
195+
196+
from cycler import concat
197+
concat(color_cycle, color_cycle)
198+
183199
184200
Slicing
185201
-------

test_cycler.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import six
44
from six.moves import zip, range
5-
from cycler import cycler, Cycler
5+
from cycler import cycler, Cycler, concat
66
from nose.tools import (assert_equal, assert_not_equal,
77
assert_raises, assert_true)
8-
from itertools import product, cycle
8+
from itertools import product, cycle, chain
99
from operator import add, iadd, mul, imul
1010

1111

@@ -279,3 +279,20 @@ def test_starange_init():
279279
c2 = cycler('lw', range(3))
280280
cy = Cycler(list(c), list(c2), zip)
281281
assert_equal(cy, c + c2)
282+
283+
284+
def test_concat():
285+
a = cycler('a', range(3))
286+
b = cycler('a', 'abc')
287+
for con, chn in zip(a.concat(b), chain(a, b)):
288+
assert_equal(con, chn)
289+
290+
for con, chn in zip(concat(a, b), chain(a, b)):
291+
assert_equal(con, chn)
292+
293+
294+
def test_concat_fail():
295+
a = cycler('a', range(3))
296+
b = cycler('b', range(3))
297+
assert_raises(ValueError, concat, a, b)
298+
assert_raises(ValueError, a.concat, b)

0 commit comments

Comments
 (0)