input: Write a python function to perform gradient descent for linear regression and return the optimized coefficients.
  assert np.allclose(gradient_descent(np.array([1,2,3,4]), np.array([2,4,6,8]), 0.01, 1000), (0.0, 2.0), atol=0.1)
  assert np.allclose(gradient_descent(np.array([1,2]), np.array([1,2]), 0.01, 1000), (0.0, 1.0), atol=0.1)
output: def gradient_descent(X, y, learning_rate, iterations):
      m = len(y)
      theta0 = 0.0
      theta1 = 0.0
      
      for _ in range(iterations):
          y_pred = theta0 + theta1 * X
          error = y_pred - y
          
          theta0_grad = (1/m) * np.sum(error)
          theta1_grad = (1/m) * np.sum(error * X)
          
          theta0 = theta0 - learning_rate * theta0_grad
          theta1 = theta1 - learning_rate * theta1_grad
          
      return theta0, theta1