input: Write a function named `gini` to calculate the Gini coefficient of a given dataset. The function should accept an array as input and return the Gini coefficient as a float. If the input array is empty, the function should return 0.0.
  
  def gini(x):
      """Calculate Gini Coefficient of a given dataset."""
      if len(x) == 0:
          return 0.0
      
      # calculate the frequency of each item in x
      x_value_counts = x.value_counts().sort_index()
  
      # calculate the cumulative sum of x_value_counts
      x_cum_sum = x_value_counts.cumsum()
  
      # calculate the Lorenz values
      n = len(x)
      lorenz = x_cum_sum / n
      lorenz = np.insert(lorenz, 0, 0) # add 0 to the beginning of array
  
      # calculate the Gini Coefficient
      width = lorenz[:-1] - lorenz[1:]
      gini_coef = (1 / n) * sum(width * (lorenz[1:] + lorenz[:-1]))
  
      return gini_coef
  
  if __name__ == '__main__':
      x = np.array([2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,21])
      gini_coef = gini(x)
      assert gini_coef == 0.605
  
      x = np.array([])
      gini_coef = gini(x)
      assert gini_coef == 0.0
output: def gini(x):
      if len(x) == 0:
          return 0.0
      
      x_sorted = sorted(x)
      n = len(x)
      cum_x = [0] * n
      for i in range(n):
          cum_x[i] = cum_x[i - 1] + x_sorted[i]
      
      lorenz = [cum_x[i] / cum_x[-1] for i in range(n)]
      lorenz.insert(0, 0)
      
      width = [lorenz[i] - lorenz[i + 1] for i in range(n)]
      gini_coef = (1 / n) * sum(width[i] * (lorenz[i + 1] + lorenz[i]) for i in range(n))
      
      return gini_coef