input: Write a function to find the shortest path between two points in a matrix. The function should return the length of the shortest path. If no path exists, return math.inf. The function should consider movement in all four directions (up, down, left, right). Cells containing the value 0 are passable, while other values are obstacles.
  
  def shortest_path(matrix, start, end):
    queue = []
    min_len = math.inf
    queue.append([start])
    while queue:
      path = queue.pop(0)
      x, y = path[-1]
      if (x, y) == end:
        if len(path) < min_len:
          min_len = len(path)
      for dx, dy in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
        new_x, new_y = x + dx, y + dy
        if 0 <= new_x < len(matrix) and 0 <= new_y < len(matrix[0]):
          if matrix[new_x][new_y] == 0:
            queue.append(path + [(new_x, new_y)])
    return min_len
  
  assert shortest_path([[2, 3, 5], [1, 7, 6], [3, 0, 9]], (0, 0), (2, 2))==math.inf
  assert shortest_path([[0, 3, 5], [0, 7, 6], [0, 0, 0]], (0, 0), (2, 2))==5
output: 
  def shortest_path(matrix, start, end):
    queue = []
    min_len = math.inf
    queue.append([start])
    while queue:
      path = queue.pop(0)
      x, y = path[-1]
      if (x, y) == end:
        if len(path) < min_len:
          min_len = len(path)
      for dx, dy in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
        new_x, new_y = x + dx, y + dy
        if 0 <= new_x < len(matrix) and 0 <= new_y < len(matrix[0]):
          if matrix[new_x][new_y] == 0:
            queue.append(path + [(new_x, new_y)])
    return min_len
  