from enum import Enum class LabelMode(Enum): AddFeature = "Feature" IgnoreFeature = "Ignore" class FactorUtils(object): @staticmethod def extract_factors(string_factors): string_factors = string_factors.strip() if not string_factors: return {} list_factors = [] eval_factor_units = string_factors.split(';') for eval_factor_unit in eval_factor_units: try: factor = int(eval_factor_unit) list_factors.append(factor) except ValueError: string_bounds = eval_factor_unit.split('-') if len(string_bounds) != 2: raise AttributeError('Range need to contain exactly two numbers!') begin_range = int(string_bounds[0]) end_range = int(string_bounds[1]) list_factors += list(range(begin_range, end_range + 1)) return set(list_factors) @staticmethod def factors_to_string(factors): if len(factors) == 0: return '' parts = [] factors_list = sorted(factors) begin = factors_list[0] for i in range(1, len(factors_list)): if factors_list[i] != factors_list[i - 1] + 1: end = factors_list[i - 1] if begin != end: parts.append('{}-{}'.format(begin, end)) else: parts.append(str(begin)) begin = factors_list[i] end = len(factors_list) - 1 if begin != factors_list[end]: parts.append('{}-{}'.format(begin, factors_list[end])) else: parts.append(str(begin)) return ';'.join(parts) @staticmethod def compress_string_factors(string_factors): factors = FactorUtils.extract_factors(string_factors) compressed_string_factors = FactorUtils.factors_to_string(factors) return compressed_string_factors @staticmethod def single_range_to_string(left, right): if left != right: return "{}-{}".format(left, right) else: return "{}".format(left) @staticmethod def group_factors_by_range(factors_set): factors = sorted(list(factors_set)) is_start = [] for i in range(0, len(factors)): is_start.append(i == 0 or (factors[i] != factors[i - 1] + 1)) grouped_factors = [] i = 0 while i < len(factors): if is_start[i]: grouped_factors.append([]) grouped_factors[-1].append(factors[i]) i += 1 return grouped_factors @staticmethod def factors_to_ranges_string(factors_set): if factors_set is None or len(factors_set) == 0: return "None" grouped_factors = FactorUtils.group_factors_by_range(factors_set) return ';'.join([FactorUtils.single_range_to_string(min(x), max(x)) for x in grouped_factors]) @staticmethod def create_label(all_eval_features, removed_features, label_mode): eval_features = set(all_eval_features) if label_mode == LabelMode.AddFeature: add_features = eval_features - set(removed_features) return "Features: {}".format(FactorUtils.factors_to_ranges_string(add_features)) else: return "Ignore: {}".format(FactorUtils.factors_to_ranges_string(set(removed_features)))