text: from BlackBoxAuditing.repairers.AbstractRepairer import AbstractRepairer
  import BlackBoxAuditing.repairers.CategoricRepairer as CategoricRepairer
  from BlackBoxAuditing.repairers.binning.Binner import make_histogram_bins
  from BlackBoxAuditing.repairers.binning.BinSizes import FreedmanDiaconisBinSize as bin_calculator
  from BlackBoxAuditing.repairers.calculators import get_median
  
  
  class Repairer(AbstractRepairer):
    def __init__(self, *args, **kwargs):
      super(Repairer, self).__init__(*args, **kwargs)
      self.categoric_repairer = CategoricRepairer.Repairer(*args, **kwargs)
  
    def repair(self, data_to_repair):
  
      # Convert the "feature_to_repair" into a pseudo-categorical feature by
      # applying binning on that column.
      binned_data = [row[:] for row in data_to_repair]
      index_bins = make_histogram_bins(bin_calculator, data_to_repair, self.feature_to_repair)
  
      category_medians = {}
      for i, index_bin in enumerate(index_bins):
        bin_name = "BIN_{}".format(i) # IE, the "category" to replace numeric values.
        for j in index_bin:
          binned_data[j][self.feature_to_repair] = bin_name
        category_vals = [data_to_repair[j][self.feature_to_repair] for j in index_bin]
        category_medians[bin_name] = get_median(category_vals, self.kdd)
  
      repaired_data = self.categoric_repairer.repair(binned_data)
  
      # Replace the "feature_to_repair" column with the median numeric value.
      for i in range(len(repaired_data)):
        if self.repair_level > 0:
          rep_category = repaired_data[i][self.feature_to_repair]
          repaired_data[i][self.feature_to_repair] = category_medians[rep_category]
        else:
          repaired_data[i][self.feature_to_repair] = data_to_repair[i][self.feature_to_repair]
      return repaired_data
  
  
  def test():
    test_sample()
  
  def test_sample():
    data = [[float(i),float(i)*2, 1] for i in range(0, 150)]
    feature_to_repair = 0
    repairer = Repairer(data, feature_to_repair, 0.5, False)
    repaired_data = repairer.repair(data)
    print("repaired_data altered?", repaired_data != data)
  
    repairer = Repairer(data, feature_to_repair, 0.0, False)
    repaired_data = repairer.repair(data)
    print("repaired_data unaltered for repair level=0?", repaired_data == data)
  
  
  if __name__=="__main__":
    test()
  
  