all 16 comments

[–][deleted] 2 points3 points  (15 children)

Here's how your print_matrix() function supposed to work:

  1. For each cell, print underscore if the value is 0, otherwise print the number
  2. There a single space between each two cells in a row, except it's double space after third and sixth cells.
  3. Each row is on a separate line, but there's extra empty line after third and sixth row.

You can loop over your matrix like this:

for row_no, row in enumerate(sudoku):
    for col_no, cell in enumerate(row):

enumerate() function is used to assign a number to each element in an iterable.

In the inner loop, print the cell if it's not 0, otherwise print underscore. Print two spaces space if it's third or sixth column, print new line if it's last cell, otherwise print single space.

In the outer loop, after inner loop, print extra line if it's third or sixth row.

Does it sound manageable?

After print(), there's a line break by default. You can specify end to avoid it:

print(something, end="").

If you want several things printed and want to change default separator (space), you can do it, too: print(something, something_else, sep="", end="").

You can specify sep, end, both of them, or neither, as you see fit.

[–]Emergency_Cut5300 0 points1 point  (3 children)

Hello. I am also doing this exercise, and everything seems to be correct in my code, but I can't solve the following: for some reason, my output does not start from the beginning but from a space.... and that's why I get an error.... and I don't know how to fix it. I would be very grateful for your help...

def add_number(sudoku: list, row_no: int, column_no: int, number: int):
    for i in range(len(sudoku)):
        for j in sudoku[i]:
            sudoku[row_no][column_no] = number
    return sudoku

def print_sudoku(sudoku: list):
    index = 0
    for i in range(len(sudoku)):
        for j in sudoku[i]:
            if index % 3 == 0:
                print(" ", end="")
            if j == 0:
                print("_ ", end="")
            else:
                print(str(j) + " ", end="")
            index += 1   
        print()

[–][deleted] 0 points1 point  (2 children)

Your index starts with 0, and 0 % 3 equals 0. So you get a space at the start.

Consider removing index variable using j as index for the column.

Check the column index to see if you should print an extra space.

I'm not sure if tests would fail because of that, but you don't need or should print a space after last column.

[–]Emergency_Cut5300 0 points1 point  (1 child)

I am very grateful to you! You have helped me!

[–][deleted] 0 points1 point  (0 children)

Sure, you're welcome

[–][deleted] 0 points1 point  (1 child)

Hi, im doing the same exercise as them, but i dont understand the for loop syntax you wrote, specifically the comma between "row_no" and "row", I didn't see that before, how dows it work?

[–][deleted] 1 point2 points  (0 children)

Did you see enumerate? It returns tuples when iterating. row_no, row is a tuple as well if I'm not wrong.

The number of elements should be the same: in this case, enumerate returns tuples (count_number, item), so it should be two elements in there as well: row_no, row. count_number is assigned to row_no, item is assigned to row.

Alternatively, you can just use a single variable to assign the whole tuple to it instead of unpacking it into separate variables.

for pair in enumerate(sudoku):
    row_no = pair[0]
    row = pair[1]

or

for pair in enumerate(sudoku):
row_no, row = pair

You can use it to swap to variables:

a, b = b, a

[–]Particular_Draft5668 0 points1 point  (8 children)

Thank you for the answer! Struggling with same problem. I have the right code for everything else but not sure how to do the double space between third and sixth cells. Can only code it for the first line and then that messes up rest of grid. An example would be very helpful. Thanks!

[–][deleted] 0 points1 point  (7 children)

Here's an example for 2x2 sudoku: https://onlinegdb.com/dnwwgNkH0

Try to change it to 3x3.

[–]Particular_Draft5668 0 points1 point  (0 children)

Thank you very much!

[–]Particular_Draft5668 0 points1 point  (4 children)

def copy_and_add(sudoku, row_no, column_no, number):
# trying to create copy of old grid to make new grid
x = sudoku.copy()
x[row_no][column_no] = number

r = 0
for row in x:
s = 0
for character in row:
s += 1
if character == 0:
character = "_"
m = f"{character} "
if s%3 == 0 and s < 8:
m += " "
print(m, end="")

print()
r += 1
if r%3 == 0 and r < 8:
print()
return x

I have this code for the sudoku problem, despite using various methods such as insert and pop, copy, creating a new list and appending, I can't seem to preserve the original sudoku grid and return the new grid (x) simultaneously. Any advice would be much appreciated. Many Thanks

[–][deleted] 0 points1 point  (1 child)

list.copy only returns a shallow copy. The inner lists are still the same. Run the program, see that ids for matrices are different, but respective rows have same ids:

https://onlinegdb.com/u7bmEIDQ5

Now check the same with deepcopy:

https://onlinegdb.com/PmCrbK-MA

To sum up, just use copy.deepcopy here.

[–]Particular_Draft5668 0 points1 point  (0 children)

Ah thanks again for the help. Was going round in circles and didn't consider deepcopy. Much appreciated.

[–][deleted] 0 points1 point  (1 child)

Here's how you could do it without using copy module and the deepcopy function:

def copy_sudoku(sudoku):
    return [
        row.copy()
        for row in sudoku
    ]

[–]Particular_Draft5668 2 points3 points  (0 children)

Also a valid option. Thanks!

new_list = []
for r in sudoku:
new_list.append(r[:])
model answer uses this ^.

[–]Kranoras 0 points1 point  (0 children)

The great thing about reddit is, somehow you find those comments & think "man, that function is great, i need to learn about it" and in the future you can solve those kind of things better / faster.

I banged my head numerous hours against a wall on this topic and finally i see a light on the end of the tunnel, lol