Learn Classes and Objects by Building a Sudoku Solver - Step 74

Tell us what’s happening:

I am trying use list comprehension with an if/else condition to have a ‘*’ symbol for each zero otherwise convert each iteration (number in row) into a string . I have tried mirroring the syntax setups and switched the if/else statements around and am still getting an error.

See below for the error message:
"Sorry, your code does not pass. Keep trying.

The list comprehension assigned to the row_str variable should call str() on each item i in row if i is truthy, and it should evaluate to '*' otherwise."

Your code so far

class Board:
    def __init__(self, board):
        self.board = board

# User Editable Region

    def __str__(self):
        board_str = ''
        for row in self.board:
            row_str = ['*' if i == 0 else str(i) for i in row]

# User Editable Region

    def find_empty_cell(self):
        for row, contents in enumerate(self.board):
            try:
                col = contents.index(0)
                return row, col
            except ValueError:
                pass
        return None

    def valid_in_row(self, row, num):
        return num not in self.board[row]

    def valid_in_col(self, col, num):
        return all(self.board[row][col] != num for row in range(9))

    def valid_in_square(self, row, col, num):
        row_start = (row // 3) * 3
        col_start = (col // 3) * 3
        for row_no in range(row_start, row_start + 3):
            for col_no in range(col_start, col_start + 3):
                if self.board[row_no][col_no] == num:
                    return False
        return True

    def is_valid(self, empty, num):
        row, col = empty
        valid_in_row = self.valid_in_row(row, num)
        valid_in_col = self.valid_in_col(col, num)
        valid_in_square = self.valid_in_square(row, col, num)
        return all([valid_in_row, valid_in_col, valid_in_square])

    def solver(self):
        if (next_empty := self.find_empty_cell()) is None:
            return True
        for guess in range(1, 10):
            if self.is_valid(next_empty, guess):
                row, col = next_empty
                self.board[row][col] = guess
                if self.solver():
                    return True
                self.board[row][col] = 0
        return False

def solve_sudoku(board):
    gameboard = Board(board)
    print(f'Puzzle to solve:\n{gameboard}')
    if gameboard.solver():
        print(f'Solved puzzle:\n{gameboard}')
    else:
        print('The provided puzzle is unsolvable.')
    return gameboard

puzzle = [
  [0, 0, 2, 0, 0, 8, 0, 0, 0],
  [0, 0, 0, 0, 0, 3, 7, 6, 2],
  [4, 3, 0, 0, 0, 0, 8, 0, 0],
  [0, 5, 0, 0, 3, 0, 0, 9, 0],
  [0, 4, 0, 0, 0, 0, 0, 2, 6],
  [0, 0, 0, 4, 6, 7, 0, 0, 0],
  [0, 8, 6, 7, 0, 4, 0, 0, 0],
  [0, 0, 0, 5, 1, 9, 0, 0, 8],
  [1, 7, 0, 0, 0, 6, 0, 0, 5]
]

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15

Challenge Information:

Learn Classes and Objects by Building a Sudoku Solver - Step 74

This is the original message with the instructions :
" Step 74

Modify the row_str comprehension to give a string only when the item is not zero, and an asterisk character otherwise."

In principle it’s correct, and the outcome is exactly the one expected. But the test accept the answer the other way around.

You should keep str(i) as the “main” expression to evaluate and have an asterisk in the else part (you need to change the condition of the if for this to work).

Anyway, I’ll open an issue to modify the test and accept other solutions.

Tried it this way still showing an error message . is there a small detail I am missing now? Really appreciate the help!

def __str__(self):
    board_str = ''
    for row in self.board:
        row_str = [str(i) if i != 0 else '*' for i in row]

Again correct in principle, but there is a simpler way to express if i is not 0 or “Truthy”. If i is not 0 then it evaluates as True

1 Like

Thank you so much every one I always forget to simplify it . Just a bad habit :sweat_smile:

1 Like

I think it’s great to just write something that will work, as you did, even if it’s your first idea. You can simplify or optimize it later, and eventually those optimizations will become more of a habit.

In this case, the test works one way…

1 Like