text: sodoku_board = [
          [7, 8, 0, 4, 0, 0, 1, 2, 0],
          [6, 0, 0, 0, 7, 5, 0, 0, 9],
          [0, 0, 0, 6, 0, 1, 0, 7, 8],
          [0, 0, 7, 0, 4, 0, 2, 6, 0],
          [0, 0, 1, 0, 5, 0, 9, 3, 0],
          [9, 0, 4, 0, 6, 0, 0, 0, 5],
          [0, 7, 0, 3, 0, 0, 0, 1, 2],
          [1, 2, 0, 0, 0, 7, 4, 0, 0],
          [0, 4, 9, 2, 0, 6, 0, 0, 7]
  ]
  
  
  def print_board(board):
      # prints a line very third row
      for i in range(len(board)):
          if i % 3 == 0 and i != 0:
              print("-------------------------------")
          # prints a line very third column
          for j in range(len(board[0])):
              if j % 3 == 0 and j != 0:
                  print(" | ", end = " ")
              # once it reaches the end add blanks
              if j == 8:
                  print(board[i][j])
              else:
                  print(str(board[i][j]) +  " ", end = " ")
  
  
  
  def find_empty(board):
      # Finds the empty spaces (0)
      for i in range(len(board)):
          for j in range(len(board[0])):
              if board[i][j] == 0:
                  return (i, j) # row, column
      
      return None
  
  
  def valid(board, pos, num):
      """
      Returns if the attempted move is valid
      :param bo: 2d list of ints
      :param pos: (row, col)
      :param num: int
      :return: bool
      """
  
      # Check row
      for i in range(0, len(board)):
          if board[pos[0]][i] == num and pos[1] != i:
              return False
  
      # Check Col
      for i in range(0, len(board)):
          if board[i][pos[1]] == num and pos[1] != i:
              return False
  
      # Check box
  
      box_x = pos[1]//3
      box_y = pos[0]//3
  
      for i in range(box_y*3, box_y*3 + 3):
          for j in range(box_x*3, box_x*3 + 3):
              if board[i][j] == num and (i,j) != pos:
                  return False
  
      return True
  
  
  
  def solve(board):
      """
      Solves a sudoku board using backtracking
      :param board: 2d list of ints
      :return: solution
      """
      find = find_empty(board)
      if find:
          row, col = find
      else:
          return True
  
      for i in range(1,10):
          if valid(board, (row, col), i):
              board[row][col] = i
  
              if solve(board):
                  return True
  
              board[row][col] = 0
  
      return False
  
  
  
  
  print("\n----- Unlsolved Board -----")
  print_board(sodoku_board) # Before
  print("\n")
  solve(sodoku_board)
  print("--- Solved Using BackTracking Algorithm ---")
  print_board(sodoku_board) # After