input: Write a function to implement the Gradient Descent Algorithm for a given set of input features and target values, with specified learning rate and number of iterations. The function should return the final computed values of the slope and intercept after all iterations. If the input features or target values are empty, the function should return (0, 0).
  assert gradient_descent([1, 2, 3], [2, 4, 6], 0.01, 100)==(2.0, 0.0)
  assert gradient_descent([1, 2, 3], [3, 5, 7], 0.01, 100)==(1.9999999999999956, 1.0000000000000036)
  assert gradient_descent([1, 3, 5, 7], [2, 6, 10, 14], 0.01, 100)==(2.0, 0.0)
  assert gradient_descent([], [], 0.01, 100)==(0, 0)
  assert gradient_descent([1, 2, 3], [1, 4, 9], 0.01, 100)==(2.999999999999995, -0.9999999999999973)
output: def gradient_descent(features, targets, learning_rate, num_iterations):
      if not features or not targets:
          return (0, 0)
      
      n = len(features)
      slope = 0
      intercept = 0
      
      for _ in range(num_iterations):
          predicted = [slope * x + intercept for x in features]
          slope_gradient = (-2/n) * sum(features[i] * (targets[i] - predicted[i]) for i in range(n))
          intercept_gradient = (-2/n) * sum(targets[i] - predicted[i] for i in range(n))
          slope -= learning_rate * slope_gradient
          intercept -= learning_rate * intercept_gradient
      
      return (slope, intercept)