In a bigger program I made I need to be able to generate a grid with n rows and m columns. After that I need a function that will let me rotate this grid and with it rotate the values of the original grid.

This is the code that let's me generate a grid:

``````class Grid(object):
def __init__(self, width, height):
self.grid = []
self.width = width
self.height = height
self.length = width * height
for x in range(self.width):
col = []
for y in range(self.height):
col.append(Cell(x, y, self.grid))
self.grid.append(col)

def __getitem__(self, (x, y)):
return self.grid[x][y]

def printGrid(self):
for y in range(len(self.grid)):
for x in range(len(self.grid)):
print self.grid[x][y].value,
print

class Cell(object):
def __init__(self, x, y, grid):
self.x = x
self.y = y
self.grid = grid
self.value = 0
self.clusterId = -1

my_grid = Grid(5, 3)
my_grid[0, 0].value = 1
my_grid[4, 0].value = 2
my_grid[0, 2].value = 3
my_grid[4, 2].value = 4
my_grid.printGrid()``````

It outputs the following:

1 0 0 0 2
0 0 0 0 0
3 0 0 0 4

Say we take the following notation of cell locations:

A B C D E
---------------
0| 1 0 0 0 2
1| 0 0 0 0 0
2| 3 0 0 0 4

I want to rotate the grid so it becomes:

0 1 2
---------------
A| 3 0 1
B| 0 0 0
C| 0 0 0
D| 0 0 0
E| 4 0 2

I tried to notate what happened per cell in the following table:

SOURCE | ROTATED
A0 1 | 3
A1 0 | 0
A2 3 | 1
B0 0 | 0
B1 0 | 0
B2 0 | 0
C0 0 | 0
C1 0 | 0
C2 0 | 0
D0 0 | 0
D1 0 | 0
D2 0 | 0
E0 2 | 4
E1 0 | 0
E2 4 | 2

I've tried in a rotate function to take the original grid's width and height, and from that instantiate a destination grid by

``````def rotate(self, n):
source = self
width = (source.width)
height = (source.height)
n %= 4
if n == 0:
pass
if n == 1:
destination = Grid(height, width)
for x in range(destination.height):
for y in range(destination.width):
#???
destination.printGrid()``````

Where n == 1 stands for rotating 1 time by 90 degrees. How should I code my for loop to do the proper rotation?

I've tried it earlier with thanks to Gribouillis's code:

``````def rotated(self, n):
L = self.toList()
n %=4
if n ==0 :
pass
elif n ==1 :
L =[list (x )for x in zip (*reversed (L))]
elif n ==2 :
L =[list (reversed (x ))for x in reversed (L)]
else :
L =[list (x )for x in reversed (zip (*L))]
return Grid.fromList(L)

def toList(self):
return [tuple(cell.value for cell in row) for row in self.grid]

@staticmethod
def fromList(L):
height, width = len(L), len(L)
self = Grid(width, height)
for x in range(height):
for y in range(width):
self[(x,y)].value = L[x][y]
return self``````

Unfortunately this let's me only rotate square grids and after talking to my teacher he said the rotate function should be more simple, with for loops like I try to do now. Despite I'm trying to logically think what sould happen in this for loop I haven't found out till now.

Can someone point out what I should do in the new rotate method so it can properly rotate square AND rectangular grids (with different width and height)?

Thanks in advance for helping me out here :)

Pfeeeew :)

I reworked on my loop and wrote everything out to finally come to the solution (i hope :P):

Print x, y for destination grid:

``````def rotate(self, n):
source = self
width = (source.width)
height = (source.height)
n %= 4
if n == 0:
pass
if n == 1:
destination = Grid(height, width)
print destination.width
print destination.height
print ('-'*20)
for x in range(destination.width):
for y in range(destination.height):
print x, y``````
``````1 0 0 0 2
0 0 0 0 0
3 0 0 0 0``````

should become:

``````3 0 1
0 0 0
0 0 0
0 0 0
4 0 2``````
``````x, y      destination value:  describing in source[...,...].value notation:
0, 0     3                             source[0, 2].value
0, 1     0                             source[1, 2].value
0, 2     0                             source[2, 2].value
0, 3     0                             source[3, 2].value
0, 4     4                             source[4, 2].value
1, 0     0                             source[0, 1].value
1, 1     0                             source[1, 1].value
1, 2     0                             source[2, 1].value
1, 3     0                             source[3, 1].value
1, 4     0                             source[4, 1].value
2, 0     1                             source[0, 0].value
2, 1     0                             source[1, 0].value
2, 2     0                             source[2, 0].value
2, 3     0                             source[3, 0].value
2, 4     2                             source[4, 0].value``````

Then I could transform this description of source[...,...].value to something i could use in the for loop.
The first part was source[y, ...].value, and after some looking I found that the second part was equal to destination.width-1-x what's giving me:

destination[x, y].value = source[y, destination.width-1-x].value

``````class Grid(object):
def __init__(self, width, height):
self.grid = []
self.width = width
self.height = height
self.length = width * height
for x in range(self.width):
col = []
for y in range(self.height):
col.append(Cell(x, y, self.grid))
self.grid.append(col)

def __getitem__(self, (x, y)):
return self.grid[x][y]

def rotate(self, n):
source = self
width = (source.width)
height = (source.height)
n %= 4
if n == 0:
pass
if n == 1:
destination = Grid(height, width)
for x in range(destination.width):
for y in range(destination.height):
destination[x, y].value = source[y, destination.width-1-x].value
destination.printGrid()

def printGrid(self):
for y in range(len(self.grid)):
for x in range(len(self.grid)):
print self.grid[x][y].value,
print

class Cell(object):
def __init__(self, x, y, grid):
self.x = x
self.y = y
self.grid = grid
self.value = 0
self.clusterId = -1

my_grid = Grid(5, 3)
my_grid[0, 0].value = 1
my_grid[4, 0].value = 2
my_grid[0, 2].value = 3
my_grid[4, 2].value = 4
my_grid.printGrid()
print ('-'*20)
my_grid.rotate(1)``````
``````OUTPUT:
1 0 0 0 2
0 0 0 0 0
3 0 0 0 4
--------------------
3 0 1
0 0 0
0 0 0
0 0 0
4 0 2``````

So it seems to work now, allthough I don't know if anyone has more ideas on this to improve or if I'm doing something wrong still? Let me know please :)
Sorry for the long explanation, I guess I was just happy to find the solution with some good old logic thinking (something which I suck at most of the times I guess :P)

commented: congratulations! +2