[Tutor] Making Doubly Linked List with Less Lines of Code.

Dave Angel davea at davea.name
Fri Jan 2 18:08:13 CET 2015


On 01/02/2015 11:37 AM, WolfRage wrote:
> On 01/02/2015 02:21 AM, Steven D'Aprano wrote:
>> What is the purpose of the **kwargs? It doesn't get used, it just
>> silently ignores them.
>
> Hopefully you got the answer for this from the previous message.
>>
>> Why does the GameTile record the coordinates as strings?
>
> Hopefully you got the answer for this from the previous message.
>>
>> Your lookup_node method returns a GameTile or False on failure:
>>
>>      def lookup_node(self, x, y, ):
>>          if not self.check_bounds(x, y):
>>              return False
>>          return self.grid[y][x]
>>
>> I'm not sure about that design. I wonder whether it would be better to
>> return None, or raise an exception.
> What would you suggest this code does on error, when the Node looked up
> is out of bounds?
>
> Latest copy of the code. I think I got every ones suggestion.
>
> import sys
>
>
> class GameTile():
>      def __init__(self, col, row, **kwargs):
>          # id is (X,Y)
>          self.id = str(row) + ',' + str(col)
>          self.col = col
>          self.row = row
>
>      def __str__(self):
>          return '%d, %d' % (self.col, self.row)
>
>
> class GameGrid():
>      def __init__(self, cols=8, rows=7, **kwargs):

You probably want to reverse the order of the parameters;  you've got 
almost everything else row-major

>          self.cols = cols
>          self.rows = rows
>          self.make_grid()
>
>      def make_grid(self):
>          # grid is 2d array as x, y ie [x][y].
>          self.grid = [[None] * self.cols for i in range(self.rows)]
>          for row in range(self.rows):
>              for col in range(self.cols):
>                  self.grid[row][col] = GameTile(row=row, col=col)

Since both stages are being done in the same method, you don't need the 
part which initializes to None.

try something like:

     def make_grid(self):
         # grid is 2d array as x, y ie [x][y].
         self.grid = []
         for row_num in range(self.rows):
             self.grid.append([])
             for col_num in range(self.cols):
                 self.grid[-1].append(GameTile(row=row_num, col=col_num))

or even

     def make_grid(self):
         # grid is 2d array as x, y ie [x][y].
         self.grid = []
         for row_num in range(self.rows):
             self.grid.append( [GameTile(row=row_num, col=col_num)  for 
col_num in range(self.cols)] )

>
>      def print_by_row(self):
>          for col in self.grid:
>              for row in col:
>                  print(row)

This cannot work.  The items in self.grid are rows.  Calling one of them 
col doesn't make it so.  In other words, the method as written will do 
exactly what print_by_col() does.

Try the following:

     def print_by_row(self):
         for col_number in range(self.cols):
             for row in self.grid:
                 print(row[col_number])


>
>      def print_by_col(self):
>          for row in self.grid:
>              for col in row:
>                  print(col)

This one should work fine.  But one of the names could be improved:


     def print_by_col(self):
         for row in self.grid:
             for tile in row:
                 print(tile)

>
>      def check_bounds(self, x, y):
>          return (0 <= x < self.rows) and (0 <= y < self.cols)
>
>      def lookup_node(self, x, y):
>          if not self.check_bounds(x, y):
>              return False
>          return self.grid[x][y]
>
>      def draw(self):
>          for col in self.grid:
>              print(end='| ')
>              for row in col:
>                  print(row, end=' | ')
>              print()
>
>
> grid = GameGrid(3, 3)
> grid.draw()
> print(sys.getsizeof(grid.grid))
>

All code untested.  i hope it helps.

-- 
DaveA


More information about the Tutor mailing list