def union(self, other): """Find the union with another set. Parameters ---------- other : set, FiniteSet, RegexSet, IntegerSet, EmptySet or UniversalSet Returns ------- The union set """ if type(other) == set: return FiniteSet(self.fset.union(other)) elif isinstance(other, FiniteSet): return FiniteSet(self.fset.union(other.fset)) elif isinstance(other, RegexSet): return RegexSet(self.fset).union(other) elif isinstance(other, IntegerSet): for element in self.fset: if type(element) != int: try: element = int(element) except: raise AttributeSetError( "Element '%s' of a finite set is not an " "integer (%s)" % (str(element), str(type(element))) ) return IntegerSet(self.fset).union(other) elif isinstance(other, EmptySet): return copy.deepcopy(self) elif isinstance(other, UniversalSet): return UniversalSet() else: raise AttributeSetError("Invalid type of attribute set!")
def intersection(self, other): """Intersection of two integer sets.""" def interval_intersect(interval1, interval2): start1, end1 = interval1 start2, end2 = interval2 common_start = max(start1, start2) common_end = min(end1, end2) if common_start <= common_end: return (common_start, common_end) return None new_intervals = [] if isinstance(other, IntegerSet): for interval1 in self.intervals: for interval2 in other.intervals: common = interval_intersect(interval1, interval2) if common: new_intervals.append(common) return IntegerSet(new_intervals) elif isinstance(other, set): try: for element in other: int_element = int(element) if self.contains(int_element): new_intervals.append((int_element, int_element)) return IntegerSet(new_intervals) except: raise AttributeSetError( "Set '%s' contains non-integer elements!" % str(other) ) elif isinstance(other, FiniteSet): try: for element in other.fset: int_element = int(element) if self.contains(int_element): new_intervals.append((int_element, int_element)) return IntegerSet(new_intervals) except: raise AttributeSetError( "Set '%s' contains non-integer elements!" % str(other) ) elif isinstance(other, UniversalSet): return copy.deepcopy(self) elif isinstance(other, EmptySet): return EmptySet() else: raise AttributeSetError( "Cannot intersect '%s' with an integer set!" % str(other) )
def __init__(self, interval_list): """Initialize IntegerSet object. Takes a collection of tuples or ints normalizes the intervals and singletons and creates a set of intervals and singletons. """ starts = list() ends = list() for interval in interval_list: try: start, end = interval if start > end: raise AttributeSetError( "Invalid integer interval: [%s, %s]" % (str(start), str(end))) else: try: start = int(start) except OverflowError: pass starts.append(start) try: end = int(end) except OverflowError: pass ends.append(end) except (TypeError, ValueError): try: interval = int(interval) except OverflowError: pass starts.append(interval) ends.append(interval) new_intervals = list() sorted_starts_ind = np.argsort(starts) visited = set() for i, index in enumerate(sorted_starts_ind): if index not in visited: visited.add(index) current_end = ends[index] for j in range(i + 1, len(sorted_starts_ind)): if starts[sorted_starts_ind[j]] - 1 > ends[index]: break else: visited.add(sorted_starts_ind[j]) current_end = max(current_end, ends[sorted_starts_ind[j]]) # in case new interval overlaps # with newly constructed interval if len(new_intervals) > 0 and\ starts[index] <= new_intervals[-1][1] + 1: new_intervals[-1] = (new_intervals[-1][0], max(current_end, new_intervals[-1][1])) else: new_intervals.append((starts[index], current_end)) self.intervals = new_intervals return
def difference(self, other): """Find the difference set with another set. Finds a `self` - `other` set. Parameters ---------- other : set, FiniteSet, RegexSet, IntegerSet, EmptySet or UniversalSet Returns ------- The difference set """ if type(other) == set: return FiniteSet(self.fset.difference(other)) elif isinstance(other, FiniteSet): return FiniteSet(self.fset.difference(other.fset)) elif isinstance(other, RegexSet): elements_to_keep = [] for element in self.fset: if not other.match(str(element)): elements_to_keep.append(element) return FiniteSet(elements_to_keep) elif isinstance(other, IntegerSet): for element in self.fset: if type(element) != int: try: element = int(element) except: raise AttributeSetError( "Element '%s' of a finite set is not an " "integer (%s)" % (str(element), str(type(element))) ) return IntegerSet(self.fset).difference(other) elif isinstance(other, EmptySet): return copy.deepcopy(self) elif isinstance(other, UniversalSet): return FiniteSet() else: raise AttributeSetError("Invalid type of attribute set!")
def _regex_to_string(a): if isinstance(a, str): return a elif isinstance(a, re._pattern_type): return a.pattern elif isinstance(a, RegexSet): if a.pattern is not None: return a.pattern else: return None else: raise AttributeSetError("Cannot convert regex to string!")
def union(self, other): """Union of two integer sets.""" if isinstance(other, IntegerSet): return IntegerSet(self.intervals + other.intervals) elif isinstance(other, set): other_intervals = [] for element in other: try: int_element = int(element) except: raise AttributeSetError( "Set '{}' contains non-integer element '{}'".format( str(other), element)) if not self.contains(int_element): other_intervals.append((int_element, int_element)) return IntegerSet(self.intervals + other_intervals) elif isinstance(other, FiniteSet): other_intervals = [] for element in other.fset: try: int_element = int(element) except: raise AttributeSetError( "Set '{}' contains non-integer element '{}'".format( str(other), element)) if not self.contains(int_element): other_intervals.append((int_element, int_element)) return IntegerSet(self.intervals + other_intervals) elif isinstance(other, UniversalSet): return UniversalSet() elif isinstance(other, EmptySet): return copy.deepcopy(self) else: raise AttributeSetError( "Cannot intersect '%s' with an integer set!" % str(other) )
def included(a): if isinstance(a, str): other_exp = parse(a) elif isinstance(a, re._pattern_type): other_exp = parse(a.pattern) elif isinstance(a, RegexSet): if a.pattern: other_exp = parse(a.pattern) else: return False else: raise AttributeSetError( "Regexp object should be of type `str` or `re._pattern_type`!" ) return (self_exp & other_exp.everythingbut()).empty()
def issubset(self, other): """Test if subset of another set. Parameters ---------- other : set, FiniteSet, RegexSet, IntegerSet, EmptySet or UniversalSet Returns ------- `True` is `self` defines a subset of `other`, `False` otherwise """ if type(other) == set: return self.fset.issubset(other) elif isinstance(other, FiniteSet): return self.fset.issubset(other.fset) elif isinstance(other, RegexSet): for element in self.fset: if element is not None: if not other.match(str(element)): return False elif isinstance(other, IntegerSet): for element in self.fset: if element is not None: if type(element) != int: try: element = int(element) except: raise AttributeSetError( "Element '%s' of a finite set is not an " "integer (%s)" % (str(element), str(type(element))) ) if not other.contains(element): return False elif isinstance(other, EmptySet): return False elif isinstance(other, UniversalSet): return True else: return False return True