class RelationList(): '''Relation list class.''' def __init__(self, lis=[], /): self.lis = lis self.relations = [] self.elm = {} for i in range(len(lis)): self.elm[lis[i]] = 0 def __str__(self): return str(self.lis) def __repr__(self): return repr((self.lis, self.relations, self.elm)) def __iter__(self): a = [] for i in range(len(self.lis)): a.append(self.lis[i], self.elm[lis[i]]) return iter(a) def __len__(self): return len(self.lis) def __add__(self, other): # Note: this will discard all relations for both relation lists. return RelationList(self.lis+other.lis) @property def value(self): '''Returns the value of the list.''' return self.lis def relate(self, val1, val2, /, *, mode='break', assignment=None): '''Creates a relation between two elements.''' if val1 not in self.lis and val2 not in self.lis: raise ValueError(f"Values {val1} and {val2} not found.") elif val1 not in self.lis: raise ValueError(f"Value {val1} not found.") elif val2 not in self.lis: raise ValueError(f"Value {val2} not found.") if mode not in ('break', 'delete'): raise ValueError("Invaild mode.") if (val1, val2, mode, assignment) in self.relations: return self.relations.append((val1, val2, mode, assignment)) self.elm[val1] += 1 self.elm[val2] += 1 def add(self, val, /, index=-1): '''Appends a new element to the assigned index in the list.''' if index == -1: self.lis.append(val) else: self.lis.insert(index, val) self.elm[val] = 0 def delete(self, val, /, *, err="raise"): '''Deletes an element in the list.''' if val not in self.lis: if err == "raise": raise ValueError(f"Value {val} not found.") elif err == "ignore": return elif err == "append": self.lis.add(val) else: if self.elm[val] == 0: self.lis.remove(val) else: for i in range(len(r := self.relations)): if val in (r[i][0], r[i][1]): y = r[i][1] if val == r[i][0] else r[i][0] if r[i][2] == 'break': del r[i] self.elm[y] -= 1 del self.elm[val] self.lis.remove(val) else: del r[i] self.lis.remove(y) self.lis.remove(val) del self.elm[val] del self.elm[y] def relate_all(self, mode='break', assignments=None): '''Create relations between all elements.''' self.relatiosns.clear() for i in range(len(li := self.lis)-1): for j in range(i+1, len(li)-1): if not isinstance(assignments, (list, tuple)): self.relate(li[i], li[j], mode, assignments) else: try: self.relate(li[i], li[j], mode, assignments[i]) except IndexError: self.relate(li[i], li[j], mode, None) def get_relates(self, val, /): '''Returns all of the relations with the element.''' if val not in self.lis: raise ValueError(f"Value {val} not found.") a = [] for i in range(len(r := self.relations)): if val in r[i]: a.append(r[i]) return a def get_assignment(self, val1, val2): '''Returns the assignment assigned between two elements.''' for i in range(len(r := self.relations)): if val1 in r[i] and val2 in r[i]: return r[i][3] raise ValueError(f"Relation between {val1} and {val2} not found.")