5
\$\begingroup\$

Character Picture Grid

Say you have a list of lists where each value in the inner lists is a one-character string, like this:

grid = [['.', '.', '.', '.', '.', '.'],
 ['.', 'O', 'O', '.', '.', '.'],
 ['O', 'O', 'O', 'O', '.', '.'],
 ['O', 'O', 'O', 'O', 'O', '.'],
 ['.', 'O', 'O', 'O', 'O', 'O'],
 ['O', 'O', 'O', 'O', 'O', '.'],
 ['O', 'O', 'O', 'O', '.', '.'],
 ['.', 'O', 'O', '.', '.', '.'],
 ['.', '.', '.', '.', '.', '.']]

You can think of grid[x][y] as being the character at the x- and y-coordinates of a "picture" drawn with text characters. The (0, 0) origin will be in the upper-left corner; the x-coordinates increase going right, and the y-coordinates increase going down.

Copy the previous grid value, and write code that uses it to print the image.

..OO.OO..
.OOOOOOO.
.OOOOOOO.
..OOOOO..
...OOO...
....O....

My solution:

def logic_grid(grid):
 for x in range(6):
 for y in range(9):
 if y < 8:
 print(grid[y][x], end='')
 else:
 print(grid[y][x])
def main():
 grid = [['.', '.', '.', '.', '.', '.'],
 ['.', 'O', 'O', '.', '.', '.'],
 ['O', 'O', 'O', 'O', '.', '.'],
 ['O', 'O', 'O', 'O', 'O', '.'],
 ['.', 'O', 'O', 'O', 'O', 'O'],
 ['O', 'O', 'O', 'O', 'O', '.'],
 ['O', 'O', 'O', 'O', '.', '.'],
 ['.', 'O', 'O', '.', '.', '.'],
 ['.', '.', '.', '.', '.', '.']]
 start = logic_grid(grid)
 
if __name__ == '__main__':
 main()
Toby Speight
87.1k14 gold badges104 silver badges322 bronze badges
asked Jun 12, 2023 at 10:22
\$\endgroup\$
1
  • \$\begingroup\$ As it is, your grid represents a list of columns. Would it also be acceptable to rearrange the data to have a list of rows instead, or is this a hard requirement? \$\endgroup\$ Commented Jun 13, 2023 at 17:01

4 Answers 4

7
\$\begingroup\$

In Python, you rarely need to iterate using indexes. Iterate directly over the values themselves, not their indexes. [The latter is what programmers working in poorer languages have to do.]

Question the assignment. In my opinion, the function should not take a grid and print it. Rather, it should return the grid as a string. The latter is more flexible and more in line with the general principle of organizing programs around data-oriented, side-effect-free functions.

Don't hard-code the function to one specific grid. A key purpose of functions is to generalize behavior so it can be reused. If the function hardcodes the grid's dimensions, that generality disappears.

Python iterables can be joined together into strings. This is a basic operation. Take advantage of it.

def main():
 # Printing happens out at this level.
 grid = [...]
 print(grid_to_str(grid))
 
def grid_to_str(grid):
 # No side effects here. Just data in and data out.
 # As noted by RootTwo, we have to transpose the grid.
 return '\n'.join(
 ''.join(row)
 for row in zip(*grid)
 )
if __name__ == '__main__':
 main()
answered Jun 12, 2023 at 19:18
\$\endgroup\$
3
  • 1
    \$\begingroup\$ The grid is stored by columns. So the '\n'.join(''.join(row) ... ) would result in a picture on its side. \$\endgroup\$ Commented Jun 13, 2023 at 7:25
  • 5
    \$\begingroup\$ @RootTwo Unfortunate. Rotate your monitor? \$\endgroup\$ Commented Jun 13, 2023 at 7:42
  • 4
    \$\begingroup\$ That call to map is unnecessary, you can just write for row in zip(*grid). \$\endgroup\$ Commented Jun 13, 2023 at 9:35
5
\$\begingroup\$

Currently you are making assumptions in logic_grid about grid. With the current setup it's fine, but if later grid becomes larger/smaller, the image will not print correctly. Instead of hardcoding in values for the array length, use len

def logic_grid(grid):
 # adding validation here to make sure grid is initialized would also be a good idea
 for x in range(len(grid[0])):
 for y in range(len(grid)):
 if y < len(grid)-1:
 print(grid[y][x], end='')
 else:
 print(grid[y][x])

I would also suggest using a better function name as logic_grid doesn't do anything besides printing, so something like print_grid or display_grid would describe what the function does much better.

Toby Speight
87.1k14 gold badges104 silver badges322 bronze badges
answered Jun 12, 2023 at 11:31
\$\endgroup\$
2
  • \$\begingroup\$ How do you mean validation? \$\endgroup\$ Commented Jun 12, 2023 at 12:59
  • \$\begingroup\$ @JarneVercruysse validation like type(grid) is list and len(grid)>0) \$\endgroup\$ Commented Jun 12, 2023 at 13:41
4
\$\begingroup\$

You can use zip to transpose the itearble of iterables. Like this:

print('\n'.join(''.join(i) for i in zip(*grid)))

(and this code above is the solution)

Another example: dot product of two math vectors with zip

dot_product = lambda x,y:sum(i*j for i,j in zip(x,y))
answered Jun 12, 2023 at 21:31
\$\endgroup\$
1
\$\begingroup\$

You don't need zip() and you don't need len(). Just concatenate each row to a string then print the row:

for row in grid:
 the_row = ''
 for i in row:
 the_row += i
 print(the_row)
answered Jun 13, 2023 at 17:24
\$\endgroup\$
1
  • \$\begingroup\$ You need zip because the data is sideways. If you try this way the image will be on its side. \$\endgroup\$ Commented Jun 13, 2023 at 18:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.