Repository: sympy/sympy (Python)

Issue:
iterables could use rotations
Would a simple routine to return the rotations of a sequence be something useful in iterables?
```python
def rotations(s, dir=1):
    """Return a generator giving the items in s as list where
    each subsequent list has the items rotated to the left (default)
    or right (dir=-1) relative to the previous list.

    Examples
    ========

    >>> list(rotations([1,2,3]))
    [[1, 2, 3], [2, 3, 1], [3, 1, 2]]
    >>> list(rotations([1,2,3], -1))
    [[1, 2, 3], [3, 1, 2], [2, 3, 1]]
    """
    seq = list(s)
    for i in range(len(seq)):
        yield seq
        seq = rotate_left(seq, dir)
```


Discussion:
I would like to take this.



Patch:
diff --git a/sympy/utilities/__init__.py b/sympy/utilities/__init__.py
index 4a5f8d59608f..96bb668185b6 100644
--- a/sympy/utilities/__init__.py
+++ b/sympy/utilities/__init__.py
@@ -5,7 +5,8 @@
     variations, numbered_symbols, cartes, capture, dict_merge,
     postorder_traversal, interactive_traversal,
     prefixes, postfixes, sift, topological_sort, unflatten,
-    has_dups, has_variety, reshape, default_sort_key, ordered)
+    has_dups, has_variety, reshape, default_sort_key, ordered,
+    rotations)
 
 from .misc import filldedent
 
diff --git a/sympy/utilities/iterables.py b/sympy/utilities/iterables.py
index 935bef529bc3..a03d97fa6124 100644
--- a/sympy/utilities/iterables.py
+++ b/sympy/utilities/iterables.py
@@ -2340,3 +2340,23 @@ def signed_permutations(t):
     """
     return (type(t)(i) for j in permutations(t)
         for i in permute_signs(j))
+
+
+def rotations(s, dir=1):
+    """Return a generator giving the items in s as list where
+    each subsequent list has the items rotated to the left (default)
+    or right (dir=-1) relative to the previous list.
+
+    Examples
+    ========
+
+    >>> from sympy.utilities.iterables import rotations
+    >>> list(rotations([1,2,3]))
+    [[1, 2, 3], [2, 3, 1], [3, 1, 2]]
+    >>> list(rotations([1,2,3], -1))
+    [[1, 2, 3], [3, 1, 2], [2, 3, 1]]
+    """
+    seq = list(s)
+    for i in range(len(seq)):
+        yield seq
+        seq = rotate_left(seq, dir)


Test patch:
diff --git a/sympy/utilities/tests/test_iterables.py b/sympy/utilities/tests/test_iterables.py
index 9998af33e1b0..2fb1f5692f6a 100644
--- a/sympy/utilities/tests/test_iterables.py
+++ b/sympy/utilities/tests/test_iterables.py
@@ -15,7 +15,7 @@
     multiset_permutations, necklaces, numbered_symbols, ordered, partitions,
     permutations, postfixes, postorder_traversal, prefixes, reshape,
     rotate_left, rotate_right, runs, sift, subsets, take, topological_sort,
-    unflatten, uniq, variations, ordered_partitions)
+    unflatten, uniq, variations, ordered_partitions, rotations)
 from sympy.utilities.enumerative import (
     factoring_visitor, multiset_partitions_taocp )
 
@@ -732,3 +732,9 @@ def test_ordered_partitions():
                 sum(1 for p in f(i, j, 1)) ==
                 sum(1 for p in f(i, j, 0)) ==
                 nT(i, j))
+
+
+def test_rotations():
+    assert list(rotations('ab')) == [['a', 'b'], ['b', 'a']]
+    assert list(rotations(range(3))) == [[0, 1, 2], [1, 2, 0], [2, 0, 1]]
+    assert list(rotations(range(3), dir=-1)) == [[0, 1, 2], [2, 0, 1], [1, 2, 0]]