Re: [long] nested lists as arrays

2005-02-20 Thread [EMAIL PROTECTED]
great thanks

-- 
http://mail.python.org/mailman/listinfo/python-list


Problem with nested lists as arrays

2005-02-14 Thread benjamin . cordes
Hello,

For a class modeling the block puzzle I use nested lists as arrays.
Within this class there is a method for swaping elements. I have lots
of trouble with that method but can't figure it out. It has probably to
do with my unuseful approach to nested lists, but I don't want to write
the code again. As I am a python newbie any other comments on the code
will be appreciated. Thanks for any help.

# Puzzle.py
# class for a sliding block puzzle

# an starting state of a 8-puzzle could look like the following:
# 
# | 7  2  4  |
# |  |
# | 5  X  6  |
# |  |
# | 8  3  1  |
# 

# the goal is to reach this state:
# 
# | X  1  2  |
# |  |
# | 3  4  5  |
# |  |
# | 6  7  8  |
# 

import copy

class Puzzle:

def __init__(self, dim):
   self.dim = dim
   self.elements = [[0 for column in range(dim)] for row in
range(dim) ]


def getEmptySlot(self):
i = 0
j = 0
while i  = self.dim-1:
while j  = self.dim-1:
if self.elements[j][i] == -1:
return [j, i]
j = j+1
j = 0
i = i + 1

def performMove(self, direction):
slot = self.getEmptySlot()

if (direction == up):
self.swapElements(slot[1], slot[0], slot[1]+1, slot[0])

elif (direction == down):
self.swapElements(slot[1], slot[0], slot[1]-1, slot[0])

elif direction == left:
self.swapElements(slot[1], slot[0], slot[1], slot[0]-1)
elif (direction == right):
self.swapElements(slot[1], slot[0], slot[1], slot[0]+1)

def swapElements(self, fromx, fromy, tox, toy):
dummy = self.elements[toy][tox]

self.elements[toy][tox] = self.elements[fromy][fromx]
self.elements[fromy][fromx] = dummy

def getPossibleMoves(self):
emptySlot = self.getEmptySlot()
y = emptySlot[1]
x = emptySlot[0]
north = (y == 0)
south = (y == (self.dim-1))
west = (x == 0)
east = (x == (self.dim-1))

middle = not(north or south or west or east)

northwest = north and west
northeast = north and east
southwest = south and west
southeast = south and east
# orientation has to be distinct
# save original values
orignorth = north
origsouth = south
# original north or south
orignors = north or south

north = north and not (west or east)
south = south and not (west or east)
west = west and not (orignors)
east = east and not (orignors)

if middle:
return [up, down, left, right]
elif north:
return [up, left, right]
elif south:
return [down, left, right]
elif west:
return [up, down, left]
elif east:
return [up, down, right]
elif northwest:
return [up, left]
elif northeast:
return [up, right]
elif southwest:
return [down, left]
elif southeast:
return [down, right]
   
# ~Puzzle.py

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Problem with nested lists as arrays

2005-02-14 Thread Diez B. Roggisch
Some general remarks:

 def getEmptySlot(self):
 i = 0
 j = 0
 while i  = self.dim-1:
 while j  = self.dim-1:
 if self.elements[j][i] == -1:
 return [j, i]
 j = j+1
 j = 0
 i = i + 1

make this:

def getEmptySlot(self):
for i in xrange(self.dim):
for j in xrange(self.dim):
if self.elements[i][j] == -1:
return (i,j)

 def getPossibleMoves(self):
 emptySlot = self.getEmptySlot()
 y = emptySlot[1]
 x = emptySlot[0]

make this:

x,y = self.getEmptySlot()



-- 
Regards,

Diez B. Roggisch
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Diez B. Roggisch
[EMAIL PROTECTED] wrote:

 Hi,
 
 why can't I do this:
 
 dummy = self.elements[toy][tox]
 
 self.elements[toy][tox] = self.elements[fromy][fromx]
 self.elements[fromy][fromx] = dummy
 
 after initialising my nested list like this:
 
self.elements = [[0 for column in range(dim)] for row in
 range(dim) ]

Works for me:

dim = 10
elements = [[0 for column in xrange(dim)] for row in
xrange(dim) ]

toy, tox = (2,5)
fromy, fromx = (7,5)

dummy =elements[toy][tox]
elements[toy][tox] = elements[fromy][fromx]
elements[fromy][fromx] = dummy


And use xrange instead of range.
-- 
Regards,

Diez B. Roggisch
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread bruno modulix
[EMAIL PROTECTED] wrote:
Hi,
why can't I do this:
dummy = self.elements[toy][tox]
self.elements[toy][tox] = self.elements[fromy][fromx]
self.elements[fromy][fromx] = dummy
after initialising my nested list like this:
   self.elements = [[0 for column in range(dim)] for row in
range(dim) ]
Sorry, I'm not psychic enough to guess what is exactly your problem:
- what do you mean can't do ?  You have a traceback ? please post it. 
You have unexpected results ? please describe.
- what are self, dim, toy, tox, fromy, fromx ?
- is all that code in the same method ?
- etc etc

So please post more informations if you expect us to help you.
Note that the following code is correct:
 l = [[0 for i in range(3)] for y in range(3)]
 l
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
 l[0][0] = 1
 l
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]
 l[0][0], l[0][1] = l[0][1], l[0][0]
 l
[[0, 1, 0], [0, 0, 0], [0, 0, 0]]

So I guess that your problem has nothing to do with nested lists.
(Also note BTW that, thanks to the magic of multiple assignement, you 
don't need the dummy stuff. The pythonic idiom for swapping 2 bindings is
a, b = b, a)


--
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for 
p in '[EMAIL PROTECTED]'.split('@')])
--
http://mail.python.org/mailman/listinfo/python-list


nested lists as arrays

2005-02-14 Thread naturalborncyborg
Hi, I'm using nested lists as arrays and having some problems with
that approach. In my puzzle class there is a swapelement method which
doesn't work out. Any help and comments on the code will be
appreciated. Thanks.

# Puzzle.py
# class for a sliding block puzzle

# an starting state of a 8-puzzle could look like the following:
# where X is an empty space and the move up in the example would move
6 to X
# X is represented as -1 in the array
# 
# | 7  2  4  |
# |  |
# | 5  X  6  |
# |  |
# | 8  3  1  |
# 

# the goal is to reach this state:
# 
# | X  1  2  |
# |  |
# | 3  4  5  |
# |  |
# | 6  7  8  |
# 

import copy

class Puzzle:

def __init__(self, dim):
   self.dim = dim
   self.elements = [[0 for column in range(dim)] for row in
range(dim) ]
 
def getEmptySlot(self):
i = 0
j = 0
while i  = self.dim-1:
while j  = self.dim-1:
if self.elements[j][i] == -1:
return [j, i]
j = j+1
j = 0
i = i + 1

def performMove(self, direction):
slot = self.getEmptySlot()

if (direction == up):
self.swapElements(slot[1], slot[0], slot[1]+1, slot[0])
elif (direction == down):
self.swapElements(slot[1], slot[0], slot[1]-1, slot[0])
elif direction == left:
self.swapElements(slot[1], slot[0], slot[1], slot[0]-1)
elif (direction == right):
self.swapElements(slot[1], slot[0], slot[1], slot[0]+1)

def swapElements(self, fromx, fromy, tox, toy): 
dummy = self.elements[toy][tox]

self.elements[toy][tox] = self.elements[fromy][fromx]
self.elements[fromy][fromx] = dummy

def getPossibleMoves(self):
emptySlot = self.getEmptySlot()   
y = emptySlot[1]
x = emptySlot[0]
north = (y == 0)
south = (y == (self.dim-1))
west = (x == 0)
east = (x == (self.dim-1))

middle = not(north or south or west or east)

northwest = north and west
northeast = north and east
southwest = south and west
southeast = south and east
# orientation has to be distinct
# save original values
orignorth = north
origsouth = south
# original north or south
orignors = north or south

north = north and not (west or east)
south = south and not (west or east)
west = west and not (orignors)
east = east and not (orignors)

if middle:
return [up, down, left, right]
elif north:
return [up, left, right]
elif south:
return [down, left, right]
elif west:
return [up, down, left]
elif east:
return [up, down, right]
elif northwest:
return [up, left]
elif northeast:
return [up, right]
elif southwest:
return [down, left]
elif southeast:
return [down, right]
   
# ~Puzzle.py
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread [EMAIL PROTECTED]

Diez B. Roggisch wrote:
 [EMAIL PROTECTED] wrote:

  Hi,
 
  why can't I do this:
 
  dummy = self.elements[toy][tox]
 
  self.elements[toy][tox] = self.elements[fromy][fromx]
  self.elements[fromy][fromx] = dummy
 
  after initialising my nested list like this:
 
 self.elements = [[0 for column in range(dim)] for row in
  range(dim) ]

 Works for me:

 dim = 10
 elements = [[0 for column in xrange(dim)] for row in
 xrange(dim) ]

 toy, tox = (2,5)
 fromy, fromx = (7,5)

 dummy =elements[toy][tox]
 elements[toy][tox] = elements[fromy][fromx]
 elements[fromy][fromx] = dummy


 And use xrange instead of range.
 --
 Regards,

 Diez B. Roggisch

thanks so far, and sorry for posting the topic now 3 times.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Fredrik Lundh
naturalborncyborg [EMAIL PROTECTED] wrote:

 Hi, I'm using nested lists as arrays and having some problems with
 that approach. In my puzzle class there is a swapelement method which
 doesn't work out.

what happens, and what do you expect?

 Any help and comments on the code will be appreciated.

is it elements[y][x] or elements[x][y]?  both variants seem to be used
in your code.

(fwiw, in this case, using a dictionary might be a lot easier.  store cells
as elements[x, y], use elements.get((x, y)) is None to check for empty
cells, use elements[x, y] = None or del elements[x, y] to empty a cell,
use elements = {} to clear all cells, etc).

/F 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Michael Spencer
naturalborncyborg wrote:
Hi, I'm using nested lists as arrays and having some problems with
that approach. In my puzzle class there is a swapelement method which
doesn't work out.
What doesn't work out?  On casual inspection that method seems to work:
  p = Puzzle(2)
  p.elements[0][0] = 1
  p.elements[1][1] = 2
  p.elements
[[1, 0], [0, 2]]
  p.swapElements(0,0,1,1)
  p.elements
[[2, 0], [0, 1]]
 
What should it do instead?
Michael
--
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread [EMAIL PROTECTED]
Thanks for the code.
What I want to do is this:
I want to solve the block puzzle problem.  The problem is as follows:
You have a nxn Array of Numbers and one empty space. Now you there are
up to four possible moves: up, right, down and left, so that each
neighbour of the empty slot can be moved there.

The method getEmptySlot is for getting the empty slot. The method
getPossibleMoves returns the possible moves. Perfoming a move is
swaping one element with the empty slot marked as -1.

The full executable code is appended.
The expected behaviour is that when the move is performed the
appropiate elements should be swaped. But for some reason every now and
then it swaps the wrong elements.

# Puzzle.py
# class for a sliding block puzzle

# an starting state of a 8-puzzle could look like the following:
# 
# | 7  2  4  |
# |  |
# | 5  X  6  |
# |  |
# | 8  3  1  |
# 

# the goal is to reach this state:
# 
# | X  1  2  |
# |  |
# | 3  4  5  |
# |  |
# | 6  7  8  |
# 

import random
import copy

class Puzzle:

def __init__(self, dim):
   self.dim = dim
#   self.elements = {}
#   for column in range(dim):
#   for row in range(dim):
#   elements[(column, row)] = 0
   self.elements = [[0 for column in range(dim)] for row in
range(dim) ]

def __str__(self):
s = 
i = 0
j = 0
while i  = self.dim-1:
while j  = self.dim-1:
s = s + str(self.elements[j][i])
j=j+1
s = s + \t
i=i+1
j = 0
s = s + \n
return s

def compare(self, compareTo):
if (self.dim != compareTo.dim):
return 0
i = 0
j = 0
equal = 1
while i  = self.dim-1:
while j  = self.dim-1:
 if self.elements[j][i] != compareTo.elements[j][i]:
 equal = 0
 j = j+1
i = i+1
return equal


def setAsGoalState(self):
   # create elements of puzzle
   i = 0
   j = 0
   while i = self.dim-1:
   while j = self.dim-1:
   self.elements[j][i] = i*3+j
   j=j+1
   j=0
   i=i+1

   # create empty element seperately
   self.elements[0][0] = -1


def setRandomState(self):
   # container for the elements to pick from
   container = [1,2,3,4,5,6,7,8,-1]

   # create elements of puzzle randomly
   i = 0
   j = 0
   while i = self.dim-1:
   while j = self.dim-1:
   if len(container)  0:
   randomindex = random.randint(0,len(container)-1)
   self.elements[j][i] = container[randomindex]
   del container[randomindex]
   j=j+1
   else:
   break
   j=0
   i=i+1

def getEmptySlot(self):
i = 0
j = 0
while i  = self.dim-1:
while j  = self.dim-1:
if self.elements[j][i] == -1:
return [j, i]
j = j+1
j = 0
i = i + 1

def performMove(self, direction):
slot = self.getEmptySlot()

if (direction == up):
self.swapElements(slot[1], slot[0], slot[1]+1, slot[0])

elif (direction == down):
self.swapElements(slot[1], slot[0], slot[1]-1, slot[0])

elif direction == left:
self.swapElements(slot[1], slot[0], slot[1], slot[0]-1)
elif (direction == right):
self.swapElements(slot[1], slot[0], slot[1], slot[0]+1)

def swapElements(self, fromx, fromy, tox, toy):
dummy = self.elements[toy][tox]

self.elements[toy][tox] = self.elements[fromy][fromx]
self.elements[fromy][fromx] = dummy


def getChildren(self):
moves = self.getPossibleMoves()
self.children = []
for eachMove in moves:
newchild = copy.copy(self.performMove(eachMove))
try:
self.children.append(newchild)
except:
print Exception:  + str(len(self.children))

def getPossibleMoves(self):
emptySlot = self.getEmptySlot()
y = emptySlot[1]
x = emptySlot[0]
north = (y == 0)
south = (y == (self.dim-1))
west = (x == 0)
east = (x == (self.dim-1))

middle = not(north or south or west or east)

northwest = north and west
northeast = north and east
southwest = south and west
southeast = south and east
# orientation has to be distinct
# save original values
orignorth = north
origsouth = south
# original north or south
orignors = north or south

north = north and not (west or east)
south = south and not (west or east)
west = west and not (orignors)
east = 

Re: Problem with nested lists as arrays

2005-02-14 Thread Terry Reedy

[EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]

'Having trouble' is too vague to figure out.  However, I would delete this:

def getEmptySlot(self):
i = 0
j = 0
while i  = self.dim-1:
while j  = self.dim-1:
if self.elements[j][i] == -1:
return [j, i]
j = j+1
j = 0
i = i + 1

and maintain an .empty attribute, which is trivially updated in

def swapElements(self, fromx, fromy, tox, toy):
dummy = self.elements[toy][tox]

self.elements[toy][tox] = self.elements[fromy][fromx]
self.elements[fromy][fromx] = dummy

as (fromy,fromx).  Note that there is no need to pass tox, toy to this 
routine.  Indeed, I would include the last two lines in your move routine. 
Since dummy is always the same object, I would also just keep it as 
self._dummy instead of looking it up each time.

Terry J. Reedy





-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Terry Reedy

Diez B. Roggisch [EMAIL PROTECTED] wrote in message 

And use xrange instead of range.

For small dimensions like 3,4,5, xrange is way overkill and perhaps takes 
both more space and time.  Since dim is a constant for a given puzzle, I 
would set self._range = range(dim) in __init__() and use that to iterate. 
And, as I said in another response, I would not iterate to make a move.

Terry J. Reedy




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread [EMAIL PROTECTED]
Allright. What difference in runtime and space would it make using
dictionaries instead?

Do you have a pointer for me concerning runtime of standard
manipulations in Pythons?

Thanks for tip.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread [EMAIL PROTECTED]
Allright. What difference in runtime and space would it make using
dictionaries instead?

Do you have a pointer for me concerning runtime of standard
manipulations in Pythons?

Thanks for the tip.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Fredrik Lundh
[EMAIL PROTECTED] wrote:

 Allright. What difference in runtime and space would it make using
 dictionaries instead?

is this for an interactive game?  if so, the answer is none at all.

(on my machine, you can make about 600 dict[x,y] accesses per
second, compared to 750 list[x][y] accesses...  assuming that your
algorithm needs to check each cell on the board 10 times per move, and
you want the moves to appear instantly, the slower solution should be
fast enough for a 250x250 board, compared to a 270x270 board for the
faster solution...).

/F 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Terry Reedy

[EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
def setRandomState(self):
   # container for the elements to pick from
   container = [1,2,3,4,5,6,7,8,-1]

   # create elements of puzzle randomly
   i = 0
   j = 0
   while i = self.dim-1:
   while j = self.dim-1:
   if len(container)  0:
   randomindex = random.randint(0,len(container)-1)
   self.elements[j][i] = container[randomindex]
   del container[randomindex]
   j=j+1
   else:
   break
   j=0
   i=i+1

Without reading closely, I believe that the above can generate any possible 
position.  Are you aware that half are unsolvable?  If that matters, you 
need to either find a book or site that explains the parity test for 
solvability or generate the start position from the goal position by a 
series of random moves.

Terry J. Reedy




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: nested lists as arrays

2005-02-14 Thread Michael Spencer
Terry Reedy wrote:
[EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]

  def setRandomState(self):
 # container for the elements to pick from
 container = [1,2,3,4,5,6,7,8,-1]
 # create elements of puzzle randomly
 i = 0
 j = 0
 while i = self.dim-1:
 while j = self.dim-1:
 if len(container)  0:
 randomindex = random.randint(0,len(container)-1)
 self.elements[j][i] = container[randomindex]
 del container[randomindex]
 j=j+1
 else:
 break
 j=0
 i=i+1

Without reading closely, I believe that the above can generate any possible 
position.  Are you aware that half are unsolvable?  If that matters, you 
need to either find a book or site that explains the parity test for 
solvability or generate the start position from the goal position by a 
series of random moves.

Terry J. Reedy
This covers the test for solvability - enjoy ;-): 
http://www.cs.tcd.ie/publications/tech-reports/reports.01/TCD-CS-2001-24.pdf

BTW, just because your puzzle looks like a grid doesn't neceesarily mean that 
representing the data as nested arrays is easiest.  A flat list might be just as 
good here.  It simplifies some of the operations (creating a random ordering 
becomes a one-liner), at the expense of a little more complexity in some others:

import random
class n2grid(object):
A grid for the n squared puzzle
def __init__(self,dim = 4):
   self.cells = range(dim*dim)
   self.dim = dim
   self.pos = (0,0)
def shuffle(self):
random.shuffle(self.cells)
self.pos = divmod(self.cells.index(0),self.dim)
def show(self):
for row in self._asarray():
print .join([%2s] % (cell or ) for cell in row)
def _move(self,dy,dx):
dim = self.dim
cells = self.cells
oldy, oldx = self.pos
newy, newx = oldy + dy, oldx + dx
if 0 = newx  dim and 0 = newy  dim:
ix = newy * dim + newx
ox = oldy * dim + oldx
cells[ix], cells[ox] = cells[ox], cells[ix]
self.pos = newy,newx
else:
raise Exception, Illegal move to: (%s,%s) % (newy, newx)
def move(self, dx, dy):
try:
self._move(dx,dy)
self.show()
except:
pass
def _asarray(self): #create the array representation when needed
cells = iter(self.cells)
dim = self.dim
return [[cells.next() for j in range(dim)] for i in range(dim)]
def __repr__(self):
return repr(self._asarray())

  p = n2grid()
  p.show()
 ...
[  ][ 1][ 2][ 3]
[ 4][ 5][ 6][ 7]
[ 8][ 9][10][11]
[12][13][14][15]
  p.shuffle()
  p.show()
[ 3][15][ 6][ 7]
[10][  ][12][ 5]
[ 4][ 1][14][ 8]
[ 2][11][13][ 9]
  p.move(1,1)
[ 3][15][ 6][ 7]
[10][14][12][ 5]
[ 4][ 1][  ][ 8]
[ 2][11][13][ 9]
  p.move(1,0)
[ 3][15][ 6][ 7]
[10][14][12][ 5]
[ 4][ 1][13][ 8]
[ 2][11][  ][ 9]
  p.move(1,0) # illegal (does nothing)
 
Cheers
Michael
--
http://mail.python.org/mailman/listinfo/python-list


Re: [long] nested lists as arrays

2005-02-14 Thread bruno modulix
[EMAIL PROTECTED] a écrit :
Thanks for the code.
What I want to do is this:
I want to solve the block puzzle problem.  The problem is as follows:
You have a nxn Array of Numbers and one empty space. Now you there are
up to four possible moves: up, right, down and left, so that each
neighbour of the empty slot can be moved there.
The method getEmptySlot is for getting the empty slot. The method
getPossibleMoves returns the possible moves. Perfoming a move is
swaping one element with the empty slot marked as -1.
The full executable code is appended.
s/executable/source/ !-)
The expected behaviour is that when the move is performed the
appropiate elements should be swaped. But for some reason every now and
then it swaps the wrong elements.
So the problem is not that you can't swap 2 elements, but that there 
seems to be some logical bug(s) in your code.

# Puzzle.py
# class for a sliding block puzzle
(snip)
import random
import copy
class Puzzle:
def __init__(self, dim):
   self.dim = dim
   self.elements = [[0 for column in range(dim)] for row in
range(dim) ]
So at this stage you've got 3 rows of 3 colums:
[
  ['row 0 - col 0', 'row 0 - col 1', 'row 0 - col 2'],
  ['row 1 - col 0', 'row 1 - col 1', 'row 1 - col 2'],
  ['row 2 - col 0', 'row 2 - col 1', 'row 2 - col 2']
]
Is that right ?
def __str__(self):
s = 
i = 0
j = 0
while i  = self.dim-1:
ok, looping on rows
while j  = self.dim-1:
and now looping on columns in current row...
s = s + str(self.elements[j][i])
oops ! Looks like you're addressing row[j] column[i] instead of row[i] 
column[j] !-)

j=j+1
s = s + \t
i=i+1
j = 0
s = s + \n
return s
(snip the rest of the code)
Ok, let's try with a slightly more pythonic (and thus more readable) 
version of this code (I used another method name so we can compare both 
versions):

def to_string(self):
  s = []
  for row in self.elements:
for col in row:
   s.append('%d\t' % col)
s.append('\n')
  return ''.join(s)
For testing purpose, let's modify the __init__ a bit (this will break 
the code but what, it's just to check something, we can get back to 
original code later):

def __init__(self, dim):
  self.dim = dim
  self.range = range(self.dim)
  #self.elements = [[0 for column in self.range] for row in self.range]
  self.elements = [[int('%d%d' % (row, column)) for column in 
self.range] for row in self.range]
  # check we have a correct layout, remove me when fixed:
  print %s % self.elements

and now let's try:
 p = Puzzle(3)
[[0, 1, 2], [10, 11, 12], [20, 21, 22]]
so far, so good, we have 3 rows of 3 columns each.
let's continue:
 print p.to_string()
0   1   2   
10  11  12  
20  21  22  
Ok, so our new to_string() method is ok. Now the real test:
 print p
0   10  20  
1   11  21  
2   12  22  
Remember ?

oops ! Looks like you're addressing row[j] column[i] instead of row[i] 
column[j]


Looks like we found one bug...
Let's continue and rewrite some more code:
def compare(self, other):
  if (self.dim != other.dim):
return False
  for self_row, other_row in zip(self.elements, other.elements):
for self_col, other_col in zip(self_row, other_row):
  if self_col != other_col:
return False
  return True
Ok, that one was easy. Let's try with another one
def getEmptySlot(self):
  for row in self.elements:
for cell in row:
  if cell == -1:
 return ???
Mmmm... won't work. Seems we need indices here, let's try again:
def getEmptySlot(self):
  for row in self.range:
for col in self.range:
  if self.elements[row][col] == -1:
return (row, col)
Ok, not so clean but still readable (notice how using explicit names 
like 'row' and 'col' helps understanding the code...).

Now let's do the swap:
def swapElements(self, from_cell, to_cell):
  from_row, from_col = from_cell
  to_row, to_col = to_cell
  elts = self.elements
 elts[to_row][to_col], elts[from_row][from_col] = 
elements[from_row][from_col], elts[to_row][to_col]

Mmmm... this begins to smell. I don't like having to split the coords 
like this. I'd prefer something like:

def swapElements(self, from_cell, to_cell):
  self.elements[from_cell], self.elements[to_cell] \
  = self.elements[to_cell], self.elements[from_cell]
This could be possible if we used another data structure. Something like 
 a dict of coords:value pairs. We could build it like this:

def __init__(self, dim):
  self.dim = dim
  self.range = range(self.dim)
  self.elements = {}
  for row in self.range:
for col in self.range:
  self.elements[(row,col)] = 0
and then the search for the empty slot:
def getEmptySlot(self):
  for coords, value in self.elements.items():
if value == -1:
  return coords
  assert(False)   # shouldn't be here anyway !
Hey, that looks nicer, isn't it ? But what with the __str__()