Пример #1
0
    def output_queue_generator(self, input_list):
        """
        Uses the shunting yard algorithm to tak a standard list of calculations
        and turn it intro a list of RPN, to be calculated
        :param input_list: a list of numbers, parentheses, operators and functions as its elements
        """
        self.output_queue = Queue()
        operator_stack = Stack()

        for elem in input_list:

            if isinstance(elem, numbers.Number):
                self.output_queue.push(elem)

            elif isinstance(elem, Function):
                operator_stack.push(elem)

            elif elem == '(':
                operator_stack.push(elem)

            elif elem == ')':
                stack_elem = operator_stack.pop()
                while stack_elem != '(':
                    self.output_queue.push(stack_elem)
                    stack_elem = operator_stack.pop()

            elif isinstance(elem, Operator):
                if not operator_stack.is_empty():
                    top = operator_stack.peek()
                    while (top is not None) and self.precedence_calculator(top, elem):
                        self.output_queue.push(operator_stack.pop())
                        if not operator_stack.is_empty():
                            top = operator_stack.peek()
                        else:
                            top = None
                operator_stack.push(elem)

        while not operator_stack.is_empty():
            item = operator_stack.pop()
            self.output_queue.push(item)
Пример #2
0
    def __init__(self, debug=False):
        self.functions = {
            'EXP': Function(np.exp),
            'LOG': Function(np.log),
            'SIN': Function(np.sin),
            'COS': Function(np.cos),
            'SQRT': Function(np.sqrt),
            'ABS': Function(np.abs)
        }

        self.constants = {'PI': math.pi, 'TAU': math.tau, 'E': math.e}

        self.operators = {
            '+': Operator(np.add, strength=0),
            '~': Operator(np.subtract, strength=0),
            '/': Operator(np.divide, strength=1),
            '*': Operator(np.multiply, strength=1),
        }

        self.output_queue = Queue()

        self.debug = debug
Пример #3
0
class Prim:
	"""Lazy implementation of Prim algorithm"""
	def __init__(self, graph):
		self.pq = MinQueue() #priority queue of edges
		self.mst = Queue()   #MST edges
		self.marked = [False] * len(graph) #MST vertices
		self.visit(graph, 0) #assuming graph is connected

		while self.pq:
			edge = self.pq.del_min() #repeatedly delete min edge from pq
			v = edge.either()
			w = edge.other(v)
			if self.marked[v] and self.marked[w]: continue #ignore if both endpoints on tree
			self.mst.enqueue(edge)
			if not self.marked[v]: self.visit(graph, v) #add v to tree
			if not self.marked[w]: self.visit(graph, w) #add w to tree

	def visit(self, graph, v):
		"""put vertex on the tree and its incident edges on priority queue"""
		self.marked[v] = True #add vertex to tree
		for edge in graph.adj(v):
			if not self.marked[edge.other(v)]:
				self.pq.insert(edge) #add w to pq if not in tree
Пример #4
0
class Kruskal:
	"""Kruskal's algorithm for minimum spanning tree"""
	mst = Queue() #mst -- a queue of edges 
	def __init__(self, graph):
		"""Kruskal's algorithm computes MST in time proportional to Elog(E)"""
		pq = MinQueue()
		for edge in graph.edges(): #build prioirty queue ~ O(E)
			pq.insert(edge)
		uf = UnionFind(len(graph))
		while pq and len(mst) < len(graph) - 1:	
			edge = pq.del_min() #delete-min ~ O(log(E))
			v = edge.either()
			w = edge.other(v)
			if not uf.connectged(v, w): #connected ~ O(log*(V))
				uf.union(v, w) #union ~ O(log*(V))
				mst.enqueue(edge)
Пример #5
0
	def has_augpath(self, graph, s, t):
		"""Breadth-first search"""
		self.edge_to = [False] * len(graph)
		self.marked = [False] * len(graph)
		q = Queue()
		q.enqueue(s)
		self.marked[s] = True

		while q:
			v = q.dequeue()
			for edge in graph.adj(v):
				w = edge.other(v)
				if edge.residual_capacity_to(w) > 0 and not self.marked[w]:
				#found path from s to w in the residual network?
					self.edge_to[w] = edge #save last edge on path to w
					self.marked[w] = True  #mark w
					q.enqueue(w)           #add w to queue

		return self.marked[t] #is t reachable from s in residual network?
Пример #6
0
class Calculator:
    """
    Takes a string input in correct format and returns an answer.
    Parsing included.
    """

    def __init__(self):
        self.functions = {
            'EXP': Function(numpy.exp),
            'LOG': Function(numpy.log),
            'SIN': Function(numpy.sin),
            'COS': Function(numpy.cos),
            'SQRT': Function(numpy.sqrt),
            'ABS': Function(numpy.abs)
        }

        self.operators = {
            'PLUSS': Operator(numpy.add, strength=0),
            'MINUS': Operator(numpy.subtract, strength=0),
            'DELE': Operator(numpy.divide, strength=1),
            'GANGE': Operator(numpy.multiply, strength=1),
        }

        # Parse text to fills this queue with RPN,
        # the evaluate_output_queue evaluates it to find answer
        self.output_queue = Queue()

    def calculate(self):
        """The running of the calculator"""
        print("Welcome to 'COOLCULATOR'.\n" +
              "Exit by pressing 'ENTER' without providing input\n" +
              "All operators are written in norwegian!\n" +
              "(E.g. '+' is written 'pluss')")
        equation = " "
        while equation != "":
            equation = input(">>> ")
            try:
                self.output_queue_generator(self.parse_string_to_list(equation))
                answer = self.evaluate_output_queue()
                print(">>>", answer)
            except IndexError:
                pass

    def evaluate_output_queue(self):
        """Evaluates the RPN in the queue"""
        stack = Stack()
        while not self.output_queue.is_empty():
            elem = self.output_queue.pop()
            if isinstance(elem, numbers.Number):
                stack.push(elem)
            elif isinstance(elem, Function):
                _input = stack.pop()
                stack.push(elem.execute(_input))
            elif isinstance(elem, Operator):
                _input_1 = stack.pop()
                _input_2 = stack.pop()
                stack.push(elem.execute(_input_2, _input_1))

        return stack.pop()

    def output_queue_generator(self, input_list):
        """
        Uses the shunting yard algorithm to tak a standard list of calculations
        and turn it intro a list of RPN, to be calculated
        :param input_list: a list of numbers, parentheses, operators and functions as its elements
        """
        self.output_queue = Queue()
        operator_stack = Stack()

        for elem in input_list:

            if isinstance(elem, numbers.Number):
                self.output_queue.push(elem)

            elif isinstance(elem, Function):
                operator_stack.push(elem)

            elif elem == '(':
                operator_stack.push(elem)

            elif elem == ')':
                stack_elem = operator_stack.pop()
                while stack_elem != '(':
                    self.output_queue.push(stack_elem)
                    stack_elem = operator_stack.pop()

            elif isinstance(elem, Operator):
                if not operator_stack.is_empty():
                    top = operator_stack.peek()
                    while (top is not None) and self.precedence_calculator(top, elem):
                        self.output_queue.push(operator_stack.pop())
                        if not operator_stack.is_empty():
                            top = operator_stack.peek()
                        else:
                            top = None
                operator_stack.push(elem)

        while not operator_stack.is_empty():
            item = operator_stack.pop()
            self.output_queue.push(item)

    def parse_string_to_list(self, input_string):
        """
        Parses string to be used in 'output_queue_generator'
        :param input_string: a user-written string to be calculated; assumed correct format
        :return: a string of numbers, functions and operators in a 'normal' syntax
        """

        # Make the string uppercase with no spaces,
        # ready for regex; re methods
        input_string = input_string.replace(" ", "").upper()

        regex_list = (
            '|'.join(
                self.functions.keys()),
            '|'.join(
                self.operators.keys()),
            r'\(',
            r'\)',
            r'\d+\.\d+',        # Positive float
            r'-\d+\.\d+',       # Negative float
            r'\d+',             # Positive integer
            r'-\d+')            # Negative integer

        regex = '|'.join(regex_list)

        # re.findall returns a list containing all matches
        matches = re.findall(regex, input_string)
        result = []
        for match in matches:
            # print(match)
            if match in self.functions.keys():
                result.append(self.functions[match])

            elif match in self.operators.keys():
                result.append(self.operators[match])

            elif match in ('(', ')'):
                result.append(match)

            else:   # It's a number or trash
                try:
                    result.append(float(match))
                except ValueError:
                    pass

        return result

    @staticmethod
    def precedence_calculator(top, elem):
        """
        :param top: top element of stack, can be function, operator, number
        :param elem: is a operator with a strength
        :return: if top has precedence over elem
        """

        if isinstance(top, (numbers.Number, Function)) or top in ('(', ')'):
            return False
        if isinstance(top, Operator):
            return top.strength > elem.strength
Пример #7
0
	def __iter__(self):
		"""Inorder traversal (depth-first traversal)"""
		self.queue = Queue()
		self._inorder(self.root, self.queue)
		return self
Пример #8
0
class BSTree:
	"""Symbol Table API"""
	def __init__(self):
		"""Initialize an empty symbol table (BST implementation)"""
		self.root = None

	def __iter__(self):
		"""Inorder traversal (depth-first traversal)"""
		self.queue = Queue()
		self._inorder(self.root, self.queue)
		return self

	def __len__(self):
		""""""
		if self.root is None:
			return 0
		else:
			return self._size(self.root) 

	def __next__(self):
		"""Return next element when looping through BST"""
		if len(self.queue) == 0:
			del self.queue
			raise StopIteration
		return self.queue.dequeue()

	def __repr__(self):
		"""How to visualize a BST???"""
		pass

	def _inorder(self, node, queue):
		"""Depth-first inorder traverse the tree"""
		if node is None:
			return
		self._inorder(node.left, queue)
		queue.enqueue(node.key)
		self._inorder(node.right, queue)

	def _size(self, node):
		"""Return the size of subtree rooted at node"""
		if node is None:
			return 0
		else:
			return node.count 

	def contains(self, key):
		"""Return True if key exists"""
		node = self.get(key)
		if node is None:
			return False
		else:
			return True

	def put(self, key, val):
		"""Put a key-value pair into the symbol table"""
		self.root = self._put(self.root, key, val)

	def _put(self, node, key, val):
		"""Depending on how the keys coming in, the BST will look different"""
		if node is None:
			return TreeNode(key, val)
		if key < node.key:
			node.left = self._put(node.left, key, val)
		elif key > node.key:
			node.right = self._put(node.right, key, val)
		else:
			node.val = val
		node.count = 1 + self._size(node.left) + self._size(node.right)
		return node

	def get(self, key):
		"""Return value paird with key"""
		node = self.root
		while node is not None:
			if key < node.key:
				node = node.left
			elif key > node.key:
				node = node.right
			else:
				return node.val 
		return None

	def delete(self, key):
		"""Delete key-value pair from the table

		Hibbard deletion
		*  no children, 
		* one children, 
		* two children, 
		"""
		self.root = self._delete(self.root, key)

	def _delete(self, node, key):
		"""Hibbard deletion workhorse function"""
		#fixme: need delete for left-leaning red-black tree
		if node is None:
		#no children
			return None

		if key < node.key:
			node.left = self._delete(node.left, key)
		elif key > node.key:
			node.right = self._delete(node.right, key)
		else:
			#one children
			if node.right is None: return node.left
			if node.left is None: return node.right

			#two children
			temp = node 
			node = self.min(node.right)
			node.right = self.delmin(temp.right)
			node.left = temp.left
		node.count = self._size(node.left) + self._size(node.right) + 1
		return node 

	def isempty(self):
		"""Return True if table is empty"""
		return len(self) == 0

	def min(self):
		"""Return the node with minimum key"""
		node = self.root
		while node.left is not None:
			node = node.left
		return node.key

	def max(self):
		"""Return the node with maximum key"""
		node = self.root
		while node.right is not None:
			node = node.right
		return node.key

	def floor(self, key):
		"""Return the largest key on BST that is less than or equal to (<=) 
		the given key
		"""
		node = self._floor(self.root, key)
		if node is None:
			return None
		return node.key

	def _floor(self, node, key):
		"""floor workhorse function"""
		if node is None:
			return None
		if key == node.key:
			return node
		if key < node.key:
			return self._floor(node.left, key)
		temp = self._floor(node.right, key)
		if temp is not None:
			return temp
		else:
			return node

	def ceiling(self, k):
		"""Return the smallest key on BST that is larger than or equal to (>=)
		the given key
		"""
		node = self._ceiling(self.root, key)
		if node is None:
			return None
		return node.key

	def _ceiling(self, node, key):
		"""ceiling workhorse function"""
		if node is None:
			return None
		if key == node.key:
			return node
		if key > node.key:
			return self._ceiling(node.right, key)
		temp = self._ceiling(node.left, key)
		if temp is not None:
			return temp
		else:
			return node 

	def rank(self, key):
		"""Return the number of keys less than (<) the given key"""
		return self._rank(self.root, key)

	def _rank(self, node, key):
		""""""
		if node is None:
			return 0
		if key < node.key:
			return self._rank(node.left, key)
		elif key > node.key:
			return 1 + self._size(node.left) + self._rank(node.right, key)
		else:
			return self._size(node.left)	

	def delmin(self):
		"""Delete the node with minimum key"""
		self.root = self._delmin(self.root)

	def _delmin(self, node):
		"""delmin workhorse function"""
		if node.left is None:
			return node.right
		node.left = self._delmin(node.left)
		node.count = 1 + self._size(node.left) + self._size(self.right)
		return node

	def delmax(self):
		"""Delete the node with maximum key"""
		self.root = self._delmax(self.root)

	def _delmax(self, node):
		"""delmax workhorse function"""
		if node.right is None:
			return node.left
		node.right = self._delmax(node.right)
		node.count = 1 + self._size(node.left) + self._size(self.right)
		return node
Пример #9
0
class Calculator():
    '''
    The calculator takes a string in the form of an equation, parses it into
    operators, operands, functions and parentheses. It then converts from infix
    to reverse polish notation and evaluates the expression.
    '''
    def __init__(self, debug=False):
        self.functions = {
            'EXP': Function(np.exp),
            'LOG': Function(np.log),
            'SIN': Function(np.sin),
            'COS': Function(np.cos),
            'SQRT': Function(np.sqrt),
            'ABS': Function(np.abs)
        }

        self.constants = {'PI': math.pi, 'TAU': math.tau, 'E': math.e}

        self.operators = {
            '+': Operator(np.add, strength=0),
            '~': Operator(np.subtract, strength=0),
            '/': Operator(np.divide, strength=1),
            '*': Operator(np.multiply, strength=1),
        }

        self.output_queue = Queue()

        self.debug = debug

    def calculate(self):
        '''
        Calculate the value of the RPN-equation stored in output_queue.
        '''
        stack = Stack()
        while not self.output_queue.is_empty():
            elem = self.output_queue.pop()

            if isinstance(elem, numbers.Number):
                stack.push(elem)

            if isinstance(elem, Function):
                _input = stack.pop()
                stack.push(elem.execute(_input))

            if isinstance(elem, Operator):
                _second = stack.pop()
                _first = stack.pop()
                stack.push(elem.execute(_first, _second))
        return stack.pop()

    def generate_output_queue(self, input_list):
        '''
        Converts a list of operators, functions, operands, constants and
        parentheses from infix notation to reverse polish notation using the
        shunting-yard algorithm
        '''
        def operator_precedence(top, elem):
            '''
            Function to determine wether to pop from op_stack
            '''
            precedence = False
            precedence |= isinstance(top, Function)
            if isinstance(top, Operator):
                precedence |= top.strength >= elem.strength
            precedence &= top != '('

            return precedence

        self.output_queue = Queue()
        op_stack = Stack()

        for elem in input_list:
            if isinstance(elem, numbers.Number):
                self.output_queue.push(elem)

            if isinstance(elem, Function):
                op_stack.push(elem)

            if isinstance(elem, Operator):
                if not op_stack.is_empty():
                    top = op_stack.peek()
                    while top is not None and operator_precedence(top, elem):
                        self.output_queue.push(op_stack.pop())
                        if not op_stack.is_empty():
                            top = op_stack.peek()
                        else:
                            top = None
                op_stack.push(elem)

            if elem == '(':
                op_stack.push(elem)

            if elem == ')':
                next_op = op_stack.pop()
                while next_op != '(':
                    self.output_queue.push(next_op)
                    next_op = op_stack.pop()

        while not op_stack.is_empty():
            elem = op_stack.pop()
            self.output_queue.push(elem)

        if self.debug:
            print(f'\nParsed string: {input_list}')
            print(f'Output queue:  {self.output_queue._items}\n')

    def parse_string_to_list(self, input_str):
        '''
        Parse input_str into a list of operators, operands, parentheses,
        constants and functions, using regular expressions. Then substitute the
        functions and operators found with their corresponding wrapper object.
        Strings in the form of positive or negative integers/floats are
        converted to float.
        '''

        re_parts = (
            r'-?\d+\.\d+',  # Floating point numbers
            r'-?\d+',  # Integers
            r'\(|\)',  # Parentheses
            r'\+|\~|\*|/|',  # Operators
            '|'.join(self.functions.keys()),  # Functions
            '|'.join(self.constants.keys()),  # Constants
        )

        regex = '|'.join(re_parts)

        # re.findall preserves the order of the matches
        matches = re.findall(regex, input_str.upper())

        result = []
        for match in matches:
            # Function
            if match in self.functions.keys():
                result += [self.functions[match]]

            # Operator
            elif match in self.operators.keys():
                result += [self.operators[match]]

            # Constants
            elif match in self.constants.keys():
                result += [self.constants[match]]

            # Parentheses
            elif match in ('(', ')'):
                result += [match]

            # Probably a number
            else:
                try:
                    result += [float(match)]
                except ValueError:
                    pass

        return result