input: Write a function to implement the Gradient Descent Algorithm for linear regression. The function should take as input a list of x values, a list of y values, a learning rate, and the number of iterations. It should return the final values of the slope (m) and the intercept (b) after performing the gradient descent optimization.
  assert gradient_descent([1, 2, 3, 4, 5], [3, 5, 7, 9, 11], 0.01, 1000) == (2.0, 1.0)
  assert gradient_descent([1, 2, 3, 4, 5], [2, 4, 6, 8, 10], 0.01, 1000) == (2.0, 0.0)
  assert gradient_descent([1, 2, 3, 4, 5], [4, 7, 10, 13, 16], 0.01, 1000) == (3.0, 1.0)
  assert gradient_descent([1, 2, 3, 4, 5], [5, 7, 9, 11, 13], 0.01, 1000) == (2.0, 3.0)
  assert gradient_descent([], [], 0.01, 1000) == (0.0, 0.0)
output: def gradient_descent(x, y, learning_rate, num_iterations):
      m, b = 0.0, 0.0
      n = len(x)
      if n == 0:
          return m, b
      for _ in range(num_iterations):
          y_pred = [m * xi + b for xi in x]
          dm = (-2/n) * sum(xi * (yi - y_predi) for xi, yi, y_predi in zip(x, y, y_pred))
          db = (-2/n) * sum(yi - y_predi for yi, y_predi in zip(y, y_pred))
          m -= learning_rate * dm
          b -= learning_rate * db
      return m, b