Title: Not able to find a 'naked single' in a Sudoku board
Tags: python,python-3.x

Question: For my 2nd newbie project I an coding a program to solve Sudoki puzzles. In the example code below there are two 9x9 Sudoku boards lists, the one in use results in 7 'naked singles found' while the other one results in 0 'naked singles found'. Both boards have 'naked singles' in them, but only one board reports this. I feel like I am missing a step in my logic somewhere.
The 'logic' for finding 'naked singles' is defined as:- "A naked single is that what remains after you have applied your solving techniques, by eliminating other candidates. A naked single is the last remaining candidate in a cell. Alternative terms are Forced Digit and Sole Candidate."
# 2nd board with hidden singles but none can be found
# board = [
#     [0, 0, 5, 3, 0, 0, 0, 0, 0],
#     [8, 0, 0, 0, 0, 0, 0, 2, 0],
#     [0, 7, 0, 0, 1, 0, 5, 0, 0],
#     [4, 0, 0, 0, 0, 5, 3, 0, 0],
#     [0, 1, 0, 0, 7, 0, 0, 0, 6],
#     [0, 0, 3, 2, 0, 0, 0, 8, 0],
#     [0, 6, 0, 5, 0, 0, 0, 0, 9],
#     [0, 0, 4, 0, 0, 0, 0, 3, 0],
#     [0, 0, 0, 0, 0, 9, 7, 0, 0]
# ]

# Board three, has hidden singles but none can be found
# board = [
#      [0, 0, 0, 7, 0, 6, 0, 0, 0],
#      [0, 0, 9, 0, 3, 0, 0, 0, 2],
#      [0, 6, 0, 9, 0, 0, 0, 0, 1],
#      [0, 0, 5, 0, 1, 0, 4, 0, 0],
#      [0, 0, 6, 0, 0, 0, 7, 0, 0],
#      [0, 3, 0, 0, 7, 4, 8, 0, 0],
#      [8, 0, 0, 0, 9, 0, 1, 0, 0],
#      [0, 0, 0, 0, 0, 0, 0, 0, 0],
#      [0, 0, 3, 0, 4, 0, 0, 0, 5]
# ]

def count_naked_singles(board):
    count = 0
    for i in range(9):
        for j in range(9):
            if board[i][j] == 0:
                possibilities = set(range(1, 10))
                # Check row
                for k in range(9):
                    possibilities.discard(board[i][k])
                # Check column
                for k in range(9):
                    possibilities.discard(board[k][j])
                # Check box
                box_row = (i // 3) * 3
                box_col = (j // 3) * 3
                for m in range(box_row, box_row + 3):
                    for n in range(box_col, box_col + 3):
                        possibilities.discard(board[m][n])
                if len(possibilities) == 1:
                    count += 1
    return count


# test board with 7 naked singles
board = [
    [0, 0, 0, 7, 0, 2, 9, 0, 0],
    [0, 9, 0, 0, 8, 1, 2, 0, 0],
    [8, 7, 2, 4, 5, 0, 0, 1, 3],
    [1, 0, 0, 0, 7, 0, 4, 2, 0],
    [9, 0, 0, 1, 0, 5, 0, 0, 8],
    [0, 4, 0, 0, 0, 0, 5, 6, 0],
    [0, 3, 5, 8, 0, 4, 0, 9, 6],
    [0, 8, 0, 0, 3, 6, 7, 0, 0],
    [0, 0, 0, 5, 0, 0, 0, 3, 2]
]
count = count_naked_singles(board)
print(f"Number of naked singles found is {count}")

I have tried different Sudoku boards, three of which are included with the supplied code. Sometimes my function will find 'hidden singles' sometimes it misses them. The active 'board' with my code has been tested further and can be completed with a modiefied version of my function count_naked_singles(board) by just finding 'naked singles'.
So my question is: Why is my function count_naked_singles(board): not able to find 'naked single(s)' in all Sudoku boards that have these features in them?

Answer: You've done a great job of eliminating the direct cases where the row, boxes or columns cancel out possibilities. However, there is another way to have a naked single. If no other cell in your row can have a 4, then YOU must have a 4. Or if no other cell in your column can have a 4, then YOU must have a 4. Or, if no other cell in your box can have a 4, then YOU must have a 4.
So, eliminations help you find naked singles, but you must also look at the possibilities of those around you. For all of your possibilities, if all the possibilities in your row do not contain them, then, you are it. Save your possibilities for each position. Then do another pass where you check each possibility for nakedness among its row, or column, or box.