def __init__(self, name: str, algo: StateSet, head=None, comments=""): assert isinstance(name, str), ARgorithmError("Name should be of type string") self.name = name self._id = str(id(self)) try: assert isinstance(algo, StateSet) self.algo = algo except AssertionError as e: raise ARgorithmError("algo should be of type StateSet") from e self.state_generator = DoublyLinkedListState(self.name, self._id) if head: assert self.algo == head.algo, ARgorithmError( "The head node belongs to a different StateSet") self._flag = False self.head = head self.tail = head self._flag = True state = self.state_generator.dll_declare(self.head, self.tail, comments) self.algo.add_state(state)
def __init__(self, name: str, algo: StateSet, data: iterable = None, comments=""): try: assert isinstance(name, str) self.state_generator = SetState(name, str(id(self))) except Exception as ex: raise ARgorithmError('Give valid name to data structure') from ex try: assert isinstance(algo, StateSet) self.algo = algo except Exception as ex: raise ARgorithmError( "Set structure needs a reference of template to store states" ) from ex self.body = set() if data: for x in data: if isinstance(x, ARgorithmHashable): self.body.add(x.to_json()) elif isinstance(x, (int, str, bool, float, generic)): self.body.add(x) else: raise TypeError( "Invalid key error : Please provide data with ARgorithmHashable type or (int, float, bool, str)" ) self.__working_set = set(data) if data else set() state = self.state_generator.set_declare(self.body, comments=comments) self.algo.add_state(state)
def __init__(self, name: str, algo: StateSet, data=None, shape=None, fill=0, dtype=int, comments=""): try: assert isinstance(name, str) self.state_generator = ArrayState(name, str(id(self))) except Exception as ex: raise ARgorithmError('Give valid name to data structure') from ex try: assert isinstance(algo, StateSet) self.algo = algo except Exception as ex: raise ARgorithmError( "array structure needs a reference of template to store states" ) from ex if data is not None: check_dimensions(data) self.body = np.array(data) self.dtype = self.body.dtype state = self.state_generator.array_declare(self.body, comments) self.algo.add_state(state) return self.dtype = dtype self.body = np.full(fill_value=fill, shape=shape, dtype=dtype) state = self.state_generator.array_declare(self.body, comments) self.algo.add_state(state)
def pop_front(self): """Pops first element of List. Raises: ARgorithmError: Raised if list is empty Returns: element: The first element of list Example: >>> lis List([5, 1, 2, 3, 7]) >>> lis.pop_front() 5 >>> lis List([1, 2, 3, 7]) """ if self.head is None: raise ARgorithmError("Empty list") data = self.head.value self.head = self.head.next if self.head: self.head.prev = None else: self.tail = None self.size -= 1 return data
def __setattr__(self, key, value): """The __setattr__ function is overriden to listen to state changes in the head. Raises: ARgorithmError: Raised if head pointer is not type None or DoublyLinkedListNode """ if key in ['head', 'tail'] and value: assert isinstance(value, DoublyLinkedListNode), ARgorithmError( "next should be of type None or DoublyLinkedListNode") last_head = None last_tail = None if key == 'head' and self._flag: last_head = self.head._id if self.head else "none" elif key == 'tail' and self._flag: last_tail = self.tail._id if self.tail else "none" self.__dict__[key] = value if key == 'head' and self._flag: state = self.state_generator.dll_head( self.head, self.tail, last_head=last_head, comments="head pointer shifts") self.algo.add_state(state) if key == 'tail' and self._flag: state = self.state_generator.dll_tail( self.head, self.tail, last_tail=last_tail, comments="tail pointer shifts") self.algo.add_state(state)
def poll(self, comments=""): """pops first element from priority queue. Args: comments (str, optional): Comments for descriptive format. Defaults to "". Raises: ARgorithmError: If priority queue is empty Returns: element : first element of priority queue Example: >>> pq.offer(2) >>> pq.offer(4) >>> pq.offer(3) >>> pq.poll() 2 >>> pq.poll() 3 >>> pq.poll() 4 """ if self.empty(): raise ARgorithmError('queue is empty') item = heapq.heappop(self.body) state = self.state_generator.priorityqueue_poll(body=self.body, element=item, comments=comments) self.algo.add_state(state) return item
def pop_back(self): """Pops first element of List. Raises: ARgorithmError: Raised if list is empty Returns: element: The first element of list Example: List([1, 2, 3, 7]) >>> lis.pop_back() 7 >>> lis List([1, 2, 3]) """ if self.head is None: raise ARgorithmError("Empty list") data = self.tail.value self.tail = self.tail.prev if self.tail: self.tail.next = None else: self.head = None self.size -= 1 return data
def __setattr__(self,key,value): """The __setattr__ function is overriden to listen to state changes in the value of node or the next attribute. Raises: ARgorithmError: Raised if next pointer is not type None or LinkedListNode """ if key == 'next' and value: assert isinstance(value,LinkedListNode) , ARgorithmError("next should be of type None or LinkedListNode") last_value = None last_next = None if key == 'value' and self._flag: last_value = self.value elif key == 'next' and self._flag: last_next = self.next self.__dict__[key] = value if key == 'next' and self._flag: if last_next or self.next: state = self.state_generator.llnode_next( value=self.value, _next=self.next, last_next=last_next, comments="next pointer updated" ) self.algo.add_state(state) elif key == 'value' and self._flag: state = self.state_generator.llnode_iter( value=self.value, _next=self.next, last_value=last_value, comments="value updated" ) self.algo.add_state(state)
def peek(self, comments=""): """peeks at first element of priority queue. Args: comments (str, optional): Comments for descriptive format. Defaults to "". Raises: ARgorithmError: If priority queue is empty Returns: element : first element of priority queue Example: >>> pq.offer(4) >>> pq.offer(3) >>> pq.offer(5) >>> pq.peek() 3 >>> pq.peek() 3 """ if self.empty(): raise ARgorithmError('queue is empty') item = self.body[0] state = self.state_generator.priorityqueue_peek(self.body, comments) self.algo.add_state(state) return item
def __delitem__(self, key): """deletes the entry associated with 'key' in the Map Args: key (ARgorithmHashable or (int, str, float, bool)) : key to lookup in dict comments (str, optional): Comments for descriptive purpose. Defaults to "". Example: >>> map Map({"abc":2, "efg":3}) >>> del map["abc"] # __delitem__ usage >>> map Map({"efg":3}) """ try: value = None if isinstance(key, ARgorithmHashable): value = self.body[key.to_json()] del self.body[key.to_json()] else: value = self.body[key] del self.body[key] del self.__working_dict[key] state = self.state_generator.map_remove(self.body, key, value, "") self.algo.add_state(state) except Exception as e: raise ARgorithmError(f"Invalid Key Error : {str(e)}") from e
def top(self, comments=""): """returns element from stack top. Args: comments (str, optional): Comments for descriptive purpose. Defaults to "". Raises: ARgorithmError: Raised if stack is empty Returns: element: Element at stack top Example: >>> st.push(1) >>> st.push(2) >>> st.push(3) >>> st.top() 3 """ if self.empty(): raise ARgorithmError('Stack is empty') item = self.body[-1] state = self.state_generator.stack_top(self.body, comments) self.algo.add_state(state) return item
def pop(self, comments=""): """Removes element from front of queue and returns it. Args: comments (str, optional): Comments for descriptive purpose. Defaults to "". Raises: ARgorithmError: Raised if queue is empty Returns: element: The element popped from queue Example: >>> q Queue([3, 5, 4]) >>> q.pop() 3 >>> q.pop() 5 >>> q Queue([4]) """ if self.empty(): raise ARgorithmError('queue is empty') item = self.body[0] self.body = self.body[1:] state = self.state_generator.queue_pop(body=self.body, element=item, comments=comments) self.algo.add_state(state) return item
def __getitem__(self, key) -> any: """returns the value associated with 'key' in the Map Args: key (ARgorithmStructure or (int, str, float, bool)): key to lookup in dict comments (str, optional): Comments for descriptive purpose. Defaults to "". Returns: obj: value associated with the key provided Example: >>> map Map({"abc":2, "efg":3}) >>> map["abc"] 2 """ try: _value = self.__working_dict[key] value = None if isinstance(key, ARgorithmHashable): value = self.body[key.to_json()] else: value = self.body[key] state = self.state_generator.map_get(body=self.body, key=key, value=value, comments="") self.algo.add_state(state) return _value except Exception as e: raise ARgorithmError(f"Invalid Key Error : {str(e)}") from e
def __init__(self, name: str, algo: StateSet, comments: str = ""): try: assert isinstance(name, str) self._id = str(id(self)) self.state_generator = PriorityQueueState(name, self._id) except AssertionError as e: raise ARgorithmError('Give valid name to data structure') from e try: assert isinstance(algo, StateSet) self.algo = algo except AssertionError as e: raise ARgorithmError( "Queue structure needs a reference of template to store states" ) from e self.body = [] state = self.state_generator.priorityqueue_declare(comments) self.algo.add_state(state)
def __init__(self, name: str, algo: StateSet, comments: str = ""): try: assert isinstance(name, str) self.state_generator = MapState(name, str(id(self))) except Exception as ex: raise ARgorithmError('Give valid name to data structure') from ex try: assert isinstance(algo, StateSet) self.algo = algo except Exception as ex: raise ARgorithmError( "Map structure needs a reference of template to store states" ) from ex self.body = {} self.__working_dict = {} state = self.state_generator.map_declare(self.body, comments) self.algo.add_state(state)
def __setitem__(self, key, value): """As this wrapper is for immutable string, set item is not supported so an error is raised. Raises: TypeError: Raised always """ raise ARgorithmError( "'String' object does not support item assignment")
def __init__(self, name, algo, body='', comments=""): try: assert isinstance(name, str) self._id = str(id(self)) self.state_generator = StringState(name, self._id) except AssertionError as e: raise ARgorithmError('Give valid name to data structure') from e try: assert isinstance(algo, StateSet) self.algo = algo except AssertionError as e: raise TypeError( "string structure needs a reference of StateSet to store states" ) from e try: assert isinstance(body, str) self.body = body except AssertionError as e: raise ARgorithmError("String body should be of type string") from e state = self.state_generator.string_declare(self.body, comments) self.algo.add_state(state)
def __getitem__(self, key, comments=""): """overloading the item access operator to generate states and create more instances of ARgorithmToolkit Array if subarray is accessed. Args: key (index or slice): comments (str, optional): Comments for descriptive purpose. Defaults to "". Raises: ARgorithmError: Raised if key is invalid Returns: element or subarray: depending on key , the returned object can be an element or an sub-array Examples: >>> arr[1,2] 6 """ try: if isinstance(key, slice): name = f"{self.state_generator.name}_sub" return Array(name=name, algo=self.algo, data=self.body[key], comments=comments) if isinstance(key, int) and len(self.body.shape) == 1: state = self.state_generator.array_iter(body=self.body, index=key, comments=comments) self.algo.add_state(state) return self.body[key] if isinstance(key, int) or len(key) < len(self.shape()): name = f"{self.state_generator.name}_sub" state = self.state_generator.array_iter(body=self.body, index=key, comments=comments) self.algo.add_state(state) return Array(name=name, algo=self.algo, data=self.body[key], comments=comments) state = self.state_generator.array_iter(body=self.body, index=key, comments=comments) self.algo.add_state(state) return self.body[key] except Exception as ex: raise ARgorithmError(f"invalid index error : {str(ex)}") from ex
def remove(self, value=None, index=None, comments=""): """Removes element from vector.If value is given then first instance of element of that value is removed. If index is given instead then the element at that index is removed. If neither is given then the last element is deleted. Args: value (optional): Value of element to be deleted index (int, optional): Index of element which has to be deleted comments (str, optional): Comments for descriptive purpose. Defaults to "". Raises: ARgorithmError: Raised if both valur and index is given Example: >>> vec Vector([3, 3, 3, 3, 4, 5]) >>> vec.remove(index=3) >>> vec Vector([3, 3, 3, 4, 5]) >>> vec.remove() >>> vec Vector([3, 3, 3, 4]) >>> vec.remove(value=3) >>> vec Vector([3, 3, 4]) Note: Please make note of the position of arguments if passing positional arguments. It is recommended not to do that """ if index is None and value is None: self.body.pop() state = self.state_generator.vector_remove(self.body, len(self) - 1, comments) self.algo.add_state(state) elif value is None and 0 <= index < len(self): self.body = self.body[0:index] + self.body[index + 1:] state = self.state_generator.vector_remove(self.body, index, comments) self.algo.add_state(state) elif index is None: index = self.body.index(value) self.body.remove(value) state = self.state_generator.vector_remove(self.body, index, comments) self.algo.add_state(state) else: raise ARgorithmError( "Either give only a valid index or only value to be deleted , dont give both" )
def __init__(self, name, algo, data=None, comments=""): try: assert isinstance(name, str) self._id = str(id(self)) self.state_generator = VectorState(name, self._id) except AssertionError as e: raise ARgorithmError('Give valid name to data structure') from e try: assert isinstance(algo, StateSet) self.algo = algo except AssertionError as e: raise ARgorithmError( "vector structure needs a reference of template to store states" ) from e try: if data is None: data = [] assert isinstance(data, list) or data self.body = data except AssertionError as e: raise TypeError("vector body should be list") from e state = self.state_generator.vector_declare(self.body, comments) self.algo.add_state(state)
def front(self): """Returns the first element of list. Raises: ARgorithmError: Raised when list is empty Returns: element: The first element of list Example: >>> fl ForwardList([2, 1]) >>> fl.front() 2 """ if self.head is None: raise ARgorithmError("Empty list") return self.head.value
def __init__(self,algo:StateSet,value=None,comments=""): self.name = str(id(self)) self._id = str(id(self)) try: assert isinstance(algo,StateSet) self.algo = algo except AssertionError as e: raise ARgorithmError("algo should be of type StateSet") from e self.state_generator = LinkedListNodeState(self.name, self._id) self._flag = False self.value = value self.next = None self._flag = True state = self.state_generator.llnode_declare( self.value,self.next,comments ) self.algo.add_state(state)
def back(self): """Returns the last element of list. Raises: ARgorithmError: Raised when list is empty Returns: element: The last element of list Example: >>> lis List([2, 3, 5, 4, 4, 3, 3]) >>> lis.back() 3 >>> lis List([2, 3, 5, 4, 4, 3, 3]) """ if self.head is None: raise ARgorithmError("Empty list") return self.tail.value
def front(self): """Returns the first element of list. Raises: ARgorithmError: Raised when list is empty Returns: element: The first element of list Example: >>> lis List([1, 2, 3]) >>> lis.front() 1 >>> lis List([1, 2, 3]) """ if self.head is None: raise ARgorithmError("Empty list") return self.head.value
def check_dimensions(data): """This function is an internal function that helps verify the dimensions of array from user input. Args: data : data is a multi-dimensional list or tuple Raises: ARgorithmError: if data is not of correct format , it raises an ARgorithmError """ if not isinstance(data, list) and not isinstance(data, tuple): return 1 check = -1 try: for x in data: if check == -1: check = check_dimensions(x) else: assert check == check_dimensions(x) return len(data) except Exception as ex: raise ARgorithmError('please pass array of fixed dimensions') from ex
def remove(self, value): """Remove elements with given value from list. Args: value : The value which has to be removed Raises: ARgorithmError: Raised if list is empty Example: >>> lis List([2, 3, 5, 4, 4, 3, 3]) >>> lis.remove(3) >>> lis List([2, 5, 4, 4]) """ if self.head is None: raise ARgorithmError("Empty list") curr = self.head while curr: if curr.value == value: self.size -= 1 if self.size == 1: self.head = None self.tail = None break if curr.prev: curr.prev.next = curr.next else: self.head = curr.next self.head.prev = None if curr.next: curr.next.prev = curr.prev else: self.tail = curr.prev self.tail.next = None curr = curr.next
def remove(self, key, comments=""): """removes the key from the set Args: key (ARgorithmStructure or (int, str, float, bool)) : key to remove from the set comments (str, optional): Comments for descriptive purpose. Defaults to "". Example: >>> set1 Set({1,2,3}) >>> set1.remove(1) >>> set1 Set({2,3}) """ try: if isinstance(key, ARgorithmHashable): self.body.remove(key.to_json()) else: self.body.remove(key) self.__working_set.remove(key) state = self.state_generator.set_remove(self.body, key, comments) self.algo.add_state(state) except Exception as e: raise ARgorithmError(f"Invalid Key Error : {str(e)}") from e
def back(self, comments=""): """Returns back element of queue. Args: comments (str, optional): Comments for descriptive purpose. Defaults to "". Raises: ARgorithmError: Raised if queue is empty Returns: element: The element at back of queue Examples: >>> q Queue([4, 2, 1]) >>> q.back() 1 """ if self.empty(): raise ARgorithmError('queue is empty') item = self.body[-1] state = self.state_generator.queue_back(self.body, comments) self.algo.add_state(state) return item
def remove(self,value): """Remove elements with given value from list. Args: value : The value which has to be removed Raises: ARgorithmError: Raised if list is empty Example: >>> fl ForwardList([2, 2, 1]) >>> fl.remove(2) >>> fl ForwardList([1]) """ if self.head is None: raise ARgorithmError("Empty list") while value == self.head.value: temp = self.head self.head = self.head.next del temp self.size -= 1 if self.head is None: return curr = self.head while curr: if curr.next: if curr.next.value == value: temp = curr.next curr.next = curr.next.next del temp self.size -= 1 continue curr = curr.next
def pop_front(self): """Pops first element of forwardlist. Raises: ARgorithmError: Raised if list is empty Returns: element: The first element of list Example: >>> fl ForwardList([2, 1]) >>> fl.pop_front() 2 """ if self.head is None: raise ARgorithmError("Empty list") data = self.head.value temp = self.head self.head = self.head.next del temp self.size -= 1 return data