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))
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 @ . .
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))
There are serious problems with the posted code:
- The
__str__
method prints an empty grid, and returnsstr(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 asarr
, and then prints it, while modifyingarr
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 @ . .