[Tutor] cyclically rotate a seq

Kent Johnson kent37 at tds.net
Fri Mar 11 12:04:41 CET 2005


kevin parks wrote:
> Hi folks,
> 
> I am trying to cyclically rotate a seq until it reached the beginning 
> stage again.
> I would like to be able to rotate in both directions and using any 
> arbitrary interval.

I think the code is correct but I have a few suggestions below.

> 
> #!/usr/bin/env python
> 
> import sys
> import random
> 
> 

If you make these comments into a docstring (a triple-quoted string that starts the method) then 
they will be accessible to IDEs, help(rotate), etc.

> # cyclically rotate a sequence
> # -- --------------------------------------------------------
> # should work on any sequence type
> # should work with any hop(n) interval
> # should also work in both directions (left or right)
> # -- --------------------------------------------------------
> 
> def rotate(seq, n=1):
>     if len(seq) == 0:
>         return seq

I would also check for seq == None. An easy way to check for both None and an empty sequence is
   if not seq:
     return seq

This will reject also a few other things you probably don't care about such as the number 0 and an 
empty dict...

>     # Normalize n, using modulo - even works for negative n
>     n = n % len(seq)
>     return seq[n:] + seq[:n]
> 
>        
> def test():
>     start = 1
>     x = [7, 2, 1, 0, 11, 6, 5, 4]
>     print; print x; print '--' * 8
>     for i in range(len(x)):
If you use
   for i in range(1, len(x)+1)
then you don't need start, i will have the same value
>         out = rotate(x, start)
>         print out
>         start = start + 1

Your test is not nearly as thorough as your docs suggest. You don't test rotation by a negative 
number or by a number bigger than len(x).

You might want to write this as a unittest so the results are checked automatically instead of you 
having to eyeball them each time. Here is a start:

import unittest

class RotateTest(unittest.TestCase):
     def test_rotate(self):
         x = [7, 2, 1, 0, 11, 6, 5, 4]
         out = rotate(x, 1)
         self.assertEquals([2, 1, 0, 11, 6, 5, 4, 7], out)

         out = rotate(x, -1)
         self.assertEquals([4, 7, 2, 1, 0, 11, 6, 5], out)

if __name__ == '__main__':
     unittest.main()


Kent



More information about the Tutor mailing list