how can i add the change of the symbol to the same grid instead of separate outputs for each change

Question:

The issue with my code is that the move is not being updated onto the same grid. instead it gives an output of the upgrades on separate grids.

The function takes in the coordinates by coords and the colour change symbol from colour_name and it should change the particular coordinate symbol accordingly and it should update the same grid instead of each move on a separate grid.

The expected grids

 A B C D E
 5 . . . . .
 4 . . . . .
 3 . . . . .
 2 . . . . .
 1 . O @ @ .

   A B C D E
 5 . . . . .
 4 . . . . .
 3 . . . . .
 2 . . . . .
 1 . O . @ .

the output i get is the following

A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . O . . .
  A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . . @ . .
  A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . . . @ .
def set_colour(self, coords, colour_name):
    self.coords = coords  # takes in the coordinates of the move
    self.colour_name = colour_name  # takes in the colour change

    colour_change = self.colour_name  # assigning the colour changed to
    colour__change = "'" + colour_change + "'"  # to make it 'B' or 'W'
    self.coords = coords #takes in the coordinates
    self.colour_name = colour_name #takes in the colour change

    # Assertation errors--------------------------------
    move = self.coords #takes in the coordinates of the move

    alphabetical_coord = move[0]  # assigning the alphabetical coordinate to a seperate variable

    numerical_coord = move[1:len(move)]  # assigning the numerical coordinate to a seperate variable

    # AssertionError-----------------------------
    assert (int(ord(alphabetical_coord)) > 64 and int(ord(alphabetical_coord)) < 91), "row out of range"
    assert (int(numerical_coord) > 0 and int(numerical_coord) < 27), "column out of range"
    # ------------------------------------------------------------------------------------------------
    colour_change = self.colour_name  # assigning the colour changed to
    colour__change = "'" + colour_change + "'" #to make it 'B' or 'W'

    # Draw the grid------------------------------------------------------------------------------------

    from string import ascii_uppercase as letters  # importing the alphabetical letters as uppercase
    a_letters = list(letters[:self.size])  # getting the alphabetical letters based on the number of columns
    num = iter(range(1, (self.size + 1)))  # getting the numerical characters based on the number of rows
    arr = [[self.points.get('E') for i in range(self.size)] for i in range(self.size)]  # creating an array of the empty spots
    import functools
    play = True
    while play == True: #While loop for the creation of the board by creating strings of the symbols
        move = list(move) #converting the coordinates into a list
        num=iter(range(1, (self.size + 1)))
        print('  ' + ' '.join(a_letters))  # to adjust the space with the alphabetical letters with the rest of the grid
        #arr[-int(numerical_coord)][a_letters.index(alphabetical_coord)] = self.points.get(str(colour_change)) #adds the symbol to the grid

        for i in arr:  # using the loop to create the grid with the numerical characters
             print(-(next(num) - (self.size + 1)), end=' ')  # to make the numbers descend
             print(' '.join(i))
             arr[-int(numerical_coord)][a_letters.index(alphabetical_coord)] = self.points.get(str(colour_change)) #adds the symbol to the grid
        return str(Board)

b.set_colour("B1", "W")
b.set_colour("C1", "B")
b.set_colour("D1", "B")
print(b)

the entire code is below
 which would make more sense i guess
class Board():

#A dictionary created for the colours and the specific symbols
points = {'E': '.', 'B': '@', 'W': 'O'}


#Constructor--------------------------------------
def __init__(self, size=19,from_strings=str):
    self.size = size
    self.from_strings=from_strings

    #Assertation error
    assert (self.size > 1 and self.size < 27), "Illegal board size: must be between 2 and 26."  # raising the assertation error if not within the ranges

    #need to do the assertion errors properly
    # assert type(self.from_strings)==list,"input is not a list"
    # assert len(self.from_strings)==self.size, "length of input list does not match size"
    # for i in self.from_strings:
    #     assert type(i)==str, "row "+i+" is not a string"
    #     assert len(i)==self.size,"length of row "+i+" does not match size"
    #     assert i== b[i], "invalid character in row "+i



#Methods------------------------------------------



def __str__(self):
    from string import ascii_uppercase as letters  # importing the alphabetical letters as uppercase
    a_letters = list(letters[:self.size])  # getting the alphabetical letters based on the number of columns
    num = iter(range(1, (self.size + 1)))  # getting the numerical characters based on the number of rows
    arr = [[self.points.get('E') for i in range(self.size)] for i in
           range(self.size)]  # creating an array of the empty spots

    # arr = [['.' for i in range(self.size)] for i in range(self.size)]  # creating an array of the empyty spots
    print('  ' + ' '.join(a_letters))  # to adjust the space with the alphabetical letters with the rest of the grid
    for i in arr:  # using the loop to create the grid with the numerical characters
        print(-(next(num) - (self.size + 1)), end=' ')  # to make the numbers descend

        print(' '.join(i))
    return str(Board)


def get_size(self):  # returns the size of the board
    return self.size


def set_colour(self, coords, colour_name):
    self.coords = coords  # takes in the coordinates of the move
    self.colour_name = colour_name  # takes in the colour change

    colour_change = self.colour_name  # assigning the colour changed to
    colour__change = "'" + colour_change + "'"  # to make it 'B' or 'W'
    self.coords = coords #takes in the coordinates
    self.colour_name = colour_name #takes in the colour change

    # Assertation errors--------------------------------
    move = self.coords #takes in the coordinates of the move

    alphabetical_coord = move[0]  # assigning the alphabetical coordinate to a seperate variable

    numerical_coord = move[1:len(move)]  # assigning the numerical coordinate to a seperate variable

    # AssertionError-----------------------------
    assert (int(ord(alphabetical_coord)) > 64 and int(ord(alphabetical_coord)) < 91), "row out of range"
    assert (int(numerical_coord) > 0 and int(numerical_coord) < 27), "column out of range"
    # ------------------------------------------------------------------------------------------------
    colour_change = self.colour_name  # assigning the colour changed to
    colour__change = "'" + colour_change + "'" #to make it 'B' or 'W'

    # Draw the grid------------------------------------------------------------------------------------

    from string import ascii_uppercase as letters  # importing the alphabetical letters as uppercase
    a_letters = list(letters[:self.size])  # getting the alphabetical letters based on the number of columns
    num = iter(range(1, (self.size + 1)))  # getting the numerical characters based on the number of rows
    arr = [[self.points.get('E') for i in range(self.size)] for i in range(self.size)]  # creating an array of the empty spots
    import functools
    play = True
    while play == True: #While loop for the creation of the board by creating strings of the symbols
        move = list(move) #converting the coordinates into a list
        num=iter(range(1, (self.size + 1)))
        print('  ' + ' '.join(a_letters))  # to adjust the space with the alphabetical letters with the rest of the grid
        #arr[-int(numerical_coord)][a_letters.index(alphabetical_coord)] = self.points.get(str(colour_change)) #adds the symbol to the grid
        
        for i in arr:  # using the loop to create the grid with the numerical characters
             print(-(next(num) - (self.size + 1)), end=' ')  # to make the numbers descend
             print(' '.join(i))
             arr[-int(move[1])][a_letters.index(move[0])] = self.points.get(str(colour_change)) #adds the symbol to the grid

             #arr[-int(numerical_coord)][a_letters.index(alphabetical_coord)] = self.points.get(str(colour_change)) #adds the symbol to the grid
        return str(Board)

def get_colour(self, coords):
    #Assertation errors
    assert (len(coords) == 2 or len(coords) == 3), "invalid colour name"
    return self.colour_name  # returns the colour of the point at the given corrdinates

def to_strings(self):
    m=[]
    a=[]
    for i in range(1):
        for i in self.arr:
            x = " ".join(str(i).split(",")) #removes the comma in between the characters
            x = x + x[1]
            for x in i:
                m += x
                m_list_tostring = ''.join([str(elem) for i, elem in enumerate(i)]) #to convert the list of characters into a string
            a.append(m_list_tostring) #apending the lists of strings using append
        return (a) #returns the string of the board

b = Board()
print(b)
b = Board(5)
b.set_colour("B1", "W")
b.set_colour("C1", "B")
b.set_colour("D1", "B")
print(b)
print(b.get_colour("C1"))
b.set_colour("C1", "E")
print(b)
#b.set_colour("C1", "G") ----------------------------------------
b = Board(3, ["O.O", ".@.", "@O."])
print(b)
# print(b.to_strings())
# c = Board(b.get_size(), b.to_strings())
#  print(str(b) == str(c))
Asked By: Anne Tillekeratne

||

Answers:

There are serious problems with the posted code:

  • The __str__ method prints an empty grid, and returns str(Board). It should not print anything, and return a string representation of the board, not an empty board.
  • The set_colour method creates an empty grid as arr, and then prints it, while modifying arr to have the requested color change.
  • The code is very hard to read because it’s full of bad practices

To get the behavior you want, I suggest the following steps:

  • Create the grid once, in the constructor
  • Make set_colour just update the cell at the specified coordinates, and do nothing else
  • Make the __str__ method return a string representation of the grid

A basic implementation of just the above, ignoring the rest of the code:

from string import ascii_uppercase as letters


class Board:
    points = {'E': '.', 'B': '@', 'W': 'O'}

    def __init__(self, size=19):
        assert 2 <= size <= 26, "Illegal board size: must be between 2 and 26."

        self.size = size
        self.grid = [['E'] * size for _ in range(size)]

    def __str__(self):
        heading = '  ' + ' '.join(letters[:self.size])
        lines = [heading]
        for r, row in enumerate(self.grid):
            line = f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
            lines.append(line)
        return 'n'.join(lines)

    def _to_row_and_column(self, coords):
        # destructure coordinates like "B2" to "B" and 2
        alpha, num = coords
        colnum = ord(alpha) - ord('A') + 1
        rownum = self.size - int(num) + 1

        assert 1 <= rownum <= self.size
        assert 1 <= colnum <= self.size

        return rownum, colnum

    def set_colour(self, coords, colour_name):
        rownum, colnum = self._to_row_and_column(coords)
        assert colour_name in self.points

        self.grid[rownum - 1][colnum - 1] = colour_name

    def get_colour(self, coords):
        rownum, colnum = self._to_row_and_column(coords)
        return self.grid[rownum - 1][colnum - 1]



b = Board(5)
print(b)
b.set_colour("B1", "W")
print(b)
b.set_colour("C1", "B")
print(b)

Output:

  A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . . . . .
  A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . O . . .
  A B C D E
5 . . . . .
4 . . . . .
3 . . . . .
2 . . . . .
1 . O @ . .
Answered By: janos
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.